当前位置:网站首页>人脸识别示例代码解析(二)——人脸识别解析
人脸识别示例代码解析(二)——人脸识别解析
2022-08-09 14:56:00 【LayeZhao】
上一篇我们初步分析了下示例代码facedetector的程序参数解析部分。其中参数解析的过程如下:
其中第4步黄色标注的部分cascadeName,是我们人脸识别分类器的主要参数。
在openCV中,实现了著名的haar特征检测算法,而依托该算法分类器,我们可以实现人脸识别、定位。
该算法基于特征模板的滑动计算图像特征,从而区分物体的显著轮廓。
这些特征模板形似以下图像:
试想用这些黑白二值图像”蒙”在你的图像或部分图像上,然后你原来的图像被分成“黑”“白”两类区域,最后用黑色区域和白色区域的像素进行简单的加减运算,便能得到图像的基本特征。
例如,我们将模板窗口(3)“蒙”在鼻子部位,便能得到相契合的特征,将模板窗口(4)放在双眼部位,同样能得到与双眼部位契合的特征。

但是如何根据不同图像来确定特征模板窗口的大小,和它们应该放置的位置呢。比如上图,我们怎么知道将特定大小的“上黑下白”特征模板固定在图像的高度3/4上?
答案就是,我们让不知劳累的计算机,测试各种位置和大小。
这是一个巨大的工作量,首先我们如果确定具体特征模板窗口大小为24,24。那么我们就得将待检测图像分为若干个24,24大小区域,试图分别用不同特征模板检测*区域图像是否“匹配”某特征,那么单单一个窗口匹配次数是大于160000,这依然将是一个巨大的工作量。

但如果引入级联分类器——Cascade Classifiers,那么工作量就会极大的缩减。
拿人脸检测来讲,先用一些特征,确定该区域图像“有脸”以及“无脸“,丢掉”无脸“部分,然后再用其他特征检测,来进一步确定特征的是否存在,以及确定其特征位置。
这个过程使得我们匹配特征的过程产生一个“级联“的工作模式,每往下走一层,就会”丢掉“一些无关的区域,这样特征就越来越精确。

从上述过程当中我们可以看到,单独一个特征不能确定最终结果,而是多个特征的级联联合使得最终我们能够做出一个精确的判断。
我们把单个特征的检测叫做弱分类器(因为它不能单独确定最终结果),而把这些弱分类器级联成的最终分类器成为强分类器。可见最终的强分类器是在集成算法的基础上构建的。
好吧,言归正传,openCV实现了这个强分类器,用CascadeClassifier类封装该分类器。你可以实例化该类对象,并设计一个训练计划,来训练想要的特征检测器。
对与人脸检测来说,openCV已经帮我们训练好了分类器,该分类器的参数数据保存在一个xml文件中。

在实际使用过程中,这个文件的路径将作为重要的参数和被检测图像一起传给CascadeClassifier对象,接着对被检测图像中人脸进行定位。
而上一篇中,解析出的参数cascadeName,正是这个文件路径
我们接着上一篇,继续往下做,得到cascadeName后,构造CascadeClassifier对象”cascade”。
然后利用classifier对被检测图像进行人脸预测。
同样,我们简化源代码,此次只对单张图像进行检测。
//根据分类器模板路径cascadeName构造级联分类器(CascadeClassifier)对象"cascade"
cv::CascadeClassifier cascade(cascadeName);
//读入被检测图像
Mat image = imread("D:/试验/test/baby.png");
//定义灰度图像,用于暂存原图像对应的灰度图。
Mat gray;
//将原被检测图像从真彩色图像转换为灰度图
cvtColor(image, gray, cv::COLOR_BGR2GRAY);
//定义一个向量(数组),用于存放所检测出的人脸位置(注意:可能并不只有一个人脸)
vector<Rect> faces;
//启动检测
cascade.detectMultiScale(gray,faces);
//用红色矩形绘制人脸位置结果
for (int i = 0; i < faces.size(); i++)
{
cv::rectangle(image, faces[i], Scalar(255, 0, 0));
}
//显示最终被“标记”的图像
imshow("检测人脸", image);
//等待用户输入任意键结束程序
waitKey();
运行结果:

最后发下关于类CasadeClassifier的官方文档解释,本篇博文多是对该文档的总结https://docs.opencv.org/3.4/db/d28/tutorial_cascade_classifier.html
边栏推荐
猜你喜欢
随机推荐
【小白必看】初始C语言(下)
WebGL:BabylonJS入门——初探:我的世界
【研究生工作周报】(第十二周)
Xgboost系列-XGB实际参数调优指南附源码
22考研中国地质大学-总结
A shortcut method for writing menu commands in C
解决跨域问题的三种方式
模型训练的auc和loss比较问题
数字图像处理的基本原理和常用方法
仪表盘
stream去重相同属性对象
关于初级程序员职场如何提升技能的几点建议?
Different compilers, different modes, impact on results
PAT1027 打印沙漏
面试合集
研究生工作周报(第十三周)
记一次解决Mysql:Incorrect string value: ‘\xF0\x9F\x8D\x83\xF0\x9F...‘ for column 插入emoji表情报错问题
Noun concept summary (not regularly updated ~ ~)
为什么要学编译原理
关于亚马逊测评你了解多少?









