Opencv——級聯分類器(AdaBoost)


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-bgthreshbgcolor+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>

    輸出樣本的高度(以像素為單位)。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM