若该文为原创文章,未经允许不得转载
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/106057214
各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究
红胖子(红模仿)的博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬结合等等)持续更新中...(点击传送门)
OpenCV开发专栏(点击传送门)
上一篇:《OpenCV开发笔记(五十三):红胖子8分钟带你深入了解模板匹配识别(图文并茂+浅显易懂+程序源码)》
下一篇:持续补充中…
前言
红胖子来也!!!
上一篇使用了模板匹配去识别人脸,本篇章使用OpenCV提供的级联分类器进行人脸识别。
Demo
人脸识别技术
人脸识别技术有两大类:
基于几何特征的人脸检测
使用人脸组合的几何特征的方式识别人脸,人脸的几何特征:眼睛、眉毛、鼻子、脸颊、额头、嘴巴、下巴等等;
基于统计特征的人脸检测
使用模式识别的方法实现特性人脸的训练,在进行相似度判断,如神经网络等分类方法。
Haar级联分类器
概述
Haar级联分类器就是基于Haar特征的级联分类器,涉及到两个概念:一个是Haar特征,一个是级联分类器。
Haar特征
本篇章Demo是基于Haar特征的,使用了openCV自带的Haar分类器初始化文件。
(关于具体的将会在后续的文章中解说)
级联分类器
级联分类器类的检测框架简而言之就是一个多尺度缩放+滑动窗口遍历搜索的框架。
级联分类器试讲若干个分类器进行连接,从而构成一种多项式的强分类方法,单个分类器可以由若干个弱分类器加权组成。
(关于具体的将会在后续的文章中解说)
OpenCV基于级联分类器的人脸识别
级联分类器类CascadeClassifier
OpenCV提供了CascadeClassifier用于检测物体的级联分类器,其使用过程是先需要读取加载一个文件读取分类器。
bool CascadeClassifier::load( const String& filename );
- 参数一:String类型的filename,读取级联分类器初始化文件;
然后使用人脸检测函数,进行人脸检测。
级联分类器检测人脸函数原型
(注意:有三个重载函数)
void CascadeClassifier::detectMultiScale( InputArray image,
std::vector<Rect>& objects,
double scaleFactor = 1.1,
int minNeighbors = 3,
int flags = 0,
Size minSize = Size(),
Size maxSize = Size());
- 参数一:InputArray类型的image,包含检测到对象的图像的CV_8U类型的图像矩阵,即Mat;
- 参数二:std::vector<Rect>类型的objects,矩形的对象向量,其中每个矩形包含检测到的对象矩形可能部分位于原始图像之外,即人脸区域矩形;
- 参数三:double类型的scaleFactor,指定在每个图像比例下图像大小减小的程度;
- 参数四:int类型的minNeighbors,匹配成功所需要的周围矩形框的数目(由于调整滑动窗口的大小和很多误报),每一个特征匹配到的区域都是一个矩形框,只有多个矩形框同时存在的时候,才认为是匹配成功,比如人脸,这个默认值是3;
- 参数五:int类型的flags,标记与函数中的旧级联具有相同含义的参cvHaarDetectObjects,它不用于新的级联,类型参照:
- 参数六:Size类型的fminSize,最小可能的对象大小。小于该值的对象将被忽略;
- 参数七:Size类型的maxSize,最大可能对象大小。大于该值的对象将被忽略。如果“maxSize==minSize”模型是按单个比例计算的;
openCV级联分类器初始化文件
Demo涉及其他相关技术
OpenCV操作视频,请查看博文:《OpenCV开发笔记(四):OpenCV图片和视频数据的读取与存储》
OpenCV绘制图形,请查看博文:《OpenCV开发笔记(七):OpenCV基础图形绘制》
Demo源码
void OpenCVManager::testCascadeClassifier()
{
cv::String windowName = _windowTitle.toStdString();
cvui::init(windowName);
cv::Mat windowMat = cv::Mat(cv::Size(520, 400),
CV_8UC3);
cv::VideoCapture videoCapture;
videoCapture.open("E:/testFile/4.avi");
// videoCapture.open("E:/testFile/4.mp4");
cv::Mat mat;
cv::Mat dstMat;
int currentIndex = 0;
// 级联人脸分类器
cv::CascadeClassifier cascadeClassifier;
cascadeClassifier.load("E:/qtProject/openCVDemo/openCVDemo/modules/openCVManager/data/haarcascades/haarcascade_frontalface_alt.xml");
while(true)
{
// 刷新全图黑色
windowMat = cv::Scalar(0, 0, 0);
currentIndex = videoCapture.get(cv::CAP_PROP_POS_FRAMES);
videoCapture >> mat;
if(!mat.empty())
{
dstMat = mat.clone();;
// 灰度变换
cv::Mat grayMat;
cv::cvtColor(dstMat, grayMat, CV_BGR2GRAY);
// 直方图均衡化
cv::Mat histMat;
cv::equalizeHist(grayMat, histMat);
// 多尺度人脸检测
std::vector<cv::Rect> faces;
cascadeClassifier.detectMultiScale(histMat,
faces,
1.1,
3,
0 | cv::CASCADE_SCALE_IMAGE,
cv::Size(10, 10));
qDebug() << __FILE__ << __LINE__ << "faces number:" << faces.size();
// 人脸检测结果判定
for(int index = 0; index < faces.size(); index++)
{
// 检测到人脸
cv::rectangle(dstMat, faces.at(index), cv::Scalar(0, 0, 255));
}
// 视频复制
mat = windowMat(cv::Range(0, 0 + dstMat.rows),
cv::Range(0, 0 + dstMat.cols));
cv::addWeighted(mat, 0.0f, dstMat, 1.0f, 0.0f, mat);
}
// 更新
cvui::update();
// 显示
cv::imshow(windowName, windowMat);
// esc键退出
int key = cv::waitKey(0);
switch (key) {
case 97: // 'a' 往前一帧
currentIndex--;
if(currentIndex < 0)
{
currentIndex = 0;
}
videoCapture.set(cv::CAP_PROP_POS_FRAMES, currentIndex);
break;
case 115: // ‘s’ 往后一帧
break;
default:
break;
}
if(key == 27)
{
break;
}
}
}
工程模板:对应版本号v1.49.0
对应版本号v1.49.0
上一篇:《OpenCV开发笔记(五十三):红胖子8分钟带你深入了解模板匹配识别(图文并茂+浅显易懂+程序源码)》
下一篇:持续补充中…
原博主博客地址:https://blog.csdn.net/qq21497936
原博主博客导航:https://blog.csdn.net/qq21497936/article/details/102478062
本文章博客地址:https://blog.csdn.net/qq21497936/article/details/106057214