同一个工程之前使用的ncnn版本记得不太清楚了,貌似是下面两个版本中的一个
20170919和20171017,当时mat.data的类型还是float * ;
前两天更新了ncnn的版本,自己编译的libncnn.a文件;发现之前的模型用了之后检测结果不对,做了几个实验,用了 caffe的模型 转为ncnn模型:
1.正确的结果
操作方式:旧版的ncnn,使用相对版本的caffe2ncnn直接转换caffe模型,得出正确的结果
2.错误结果a
操作方式:最新代码编译出来ncnn库,以及相对应的caffe2ncnn工具转换直接转换"caffe的模型",最后跑出来的结果与 1 中结果不一致;
3.错误结果b
操作方式:最新代码编译出来ncnn库,使用caffe的工具升级caffer模型,即下面命令升级caffe
upgrade_net_proto_text [old prototxt] [new prototxt]
upgrade_net_proto_binary [old caffemodel] [new caffemodel]
然后用相对应的caffe2ncnn工具转换直接转换 "升级后的caffe的模型",最后跑出来的结果与 1 中结果不一致;而且是pnet的forward结果不一样;
现象:
3中pnet的forward结果的shape与 1中pnet的forward结果的shape是一样的;
但是当我遍历打印mat的值时,发现其中的值都是不一样的
打印的代码:
vector<FaceDetector::BBox> FaceDetector::Detect(ncnn::Mat &img_, const IMAGE_DIRECTION orient,
int min_size, float scale_factor) {
vector<BBox> finalBbox_;
img = img_;
img_w = img.w;
img_h = img.h;
img.substract_mean_normalize(mean_vals, norm_vals);
//当时这里min_size是考虑到最小人脸多小不去做识别,优化速度来考虑的,给的40
float minl = img_w < img_h ? img_w : img_h;
int MIN_DET_SIZE = 12;
float m = (float) MIN_DET_SIZE / min_size;
minl *= m;
float factor = scale_factor;
int factor_count = 0;
vector<float> scales_;
while (minl > MIN_DET_SIZE) {
if (factor_count > 0)m = m * factor;
scales_.push_back(m);
minl *= factor;
factor_count++;
}
OrderScore order;
int count = 0;
for (size_t i = 0; i < scales_.size(); i++) {
int hs = (int) ceil(img_h * scales_[i]);
int ws = (int) ceil(img_w * scales_[i]);
ncnn::Mat in;
resize_bilinear(img_, in, ws, hs);
ncnn::Extractor ex = pnet.create_extractor();
ex.set_light_mode(true);
ex.set_num_threads(OMP_NUM);
ex.input("data", in);
ncnn::Mat score_, location_;
ex.extract("prob1", score_);
ex.extract("conv4-2", location_);
LOGI("first score_.shape=( %d, %d, %d) location_.shape=( %d, %d, %d)\n",score_.h,score_.w, score_.c, location_.h,location_.w, location_.c);
std::vector<BBox> boundingBox_;
std::vector<OrderScore> bboxScore_;
generateBBox(score_, location_, boundingBox_, bboxScore_, scales_[i]);
// LOGI("first %d boundingBox_.size=%d\n",i, boundingBox_.size());
nms_cpu(boundingBox_, bboxScore_, nms_threshold[0], UNION);
for (vector<BBox>::iterator it = boundingBox_.begin(); it != boundingBox_.end(); it++) {
if ((*it).exist) {
firstBbox_.push_back(*it);
order.score = (*it).score;
order.oriOrder = count;
firstOrderScore_.push_back(order);
count++;
}
}
bboxScore_.clear();
boundingBox_.clear();
}
//the first stage's nms
if (count < 1)return finalBbox_;
nms_cpu(firstBbox_, firstOrderScore_, nms_threshold[1], UNION);
refineAndSquareBbox(firstBbox_, img_h, img_w);
LOGE("firstBbox_.size()=%d\n", firstBbox_.size());
....
//second statge
......
}
void FaceDetector::generateBBox(ncnn::Mat score, ncnn::Mat location, vector<BBox> &boundingBox_,
vector<OrderScore> &bboxScore_, float scale) {
int stride = 2;
int cellsize = 12;
int count = 0;
//score p
float *p = score.channel(1);
float *q = score.channel(0);
// float *plocal = location.data;
float *l0 = location.channel(0);
float *l1 = location.channel(0);
float *l2 = location.channel(0);
float *l3 = location.channel(0);
LOGI("cxy ==============localtion");
for(int i=0; i< location.h; i++) {
for (int j = 0; j < location.w; j++) {
LOGI("cxy *l0=%f *l1=%f *l2=%f *l3=%f",*l0, *l1, *l2, *l3);
l0++; l1++; l2++; l3++;
}
}
LOGI("cxy ==============score");
BBox bbox;
OrderScore order;
for (int row = 0; row < score.h; row++) {
for (int col = 0; col < score.w; col++) {
LOGI("cxy *p=%f *q=%f",*p, *q);
if (*p > threshold[0]) {
bbox.score = *p;
order.score = *p;
order.oriOrder = count;
bbox.x1 = round((stride * col + 1) / scale);
bbox.y1 = round((stride * row + 1) / scale);
bbox.x2 = round((stride * col + 1 + cellsize) / scale);
bbox.y2 = round((stride * row + 1 + cellsize) / scale);
bbox.exist = true;
bbox.area = (bbox.x2 - bbox.x1) * (bbox.y2 - bbox.y1);
for (int channel = 0; channel < 4; channel++)
bbox.regreCoord[channel] = ((float *) location.channel(channel))[0];
boundingBox_.push_back(bbox);
bboxScore_.push_back(order);
count++;
}
p++;
q++;
// plocal++;
}
}
}
步骤1打印的结果:
02-09 16:40:27.149 7237-7725/com.wx.album.demo I/FaceDetectActivity: 5 (r,g,b,a)=(-113,87,-122,-1)
02-09 16:40:27.149 7237-7725/com.wx.album.demo I/FaceDetectActivity: ---5 (r,g,b,a)=(6e7776ff)
02-09 16:40:27.149 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: data length=393216
02-09 16:40:27.149 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: native Detect----width*height=256*384
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: first score_.shape=( 53, 34, 2) location_.shape=( 53, 34, 4)
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy ==============localtion
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.010091 *l1=-0.010091 *l2=-0.010091 *l3=-0.010091
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.034791 *l1=-0.034791 *l2=-0.034791 *l3=-0.034791
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.017588 *l1=-0.017588 *l2=-0.017588 *l3=-0.017588
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.013194 *l1=-0.013194 *l2=-0.013194 *l3=-0.013194
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.008050 *l1=-0.008050 *l2=-0.008050 *l3=-0.008050
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.018748 *l1=-0.018748 *l2=-0.018748 *l3=-0.018748
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.054014 *l1=-0.054014 *l2=-0.054014 *l3=-0.054014
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.099514 *l1=-0.099514 *l2=-0.099514 *l3=-0.099514
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.115605 *l1=-0.115605 *l2=-0.115605 *l3=-0.115605
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.056714 *l1=-0.056714 *l2=-0.056714 *l3=-0.056714
步骤3打印的结果:
02-09 16:53:27.621 14330-19685/com.wx.album.demo I/FaceDetectActivity: 5 (r,g,b,a)=(-113,87,-122,-1)
02-09 16:53:27.621 14330-19685/com.wx.album.demo I/FaceDetectActivity: ---5 (r,g,b,a)=(6e7776ff)
02-09 16:53:27.621 14330-19685/com.wx.album.demo I/WX_FACE_DETECT_JNI: data length=393216
02-09 16:53:27.621 14330-19685/com.wx.album.demo I/WX_FACE_DETECT_JNI: native Detect----width*height=256*384
02-09 16:53:27.645 14330-19685/com.wx.album.demo I/WX_FACE_DETECT_JNI: first score_.shape=( 53, 34, 2) location_.shape=( 53, 34, 4)
02-09 16:53:27.645 14330-19685/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy ==============localtion
02-09 16:53:27.645 14330-19685/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.064085 *l1=0.064085 *l2=0.064085 *l3=0.064085
02-09 16:53:27.646 14330-19685/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.066753 *l1=0.066753 *l2=0.066753 *l3=0.066753
02-09 16:53:27.646 14330-19685/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.069597 *l1=0.069597 *l2=0.069597 *l3=0.069597
02-09 16:53:27.646 14330-19685/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.013377 *l1=0.013377 *l2=0.013377 *l3=0.013377
02-09 16:53:27.646 14330-19685/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.000714 *l1=-0.000714 *l2=-0.000714 *l3=-0.000714
02-09 16:53:27.646 14330-19685/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.019337 *l1=-0.019337 *l2=-0.019337 *l3=-0.019337
02-09 16:53:27.646 14330-19685/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.025768 *l1=-0.025768 *l2=-0.025768 *l3=-0.025768
02-09 16:53:27.646 14330-19685/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.047746 *l1=-0.047746 *l2=-0.047746 *l3=-0.047746
02-09 16:53:27.646 14330-19685/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.007314 *l1=-0.007314 *l2=-0.007314 *l3=-0.007314
02-09 16:53:27.646 14330-19685/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.062976 *l1=0.062976 *l2=0.062976 *l3=0.062976
还请楼主帮忙看看什么情况? 谢谢
pnet 的输出依然使用 out.channel(i)
rnet 和 onet 输出 *(out.data + out.cstep * i) 改为 out[i]
github上原始MTCNN是matlab训练的 col-major 模型,所以结果不正确
https://github.com/Tencent/ncnn/wiki/FAQ-ncnn-produce-wrong-result
嗯嗯,刚刚测试了下,确实是那个原因,我已经按照楼主说的做了测试,但是还是发现结果有点差异,最后pnet, rnet,onet的找到的bindingBox数量虽然与之前老版本中的数量一致;
但是发现找到的人脸不准,仔细查看了下forward的结果,发现有细微差别
原来正确的结果:
02-09 16:40:27.149 7237-7725/com.wx.album.demo I/FaceDetectActivity: 5 (r,g,b,a)=(-113,87,-122,-1)
02-09 16:40:27.149 7237-7725/com.wx.album.demo I/FaceDetectActivity: ---5 (r,g,b,a)=(6e7776ff)
02-09 16:40:27.149 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: data length=393216
02-09 16:40:27.149 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: native Detect----width*height=256*384
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: first score_.shape=( 53, 34, 2) location_.shape=( 53, 34, 4)
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy ==============localtion
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.010091 *l1=-0.010091 *l2=-0.010091 *l3=-0.010091
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.034791 *l1=-0.034791 *l2=-0.034791 *l3=-0.034791
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.017588 *l1=-0.017588 *l2=-0.017588 *l3=-0.017588
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.013194 *l1=-0.013194 *l2=-0.013194 *l3=-0.013194
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.008050 *l1=-0.008050 *l2=-0.008050 *l3=-0.008050
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.018748 *l1=-0.018748 *l2=-0.018748 *l3=-0.018748
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.054014 *l1=-0.054014 *l2=-0.054014 *l3=-0.054014
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.099514 *l1=-0.099514 *l2=-0.099514 *l3=-0.099514
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.115605 *l1=-0.115605 *l2=-0.115605 *l3=-0.115605
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.056714 *l1=-0.056714 *l2=-0.056714 *l3=-0.056714
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.039420 *l1=0.039420 *l2=0.039420 *l3=0.039420
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.165425 *l1=0.165425 *l2=0.165425 *l3=0.165425
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.146497 *l1=0.146497 *l2=0.146497 *l3=0.146497
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.062257 *l1=0.062257 *l2=0.062257 *l3=0.062257
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.105753 *l1=0.105753 *l2=0.105753 *l3=0.105753
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.091465 *l1=0.091465 *l2=0.091465 *l3=0.091465
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.105839 *l1=0.105839 *l2=0.105839 *l3=0.105839
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.087600 *l1=0.087600 *l2=0.087600 *l3=0.087600
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.123140 *l1=0.123140 *l2=0.123140 *l3=0.123140
02-09 16:40:27.174 7237-7725/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.058920 *l1=0.058920 *l2=0.058920 *l3=0.058920
找不到人脸的结果:
02-09 19:59:56.944 20946-21405/com.wx.album.demo I/FaceDetectActivity: 5 (r,g,b,a)=(-113,87,-122,-1)
02-09 19:59:56.944 20946-21405/com.wx.album.demo I/FaceDetectActivity: ---5 (r,g,b,a)=(6e7776ff)
02-09 19:59:56.944 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: data length=393216
02-09 19:59:56.944 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: native Detect----width*height=256*384
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: first score_.shape=( 53, 34, 2) location_.shape=( 53, 34, 4)
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy ==============localtion
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.010091 *l1=-0.010091 *l2=-0.010091 *l3=-0.010091
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.034791 *l1=-0.034791 *l2=-0.034791 *l3=-0.034791
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.017589 *l1=-0.017589 *l2=-0.017589 *l3=-0.017589
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.013194 *l1=-0.013194 *l2=-0.013194 *l3=-0.013194
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.008050 *l1=-0.008050 *l2=-0.008050 *l3=-0.008050
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.018748 *l1=-0.018748 *l2=-0.018748 *l3=-0.018748
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.054014 *l1=-0.054014 *l2=-0.054014 *l3=-0.054014
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.099514 *l1=-0.099514 *l2=-0.099514 *l3=-0.099514
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.115604 *l1=-0.115604 *l2=-0.115604 *l3=-0.115604
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=-0.056714 *l1=-0.056714 *l2=-0.056714 *l3=-0.056714
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.039420 *l1=0.039420 *l2=0.039420 *l3=0.039420
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.165425 *l1=0.165425 *l2=0.165425 *l3=0.165425
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.146497 *l1=0.146497 *l2=0.146497 *l3=0.146497
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.062257 *l1=0.062257 *l2=0.062257 *l3=0.062257
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.105753 *l1=0.105753 *l2=0.105753 *l3=0.105753
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.091465 *l1=0.091465 *l2=0.091465 *l3=0.091465
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.105839 *l1=0.105839 *l2=0.105839 *l3=0.105839
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.087600 *l1=0.087600 *l2=0.087600 *l3=0.087600
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.123140 *l1=0.123140 *l2=0.123140 *l3=0.123140
02-09 19:59:56.966 20946-21405/com.wx.album.demo I/WX_FACE_DETECT_JNI: cxy *l0=0.058920 *l1=0.058920 *l2=0.058920 *l3=0.058920
不知道是不是这个原因导致最后的输出结果不准确
caffe2ncnn_mtcnn.cpp.txt
已经按照楼主所说方式改了下面pnet,rnet,onet的取值方式
pnet 的输出依然使用 out.channel(i)
rnet 和 onet 输出 *(out.data + out.cstep * i) 改为 out[i]
另外我用的模型是 ElegantGod作者提供的 ;之前正确的模型貌似也是这个,而且也参照了工程里面的代码caffe2ncnn_mtcnn.cpp mergy到最新的caffe2ncnn.cpp中,修改后的文件参照附件caffe2ncnn_mtcnn.cpp.txt
今天又仔细检测了下代码,确实是自己没改完全,我后面的rnet和onet取结果方式没改过来,抱歉!
不过还是有点不明白
为什么
pnet 的输出依然使用 out.channel(i)
rnet 和 onet 输出 *(out.data + out.cstep * i) 改为 out[i]
@cxy200927099 你好 ,我下载了最新的ncnn,使用了你提供的caffe2ncnn_mtcnn.cpp.txt转换工具
代码修改了rnet onet如下
if(score.channel(1)[0] > threshold[2]) 修改为 if(score[0] > threshold[2])
it->regreCoord[channel]=bbox.channel(channel)[0]; 修改为 it->regreCoord[channel]=bbox[channel];
结果人脸框个数和之前ElegantGod作者提供的是一样的,但是位置不对。是我代码还没改完吗?
mtcnn代码更新新的ncnn后,在ncnn::Mat类型的赋值, img = img_ 出现错误是什么原因?
你好,想请问下你pnet的预测结果是怎么解析的
Most helpful comment
今天又仔细检测了下代码,确实是自己没改完全,我后面的rnet和onet取结果方式没改过来,抱歉!
不过还是有点不明白
为什么
pnet 的输出依然使用 out.channel(i)
rnet 和 onet 输出 *(out.data + out.cstep * i) 改为 out[i]