Opencv——级联分类器(AdaBoost)_xml

Opencv——级联分类器(AdaBoost)_xml_02

API说明:



1 cv::CascadeClassifier::detectMultiScale(InputArray image,//输入灰度图像
2 CV_OUT std::vector<Rect>& objects,//返回目标的外接矩形
3 double scaleFactor = 1.1,//检测的尺度跳变量,这个值越大,某些尺寸的对象无法被检测,但检测更快
4 int minNeighbors = 3,//有多少个重叠的检测标记才被认为有小
5 int flags = 0,  //新版本中没用
6 Size minSize = Size(),//目标的最小尺寸
7 Size maxSize = Size()//目标的最大尺寸,可以排除尺寸不合理的对象
8 );


利用opencv自带的数据进行人脸检测:



1 #include <opencv2/opencv.hpp>
2 #include <iostream>
3
4 using namespace cv;
5 using namespace std;
6
7 String fileName = "D:/opencv3.1/opencv/build/etc/haarcascades/haarcascade_frontalface_alt.xml";//设置文件路径
8 CascadeClassifier face_classifier;//创建分类器
9
10 int main(int argc, char** argv) {
11 if (!face_classifier.load(fileName)) {//加载分类数据
12 printf("could not load face feature data...\n");
13 return -1;
14 }
15
16 Mat src = imread("D:/vcprojects/images/test.png");
17 if (src.empty()) {
18 printf("could not load image...\n");
19 return -1;
20 }
21 imshow("input image", src);
22 Mat gray;
23 cvtColor(src, gray, COLOR_BGR2GRAY);//转成灰度图
24 equalizeHist(gray, gray);//直方图均衡化,提高对比度
25
26 vector<Rect> faces;
27 face_classifier.detectMultiScale(gray, faces, 1.2, 3, 0, Size(24, 24));//在多尺度上检测
28 for (size_t t = 0; t < faces.size(); t++) {
29 rectangle(src, faces[static_cast<int>(t)], Scalar(0, 0, 255), 2, 8, 0);
30 }
31
32 imshow("detect faces", src);
33 waitKey(0);
34 return 0;
35 }


进阶:人眼检测

 



1 #include<opencv2/opencv.hpp>
2 #include<iostream>
3
4 using namespace cv;
5 using namespace std;
6
7 CascadeClassifier face_cascader;
8 CascadeClassifier eye_cascader;
9 String facefile = "D:/opencv3.1/opencv/build/etc/haarcascades/haarcascade_frontalface_alt.xml";
10 String eyefile = "D:/opencv3.1/opencv/build/etc/haarcascades/haarcascade_eye.xml";
11
12 int main(int argc, char** argv) {
13 if (!face_cascader.load(facefile)) {
14 printf("could not load face feature data...\n");
15 return -1;
16 }
17 if (!eye_cascader.load(eyefile)) {
18 printf("could not load eye feature data...\n");
19 return -1;
20 }
21 namedWindow("camera-demo", CV_WINDOW_AUTOSIZE);
22 VideoCapture capture(0);
23 Mat frame;
24 Mat gray;
25 vector<Rect> faces;
26 vector<Rect> eyes;
27 while (capture.read(frame)) {
28 cvtColor(frame, gray, COLOR_BGR2GRAY);
29 equalizeHist(gray, gray);
30 face_cascader.detectMultiScale(gray, faces, 1.2, 3, 0, Size(30, 30));
31
32 //眼睛一定在人脸范围内,通过截取ROI,缩小检测范围提高检测的准确度和速度
33 for (size_t t = 0; t < faces.size(); t++) {
34 Rect roi;
35 roi.x = faces[static_cast<int>(t)].x;
36 roi.y = faces[static_cast<int>(t)].y;
37 roi.width = faces[static_cast<int>(t)].width;
38 roi.height = faces[static_cast<int>(t)].height / 2;
39 Mat faceROI = frame(roi);//截取眼睛ROI,在脸的上半部分
40 eye_cascader.detectMultiScale(faceROI, eyes, 1.2, 3, 0, Size(20, 20));
41 for (size_t k = 0; k < eyes.size(); k++) {
42 Rect rect;
43 rect.x = faces[static_cast<int>(t)].x + eyes[k].x;
44 rect.y = faces[static_cast<int>(t)].y + eyes[k].y;
45 rect.width = eyes[k].width;
46 rect.height = eyes[k].height;
47 rectangle(frame, rect, Scalar(0, 255, 0), 2, 8, 0);//坐标变换得到眼睛真正的坐标
48 }
49 rectangle(frame, faces[static_cast<int>(t)], Scalar(0, 0, 255), 2, 8, 0);
50 }
51 imshow("camera-demo", frame);
52 char c = waitKey(30);
53 if (c == 27) {
54 break;
55 }
56 }
57 waitKey(0);
58 return 0;
59 }


 

级联分类器+模板匹配提高检测的稳定性,实现眼睛的追踪: 



1 #include <opencv2/opencv.hpp>
2 #include <iostream>
3
4 using namespace cv;
5 using namespace std;
6
7 String facefile = "D:/opencv3.1/opencv/build/etc/haarcascades/haarcascade_frontalface_alt.xml";//人脸数据
8 String lefteyefile = "D:/opencv3.1/opencv/build/etc/haarcascades/haarcascade_eye.xml";//左眼数据
9 String righteyefile = "D:/opencv3.1/opencv/build/etc/haarcascades/haarcascade_eye.xml";//右眼数据
10 CascadeClassifier face_detector;
11 CascadeClassifier leftyeye_detector;
12 CascadeClassifier righteye_detector;
13
14 Rect leftEye, rightEye;
15 //Mat& im:ROI区域的图片
16 //Mat& tpl:模板图片
17 //Rect& rect:输入原来目标的外接矩形,返回目标的新外接矩形
18 void trackEye(Mat& im, Mat& tpl, Rect& rect) {
19 Mat result;
20 int result_cols = im.cols - tpl.cols + 1;
21 int result_rows = im.rows - tpl.rows + 1;
22
23 // 模板匹配
24 result.create(result_rows, result_cols, CV_32FC1);
25 matchTemplate(im, tpl, result, TM_CCORR_NORMED);
26
27 // 寻找位置
28 double minval, maxval;
29 Point minloc, maxloc;
30 minMaxLoc(result, &minval, &maxval, &minloc, &maxloc);
31 if (maxval > 0.75) {
32 rect.x = rect.x + maxloc.x;//从ROI中的坐标变换为原图的坐标
33 rect.y = rect.y + maxloc.y;
34 }
35 else {
36 rect.x = rect.y = rect.width = rect.height = 0;
37 }
38 }
39
40 int main(int argc, char** argv) {
41 //加载特征数据
42 if (!face_detector.load(facefile)) {
43 printf("could not load data file...\n");
44 return -1;
45 }
46 if (!leftyeye_detector.load(lefteyefile)) {
47 printf("could not load data file...\n");
48 return -1;
49 }
50 if (!righteye_detector.load(righteyefile)) {
51 printf("could not load data file...\n");
52 return -1;
53 }
54
55 Mat frame;
56 VideoCapture capture(0);
57 namedWindow("demo-win", CV_WINDOW_AUTOSIZE);
58
59 Mat gray;
60 vector<Rect> faces;
61 vector<Rect> eyes;
62 Mat lefttpl, righttpl; // 模板
63 while (capture.read(frame)) {
64 flip(frame, frame, 1);
65 cvtColor(frame, gray, COLOR_BGR2GRAY);
66 equalizeHist(gray, gray);
67 face_detector.detectMultiScale(gray, faces, 1.1, 3, 0, Size(30, 30));//检测人脸
68 for (size_t t = 0; t < faces.size(); t++) {
69 rectangle(frame, faces[t], Scalar(255, 0, 0), 2, 8, 0);
70
71 // 计算 offset ROI
72 int offsety = faces[t].height / 4;
73 int offsetx = faces[t].width / 8;
74 int eyeheight = faces[t].height / 2 - offsety;
75 int eyewidth = faces[t].width / 2 - offsetx;
76
77 // 截取左眼区域
78 Rect leftRect;
79 leftRect.x = faces[t].x + offsetx;
80 leftRect.y = faces[t].y + offsety;
81 leftRect.width = eyewidth;
82 leftRect.height = eyeheight;
83 Mat leftRoi = gray(leftRect);
84
85 // 检测左眼
86 leftyeye_detector.detectMultiScale(leftRoi, eyes, 1.1, 1, 0, Size(20, 20));
87 if (lefttpl.empty()) {
88 if (eyes.size()) {
89 leftRect = eyes[0] + Point(leftRect.x, leftRect.y);
90 lefttpl = gray(leftRect);
91 rectangle(frame, leftRect, Scalar(0, 0, 255), 2, 8, 0);
92 }
93 }
94 else {
95 // 跟踪, 基于模板匹配
96 leftEye.x = leftRect.x;
97 leftEye.y = leftRect.y;
98 trackEye(leftRoi, lefttpl, leftEye);
99 if (leftEye.x > 0 && leftEye.y > 0) {
100 leftEye.width = lefttpl.cols;
101 leftEye.height = lefttpl.rows;
102 rectangle(frame, leftEye, Scalar(0, 0, 255), 2, 8, 0);
103 }
104 }
105
106 // 截取右眼区域
107 Rect rightRect;
108 rightRect.x = faces[t].x + faces[t].width / 2;
109 rightRect.y = faces[t].y + offsety;
110 rightRect.width = eyewidth;
111 rightRect.height = eyeheight;
112 Mat rightRoi = gray(rightRect);
113
114 // 检测右眼
115 righteye_detector.detectMultiScale(rightRoi, eyes, 1.1, 1, 0, Size(20, 20));
116 if (righttpl.empty()) {
117 if (eyes.size()) {
118 rightRect = eyes[0] + Point(rightRect.x, rightRect.y);
119 righttpl = gray(rightRect);
120 rectangle(frame, rightRect, Scalar(0, 255, 255), 2, 8, 0);
121 }
122 }
123 else {
124 // 跟踪, 基于模板匹配
125 rightEye.x = rightRect.x;
126 rightEye.y = rightRect.y;
127 trackEye(rightRoi, righttpl, rightEye);
128 if (rightEye.x > 0 && rightEye.y > 0) {
129 rightEye.width = righttpl.cols;
130 rightEye.height = righttpl.rows;
131 rectangle(frame, rightEye, Scalar(0, 255, 255), 2, 8, 0);
132 }
133 }
134 }
135 imshow("demo-win", frame);
136 char c = waitKey(100);
137 if (c == 27) { // ESC
138 break;
139 }
140 }
141
142 // release resource
143 capture.release();
144 waitKey(0);
145 return 0;
146 }


自定义级联分类器的训练和使用:待续

 

 

命令行参数:

  • -vec <vec_file_name>

输出文件,内含用于训练的正样本。


  • -img <image_file_name>

输入图像文件名(例如一个公司的标志)。


  • -bg <background_file_name>

背景图像的描述文件,文件中包含一系列的图像文件名,这些图像将被随机选作物体的背景。


  • -num <number_of_samples>

生成的正样本的数目。


  • -bgcolor <background_color>

背景颜色(目前为灰度图);背景颜色表示透明颜色。因为图像压缩可造成颜色偏差,颜色的容差可以由 -bgthresh 指定。所有处于 bgcolor-bgthresh 和 bgcolor+bgthresh 之间的像素都被设置为透明像素。


  • -bgthresh <background_color_threshold>
  • -inv

如果指定该标志,前景图像的颜色将翻转。


  • -randinv

如果指定该标志,颜色将随机地翻转。


  • -maxidev <max_intensity_deviation>

前景样本里像素的亮度梯度的最大值。


  • -maxxangle <max_x_rotation_angle>

X轴最大旋转角度,必须以弧度为单位。


  • -maxyangle <max_y_rotation_angle>

Y轴最大旋转角度,必须以弧度为单位。


  • -maxzangle <max_z_rotation_angle>

Z轴最大旋转角度,必须以弧度为单位。


  • -show

很有用的调试选项。如果指定该选项,每个样本都将被显示。如果按下 Esc 键,程序将继续创建样本但不再显示。


  • -w <sample_width>

输出样本的宽度(以像素为单位)。


  • -h <sample_height>

输出样本的高度(以像素为单位)。