OpenCV人脸检测

由于光照、遮挡和倾斜等原因,部分人脸和眼睛并不能正确检测。。

// 简单的人脸检测

#include <iostream>
#include <vector>
#include <opencv2\opencv.hpp>
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"

using namespace std;
using namespace cv;

// 把opencv\sources\data\haarcascades\haarcascade_frontalface_alt.xml和haarcascade_eye_tree_eyeglasses.xml
// 这两个文件复制到工程路径下
String face_cascade_name = "haarcascade_frontalface_alt.xml";
String eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
// 检测物体的级联分类器类
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;
string window_name = "Capture - Face detection";


void detectAndDisplay(Mat frame)
{
    std::vector<Rect> faces;
    Mat frame_gray;

    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
    // 使灰度图象直方图均衡化,可以将比较淡的图像变换为比较深的图像(即增强图像的亮度及对比度)
    equalizeHist(frame_gray, frame_gray);

    /*
    CascadeClassifier::detectMultiScale(const Mat& image, vector<Rect>& objects, double scaleFactor = 1.1,
    int minNeighbors = 3, int flags = 0, Size minSize = Size(), Size maxSize = Size())
    参数:
        image – 需要检测的 CV_8U 输入矩阵。
        objects – 输出vector载体容器用于保存被识别的物体矩阵。
        scaleFactor – 指定每张图片的缩小比例的参数。
        minNeighbors – 指定每个候选矩阵至少包含的邻近元素个数。 越大正确率越高
        flags – 与旧版级联分类器模型函数cvHaarDetectObjects的flags相同.此参数不被用于新版模型。
        minSize – 最小可能的对象的大小,小于的对象将被忽略。
        maxSize – 最大可能的对象的大小,大于的对象将被忽略。
    */

    // 人脸检测
    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));

    for (size_t i = 0; i < faces.size(); i++)
    {
        // 画椭圆标记
        Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);
        ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(0, 255, 0), 2, 8, 0);

        Mat faceROI = frame_gray(faces[i]);
        std::vector<Rect> eyes;
        // 在脸中检测眼睛
        eyes_cascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(10, 10));

        for (size_t j = 0; j < eyes.size(); j++)
        {
            // 画圆标记
            Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2);
            int radius = cvRound((eyes[j].width + eyes[j].height)*0.25);
            circle(frame, eye_center, radius, Scalar(255, 0, 0), 3, 8, 0);
        }
    }
    
    imshow(window_name, frame);
}

int main(void)
{
    VideoCapture capture;
    Mat frame;

    frame = imread("image.jpg");

    // 加载级联(cascades)
    if (!face_cascade.load(face_cascade_name)){ printf("--(!)Error loading\n"); return -1; };
    if (!eyes_cascade.load(eyes_cascade_name)){ printf("--(!)Error loading\n"); return -1; };

    // 读取视频
    //capture.open(0);
    //if (capture.isOpened())
    //{
    //    for (;;)
    //    {
    //        capture >> frame;

    //        // 对当前帧使用分类器
    //        if (!frame.empty())
    //        {
    //            detectAndDisplay(frame);
    //        }
    //        else
    //        {
    //            break;
    //        }

    //        waitKey(5);
    //    }
    //}

    if (!frame.empty())
    {
        detectAndDisplay(frame);
    }
    else
    {
    }

    waitKey(0);
    return 0;
}

 

posted @ 2016-02-12 18:22  ht-beyond  阅读(690)  评论(0编辑  收藏  举报