版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1338326
问题来源 How does MTCNN perform vs DLIB for face detection?
前面一直做人脸检测相关内容,然后对比了下dib以及MTCNN的人脸检测效果主要是速度,以及FDDB准确率。最后给出生成FDDB测试文件的C++代码。
注本文的MTCNN效果检测准确率不是最优的,最优的在FDDB上可达95%,测试效果如下:
可以看到三种方法:
dlib的作者非要说我的测试有问题,如果谁感兴趣可以使用dlib测试下FDDB的结果。
在CPU和GPU模式下,对于三种不同尺寸的图片,运行一千次测试平均的时效:
MTCNN(既检测人脸又做landmark):
dlib (仅仅检测人脸):
MTCNN(既检测人脸又做landmark):
dlib (仅仅检测人脸):
可以看到:
dlib c++生成FDDB结果代码如下(至于怎么使用FDDB测试可见前面blog,有py实现)或者我的stackoverflow回答:
#include <iostream>
#include <dlib/dnn.h>
#include <dlib/data_io.h>
#include <dlib/image_processing.h>
#include <dlib/gui_widgets.h>
using namespace std;
using namespace dlib;
// ----------------------------------------------------------------------------------------
template <long num_filters, typename SUBNET> using con5d = con<num_filters,5,5,2,2,SUBNET>;
template <long num_filters, typename SUBNET> using con5 = con<num_filters,5,5,1,1,SUBNET>;
template <typename SUBNET> using downsampler = relu<affine<con5d<32, relu<affine<con5d<32, relu<affine<con5d<16,SUBNET>>>>>>>>>;
template <typename SUBNET> using rcon5 = relu<affine<con5<45,SUBNET>>>;
using net_type = loss_mmod<con<1,9,9,1,1,rcon5<rcon5<rcon5<downsampler<input_rgb_image_pyramid<pyramid_down<6>>>>>>>>;
// ----------------------------------------------------------------------------------------
void getAllImgPaths(const std::string& file, std::vector<std::string>& vecPaths){
std::fstream fStream(file);
std::string sLine;
while (std::getline(fStream, sLine)){
if (sLine.size() > 0){
vecPaths.emplace_back(sLine);
}
}
fStream.close();
}
void writeStrVecToFile(const std::string& file, const std::vector<std::string>& vecStr){
std::ofstream fout(file);
for (auto const& x:vecStr){
fout<<x<<'\n';
}
fout.close();
}
int main(){
std::string fPath = "/home/xy/face_sample/evaluation/compareROC/FDDB-folds/filePath.txt";
std::vector<std::string> vecImgPaths;
getAllImgPaths(fPath, vecImgPaths);
std::string imgBaseDir = "/home/xy/face_sample/evaluation/compareROC/originalPics/";
std::vector<std::string> vecDetRet;
string model_path = "/home/xy/anaconda2/lib/python2.7/site-packages/face_recognition_models/models/mmod_human_face_detector.dat";
net_type net;
deserialize(model_path) >> net;
for (auto const& img_name:vecImgPaths){
std::string imgFullPath = imgBaseDir + img_name + ".jpg";
matrix<rgb_pixel> img;
load_image(img, imgFullPath);
auto dets = net(img);
vecDetRet.push_back(img_name);
vecDetRet.push_back(std::to_string(dets.size()));
for (auto det:dets){
using std::to_string;
// sFaceInfo like 49 55 193 193 0.999784
std::string sFaceInfo = to_string(det.rect.left()) + " " + to_string(det.rect.top()) + " " +
to_string(det.rect.width()) + " " + to_string(det.rect.height()) + " " + to_string(1);
std::cout<<sFaceInfo<<std::endl;
vecDetRet.push_back(sFaceInfo);
}
}
// write face detect result to txt file for fddb compare
std::string fddbTxtPath = "fddb_ret.txt";
writeStrVecToFile(fddbTxtPath, vecDetRet);
}