现在读者对图片的数据表示方式以及人脸识别的基本原理已经有所了解。本节利用开源工具来具体实现人脸检测和人脸识别,所用数据可在教材资源平台下载。人脸识别是一个复杂的问题,为了达到一定的准确率,所需的工程量远远不是本教材这一节的内容所能描述的,读者可在实践过程中继续探索。
上一节简单介绍了人脸检测背后的原理,下面首先通过OpenCV来实现人脸检测。
使用以下命令在Python环境中加载OpenCV模块。
In[1]:import cv2
#引入OpenCV模块
In[2]:faceClassifier=cv2.CascadeClassifier('haarcascade_front
alface_default.xml')
#构建OpenCV模块提供的脸部分类器,它用Harr特征检测脸部
In[3]:objImage=cv2.imread('facedetect.jpg')
#读取要进行人脸检测的图片
In[4]:cvtImage=cv2.cvtColor(objImage,cv2.COLOR_BGR2GRAY)
#将图片转化为灰度图像(Gray)
In[5]:foundFaces=faceClassifier.detectMultiScale(objImage,sca
leFactor=1.3,minNeighbors=9,minSize=(50,50),fl
ags=cv2.cv.CV_HAAR_SCALE_IMAGE)
#该命令返回检测到的脸部,每一张检测到的脸都会给出左上角的坐标和脸部
#区域的长和宽。相当于描述了一个方框,将脸部圈起来
In[6]:facenumbers=len(foundFaces)
#该命令给出检测到的人脸数量
In[7]:for(x,y,w,h)in foundFaces:
cv2.rectangle(objImage,(x,y),(x+w,y+h),(0,0,255),2)
#该命令按照返回结果画出红框
In[8]:cv2.imshow(objImage)
#显示标注脸部识别结果的图片
读者可以灵活运用以上命令,进一步拓展应用场景。例如,利用摄像头实时捕捉人脸并检测,同时还可以将检测到的人脸,利用返回的红框进行截图保留,并使用这些图片进行人脸识别。
人脸识别有很多实现方式,可以完全通过自己编写代码实现识别的全过程,也可以利用已经开源的模块。本书将使用开源的face-recognition模块来实现人脸识别。首先使用如下命令行进行安装。
pip install face-recognition
其实通过如下代码,face-recognition也可以在一张图片中检测人脸个数并圈出人脸,从而实现人脸检测的任务。读者可以对比两种检测方法的性能。
In[1]:import face_recognition
#引入face_recognition 模块
from skimage import draw,io
#和前面不同,这里用skimage来显示图像存储图像
In[2]:image=face_recognition.load_image_file('facedetect.
jpg')
#读取要进行人脸检测的图片
In[3]:face_locations=face_recognition.face_locations(image)
# 确定每个人脸的位置,为框出人脸做准备
In[4]:len(face_locations)
Out[4]:2
# 输出结果表示有2个人脸被检测出来
In[5]:for face_location in face_locations:
# 对人脸位置进行循环
top,right,bottom,left=face_location
# 为每个人脸画四边形的四个位置,可以看出分别是四边形的上,
# 右,下,左
rr,cc=draw.polygon_perimeter([top,top,bottom,bott
om],[left,right,right,left])
# 用polygon_perimeter绘制不填充的多边形
draw.set_color(img,[rr,cc],[255,0,0])
# 设置颜色为红色
io.imsave('F:result.jpg',img)
# 保存
原始的facedetect.jpg的图像如图8-5所示。
图8-5
而result.jpg的图像如图8-6所示。
图8-6
从示例可以看到,检测完毕的图片已经圈出了检测到的人脸。
下面使用face_recognition进行人脸识别,具体过程如下。
①准备好已经标注姓名或者ID的人脸照片;
②利用face_recognition将其编码;
③读入待识别的照片并将其编码;
④调用函数进行识别,结果通过True和False来给出。
In[1]:import face_recognition
#引入模块
In[2]:binface=face_recognition.load_image_file("binface.jpg")
#读入已知姓名或者ID的图片,这里已经知道该照片中的人是Bin
In[3]:toberecognized=face_recognition.load_image_
file("toberecognized.jpg")
#读入待识别的照片
In[4]:binencoding=face_recognition.face_encodings(binface)[0]
#对已知ID的照片进行编码
In[5]:toberecognizedencoding=face_recognition.face_encodin
gs(toberecognized)[0]
#对待识别的照片进行编码
In[6]:knownfaces=[binencoding]
#将已知姓名或ID的照片编为一组。这个例子里已知照片只有一张
In[7]:results=face_recognition.compare_faces(knownfaces,
toberecognizedencoding)
#使用该函数给出结果
In[8]:results
Out[8]:[True]
# 输出结果为真,说明待检测的照片中的人脸与已知姓名的照片中的人脸是相同的
待检测照片如图8-7所示。
图8-7 Bin
识别的场景可以更丰富,比如加入更多已经标识了ID的人物照片。下面在识别对象中加入两个新的人物,他们的ID分别是Ning(图8-8)和Yao(图8-9)。读者也可以自行寻找合适的人物图片,使用这个方法看看是否能够准确识别。
图8-8 Ning
图8-9 Yao
新的代码如下。
In[1]:import face_recognition
# 导入模块
In[2]:binface=face_recognition.load_image_file("binface.jpg")
In[3]:yaoface=face_recognition.load_image_file("Yao.jpg")
In[4]:ningface=face_recognition.load_image_file("Ning.jpg")
# 读入已知ID的图片,分别是Bin,Ning和Yao
In[5]:toberecognized=face_recognition.load_image_file("bint
oberecognized.jpg")
# 读入待人脸识别的照片
In[6]:binencoding=face_recognition.face_encodings(binface)[0]
In[7]:yaoencoding=face_recognition.face_encodings(yaoface)[0]
In[8]:ningencoding=face_recognition.face_encodings(ningface)[0]
# 对已知ID的照片进行编码
In[9]:toberecognizedencoding=face_recognition.face_encodin
gs(toberecognized)[0]
# 对待识别的照片进行编码
In[10]:knownfaces=[binencoding,yaoencoding,ningencoding]
# 将三个已知ID的照片编成一组,用来进行识别
In[11]:results=face_recognition.compare_faces(knownfaces,t
oberecognizedencoding)
# 该函数给出结果
In[82]:results
Out[82]:[True,False,False]
# 输出结果中,第一次比对为真,说明待检测的照片是Bin
[1] 实际上是使用一种决策树的进化版本叫作Adaboost。