


Python培训
400-996-5531
这篇教程的作者是Shantnu Tiwari,他在底层嵌入式领域有十年的工作经验。直到发现Python前,Shantnu一直忍受着C / C ++,Python让他感觉心旷神怡。
这篇教程就是Shantnu对Python爱的分享!(#/)
这篇教程中,将用到一个令人惊讶的极简单方法来检测人脸,利用Python和OpenCV开源库。(#/)
在正式开始前,我希望你们能注意下面几点:
1. 不要尝试跳过教程直接运行代码。除了运行代码,你还必须学会如何找到代码中的BUG
2. 确保使用的是OpenCV v2(最新更新兼容OpenCV3的代码)
3. 你也许需要一个能工作的网络摄像头
4. 在提出问题前先查看其他的评论/问题,您的问题可能已被解决了
▍OpenCV
OpenCV是最受欢迎的计算机视觉库。最初用C / C ++编写,现在也提供了Python包。
OpenCV使用机器学习算法来搜索图片中的人脸。对于像人脸一样复杂的东西,没办法简单的用一个测试,告诉你找到的是不是一张人脸。相反,算法需要匹配数千个小图案/特征才能确定。
机器学习算法,将人脸识别的任务,分解成数千个较小的的容易解决的任务。这些任务也称为分类器(classifiers)。检测是否是一张人脸可能需要6000个以上的分类器,所有这些分类器都必须匹配要检测的脸部(当然在误差范围之内)。
但其中存在的问题是:对于人脸检测,算法从图片的左上角开始,沿着小块数据移动,经过每个块都要不断地问:“这是人脸吗?……这是人脸吗?……这是人脸吗?(话唠...)
由于每一块有6000个或更多的测试,可能需要进行数百万次的计算,这将使计算机停止运行。为了解决这个问题,OpenCV应用了级联(cascades)。什么是级联?最好的答案可以从词典中找到:瀑布或瀑布系列。
像一系列的瀑布一样,OpenCV级联将人脸检测分成多个阶段来解决。对于每个块,先进行非常粗略和快速的测试。如果通过,才会做进一步更详细的测试,如此这般。
算法可能具有30-50个这种级联阶段,只有在所有阶段都通过时,才会认为检测到了人脸。这种方法的优势在于,大部分的图片在最初的几个阶段都会被否决,这意味着该算法不会在这些区域浪费时间来测试所有6000个特征。不用浪费数小时,人脸检测现在可以实时进行。
▍级联实战
虽然理论听起来可能有点复杂,但实践却很简单。级联本身只是一堆包含用于检测对象的OpenCV数据XML文件。您只需初始化所选用级联,它就可以开始工作了。
由于人脸检测很普遍,因此OpenCV内置了一些级联,可用于检测从脸部到眼睛到手和腿的所有内容。甚至还包括非人类事物的级联。例如,你经营了一家香蕉店,这篇就介绍了如何追踪偷窃香蕉的人!(#/341ZW3)
▍安装OpenCV
首先,你要找到符合你操作系统的安装文件。(#/releases.html)
我发现安装OpenCV是该教程中最难的部分。如果您遇到奇怪的无法解释的错误,很可能是由于库冲突,32/64位差异等原因。我发现使用Linux虚拟机并且从头开始安装OpenCV是最简单的方法。
安装完成后,您可以通过启动Python会话并键入以下内容来测试它是否工作:
$ python
>>> import cv2
>>>
如果你没遇到任何报错,那我们就可以进行到下一部分了。
▍了解代码
你可以从这个repo(https://github.com/shantnu/FaceDetect/)下载该教程要用到的代码,让我们分开来看:face_detect.py脚本,abba.png图片和haarcascade_frontalface_default.xml。
# Get user supplied values
imagePath = sys.argv[1]
cascPath = sys.argv[2]
首先将图像和级联命名为命令行参数。我们将使用Abba图像以及默认级联来检测OpenCV提供的人脸。
# Create the haar cascade
faceCascade = cv2.CascadeClassifier(cascPath)
接下来我们创建一个级联,并用我们的人脸级联进行初始化。将脸部级联加载到内存中便于随时使用。请记住,级联只是一个XML文件,其中包含了检测人脸的数据。
# Read the image
image = cv2.imread(imagePath)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
读取图像并将其转换为灰度模式。OpenCV中的许多操作都是以灰度模式完成的。
# Detect faces in the image
faces = faceCascade.detectMultiScale(
gray,
scaleFactor=1.1,
minNeighbors=5,
minSize=(30, 30),
flags = cv2.cv.CV_HAAR_SCALE_IMAGE
)
该函数用来检测脸部,是我们代码的关键部分,因此让我们来看看它的参数。
1. detectMultiScale 函数是检测对象的通用函数。因为我们在人脸级联上调用它,它就可以用来检测人脸。它的第一个参数要求灰度图像。
2. 第二个参数是scaleFactor。由于某些面部可能更靠近相机,所以它们会比靠后的那些脸部显得更大。比例因子可以补偿这一点。
3. 检测算法使用移动窗口来检测物体。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)
函数返回4个值:矩形的x和y位置以及矩形的宽度和高度(w,h)。
利用rectangle()内置函数,我们根据这4个值绘制矩形。
cv2.imshow("Faces found",image)
cv2.waitKey(0)
最后,显示画过矩形的图像,并等待用户按下一个键。
▍检查结果
让我们用 Abba 的照片试一下:
$ python face_detect.py abba.png haarcascade_frontalface_default.xml
看起来运行的不错,那下一张呢:
嗯……检测到了不属于人脸的部分
。将参数scaleFactor调整到到1.2,看是否修正了检测错误。
结果如何?嗯,第一张照片拍摄时离高品质相机非常近。第二个似乎是从较远的地方拍摄的,可能是手机。这就是为什么必须调整scaleFactor的原因。正如我提到的,你必须根据具体情况设置算法,以避免误报。
需要注意的是,因为检测是基于机器学习的,其结果将永远不会达到100%准确。在大多数情况下,能够获得足够好的结果,但偶尔该算法还是会将不正确的对象识别为人脸。
完整的代码可以在这里看到。(https://github.com/shantnu/FaceDetect)
▍网络摄像头扩展
如果你想使用网络摄像头来识别人脸怎么办?OpenCV能从网络摄像头抓取每个帧,然后您可以通过处理每个帧来检测人脸。尽管我五年的笔记本电脑能运行,但你可能仍需要一台强大的电脑,
UPDATED下一篇教程:用Python和网络摄像头来检测人脸。(#/blog/python/face-detection-in-python-using-a-webcam/)
填写下面表单即可预约申请免费试听! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!
Copyright © 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有