API说明:

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

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

 #include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
using namespace std; String fileName = "D:/opencv3.1/opencv/build/etc/haarcascades/haarcascade_frontalface_alt.xml";//设置文件路径
CascadeClassifier face_classifier;//创建分类器 int main(int argc, char** argv) {
if (!face_classifier.load(fileName)) {//加载分类数据
printf("could not load face feature data...\n");
return -;
} Mat src = imread("D:/vcprojects/images/test.png");
if (src.empty()) {
printf("could not load image...\n");
return -;
}
imshow("input image", src);
Mat gray;
cvtColor(src, gray, COLOR_BGR2GRAY);//转成灰度图
equalizeHist(gray, gray);//直方图均衡化,提高对比度 vector<Rect> faces;
face_classifier.detectMultiScale(gray, faces, 1.2, , , Size(, ));//在多尺度上检测
for (size_t t = ; t < faces.size(); t++) {
rectangle(src, faces[static_cast<int>(t)], Scalar(, , ), , , );
} imshow("detect faces", src);
waitKey();
return ;
}

进阶:人眼检测

 #include<opencv2/opencv.hpp>
#include<iostream> using namespace cv;
using namespace std; CascadeClassifier face_cascader;
CascadeClassifier eye_cascader;
String facefile = "D:/opencv3.1/opencv/build/etc/haarcascades/haarcascade_frontalface_alt.xml";
String eyefile = "D:/opencv3.1/opencv/build/etc/haarcascades/haarcascade_eye.xml"; int main(int argc, char** argv) {
if (!face_cascader.load(facefile)) {
printf("could not load face feature data...\n");
return -;
}
if (!eye_cascader.load(eyefile)) {
printf("could not load eye feature data...\n");
return -;
}
namedWindow("camera-demo", CV_WINDOW_AUTOSIZE);
VideoCapture capture();
Mat frame;
Mat gray;
vector<Rect> faces;
vector<Rect> eyes;
while (capture.read(frame)) {
cvtColor(frame, gray, COLOR_BGR2GRAY);
equalizeHist(gray, gray);
face_cascader.detectMultiScale(gray, faces, 1.2, , , Size(, )); //眼睛一定在人脸范围内,通过截取ROI,缩小检测范围提高检测的准确度和速度
for (size_t t = ; t < faces.size(); t++) {
Rect roi;
roi.x = faces[static_cast<int>(t)].x;
roi.y = faces[static_cast<int>(t)].y;
roi.width = faces[static_cast<int>(t)].width;
roi.height = faces[static_cast<int>(t)].height / ;
Mat faceROI = frame(roi);//截取眼睛ROI,在脸的上半部分
eye_cascader.detectMultiScale(faceROI, eyes, 1.2, , , Size(, ));
for (size_t k = ; k < eyes.size(); k++) {
Rect rect;
rect.x = faces[static_cast<int>(t)].x + eyes[k].x;
rect.y = faces[static_cast<int>(t)].y + eyes[k].y;
rect.width = eyes[k].width;
rect.height = eyes[k].height;
rectangle(frame, rect, Scalar(, , ), , , );//坐标变换得到眼睛真正的坐标
}
rectangle(frame, faces[static_cast<int>(t)], Scalar(, , ), , , );
}
imshow("camera-demo", frame);
char c = waitKey();
if (c == ) {
break;
}
}
waitKey();
return ;
}

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

 #include <opencv2/opencv.hpp>
#include <iostream> using namespace cv;
using namespace std; String facefile = "D:/opencv3.1/opencv/build/etc/haarcascades/haarcascade_frontalface_alt.xml";//人脸数据
String lefteyefile = "D:/opencv3.1/opencv/build/etc/haarcascades/haarcascade_eye.xml";//左眼数据
String righteyefile = "D:/opencv3.1/opencv/build/etc/haarcascades/haarcascade_eye.xml";//右眼数据
CascadeClassifier face_detector;
CascadeClassifier leftyeye_detector;
CascadeClassifier righteye_detector; Rect leftEye, rightEye;
//Mat& im:ROI区域的图片
//Mat& tpl:模板图片
//Rect& rect:输入原来目标的外接矩形,返回目标的新外接矩形
void trackEye(Mat& im, Mat& tpl, Rect& rect) {
Mat result;
int result_cols = im.cols - tpl.cols + ;
int result_rows = im.rows - tpl.rows + ; // 模板匹配
result.create(result_rows, result_cols, CV_32FC1);
matchTemplate(im, tpl, result, TM_CCORR_NORMED); // 寻找位置
double minval, maxval;
Point minloc, maxloc;
minMaxLoc(result, &minval, &maxval, &minloc, &maxloc);
if (maxval > 0.75) {
rect.x = rect.x + maxloc.x;//从ROI中的坐标变换为原图的坐标
rect.y = rect.y + maxloc.y;
}
else {
rect.x = rect.y = rect.width = rect.height = ;
}
} int main(int argc, char** argv) {
//加载特征数据
if (!face_detector.load(facefile)) {
printf("could not load data file...\n");
return -;
}
if (!leftyeye_detector.load(lefteyefile)) {
printf("could not load data file...\n");
return -;
}
if (!righteye_detector.load(righteyefile)) {
printf("could not load data file...\n");
return -;
} Mat frame;
VideoCapture capture();
namedWindow("demo-win", CV_WINDOW_AUTOSIZE); Mat gray;
vector<Rect> faces;
vector<Rect> eyes;
Mat lefttpl, righttpl; // 模板
while (capture.read(frame)) {
flip(frame, frame, );
cvtColor(frame, gray, COLOR_BGR2GRAY);
equalizeHist(gray, gray);
face_detector.detectMultiScale(gray, faces, 1.1, , , Size(, ));//检测人脸
for (size_t t = ; t < faces.size(); t++) {
rectangle(frame, faces[t], Scalar(, , ), , , ); // 计算 offset ROI
int offsety = faces[t].height / ;
int offsetx = faces[t].width / ;
int eyeheight = faces[t].height / - offsety;
int eyewidth = faces[t].width / - offsetx; // 截取左眼区域
Rect leftRect;
leftRect.x = faces[t].x + offsetx;
leftRect.y = faces[t].y + offsety;
leftRect.width = eyewidth;
leftRect.height = eyeheight;
Mat leftRoi = gray(leftRect); // 检测左眼
leftyeye_detector.detectMultiScale(leftRoi, eyes, 1.1, , , Size(, ));
if (lefttpl.empty()) {
if (eyes.size()) {
leftRect = eyes[] + Point(leftRect.x, leftRect.y);
lefttpl = gray(leftRect);
rectangle(frame, leftRect, Scalar(, , ), , , );
}
}
else {
// 跟踪, 基于模板匹配
leftEye.x = leftRect.x;
leftEye.y = leftRect.y;
trackEye(leftRoi, lefttpl, leftEye);
if (leftEye.x > && leftEye.y > ) {
leftEye.width = lefttpl.cols;
leftEye.height = lefttpl.rows;
rectangle(frame, leftEye, Scalar(, , ), , , );
}
} // 截取右眼区域
Rect rightRect;
rightRect.x = faces[t].x + faces[t].width / ;
rightRect.y = faces[t].y + offsety;
rightRect.width = eyewidth;
rightRect.height = eyeheight;
Mat rightRoi = gray(rightRect); // 检测右眼
righteye_detector.detectMultiScale(rightRoi, eyes, 1.1, , , Size(, ));
if (righttpl.empty()) {
if (eyes.size()) {
rightRect = eyes[] + Point(rightRect.x, rightRect.y);
righttpl = gray(rightRect);
rectangle(frame, rightRect, Scalar(, , ), , , );
}
}
else {
// 跟踪, 基于模板匹配
rightEye.x = rightRect.x;
rightEye.y = rightRect.y;
trackEye(rightRoi, righttpl, rightEye);
if (rightEye.x > && rightEye.y > ) {
rightEye.width = righttpl.cols;
rightEye.height = righttpl.rows;
rectangle(frame, rightEye, Scalar(, , ), , , );
}
}
}
imshow("demo-win", frame);
char c = waitKey();
if (c == ) { // ESC
break;
}
} // release resource
capture.release();
waitKey();
return ;
}

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

命令行参数:

  • -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>

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

Opencv——级联分类器(AdaBoost)的更多相关文章

  1. OpenCV——级联分类器(CascadeClassifier)

    级联分类器的计算特征值的基础类FeatureEvaluator 功能:读操作read.复制clone.获得特征类型getFeatureType,分配图片分配窗口的操作setImage.setWindo ...

  2. OpenCV 级联分类器

    #include "opencv2/objdetect/objdetect.hpp" #include "opencv2/highgui/highgui.hpp" ...

  3. Opencv级联分类器实现人脸识别

    在本章中,我们将学习如何使用OpenCV使用系统相机捕获帧.org.opencv.videoio包的VideoCapture类包含使用相机捕获视频的类和方法.让我们一步一步学习如何捕捉帧 - 第1步: ...

  4. OpenCV使用级联分类器实现人脸检测

    一.概述 案例:使用opencv级联分类器CascadeClassifier+其提供的特征数据实现人脸检测,检测到人脸后使用红框画出来. API介绍:detectMultiScale( InputAr ...

  5. 如何利用OpenCV自带的级联分类器训练程序训练分类器

    介绍 使用级联分类器工作包括两个阶段:训练和检测. 检测部分在OpenCVobjdetect 模块的文档中有介绍,在那个文档中给出了一些级联分类器的基本介绍.当前的指南描述了如何训练分类器:准备训练数 ...

  6. OpenCV开发笔记(七十一):红胖子8分钟带你深入级联分类器训练

    前言   红胖子,来也!  做图像处理,经常头痛的是明明分离出来了(非颜色的),分为几块区域,那怎么知道这几块区域到底哪一块是我们需要的,那么这部分就涉及到需要识别了.  识别可以自己写模板匹配.特征 ...

  7. 【原/转】opencv的级联分类器训练与分类全程记录

    众所周知,opencv下有自带的供人脸识别以及行人检测的分类器,也就是说已经有现成的xml文件供你用.如果我们不做人脸识别或者行人检测,而是想做点其他的目标检测该怎么做呢?答案自然是自己训练一个特定的 ...

  8. 利用opencv中的级联分类器进行人脸检測-opencv学习(1)

    OpenCV支持的目标检測的方法是利用样本的Haar特征进行的分类器训练,得到的级联boosted分类器(Cascade Classification).注意,新版本号的C++接口除了Haar特征以外 ...

  9. 使用OpenCV训练好的级联分类器识别人脸

    一.使用OpenCV训练好的级联分类器来识别图像中的人脸 当然还有很多其他的分类器,例如表情识别,鼻子等,具体可在这里下载: OpenCV分类器 import cv2 # 矩形颜色和描边 color ...

随机推荐

  1. Linux 文件缓存 (二)

    close系统调用入口1. 首先来到系统调用入口,主要使用__close_fd进行了具体的处理过程,并没有耗时操作.(current->files表示进程当前打开文件表信息,fd为需要关闭的文件 ...

  2. Codeforces 981H:K Paths

    传送门 考虑枚举一条路径 \(u,v\),求出所有边经过它的答案 只需要求出 \(u\) 的子树内选出 \(k\) 个可以重复的点,使得它们到 \(u\) 的路径不相交 不难发现,就是从 \(u\) ...

  3. BZOJ4144: [AMPPZ2014]Petrol(最短路 最小生成树)

    题意 题目链接 Sol 做的时候忘记写题解了 可以参考这位大爷 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...

  4. java运算符优先级别

    算数-->关系-->逻辑-->赋值

  5. [微信小程序] 微信小程序获取用户定位信息并加载对应城市信息,wx.getLocation,腾讯地图小程序api,微信小程序经纬度逆解析地理信息

    因为需要在小程序加个定位并加载对应城市信息 然而小程序自带api目前只能获取经纬度不能逆解析,虽然自己解析方式,但是同时也要调用地图,难道用户每次进小程序还要强行打开地图选择地址才定位吗?多麻烦也不利 ...

  6. css雪碧技术的用法。

    ---恢复内容开始--- 在目前前端开发阶段,页面会出现大量的小图片,服务器加载的时候比较吃力,怎么用 一种办法把图片都合并到一张图片上呢?这就用到了css雪碧技术. 雪碧技术是雪碧团队开发,也有人叫 ...

  7. 如何调试flutter应用

    The Dart Analyzer 这个工具帮助你分析代码,发现可能的错误. 运行命令行 终端进入flutter工程所在目录,执行flutter analyze 使用IntelliJ IDEA Dar ...

  8. vue.js高仿饿了么(前期整理)

    1.熟悉项目开发流程 需求分析——>脚手架工具——>数据mock——>架构设计——>代码编写——>自测——>编译打包. 2.熟悉代码规范 从架构设计.组件抽象.模块 ...

  9. laravel session的几个特点

    1. 只要访问了网站,就会创建一个临时的session 2.用户登录后sessionid就会发生变化 3.在这期间,即使使用4g网络,ip地址会不断发生变化,只要cookie中包含了sessionid ...

  10. 创建和修改 ExpressRoute 线路的对等互连

    本文将指导你执行相关步骤,以便使用 Azure 门户和 Resource Manager 部署模型创建和管理 ExpressRoute 线路的路由配置. 配置先决条件 在开始配置之前,请务必查看先决条 ...