知识点讲解博客:https://blog.csdn.net/sazass/article/details/89150468
#include<opencv2\objdetect\objdetect.hpp>
#include<opencv2\highgui.hpp>
#include<opencv2\imgproc.hpp>
#include<iostream>
using namespace std;
using namespace cv;
void detect_and_display(Mat frame);
String face, eyes;
CascadeClassifier face_cascade;//CascadeClassifier是opencv下objdetect模块中用来做目标检测的级联分类器的一个类;简而言之是滑动窗口机制+级联分类器的方式
CascadeClassifier eyes_cascade;//详情可查看博客https://blog.csdn.net/sazass/article/details/89150468
String window_name = "capture_face_and_eyes_detection";
int main(int argc,const char** argv)
{
face = "F:\\Open cv\\opencv\\build\\etc\\haarcascades\\haarcascade_frontalface_alt.xml";//脸部数据集
eyes = "F:\\Open cv\\opencv\\build\\etc\\haarcascades\\haarcascade_eye_tree_eyeglasses.xml";//眼睛数据集
VideoCapture capture;
Mat frame;
//——————————————————加载cascades——————————————
if (!face_cascade.load(face))
{
cerr << "face_cascade load error!";
}
if (!eyes_cascade.load(eyes))
{
cerr << "eyes_cascade load error!";
}
//———————————————read the video stream——————————————
capture.open(0);
if (capture.isOpened())
{
cerr << "video load error!";
}
while (capture.read(frame))
{
if (frame.empty())
{
cerr << "no capture frame load error!";
break;
}
//———————————————apply the classifier to the frame——————————————
detect_and_display(frame);
if (waitKey(10) == 27)
{
break;
}
}
return 0;
}
void detect_and_display(Mat frame)
{
vector<Rect> faces;
Mat frame_gray;
cvtColor(frame, frame_gray, COLOR_BGR2GRAY);//转化灰度图
equalizeHist(frame_gray, frame_gray);//equalizeHist(src,dst)直方图均衡化,,用于提高图像的质量
//———————————————detect face——————————————
face_cascade.detectMultiScale//调用detectMultiScale()实现多尺度检测
(
frame_gray, //输入图像
faces, //输出检测到的目标区域
1.1,//搜索前后两次窗口大小比例系数,默认1.1,即每次搜索窗口扩大10%
2, //构成检测目标的相邻矩形的最小个数 如果组成检测目标的小矩形的个数和小于minneighbors - 1 都会被排除,如果minneighbors为0 则函数不做任何操作就返回所有被检候选矩形框
0 | CASCADE_SCALE_IMAGE, //若设置为CV_HAAR_DO_CANNY_PRUNING 函数将会使用Canny边缘检测来排除边缘过多或过少的区域
Size(60,10)//能检测的最小尺寸//能检测的最大尺寸
);
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);//画出脸部的中心点
//point()创建一个2D点对象(point(x,y))
ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(0, 0, 0), 4, 8, 0);//Ellipse()用来绘制或者填充一个简单的椭圆弧或椭圆扇形
//图像。
//椭圆圆心坐标。
//轴的长度。
//偏转的角度。
//圆弧起始角的角度。.
//圆弧终结角的角度。
//线条的颜色。
//线条的粗细程度。
//线条的类型。
//圆心坐标点和数轴的精度。
Mat face_roi = frame_gray(faces[i]);
vector<Rect> eyes;
//———————————————detect eyes——————————————
eyes_cascade.detectMultiScale(face_roi, eyes, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));
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].height/2 );//画出眼睛的中心点
int randius = cvRound((eyes[j].width*0.25 + eyes[j].height*0.25));
circle(frame, eye_center, randius, Scalar(255, 2, 2), 4, 8, 0);
//circle()函数
//img为源图像指针;
//center为画圆的圆心坐标;
//radius为圆的半径;
//color为设定圆的颜色,规则根据B(蓝)G(绿)R(红);
//thickness 如果是正数,表示组成圆的线条的粗细程度,否则,表示圆是否被填充;
//line_type 线条的类型,默认是8;
//shift 圆心坐标点和半径值的小数点位数
}
}
//———————————————show time——————————————
imshow(window_name,frame);
}
//检测步骤(视频取针)
//1.load()加载xml级联分类器
//2.从视频中取帧,导出image;
//3.图像灰度化;
//4.图像resize;
//5.调用detectMultiScale()实现多尺度检测: