OpenCV人脸检测(C++代码)—— By wepon
2016-10-27 17:25
387 查看
OpenCV人脸检测(C++代码)—— By wepon
这篇文章简单总结一下人脸检测的代码实现,基于OpenCV,C++版本。之所以强调C++版本是因为OpenCV有很多其他语言的接口,之前我也写过人脸检测的Python实现《Python-OpenCV人脸检测(代码)》,这篇文章则讲C++实现,其实大同小异,C++相比于Python实现代码写起来会繁琐一点,这也是语言本身决定的吧。为了保持代码风格一致,C++实现与之前的Python实现一样,都将人脸检测、眼睛检测、框出人脸、框出眼睛、截取保存人脸各个功能封装为函数,方便移植。
1、OpenCV中人脸检测采用的算法
在安装OpenCV的路径中(window系统),我们可以发现”…\opencv\sources\data”目录下有如下三个文件夹:这正是OpenCV采用的算法。haarcascades文件下存放的是采用Haar特征的级联分类器(Cascade Classfier),hogcascades下存放采用HOG特征(梯度方向直方图)的级联分类器,lbpcascades下存放的是采用LBP特征的级联分类器。关于图像的Haar、LBP、HOG、SIFT等特征我将写另外的博文进行总结,这里就不详细展开。图中三个文件夹下存放了很多xml文件,这些是预先训练好的特征,用于构造分类器的,有人脸检测的、眼睛检测的、smile检测的、行人检测的等等。
在这篇文章中,仅以haarcascas下的”haarcascade_frontalface_alt.xml”和”haarcascade_eye.xml”作为例子。主要代码在下文讲解,更多代码也可以到我的github获取:here。
2、代码实现
这个demo以下图为输入:图像预处理
转化为灰度图
直方图均衡化
<code class="hljs bash has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">Mat img = imread(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"obama.jpg"</span>); Mat img_gray; cvtColor(img,img_gray,COLOR_BGR2GRAY ); equalizeHist(img_gray,img_gray);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
构造级联分类器
首先生成一个级联分类器的实例,然后用xml文件初始化该实例(调用load方法),最后调用该实例的detectMultiScale方法,作用在灰度图img_gray上,即可获取该图片中的各个人脸的坐标。detectMultiScale方法返回的是一个vector类型的容器,里面每个Rect存储的是人脸矩形的左上顶点、矩形宽度、矩形长度(x,y,width,height)。
<code class="hljs cpp has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;">CascadeClassifier faces_cascade; faces_cascade.load(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"haarcascade_frontalface_alt.xml"</span>); <span class="hljs-stl_container" style="box-sizing: border-box;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">vector</span><Rect></span> faces; faces_cascade.detectMultiScale(img_gray,faces,<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1.1</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>|CV_HAAR_SCALE_IMAGE, Size(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">30</span>, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">30</span>) );</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li></ul>
框出人脸、眼睛
这部分用到的是opencv里的绘图工具,可以参考opencv文档基本绘画,这里不啰嗦。ellipse画椭圆、circle画圆形,它们的参数(比如circle的圆心半径)由级联分类器返回的Rect确定。
截取和保存人脸部分
可以根据级联分类器检测返回的Rect,获取图像的ROI,然后调用imwrite方法。
<code class="hljs fix has-numbering" style="display: block; padding: 0px; background: transparent; color: inherit; box-sizing: border-box; font-family: "Source Code Pro", monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal;"><span class="hljs-attribute" style="box-sizing: border-box;">Rect roi </span>=<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;"> faces[i]; imwrite(saveName,img(roi));</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right: 1px solid rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li></ul>
由于检测出的face不只一个,所以saveName需要设计一下,具体在代码文件中有注释。
运行结果
转载请注明来源并完整保留文中链接:http://blog.csdn.net/u012162613/article/details/44081975
相关文章推荐
- OpenCV人脸检测(C++代码)
- OpenCV中人脸检测代码实现
- OpenCV - 人脸检测(face detection) 代码
- Python-OpenCV人脸检测(代码)
- Android(安卓)开发通过NDK调用JNI,使用opencv做本地c++代码开发配置方法实现边缘检测代码(2)
- opencv从摄像头读取视频并实时进行人脸检测代码
- OpenCV Haar分类器人脸检测部分代码注释
- c++结合opencv进行人脸检测
- openCV 人脸检测 VC2008代码
- 基于opencv的人脸检测代码
- Python-OpenCV人脸检测(代码)
- OpenCV学习笔记(三)人脸检测的代码分析(2)
- OpenCV学习笔记(三)人脸检测的代码分析
- OpenCV人脸检测代码分析
- opencv 利用类haar小波特征的人脸、人眼等特征检测(带代码)
- Android(安卓)开发通过NDK调用JNI,使用opencv做本地c++代码开发配置方法 边缘检测 范例代码
- 基于OpenCV的人脸检测代码
- 简单opencv人脸检测代码:LBP/Haar特征
- Android(安卓)开发通过NDK调用JNI,使用opencv做本地c++代码开发配置方法 边缘检测 范例代码
- OpenCV检测人脸实例代码