由于光照、遮挡和倾斜等原因,部分人脸和眼睛并不能正确检测。。
// 简单的人脸检测 #include <iostream> #include <vector> #include <opencv2opencv.hpp> #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" using namespace std; using namespace cv; // 把opencvsourcesdatahaarcascadeshaarcascade_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 "); return -1; }; if (!eyes_cascade.load(eyes_cascade_name)){ printf("--(!)Error loading "); 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; }