zoukankan      html  css  js  c++  java
  • 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...
    ");
    13         return -1;
    14     }
    15 
    16     Mat src = imread("D:/vcprojects/images/test.png");
    17     if (src.empty()) {
    18         printf("could not load image...
    ");
    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...
    ");
    15         return -1;
    16     }
    17     if (!eye_cascader.load(eyefile)) {
    18         printf("could not load eye feature data...
    ");
    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...
    ");
     44         return -1;
     45     }
     46     if (!leftyeye_detector.load(lefteyefile)) {
     47         printf("could not load data file...
    ");
     48         return -1;
     49     }
     50     if (!righteye_detector.load(righteyefile)) {
     51         printf("could not load data file...
    ");
     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>

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

  • 相关阅读:
    Animation用法
    英文口语及书写常用句型汇总1
    Jqplot使用总结之二(双Y轴)
    SqlServer扩展存储过程
    SQL Server常见基础操作
    C# 利用ITextSharp导出PDF文件
    go常量
    ARP协议
    go数组
    go基本数据类型
  • 原文地址:https://www.cnblogs.com/long5683/p/9862078.html
Copyright © 2011-2022 走看看