人脸检测库函数的效果比较

来源:互联网 发布:mac模拟人生中文 编辑:程序博客网 时间:2024/06/07 22:14

年前在OpenCV论坛上看到Shiqi Yu发布的免费的高性能的人脸检测库,于是down下来做了一下效果测试。感兴趣的同学,也可以做一下检测速度的比较。
本人才疏学浅,只是将它与OpenCV自带的人脸检测库函数做了一个粗浅的比较,欢迎各位大神提点。


程序功能简介:

程序实现环境:VS2010 + OpenCV 2.4.11
程序退出:在窗口中敲击回车键即可;
旋转图像:鼠标拖动窗口中的Angle轴滑块即可;
缩放图像:鼠标拖动窗口中的Scale轴滑块即可;
平移图像:在窗口中任意位置,鼠标左键拖拽图像即可;
平移图像后复原:在窗口中任意位置,单击鼠标右键即可;
切换人脸检测库函数:鼠标拖动窗口中的Mode轴滑块即可。

对于Mode值的说明:

  • 0Mode4时,检测函数采用的是OpenCV自带的级联检测模块CascadeClassifier(如何使用级联分类器做人脸检测,可以参见OpenCV的Tutorial,这里有相应的中文翻译版)。具体说明如下:

当mode=0时,加载的是lbpcascade_frontalface.xml;
当mode=1时,加载的是haarcascade_frontalface_alt.xml;
当mode=2时,加载的是haarcascade_frontalface_alt2.xml;
当mode=3时,加载的是haarcascade_frontalface_default.xml;
当mode=4时,加载的是haarcascade_frontalface_alt_tree.xml;

  • 5Mode8时,检测函数采用的是Shiqi Yu发布的[免费的高性能的人脸检测库](使用方法可参见它自带的示例程序)。具体说明如下:

当mode=5时,调用的是facedetect_frontal();
当mode=6时,调用的是facedetect_frontal_surveillance();
当mode=7时,调用的是facedetect_multiview();
当mode=8时,调用的是facedetect_multiview_reinforce();


程序代码:

#include <time.h>#include <stdio.h>#include <vector>#include <iostream>#include <opencv.hpp>#include "facedetect-dll.h"using namespace cv;using namespace std;#pragma comment(lib,"libfacedetect.lib")//#pragma comment(lib,"libfacedetect-x64.lib")//Do not change the buffer size!#define DETECT_BUFFER_SIZE 0xC004static Mat onRot(int pos, int rat, Mat* im);static Mat onAffine(Mat* im, Point2f dif);static void onMouse(int Event, int x, int y, int drag, Mat* im);static int Detect_Display(Mat& im, int mod);void main(int argc, char* argv[]){    cout<<"Hello, VS10. I'm back!"<<endl;    Mat Pic = imread("Friends2.jpg"), Cam(Pic), dst;    namedWindow("Video");   int pos = 36, rat = 10, mod = 0;    createTrackbar("Angle","Video", &pos,72);    createTrackbar("Scale","Video", &rat,40);    createTrackbar("Mode","Video", &mod,8);    setMouseCallback("Video", (MouseCallback)onMouse, &Cam);    //VideoCapture cap(0);    while((waitKey(100)&255)!=13) //Enter=13    {        dst = onRot(pos, rat, &Cam);        Detect_Display(dst, mod);        imshow("Video", dst);    }//end while}//end mainstatic int Detect_Display(Mat& im, int mod){    Mat gray;   cvtColor(im, gray, CV_BGR2GRAY); //must gray    vector<Rect> faces, eyes;   equalizeHist(gray, gray); //normalization    int *pResults = NULL; //!!! DO NOT RELEASE pResults !!!    //pBuffer is used in the facedetect_XXX functions:    unsigned char* pBuffer = (unsigned char*)malloc(DETECT_BUFFER_SIZE);    if(!pBuffer)    {fprintf(stderr, "Can not alloc buffer.\n");    return 0;}    CascadeClassifier Eyes("haarcascade_eye_tree_eyeglasses.xml"), Face;    switch(mod)    {    case 0: if(!Face.load("lbpcascade_frontalface.xml"))    return 0;        Face.detectMultiScale(gray, faces, 1.1, 2, CV_HAAR_SCALE_IMAGE|0, Size(30,30)); break;    case 1: if(!Face.load("haarcascade_frontalface_alt.xml"))   return 0;        Face.detectMultiScale(gray, faces, 1.1, 2, CV_HAAR_SCALE_IMAGE|0, Size(30,30)); break;    case 2: if(!Face.load("haarcascade_frontalface_alt2.xml"))  return 0;        Face.detectMultiScale(gray, faces, 1.1, 2, CV_HAAR_SCALE_IMAGE|0, Size(30,30)); break;    case 3: if(!Face.load("haarcascade_frontalface_default.xml"))   return 0;        Face.detectMultiScale(gray, faces, 1.1, 2, CV_HAAR_SCALE_IMAGE|0, Size(30,30)); break;    case 4: if(!Face.load("haarcascade_frontalface_alt_tree.xml"))  return 0;        Face.detectMultiScale(gray, faces, 1.1, 2, CV_HAAR_SCALE_IMAGE|0, Size(30,30)); break;    //frontal face detection: it's fast, but cannot detect side view faces.    case 5: pResults = facedetect_frontal(pBuffer, (unsigned char*)(gray.ptr(0)),                                  gray.cols, gray.rows, (int)gray.step, 1.2f, 2, 48);   break;    //frontal face detection for video surveillance: it can detect faces with bad illumination.    case 6: pResults = facedetect_frontal_surveillance(pBuffer, (unsigned char*)(gray.ptr(0)),                                  gray.cols, gray.rows, (int)gray.step, 1.2f, 2, 48);   break;    //multiview face detection: it can detect side view faces, but slower than facedetect_frontal().    case 7: pResults = facedetect_multiview(pBuffer, (unsigned char*)(gray.ptr(0)),                                  gray.cols, gray.rows, (int)gray.step, 1.2f, 2, 48);   break;    //reinforced multiview face detection: it's better but slower than facedetect_multiview().    case 8: pResults = facedetect_multiview_reinforce(pBuffer, (unsigned char*)(gray.ptr(0)),                                  gray.cols, gray.rows, (int)gray.step, 1.2f, 2, 48);   break;    }//end switch    if(mod>4)   faces.resize(pResults?(*pResults):0); //for facedetect_XXX functions    cout<<faces.size()<<" faces detected!\n";    for(int i=0; i<faces.size(); ++i) //mark each face    {        if(mod>4) //for facedetect_XXX functions        {   short* p = ((short*)(pResults+1)) + 6*i;            faces[i].x = p[0];  faces[i].width = p[2];            faces[i].y = p[1];  faces[i].height = p[3];            cout<<"face_rect = "<<faces[i]<<", neighbors = "<<p[4]<<".\n";        }//end if        rectangle(im, faces[i], Scalar(255,0,255), 2); //mark with rectangle        Mat faceROI = gray(faces[i]); //In each face, detect eyes        Eyes.detectMultiScale(faceROI, eyes, 1.1, 2, CV_HAAR_SCALE_IMAGE|0, Size(30,30));        for(int j=0; j<eyes.size(); ++j) //mark each eye        {            Point center(faces[i].x + eyes[j].x + eyes[j].width*0.5, faces[i].y + eyes[j].y + eyes[j].height*0.5);            int radius = cvRound((eyes[j].width + eyes[j].height)/4);            circle(im, center, radius, Scalar(255,0,0), 2); //mark with circle        }//end for    }//end for    free(pBuffer);  return faces.size(); //release pBuffer}//end Detect_Displaystatic Mat onRot(int pos, int rat, Mat* im){    Point center(im->cols/2, im->rows/2);    double angle = 5*pos-180, scale = 0.1*rat;    Mat rot = getRotationMatrix2D(center, angle, scale), dst;    warpAffine(*im, dst, rot, im->size());  return dst;}//end onRotstatic void onMouse(int Event, int x, int y, int drag, Mat* im){ //only effective for Picture, not fit for Cam.    static Mat res = im->clone();   static const Point ini(0,0);    static Point seed(ini), tdf(ini);   Point now(x,y);    switch(Event)    {    case CV_EVENT_LBUTTONDOWN:  seed = now; break;    case CV_EVENT_LBUTTONUP:    tdf += (now-seed);  break;    case CV_EVENT_RBUTTONUP:    res.copyTo(*im);    tdf = ini;  break;    }//end switch    if(drag==CV_EVENT_FLAG_LBUTTON) *im = onAffine(&res, tdf+(now-seed));}//end onMousestatic Mat onAffine(Mat* im, Point2f dif){    Point2f org[3],tri[3];  org[1] = Point2f(im->cols/2, 0);    org[0] = Point2f(0,0);  org[2] = Point2f(0, im->rows/2);    for(int i=0; i<3; ++i)  tri[i] = org[i] + dif;    Mat warp = getAffineTransform(org, tri), dst;    warpAffine(*im, dst, warp, im->size()); return dst;}//end onAffine

程序效果图:

mode=0
mode=0


mode=1
mode=1


mode=2
mode=2


mode=3
mode=3


mode=4
mode=4


mode=5
mode=5


mode=6
mode=6


mode=7
mode=7


mode=8
mode=8

1 0
原创粉丝点击