一、检测图片中的人脸
【流程图】
【源代码】
#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; /** 函数声明 */ void detectAndDisplay(Mat frame); /** 全局变量 */ string face_cascade_name = "haarcascade_frontalface_alt2.xml"; //string eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml"; string eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml"; CascadeClassifier face_cascade; CascadeClassifier eyes_cascade; string window_name = "Capture - Face detection"; /** @主函数 */ int main(int argc, const char** argv) { Mat frame; //-- 1. 加载级联分类器文件 if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading\n"); return -1; }; if (!eyes_cascade.load(eyes_cascade_name)) { printf("--(!)Error loading\n"); return -1; }; frame=imread("F:\\磊神图片\\2\\2.jpg"); detectAndDisplay(frame); imwrite("F:\\磊神图片\\2\\12.jpg",frame); //imshow("frame",frame); waitKey(0); return 0; } /** @函数 detectAndDisplay */ void detectAndDisplay(Mat frame) { std::vector<Rect> faces; Mat frame_gray; char temp[20]; Mat logo=imread("F:\\磊神图片\\2\\11.jpg"); 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(0, 0)); for (int i = 0; i < faces.size(); i++) { resize(logo,logo,Size(faces[i].width,faces[i].height)); rectangle(frame,Point(faces[i].x-2,faces[i].y-2),Point(faces[i].x + faces[i].width+2,faces[i].y + faces[i].height+2),Scalar(0,255,0),1,CV_AA); sprintf(temp,"Pig%d",i); putText(frame,temp,Point(faces[i].x,faces[i].y-5),FONT_HERSHEY_SIMPLEX,0.5,Scalar(255,255,255),1,CV_AA); Mat ROI=frame(Rect(faces[i].x,faces[i].y,faces[i].width,faces[i].height));//Zone0为整个ROI logo.copyTo(ROI);//logo复制到ROI上面 } //<-- 显示结果图像 imshow(window_name, frame); }
【注意点】
1、加载人脸训练模型是否成功是检测人脸的关键部分,如果没检测到人脸有可能就是加载模型失败的原因。
if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading\n"); return -1; };
2、读取图片失败,图片路径不正确。
3、人脸检测函数的参数设置
face_cascade.detectMultiScale(frame_gray, faces, 1.1,2, 0 | CV_HAAR_SCALE_IMAGE, Size(0, 0));
原型:
void detectMultiScale( const Mat& image, CV_OUT vector<Rect>& objects, double scaleFactor=1.1, int minNeighbors=3, int flags=0, Size minSize=Size(), Size maxSize=Size() );
- scaleFactor为人脸检测窗口的搜索尺度,默认为1.1,数值越小,检测率越高,但是消耗CPU。
- minNeighbors为最小相邻窗口,默认为3,同样也是数值越小,检测率越高,但是消耗CPU,同时也会带来误检。
- minSize和maxSize为搜索图片的尺寸大小,根据实际情况确定,如果不确定就把值设小点就可以了。
4、表情包的尺寸应该与ROI的尺寸相同,不然会贴不上去,使用resize()函数修改一下尺寸就可以了。
resize(logo,logo,Size(faces[i].width,faces[i].height));
Mat ROI=frame(Rect(faces[i].x,faces[i].y,faces[i].width,faces[i].height));//Zone0为整个ROI