25 行 Python 代码实现人脸识别——OpenCV 技术教程
OpenCV
OpenCV 是最流行的计算机视觉库,原本用 C 和 C++ 开发,现在也支持 Python。
它使用机器学习算法在图像中搜索人的面部。对于人脸这么复杂的东西,并没有一个简单的检测能对是否存在人脸下结论,而需要成千上万的特征匹配。算法把人脸识别任务分解成数千个小任务,每个都不难处理。这些任务也被称为分类器。
对于类似于人脸的对象,你或许需要不少于 6000 个分类器,每一个都需要成功匹配(当然,有容错率),才能检测出人脸。但这有一个问题:对于人脸识别,算法从左上角开始计算一个个数据块,不停问“这是张脸吗”。每个数据块有超过 6000 个检测,加起来的计算量会达到数百万级别,计算机很可能会让你等得花儿都谢了。
OpenCV 使用 cascades 来避免这种情况。Cascade 是什么?最佳答案已经在字典里了:一条瀑布或者连续瀑布。
好比连续瀑布,OpenCV cascade 把人脸检测问题分解为好几步。对于每个数据块,它都进行一个粗略、快速的检测。若通过,会再进行一个更仔细的检测,以此不断类推。该算法有 30 到 50 个这样的阶段,或者说 cascade。只有通过全部阶段,算法才会判断检测到人脸。这样做的好处是:大多数图形都会在头几步就产生否定反馈,算法因而不需要在它上面测试所有 6000 个特征,大大节省了时间。相对于“正常流程”耗费数个小时,这可以实时实现人脸检测。
实践中的 Cascade
它的理论也许听起来很复杂,实际操作起来其实是很简单的。这些 cascades 只是一系列包含 OpenCV 数据的 XML 文件。你用想要的 cascade 初始化代码,它自会替你做你想要的事。
由于人脸识别的普遍性,OpenCV 有一系列能检测各种东西的内置 cascade,从眼睛到手到腿都可以检测。甚至还有针对非人体物体的 cascade。比如说,如果你经营一家卖香蕉的水果店,想要监测偷香蕉的人,就有一个家伙开发了一个针对这一场景的算法!
安装 OpenCV
首选,你需要找到对应你的操作系统的正确设置文件。
我发现,安装 OpenCV 是最难的一个环节。如果你遇到奇怪的、无法解释的错误,有可能是库崩溃了、32 与 64 比特的兼容问题等等。个人经验是,只用 Linux 虚拟机,从头安装 OpenCV 最简单。
安装好之后,你可以开启一个 Python 会话,敲出下面的代码,来测试它是否能工作:
$ python
>>> import cv2
>>>
如果没弹出任何错误,你就可以到下个环节了。
理解代码
源代码可在资源库下载。记得拿好 face_detect.py 文本、abba.png 图片以及 haarcascade_frontalface_default.xml。下面,我把代码分解开来。
# Get user supplied values
imagePath = sys.argv[1]
cascPath = sys.argv[2]
将图片和 cascade 名字作为命令行参数传入。我们会用 Abba 图片和 OpenCV 提供的默认 cascade 来人脸检测。
# Create the haar cascade
faceCascade = cv2.CascadeClassifier(cascPath)
现在,我们创建一个 cascade,并用人脸 cascade 初始化。这把人脸 cascade 导入内存,所以它随时可以使用。记住,该 cascade 只是一个包含人脸检测数据的 XML 文件。
# Read the image
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
读取图片把它转化到灰度格式。
# Detect faces in the image
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
flags = cv2.cv.CV_HAAR_SCALE_IMAGE
)
该函数做的就是检测人脸,是代码核心部分。所以,我们来过一遍选项。
DetectMultiScale 函数是一个检测物体的通用函数。我们在人脸 cascade 上调用它,它检测的就是人脸。第一个选项是灰度图片。
第二个是 scaleFactor。有的人脸离镜头近,会比其他人脸更大。ScaleFactor 对此进行补偿。
检测算法使用移动窗口来检测物体。在系统宣布检测到人脸之前,minNeighbors 会对当前其周围有多少物体进行定义。MinSize 给出每个窗口的大小。
我用的是这些领域的常用值。现实中,你会拿不同的值试验窗口尺寸、扩展因素等参数,直到找出最比较合适的那一个。
当该函数认为它找到一张人脸时,会返回一个矩形列表。下一步,我们会进行循环,直到它认为检测出了什么。
print "Found {0} faces!".format(len(faces))
# Draw a rectangle around the faces
for (x, y, w, h) in faces:
cv2.rectangle(image, (x, y), (x+w, y+h), (0, 255, 0), 2)
该函数返回四个值:矩形的 x 和 y 坐标,以及它的高和宽。我们用这些值和内置的 rectangle() 函数,画出矩阵。
cv2.imshow("Faces found" ,image)
cv2.waitKey(0)
最后,我们显示该模型,等用户摁下按键。
检验结果
用 Abba 来检验。
$ python face_detect.py abba.png haarcascade_frontalface_default.xml

没有问题,试试另一张照片。

那两个东西不是脸,我们再试一次。我调整了参数,发现把 scaleFactor 调成 1.2 能去除错误检测。

发生了什么?第一张图片由高清摄像机近距离拍摄,第二章拍摄距离相对更远,而且可能是用手机拍的。这就是需要调整 scaleFactor 的原因。正如我说的,你需要按照实际场景设置算法,避免假正例。
这里,雷锋网提醒大家,由于这基于机器学习,结果永远不会 100% 精确。大多数情况下,你会得到不错的结果。但算法偶尔会失误。zehngshu5.com
最终代码在这里。
用网络摄像头
如果你想要用网络摄像头呢?OpenCV 从摄像头读取每一帧,你可以通过处理每一帧进行人脸检测。你需要一个性能强大的 PC,不过我的五岁大的笔记本用着还行。
25 行 Python 代码实现人脸识别——OpenCV 技术教程的更多相关文章
- 25行 Python 代码实现人脸检测——OpenCV 技术教程
这是篇是利用 OpenCV 进行人脸识别的技术讲解.阅读本文之前,这是注意事项: 建议先读一遍本文再跑代码——你需要理解这些代码是干什么的.成功跑一遍不是目的,能够举一反三.在新任务上找出 bug 才 ...
- 用Python在25行以下代码实现人脸识别
在本文中,我们将看到一种使用Python和开放源码库开始人脸识别的非常简单的方法. OpenCV OpenCV是最流行的计算机视觉库.最初是用C/C++编写的,现在它提供了Python的API. Op ...
- [转]7行Python代码的人脸识别
https://blog.csdn.net/wireless_com/article/details/64120516 随着去年alphago 的震撼表现,AI 再次成为科技公司的宠儿.AI涉及的领域 ...
- 7行Python代码的人脸识别
随着去年alphago 的震撼表现,AI 再次成为科技公司的宠儿.AI涉及的领域众多,图像识别中的人脸识别是其中一个有趣的分支.百度的BFR,Face++的开放平台,汉王,讯飞等等都提供了人脸识别的A ...
- 用 20 行 python 代码实现人脸识别!
点击上方"Python编程与实战",选择"置顶公众号" 第一时间获取 Python 技术干货! 阅读文本大概需要 11分钟. 今天给大家介绍一个世界上最简洁的人 ...
- 15行python代码实现人脸识别
方法一:face_recognition import cv2 import face_recognition img_path = "C:/Users/CJK/Desktop/1.jpg& ...
- 30行Python代码实现人脸检测
参考OpenCV自带的例子,30行Python代码实现人脸检测,不得不说,Python这个语言的优势太明显了,几乎把所有复杂的细节都屏蔽了,虽然效率较差,不过在调用OpenCV的模块时,因为模块都是C ...
- 10行Python代码实现人脸定位
10行python机器学习全卷机网,实现100+张人脸同时定位! 发表评论 1,049 游览 A+ 所属分类:未分类 收 藏 今天介绍一个快速定位人脸的深度学习算法MTCNN,全称是:Multi-t ...
- 20行Python代码开发植物识别 app
这篇文章介绍如何用Python快速实现一个植物识别的app,家里养了几盆多肉还叫不上名字,正好拿来识别一下.实现这样一个app只需要20行左右的代码,先来看下效果: 另外,我也开发了微信小程序版本,大 ...
随机推荐
- (一)在 Blend 中绘制形状和路径
原文:(一)在 Blend 中绘制形状和路径 https://docs.microsoft.com/zh-cn/previous-versions/jj170881(v=vs.120) 在 Blend ...
- WPF loading遮罩层 LoadingMask
原文:WPF loading遮罩层 LoadingMask 大家可能很纠结在异步query数据的时候想在wpf程序中显示一个loading的遮罩吧 今天就为大家介绍下遮罩的制作 源码下载 点击此处 先 ...
- 51nod 抽卡大赛
抽卡大赛 链接 分析: $O(n^4)$的做法比较好想,枚举第i个人选第j个,然后背包一下,求出有k个比他大的概率. 优化: 第i个人,选择一张卡片,第j个人选的卡片大于第i个人的概率是$p_j$,那 ...
- 一个JAVA程序员成长之路分享
我搞JAVA也有些日子了, 因为我比较贪玩,上进心不那么强, 总是逼不得已为了高薪跳槽才去学习, 所以也没混成什么大牛, 但好在现在也已经成家立业, 小日子过的还算滋润, 起码顶得住一月近万元的吃喝拉 ...
- vs2017+opencv4.0.1安装配置详解(win10)
一.说明 笔者之前已经安装过了vs2017,对应的opencv是3.4.0版本的.但现在想体验下opencv4的改变之处,所以下载了最新的opencv4.0.1. vs2017的安装请自行搜索安装,本 ...
- nginx的access.log文件详解
事实证明,日志文件真的是很重要很重要的.能够帮助我们快速的定位问题,并且知道用户访问的状态,浏览器,Ip,接口地址等,简直可怕.. 一.nginx的access.log(1)对博主而言,日志文件存放在 ...
- 基本的排序算法C++实现(插入排序,选择排序,冒泡排序,归并排序,快速排序,最大堆排序,希尔排序)
博主欢迎转载,但请给出本文链接,我尊重你,你尊重我,谢谢~http://www.cnblogs.com/chenxiwenruo/p/8529525.html特别不喜欢那些随便转载别人的原创文章又不给 ...
- JS 实现计算一段文字中的字节数,字母数,数字数,行数,汉字数。
看到了匹配,第一个想到了用正则表达式,哈哈,果然很方便.不过正则表达式高深莫测!我还没有研究明白啊..目前学了点皮毛.代码如下: <!DOCTYPE html PUBLIC "-//W ...
- Pair Project1:电梯控制程序
12061199 程刚 && 12061204 黎柱金 一.结对编程的优缺点 结对编程相对于一个人的编程有更多的优点,缺点也有很大不同. 首先,优点: 结队可以让两人可以更好的协 ...
- 12.12 Daily Scrum
这周末我们会集成一下反馈活跃用户的模块. 另外,今天编译的第一次测试结束,周末这两天项目的进度会比之前加快一些. Today's Task Tomorrow's Task 丁辛 实现和菜谱相关的餐 ...