Python这门语言的十分的简洁和优雅,并且有着丰富的第三方库。在这里,它只需要7行代码就能完成人脸的检测,让我们试着来玩一下吧,感受一下它的魅力。
1、首先需要导入包
所用电脑为window系统,Python版本为3.6.0
numpy(图片数字化),opencv-python(摄像头和图片处理),scipy(科学计算),dlib(人脸识别)
实际上简单的人脸检测不需要导入这么多包,只需要导入opencv-python这个就足够了。我这里写这么多是因为我看的第一篇文章用50行Python代码实现人脸检测点击打开链接,但我并没有成功,可能是因为某些方面没让我看明白。首先,我在导包的时候就碰到了一些问题。导包过程其实很简单,cmd打开命令行,然后在弹出的窗口中输入:
pip install numpy
pip install scipy
pip install opencv-python
这一步一切都很顺利
这里要说一下这个dlib包,dlib的导入就没有这么成功了,因为它依赖Boost和cmake两个包,所以在导入dlib前需要将这两个包导入。否则就会报一下错误:
怎么导入dlib了,网上方法很多是在Ubuntu下操作的,那我岂不是还要装个虚拟机或双系统才行,我想太麻烦了,其实也没必要。可以直接在网上找到自己安装Python版本对应的dlib包即可。怎么查看下载哪个包么,win7下按下windows键的所有程序中找到安装python对应的IDLE界面,打开对应的shell:
输入命令:
import pip;
print(pip.pep425tags.get_supported());即可显示需要下载的版本。
因此,我在网上找了好久,其实csdn上也有很多人上传了,但是要积分才能下,不够人性化,找到了python3.6下对应的dlib包https://pypi.python.org/pypi/dlib/19.8.1
dlib-19.8.1-cp36-cp36m-win_amd64.whl (md5)
然后cmd命令窗口cd进入下载的dlib报下的目录,输入:
pip install dlib-19.8.1-cp36-cp36m-win_amd64.whl 即可。
感觉走远了,但要作进一步的人脸识别的话,这些包必须要导入。言归正传,接下来看看7行代码如何实现检测的。
2、代码实现与说明
第一行 引入OpenCV
import cv2
openCV是一个基于BSD许可发行的跨平台计算机视觉库,可以运行在Linux、Windows和Mac OS操作系统上,轻量而且高效,用C/C++编写,同时提供Python、Ruby、Matlab等接口,实现了图像处理和计算机视觉方面的很多通用算法。
第2行 加载分类器cv2.CascadeClassifier
face_patterns = cv2.CascadeClassifier('C:/Users/###/AppData/Local/Programs/Python/Python36/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml')
这里要说明一下,找到安装openCV目录下的haarcascade_frontalface_default.xml即可。
怎么找了,我是用的PyCharm工具,点击PyCharm文件下的设置按钮,找到项目,打开:
这个并非要找的路径,但是这个提供了找到xml文件的线索,进入Python36目录下的Lib,Lib目录下的site-packages,这里有很多导入的包,进入cv2文件夹下的data,是不是感觉发现新大陆了,里面有很多xml
CascadeClassifier是OpenCV中做人脸检测时候的一个级联分类器,该类中封装的是目标检测机制即滑动窗口机制+级联分类器的方式。数据结构包括Data和FeatureEvaluator两个主要部分。Data中存储的是从训练获得的xml文件中载入的分类器数据;而FeatureEvaluator中关于特征的载入、存储和计算。这里采用的训练文件是OpenCV中默认提供的haarcascade_frontalface_default.xml。至于Haar,LBP的具体原理,可以参考OpenCV的相关文档,简单地,可以理解为人脸的特征数据。
第3行 加载目标图片imread
sample_image = cv2.imread('E:/###/pythonprojects/Face/c23e4fd29d58e9eac327b781a04d695d.jpg')
这一步是读取相应的图片,imread后是图片的路径,下面是我测试用的图片,百度图片下的:
第4行 多尺度检测detectMultiScale
faces = face_patterns.detectMultiScale(sample_image, scaleFactor=1.1, minNeighbors=5, minSize=(100, 100))
CascadeClassifier中调detectMultiScale函数进行多尺度检测,多尺度检测中会调用但尺度的方法detectSingleScale。
参数说明:
scaleFactor: 图形的缩放因子
minNeighbors:为每一个级联矩阵应该保留的邻近个数,可以理解为一个人周边有几个人脸
minSize:是检测窗口的大小
这些参数都是可以针对图片进行调整的,处理结果返回一个人脸的矩形对象列表。
第5行和第6行 为每个人脸画一个框
for (x, y, w, h) in faces:
cv2.rectangle(sample_image, (x, y), (x+w, y+h), (0, 255, 0), 2)
循环读取人脸的矩形对象列表,获得人脸矩形的坐标和宽高,然后在原图片中画出该矩形框,调用的是OpenCV的retangle方法,其中矩形框的颜色等是可调整的。
第7行 保存检测后的图片结果
cv2.imwrite('E:/###/pythonprojects/Face/smilegirl1.png', sample_image)
调用imwrite,将检测的结果保存到指定位置。打开图片:
是不是觉得很神奇了。
其实这个方法并非十全十美,我之前用截的图来进行检测但并没有得到任何结果,可见对于不太清晰的图片,该方法就会有遗漏,你看上面的第一张人脸不是也没有检测出来么。
3、整理代码
import cv2
face_patterns = cv2.CascadeClassifier('C:/Users/###/AppData/Local/Programs/Python/Python36/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml')
sample_image = cv2.imread('E:/###/pythonprojects/Face/c23e4fd29d58e9eac327b781a04d695d.jpg')
faces = face_patterns.detectMultiScale(sample_image, scaleFactor=1.1, minNeighbors=5, minSize=(100, 100))
for (x, y, w, h) in faces:
cv2.rectangle(sample_image, (x, y), (x+w, y+h), (0, 255, 0), 2)
cv2.imwrite('E:/###/pythonprojects/Face/smilegirl1.png', sample_image)
是不是更清晰了,7行代码中真正核心的是OpenCV。有兴趣的可以多花点时间研究下其中的原理。
参考链接: