如何在OpenCV中检测多个面孔?

时间:2015-11-05 13:52:50

标签: c++ opencv

我遇到一次检测多个脸的问题。以下代码仅检测一个人的正面和眼睛。我试图让它适用于所有可用面孔但我不能...请帮助< / p>

  CvCapture* capture;
    Mat frame;
    std::vector<Rect> faces;
    Mat frame_gray;
    Mat frame;
    CascadeClassifier face_cascade;
    CascadeClassifier eyes_cascade;

    face_cascade.load( "haarcascade_frontalface_alt.xml"; );
    eyes_cascade.load(  "haarcascade_eye_tree_eyeglasses.xml"; );


   capture = cvCaptureFromCAM( -1 );

  frame = cvQueryFrame( capture );
  cvtColor( frame, frame_gray, CV_BGR2GRAY );
  equalizeHist( frame_gray, frame_gray );

  face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );

  for( size_t i = 0; i < faces.size(); i++ )
  {
    Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
    ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );

    Mat faceROI = frame_gray( faces[i] );
    std::vector<Rect> eyes;    
    eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) );
    for( size_t j = 0; j < eyes.size(); j++ )
     {
       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)*0.25 );
       circle( frame, center, radius, Scalar( 255, 0, 0 ), 4, 8, 0 );
     }
  }

  imshow( "window", frame );

2 个答案:

答案 0 :(得分:1)

基本上使用您的代码(只需更改以加载单个固定图像并删除equalizeHist调用)即可获得以下结果:

输入:

enter image description here

输出:

enter image description here

输入:

enter image description here

输出:

enter image description here

所以你的代码基本上做了它应该做的事情。您的问题似乎出现在图像数据或有关图像数据的参数中。请发布样本图片。

为了确保我没有更改代码的大部分内容,我使用了:

using namespace cv;
using namespace std;

int main()
{

    cv::Mat input = cv::imread("../inputData/MultiLena.png");

    cv::Mat gray;
    cv::cvtColor(input,gray,CV_BGR2GRAY);


    //CvCapture* capture;
    //Mat frame;
    std::vector<Rect> faces;
    Mat frame_gray;
    Mat frame;
    CascadeClassifier face_cascade;
    CascadeClassifier eyes_cascade;

    face_cascade.load( "haarcascade_frontalface_alt.xml" );
    eyes_cascade.load(  "haarcascade_eye_tree_eyeglasses.xml" );


   //capture = cvCaptureFromCAM( -1 );

  //frame = cvQueryFrame( capture );
  //cvtColor( frame, frame_gray, CV_BGR2GRAY );
  //equalizeHist( frame_gray, frame_gray );

    frame_gray = gray;
    frame = input;


  face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );

  for( size_t i = 0; i < faces.size(); i++ )
  {
    Point center( faces[i].x + faces[i].width*0.5, faces[i].y + faces[i].height*0.5 );
    ellipse( frame, center, Size( faces[i].width*0.5, faces[i].height*0.5), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );

    Mat faceROI = frame_gray( faces[i] );
    std::vector<Rect> eyes;    
    eyes_cascade.detectMultiScale( faceROI, eyes, 1.1, 2, 0 |CV_HAAR_SCALE_IMAGE, Size(30, 30) );
    for( size_t j = 0; j < eyes.size(); j++ )
     {
       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)*0.25 );
       circle( frame, center, radius, Scalar( 255, 0, 0 ), 4, 8, 0 );
     }
  }

  imshow( "window", frame );


  cv::imshow("input", input);
    cv::imwrite("../outputData/multiFaces.png", input);
    cv::waitKey(0);
    return 0;
}

答案 1 :(得分:0)

也许您可以实施以下策略:

  • 检测第一张脸,它会生成一个矩形。
  • 创建一个没有那个矩阵的新Mat。
  • 分析新垫子并生成新的面部检测矩形。
  • 现在将两个rects绘制成一个视频捕获流。

请注意,只在屏幕上显示包含所选视频的背景视频流,以便系统保持高效。