opencv中的人脸检测

#include "opencv2/objdetect.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/core/utility.hpp"

#include "opencv2/videoio/videoio_c.h"
#include "opencv2/highgui/highgui_c.h"

#include <cctype>
#include <iostream>
#include <iterator>
#include <stdio.h>

using namespace std;
using namespace cv;

static void help()
{
    cout << "\nThis program demonstrates the cascade recognizer. Now you can use Haar or LBP features.\n"
        "This classifier can recognize many kinds of rigid objects, once the appropriate classifier is trained.\n"
        "It's most known use is for faces.\n"
        "Usage:\n"
        "./facedetect [--cascade=<cascade_path> this is the primary trained classifier such as frontal face]\n"
        "   [--nested-cascade[=nested_cascade_path this an optional secondary classifier such as eyes]]\n"
        "   [--scale=<image scale greater or equal to 1, try 1.3 for example>]\n"
        "   [--try-flip]\n"
        "   [filename|camera_index]\n\n"
        "see facedetect.cmd for one call:\n"
        "./facedetect --cascade=\"../../data/haarcascades/haarcascade_frontalface_alt.xml\" --nested-cascade=\"../../data/haarcascades/haarcascade_eye.xml\" --scale=1.3\n\n"
        "During execution:\n\tHit any key to quit.\n"
        "\tUsing OpenCV version " << CV_VERSION << "\n" << endl;
}

void detectAndDraw(Mat& img, CascadeClassifier& cascade, 
    CascadeClassifier& nestedCascade,
    double scale, bool tryflip);

//要使用到的两个cascade文件,用于联合检测人脸,opencv自带了多个xml文件,在opencv安装目录下的/source/data/haarcascades/ 文件夹内
string cascadeName = "D:\\Program Files (x86)\\opencv\\sources\\data\\haarcascades\\haarcascade_frontalface_alt.xml";

string nestedCascadeName = "D:\\Program Files (x86)\\opencv\\sources\\data\\haarcascades\\haarcascade_eye_tree_eyeglasses.xml";//检测眼睛

int main()
{
    CvCapture* capture = 0;
    Mat frame, frameCopy, image;
    CascadeClassifier cascade, nestedCascade;
    char *srcImageFile = "C:\\Users\\n\\\Documents\\visualstudio2012\\Projects\\opencvDemo\\opencvDemo\\3.jpg";//测试图片
    double scale = 1;
    if (!cascade.load(cascadeName))//载入cascade文件
    {
        cerr << "ERROR: Could not load classifier cascade" << endl;
        help();
        return -1;
    }
    image = imread("3.jpg");


    cvNamedWindow("result", 1);

    cout << "In image read" << endl;
    if (!image.empty())
        {
            detectAndDraw(image, cascade, nestedCascade, scale, 0);//检测人脸
            waitKey(0);
        }
    cvDestroyWindow("result");
    return 0;
}

void detectAndDraw(Mat& img, CascadeClassifier& cascade,
    CascadeClassifier& nestedCascade,
    double scale, bool tryflip)
{
    int i = 0;
    double t = 0;
    vector<Rect> faces, faces2;
    const static Scalar colors[] = { CV_RGB(0, 0, 255),
        CV_RGB(0, 128, 255),
        CV_RGB(0, 255, 255),
        CV_RGB(0, 255, 0),
        CV_RGB(255, 128, 0),
        CV_RGB(255, 255, 0),
        CV_RGB(255, 0, 0),
        CV_RGB(255, 0, 255) };//用于画线
    Mat gray, smallImg(cvRound(img.rows / scale), cvRound(img.cols / scale), CV_8UC1);

    cvtColor(img, gray, COLOR_BGR2GRAY);
    resize(gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR);
    equalizeHist(smallImg, smallImg);

    t = (double)cvGetTickCount();
    cascade.detectMultiScale(smallImg, faces,
        1.1, 2, 0
        //|CASCADE_FIND_BIGGEST_OBJECT
        //|CASCADE_DO_ROUGH_SEARCH
        | CASCADE_SCALE_IMAGE
        ,
        Size(30, 30));
    if (tryflip)
    {
        flip(smallImg, smallImg, 1);
        cascade.detectMultiScale(smallImg, faces2,
            1.1, 2, 0
            //|CASCADE_FIND_BIGGEST_OBJECT
            //|CASCADE_DO_ROUGH_SEARCH
            | CASCADE_SCALE_IMAGE
            ,
            Size(30, 30));
        for (vector<Rect>::const_iterator r = faces2.begin(); r != faces2.end(); r++)
        {
            faces.push_back(Rect(smallImg.cols - r->x - r->width, r->y, r->width, r->height));
        }
    }
    t = (double)cvGetTickCount() - t;
    printf("detection time = %g ms\n", t / ((double)cvGetTickFrequency()*1000.));
    for (vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++)
    {
        Mat smallImgROI;
        vector<Rect> nestedObjects;
        Point center;
        Scalar color = colors[i % 8];
        int radius;

        double aspect_ratio = (double)r->width / r->height;
        if (0.75 < aspect_ratio && aspect_ratio < 1.3)
        {
            center.x = cvRound((r->x + r->width*0.5)*scale);
            center.y = cvRound((r->y + r->height*0.5)*scale);
            radius = cvRound((r->width + r->height)*0.25*scale);
            circle(img, center, radius, color, 3, 8, 0);
        }
        else
            rectangle(img, cvPoint(cvRound(r->x*scale), cvRound(r->y*scale)),
            cvPoint(cvRound((r->x + r->width - 1)*scale), cvRound((r->y + r->height - 1)*scale)),
            color, 3, 8, 0);
        if (nestedCascade.empty())
            continue;
        smallImgROI = smallImg(*r);
        nestedCascade.detectMultiScale(smallImgROI, nestedObjects,
            1.1, 2, 0
            //|CASCADE_FIND_BIGGEST_OBJECT
            //|CASCADE_DO_ROUGH_SEARCH
            //|CASCADE_DO_CANNY_PRUNING
            | CASCADE_SCALE_IMAGE
            ,
            Size(30, 30));
        for (vector<Rect>::const_iterator nr = nestedObjects.begin(); nr != nestedObjects.end(); nr++)
        {
            center.x = cvRound((r->x + nr->x + nr->width*0.5)*scale);
            center.y = cvRound((r->y + nr->y + nr->height*0.5)*scale);
            radius = cvRound((nr->width + nr->height)*0.25*scale);
            circle(img, center, radius, color, 3, 8, 0);
        }
    }
    cv::imshow("result", img);
}

opencv中只有人脸检测,但是没有人脸特征点的检测方法,如果想用人脸特征点的检测还是需要借助dlib,具体请见

点击打开链接

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值