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. Java反射拾遗

    定义:Java反射机制可以让我们在编译期(Compile Time)之外的运行期(Runtime)检查类,接口,变量以及方法的信息.反射还可以让我们在运行期实例化对象,调用方法,通过调用get/set ...

  2. vue的v-html插值样式问题

    content使用html插入文本和图片 使用scoped样式,渲染失败. 原因: 解决方案: 采用全局样式 或另外再加style标签单独渲染

  3. OTSU算法学习 OTSU公式证明

    OTSU算法学习   OTSU公式证明 1 otsu的公式如下,如果当前阈值为t, w0 前景点所占比例 w1 = 1- w0 背景点所占比例 u0 = 前景灰度均值 u1 = 背景灰度均值 u = ...

  4. Android 自定义AlertDialog(退出提示框)

    有时候我们需要在游戏或应用中用一些符合我们样式的提示框(AlertDialog) 以下是我在开发一个小游戏中总结出来的.希望对大家有用. 先上效果图: 下面是用到的背景图或按钮的图片 经过查找资料和参 ...

  5. linux vim 快捷键

    vim命令模式输入a i o 这些命令进入插入模式 编辑模式命令模式输入双引号进入编辑模式 命令模式命令 命令 作用 :map Ctrl+V Ctrl+P I#<ESC> 自定义注释快捷键 ...

  6. centos7 yum安装mysql | mariaDb

    mysql解释: mysql数据库是最常用的一种数据库,下面我来在centos7的迷你版上安装一下mysql.绝对纯净的环境哦 centos:    CentOS-7-x86_64-Minimal-1 ...

  7. maven一键部署linux的tomcat(wagon-maven-plugin)

    Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Depen ...

  8. 4.HTML字符集

    1.HTML 中的预留字符必须被替换为字符实体. 一些在键盘上找不到的字符也可以使用字符实体来替换. 在 HTML 中,某些字符是预留的.您不能使用包含这些字符的文本. 在 HTML 中不能使用小于号 ...

  9. [EXCEL] 不能清除剪贴板: We couldn't free up space on the clipboard. Another program might be using it right now

    Excel复制粘贴时出现以下错误,原因是有程序占用了剪切板. We couldn't free up space on the clipboard. Another program might be ...

  10. jQuery插件实例二:年华时代插件ReturnTop回到首页

    这个插件功能在于当网页内容高度很高时,方便用户快速回到顶部.核心在于对屏幕高度的获取,定时器的使用,在引用代码后,只使用$.nhsd.returnTop();即可实现效果 效果图: 代码: ; fun ...