测试pico在lfw上的检测率。
lfw给定的文件格式:
每个名称文件夹下有一张或多张图片。
#include "io.h" std::vector<std::string> list_folders(std::string pathname) { std::vector<std::string> folders; _finddata_t folder; std::string findpath = pathname + "\\*"; long handle = _findfirst(findpath.c_str(),&folder); if(handle == -1) { std::cerr << "no such path" << std::endl; system("pause"); exit(-1); } do { if(folder.attrib & _A_SUBDIR) { if( (strcmp(folder.name, ".") != 0) && (strcmp(folder.name, "..") != 0) ) { std::string newpath = pathname + "\\" + folder.name; folders.push_back(newpath); } } }while( _findnext(handle, &folder) == 0 ); return folders; } std::vector<std::string> list_files(std::string pathname) { std::vector<std::string> files; _finddata_t file; std::string findpath = pathname + "\\*"; long handle = _findfirst(findpath.c_str(),&file); if(handle == -1) { std::cerr << "no such path" << std::endl; system("pause"); exit(-1); } do { if(!(file.attrib & _A_SUBDIR)) { files.push_back(pathname + "\\" + file.name); } }while( _findnext(handle, &file) == 0 ); return files; }这是大爷给我的代码,list_folders(),遍历给定路径下的文件夹。list_files(),遍历给定路径下的文件。
在此基础上:
std::string root = "C:\\Users\\zhuqian\\Desktop\\pico_face_detect\\lfw\\lfw"; std::vector<std::string> all = list_folders(root); for (std::vector<std::string>::const_iterator it = all.begin(); it!=all.end();++it) { //std::cout << *it << std::endl; std::vector<std::string> filename = list_files(*it); for (std::vector<std::string>::const_iterator subit = filename.begin();subit!=filename.end(); ++subit) { IplImage* img; allface += 1; // img = cvLoadImage(subit->c_str(), CV_LOAD_IMAGE_COLOR); if(!img) { printf("# cannot load image from '%s'\n", subit->c_str()); return 0; } process_image(img, 1, *it); cvReleaseImage(&img); } } std::cout << "lossdect: " << lossdect << std::endl; std::cout << "falsedect: " << falsedect << std::endl; std::cout << "allface" << allface << std::endl; std::cout << "lossdectRate: " << (double)lossdect/allface << std::endl; std::cout << "facedectRate: " << (double)falsedect/allface << std::endl;其中调用的void process_image(IplImage* frame, int draw, const std::string& path)修改如下:
if(draw) for(i=0; i<ndetections; ++i) if(qs[i]>=qthreshold) // check the confidence threshold { /*cv::Rect r1(cs[i]-ss[i]/2, rs[i]-ss[i]/2, ss[i], ss[i]); //矩阵标记 cv::Mat img(frame,0); //IplImage转Mat cv::Mat face(img(r1));*/ //取矩阵 //std::stringstream s; //s << i; //int转string的方法之一 //cv::imwrite(path + "result_" + s.str() + ".jpg", face); cvCircle(frame, cvPoint(cs[i], rs[i]), ss[i]/2, CV_RGB(255, 0, 0), 4, 8, 0); // we draw circles here since height-to-width ratio of the detected face regions is 1.0f } static int nnn=0; std::stringstream s; s << nnn++; if (ndetections==0) //记录误检漏检率,并在项目路径下写检测后的图片,便于人眼观察。 { cv::imwrite("lossdect" + s.str() + ".jpg", cv::Mat(frame,0)); lossdect += 1; } if (ndetections>1) { falsedect += ndetections-1; std::cout << path << std::endl; cv::imwrite("falsedect" + s.str() + ".jpg", cv::Mat(frame,0)); } else { cv::imwrite("right" + s.str() + ".jpg", cv::Mat(frame,0)); } // if the `verbose` flag is set, print the results to standard output if(verbose) { // for(i=0; i<ndetections; ++i) if(qs[i]>=qthreshold) // check the confidence threshold printf("%d %d %d %f\n", (int)rs[i], (int)cs[i], (int)ss[i], qs[i]); // //printf("# %f\n", 1000.0f*t); // use '#' to ignore this line when parsing the output of the program }结果:
样本:13233. 漏检84. 误检150. (漏检率:0.6%,误检率:1.1%)
还有参数设置,如果参数能够根据样本中人脸的大小(先验知识)作相应修改,效果会更好。