前两天,我问过一个大佬,像我这种没基础的多久能做一个人脸识别的小样。大佬答曰两三天吧。我深感惊讶。追问道,像我这种没基础的。大佬又曰一个星期吧,看看论文,看看源码,提升很快的。抱着将信将疑的态度,开始了人脸识别的学习。在经历两天安装openCV,dlib之后,仍然没有代码实现,直到调用了face_recogniton.
face_recognition 是啥
俺也不知道face_recognition是谁家开发的,但是听说face_recognition是世界上最简单的人脸识别库,在Python或命令行中识别和操作人脸。使用dlib最先进的人脸识别技术构建而成,并具有深度学习功能。 该模型在Labeled Faces in the Wild基准中的准确率为99.38%。
我在使用之后发现,face_recognition简直就是神器,是傻瓜般的人脸操作,使用face_recognition,十分钟学会人脸识别不是梦。
face_recognition 安装与配置
俺不知道是否需要先安装dlib,因为我已经安装dlib(费了不少劲儿)。先尝试一下pip install face_recognition
再说了,不行的那就是需要安装dlib了。安装dlib方式如下:
安装dlib
通过如下网址进入到dlib主页
https://pypi.org/project/dlib/18.17.100/
然后选择合适的版本,我选的是18.17.100,如下操作
pip install dlib==18.17.100
检测人脸,并用框框框起来
face_recognition 的人脸检测函数是face_locations(image),返回image里的所有的脸的坐标,是一个链表,每一个元素是(top, right, bottom, left)。
# -*- coding: utf-8 -*-
# @Time : 2019/11/30 11:21
# @Author : HelloWorld!
# @FileName: xxx.py
# @Software: PyCharm
# @python.version:3.6
#框脸
import face_recognition
from PIL import ImageDraw,Image
image_file='D:\\AITFPy\\Face\\data_beauty\\3.jpg'
image=face_recognition.load_image_file(image_file)
face_location=face_recognition.face_locations(image) #返回所有的脸的坐标框
top, right, bottom, left=face_location[0] #第一个脸的坐标,我们图片里只有一个脸,所以取第一个
#把原来脸的基础上画出来脸
pil_image=Image.fromarray(image)
d=ImageDraw.Draw(pil_image,'RGBA')
d.rectangle((left,top,right, bottom),outline=(0,255,0,128),width=3)
pil_image.show()
效果是下面这样的:
众里寻他千百度,查看此人在不在
下面我们在图片里寻找一下某人在不在。其操作步骤是把图片所有的人脸检测出来然后编码,与被测人脸的编码对比,如果其距离小于某个值(默认0.6),则认为某人在图片中。采用的编码调用函数是faces_encodings=face_recognition.face_encodings(image,face_locations)
,而比较函数是face_recognition.compare_faces([face_encoding],face_encoding_a66)
,里面调用了两个编码的距离计算函数face_recognition.face_distance([face_encoding], face_encoding_a66)
。
下面从红军利物浦的一张合照里找一下我们的红军太子小机灵鬼阿诺德在不在图里。帅气的合照liv2.jpg如下,小机灵鬼在范大腿和马大腿之间。太子阿诺德的定妆照a66.jpg如下:
我们首先把图片里的所有红军将士的脸框起来,然后在看看阿诺德在不在图里。
#框脸
import face_recognition
from PIL import ImageDraw,Image
image_file='D:\\AITFPy\\Face\\data_beauty\\liv2.jpg'
img_file_a66='D:\\AITFPy\\Face\\data_beauty\\a66.jpg'
image=face_recognition.load_image_file(image_file)
face_locations=face_recognition.face_locations(image) #返回所有的脸的坐标框
pil_image=Image.fromarray(image)
d=ImageDraw.Draw(pil_image,'RGBA')
#把原来脸的基础上画出来脸
for face in face_locations:
top, right, bottom, left=face
d.rectangle((left,top,right, bottom),outline=(0,255,0,128),width=3)
pil_image.show()
pil_image.save("3k.jpg")
#获取图片里面所有的脸的编码
faces_encodings=face_recognition.face_encodings(image,face_locations)
#读待测图片的脸位置和编码
image_a66=face_recognition.load_image_file(img_file_a66)
face_a66=face_recognition.face_locations(image_a66)
face_encoding_a66=face_recognition.face_encodings(image_a66,face_a66)[0]
for face_encoding in faces_encodings:
result=face_recognition.compare_faces([face_encoding],face_encoding_a66)
distance = face_recognition.face_distance([face_encoding], face_encoding_a66)
print("distance is ",distance)
if result[0]:
print("a66 is in the picture")
框脸的结果如下,除了我们的烟熏太岁马大腿都被框出来了,这也许就是人脸识别的种族歧视把。
再看一下人脸测距结果 ,我们发现阿诺德在合照里。那么他和谁更像一点distance is [0.66382813],这个更近,定位了一下是马向前马蒂普马大腿。。。,果然后卫一家亲。
distance is [0.80983155]
distance is [0.68695194]
distance is [0.42896597]
a66 is in the picture
distance is [0.8394327]
distance is [0.80912881]
distance is [0.69498012]
distance is [0.66382813]
distance is [0.75636502]
distance is [0.73218545]
distance is [0.8141693]
百变星君,美颜美图随心所欲
我们看到女孩们通过美图美颜个个赛貂蝉,在图片上摸个口红,隆个鼻都可以,那么是怎么做的呢。其中用到了读取脸部特征的函数face_landmarks_list=face_recognition.face_landmarks(image)
,face_landmarks的输出结果是关于嘴唇、眼睛等五官的特征。通过调试,我们看到有9个基本特征,以字典的数据格式存放,如下图。
今天我们给图里的人脸上口红,即在top_lip,bottom_lip这两个特征上做文章。原图如下:
经过如下操作
#美图
import face_recognition
from PIL import Image, ImageDraw
img_filename='D:\\AITFPy\\Face\\data_beauty\\9.jpg'
image=face_recognition.load_image_file(img_filename)
face_location=face_recognition.face_locations(image)
face_landmarks_list=face_recognition.face_landmarks(image)
for face_landmark in face_landmarks_list:
pil_image=Image.fromarray(image)
d=ImageDraw.Draw(pil_image,'RGBA')
d.polygon(face_landmark['top_lip'], fill=(255, 0, 0, 128))
d.polygon(face_landmark['bottom_lip'], fill=(0, 0, 0, 128))
d.line(face_landmark['top_lip'], fill=(150, 0, 0, 64), width=3)
d.line(face_landmark['bottom_lip'], fill=(150, 0, 0, 64), width=3)
pil_image.show()
pil_image.save('v.jpg')
美妆博主的效果如下:
总结
face_recognition 实在是太简单了,太方便了,搞个小玩意,做个小样,妥妥滴。然后作为一个严肃的深度学习爱好者,绝对不能仅仅局限于此,后面我们要深挖背后的技术原理,然后学习其他的人脸识别方法和框架。