【问题标题】:detect and count face on image using open cv and c++使用 open cv 和 c++ 检测和计数图像上的人脸
【发布时间】:2015-07-15 03:35:16
【问题描述】:

虽然我是初学者,但我正在使用 opencv 和 C++。我正在尝试使用 Haarcascade 从一组图像中检测和计数人脸。 我只想获取每个图像上的面孔数量。 如何编辑此代码以获取图像上的人脸数量???

// Function detectAndDisplay
void detectAndDisplay(Mat frame)
{
std::vector<Rect> faces;
Mat frame_gray;
Mat crop;
Mat res;
Mat gray;
string text;
stringstream sstm;

cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
equalizeHist(frame_gray, frame_gray);

// Detect faces
face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 |     CASCADE_SCALE_IMAGE, Size(30, 30));

// Set Region of Interest
cv::Rect roi_b;
cv::Rect roi_c;

size_t ic = 0; // ic is index of current element
int ac = 0; // ac is area of current element

size_t ib = 0; // ib is index of biggest element
int ab = 0; // ab is area of biggest element

for (ic = 0; ic < faces.size(); ic++) // Iterate through all current  elements (detected faces)

{
    roi_c.x = faces[ic].x;
    roi_c.y = faces[ic].y;
    roi_c.width = (faces[ic].width);
    roi_c.height = (faces[ic].height);

    ac = roi_c.width * roi_c.height; // Get the area of current element (detected face)

    roi_b.x = faces[ib].x;
    roi_b.y = faces[ib].y;
    roi_b.width = (faces[ib].width);
    roi_b.height = (faces[ib].height);

    ab = roi_b.width * roi_b.height; // Get the area of biggest element, at beginning it is same as "current" element

    if (ac > ab)
    {
        ib = ic;
        roi_b.x = faces[ib].x;
        roi_b.y = faces[ib].y;
        roi_b.width = (faces[ib].width);
        roi_b.height = (faces[ib].height);
    }

    crop = frame(roi_b);
    resize(crop, res, Size(128, 128), 0, 0, INTER_LINEAR); // This will be needed later while saving images
    cvtColor(crop, gray, CV_BGR2GRAY); // Convert cropped image to Grayscale

    // Form a filename
    filename = "";
    stringstream ssfn;
    ssfn << filenumber << ".png";
    filename = ssfn.str();
    filenumber++;

    imwrite(filename, gray);
    printf("filename");
    Point pt1(faces[ic].x, faces[ic].y); // Display detected faces on main window - live stream from camera
    Point pt2((faces[ic].x + faces[ic].height), (faces[ic].y + faces[ic].width));
    rectangle(frame, pt1, pt2, Scalar(0, 255, 0), 2, 8, 0);
}

// Show image
/*sstm << "Crop area size: " << roi_b.width << "x" << roi_b.height << " Filename: " << filename;
text = sstm.str();

putText(frame, text, cvPoint(30, 30), FONT_HERSHEY_COMPLEX_SMALL, 0.8, cvScalar(0, 0, 255), 1, CV_AA);
imshow("original", frame);

if (!crop.empty())
{
    imshow("detected", crop);
}
else
    destroyWindow("detected");*/

}

【问题讨论】:

  • 我建议您阅读图像,找到面孔并数数。
  • 请先学习如何使用 openCV 从文件中加载图像以及如何在窗口中显示它们。
  • int numberOfFacesInThisImage = faces.size() 在detectMultiscale之后

标签: c++ image opencv face-detection


【解决方案1】:

我不得不做类似的事情,并在 OpenCV 网站上使用了 CascadeClassifierexample

要遵循的粗略步骤是:

  1. 加载您要处理的所有图像。
  2. 对于每个图像,应用CascadeClassifier,如示例中所示,您需要传递std::vector&lt;cv::Rect&gt; 作为参数。检测后,此向量将包含所有检测到的对象的位置(在您的情况下是人脸)。
  3. 对于每张图像,返回向量的大小以了解检测到的人脸数量。

老实说,我链接的示例是您自己不费力就可以找到的。

【讨论】:

  • 谢谢,但问题是初学者,虽然这个例子和我已经找到的所有例子一样使用视频流。
  • 要从文件加载图像,请查看this link。您必须使用cv::imread() 函数。它将返回一个代表图像的cv::Mat对象,可以在我在答案中提到的示例中使用。
【解决方案2】:

修改了您发布的代码示例,只返回图像中检测到的人脸数量...

// Function to count the detected faces in your image
void countFacesInImage(Mat frame)
{
    std::vector<Rect> faces;
    Mat frame_gray;

    cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
    equalizeHist(frame_gray, frame_gray);

    // Detect faces
    face_cascade.detectMultiScale(frame_gray, faces, 1.1, 2, 0 |     CASCADE_SCALE_IMAGE, Size(30, 30));

    return faces.size();
}

如果您想了解检测到哪些人脸,哪些未检测到,可以在返回之前添加此代码:

cv::Mat tmpImage = frame.clone();
for(unsigned int i=0; i<faces.size(); ++i)
{
    cv::rectangle(tmpImage, faces[i], cv::Scalar(0,255,0), 2);
}
cv::imshow("faces", tmpImage);
cv::waitKey(0);

在每个图像之后,您必须按一个带有活动窗口“面孔”的键。您可以更改为cv::waitKey(n) 等待n 毫秒,而无需按键。

【讨论】:

  • 谢谢...确实有帮助,但我必须设置感兴趣区域吗?因为我的图片编号错误
  • 如果你想在整个图像中检测人脸,你不必使用任何 ROI(如果你需要一个 ROI,你应该只将裁剪的 ROI 图像传递给函数)。但是 haar 级联人脸检测并不那么准确,因此由于检测器的准确性,您可能会得到错误的值。听说dlib库的人脸检测器更准确,但还没测试。 dlib.net
  • 如果您想了解检测到哪些人脸,哪些没有检测到,可以尝试添加新代码 sn-p。
猜你喜欢
  • 1970-01-01
  • 2014-08-26
  • 2021-06-30
  • 2013-11-14
  • 2013-11-22
  • 2017-11-06
  • 2019-12-01
  • 2013-11-24
  • 2013-04-04
相关资源
最近更新 更多