【问题标题】:OpenCV Face Detection function only works at the second callOpenCV 人脸检测功能仅在第二次调用时有效
【发布时间】:2014-04-06 15:23:25
【问题描述】:

我在不记得的地方找到了这段代码。 问题是,它显示了图片和检测到的人脸,只是在第二次调用detectAndDisplay() 之后,作者故意让这个无限循环,但我不明白为什么。

有什么想法吗?

提前感谢您的帮助。

代码:

 #include "opencv2/objdetect/objdetect.hpp"
    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/imgproc/imgproc.hpp"

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

    using namespace std;
    using namespace cv;

    // Function Headers
    void detectAndDisplay(Mat frame);

    // Global variables
    // Copy this file from opencv/data/haarscascades to target folder
    string face_cascade_name = "c:/haarcascade_frontalface_alt.xml";
    CascadeClassifier face_cascade;
    string window_name = "Capture - Face detection";
    int filenumber; // Number of file to be saved
    string filename;

    // Function main
    int main(void)
    {
        // Load the cascade
        if (!face_cascade.load(face_cascade_name))
        {
            printf("--(!)Error loading\n");
            int ch = std::cin.get();
            return (-1);
        };

        // Read the image file
        Mat frame = imread("C:/lena.jpg");

        for (;;) // -----> here. why an infinite loop? and why it works at the second turn of this loop ?
        {
            // Apply the classifier to the frame
            if (!frame.empty())
            {
                detectAndDisplay(frame);
            }
            else
            {
                printf(" --(!) No captured frame -- Break!");
                int ch = std::cin.get();
                break;
            }

            int c = waitKey(10);

            if (27 == char(c))
            {
                break;
            }
        }

        return 0;
    }

    // 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);

            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");
    }

补充:

感谢 Mhd.Tahawi,我还找到了 this code,它又包含一个 while(true) 循环。我就是不明白为什么。

此外,如果我想在后续图像或视频中检测人脸怎么办?然后我卡在第一张图片上?

第一次调用后的输出:

第二次调用后的输出(工作):

【问题讨论】:

  • 代码与教程中的代码非常相似:docs.opencv.org/doc/tutorials/objdetect/cascade_classifier/…
  • @Mhd.Tahawi 确实如此。又是一个while(true) 循环。为什么??
  • 我没有看到任何while(true) 你的意思是你有评论的for(;;) 吗?
  • 而 true 在您发送的代码中。在我的代码中类似于 for(;;)。
  • 我处理的是网络摄像头,所以情况不同。第一次通话后发生了什么?

标签: c++ opencv computer-vision face-detection face-recognition


【解决方案1】:

等待用户输入不是全部。

即使您不关心键盘输入,也必须调用waitKey

来自OpenCV DOC

该函数是HighGUI中唯一可以获取和处理的方法 事件,因此需要定期调用它以进行正常事件 处理,除非在一个环境中使用 HighGUI 关心事件处理

在您的代码上:

imshow("original", frame);

imshow() 是 HighGui 的一个函数,代码需要定期调用waitKey,以处理其事件循环。如果不调用 waitKey,HighGui 将无法处理重绘等 Windows 事件。

所以,基本上,您允许调用 waitKey 的 HighGui 进程窗口事件。

【讨论】:

  • 好的,谢谢。那么我怎样才能让它在一个电话中工作呢?类似Rect image_to_face(img)
【解决方案2】:

只是因为作者希望程序一直运行,直到他收到用户的密钥来结束它,仅此而已。

该程序旨在处理实时视频流,仅此而已。 它与实际处理无关。

您可以将代码从循环中取出并用它处理一个图像,它仍然会以相同的方式运行

编辑: 我有同样的情况,但我正在使用网络摄像头而不是从文件中读取。硬件启动太慢,捕获帧然后将其发送到我的程序进行处理。 这是我的代码:

 VideoCapture capture;
  Mat frame;
  capture.open( 0 );
  if( capture.isOpened() )
  {
    for(;;)
    {
      capture >> frame;


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

      }

      int c = waitKey(5);
      if( (char)c == 'c' ) { break; }

    }

【讨论】:

  • 但正如我所说,我试过了,但它在第一次通话时不起作用。仅在 2nd 调用后有效。
  • 我也遇到了同样的问题,让我看看我的代码,告诉你我是怎么解决的
猜你喜欢
  • 2012-02-04
  • 2013-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-31
  • 2012-04-15
  • 2014-03-16
  • 2017-05-21
相关资源
最近更新 更多