gpt4 book ai didi

c++ - OpenCV 人脸检测功能仅在第二次调用时有效

转载 作者:行者123 更新时间:2023-11-28 07:02:51 25 4
gpt4 key购买 nike

我在某个我不记得的地方找到了这段代码。问题是,它仅在第二次调用 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) 循环。我只是不明白为什么。

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

第一次调用后的输出:

enter image description here

第二次调用后的输出(有效):

enter image description here

最佳答案

等待用户输入不是全部。

即使您不关心键盘输入,调用 waitKey 也是必不可少的。

来自 OpenCV DOC :

This function is the only method in HighGUI that can fetch and handle events, so it needs to be called periodically for normal event processing unless HighGUI is used within an environment that takes care of event processing

在您的代码上:

imshow("original", frame);

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

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

关于c++ - OpenCV 人脸检测功能仅在第二次调用时有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22183019/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com