flandmark人脸检测库的用法

来源:互联网 发布:java生成六位验证码 编辑:程序博客网 时间:2024/05/29 02:32

之前用dlib库检测人脸的68个特征点,虽然特征点比较准确,但如果被检测图片比较大,效率就比较低。而且脸部模型数据文件shape_predictor_68_face_landmarks.dat有95MB太大了。

后来发现flandmark这样一个轻量级的人脸检测库,大概只有5MB左右。检测的特征点少一些,只有8个。不过如果作一般用途,这8个点足够了。下面简单贴出相关代码。
主要参考来自于:http://cmp.felk.cvut.cz/~uricamic/flandmark/

下载的包里有例子,我作了一些修改,libflandmark也在里面。

声明所需的变量

#include "libflandmark/flandmark_detector.h"/**    5   1    2   6***          0/7***       3       4**/CvHaarClassifierCascade* faceCascade;FLANDMARK_Model * model;

初始化:

HSFaceFlandmark::HSFaceFlandmark(){    char szModuleFilePath[MAX_PATH];    int n = GetModuleFileNameA(0, szModuleFilePath, MAX_PATH); //获得当前执行文件的路径    szModuleFilePath[ strrchr(szModuleFilePath, '\\') - szModuleFilePath + 1 ] = 0;//将最后一个"\\"后的字符置为0    DBG("================= '%s'\n", szModuleFilePath);    char faceCascadeFilename[MAX_PATH];    char flandmarkmodelFilename[MAX_PATH];    sprintf(faceCascadeFilename, "%s/haarcascade_frontalface_alt.xml",szModuleFilePath);    sprintf(flandmarkmodelFilename, "%s/flandmark_model.dat",szModuleFilePath);    // Haar Cascade file, used for Face Detection.    //char faceCascadeFilename[] = "./haarcascade_frontalface_alt.xml";    // Load the HaarCascade classifier for face detection.    faceCascade = (CvHaarClassifierCascade*)cvLoad(faceCascadeFilename, 0, 0, 0);    if( !faceCascade )    {        DBG("Couldnt load Face detector '%s'\n", faceCascadeFilename);    }    model = flandmark_init(flandmarkmodelFilename);    if (model == 0)    {        DBG("Structure model wasn't created. Corrupted file flandmark_model.dat?\n");    }}

8个关键点检测的API

int detectFaceInImage(IplImage *orig, cv::Mat& img, double *landmarks){    IplImage frame = IplImage(img);    IplImage *input = cvCreateImage(cvSize(frame.width, frame.height), IPL_DEPTH_8U, 1);    cvConvertImage(&frame, input);    int bbox[4] = {0};    // Smallest face size.    CvSize minFeatureSize = cvSize(80, 80);    int flags =  CV_HAAR_DO_CANNY_PRUNING;    // How detailed should the search be.    float search_scale_factor = 1.1f;    CvMemStorage* storage;    CvSeq* rects;    int nFaces;    storage = cvCreateMemStorage(0);    cvClearMemStorage(storage);    // Detect all the faces in the greyscale image.    rects = cvHaarDetectObjects(input, faceCascade, storage, search_scale_factor, 2, flags, minFeatureSize);    nFaces = rects->total;    for (int iface = 0; iface < (rects ? nFaces : 0); ++iface)    {        CvRect *r = (CvRect*)cvGetSeqElem(rects, iface);        bbox[0] = r->x;        bbox[1] = r->y;        bbox[2] = r->x + r->width;        bbox[3] = r->y + r->height;        flandmark_detect(input, bbox, model, landmarks);        // display landmarks//        cvRectangle(orig, cvPoint(bbox[0], bbox[1]), cvPoint(bbox[2], bbox[3]), CV_RGB(255,0,0) );//        cvRectangle(orig, cvPoint(model->bb[0], model->bb[1]), cvPoint(model->bb[2], model->bb[3]), CV_RGB(0,0,255) );//        cvCircle(orig, cvPoint((int)landmarks[0], (int)landmarks[1]), 3, CV_RGB(0, 0,255), CV_FILLED);//        for (int i = 2; i < 2*model->data.options.M; i += 2)//        {//            cvCircle(orig, cvPoint(int(landmarks[i]), int(landmarks[i+1])), 3, CV_RGB(255,0,0), CV_FILLED);//        }    }//    if (nFaces > 0)//    {//        DBG("Faces detected: %d; \n", nFaces);//    }    cvReleaseMemStorage(&storage);    cvReleaseImage(&input);    return nFaces;}

用法:

//cv::Mat& img 这里就是需要检测人脸的图片,我这里都是用cv::Mat作为输入格式IplImage frameRet = IplImage(img);//这里存放检测到人脸8个特征点的坐标double landmarks[MAX_LANDMARK_POINT * 2] = {0};int faceNum = detectFaceInImage(&frameRet, img, landmarks);if(faceNum > 0){    for (int i = 0; i < 2 * MAX_LANDMARK_POINT; i += 2)    {        //cv::circle(retImg, cvPoint(int(landmarks[i]), int(landmarks[i+1])), 2, CV_RGB(255,0,0), CV_FILLED);    }}//我这里只需要8个点坐标,frameRet其实没什么用
原创粉丝点击