一、人脸识别发展
细数人脸识别发展史,我们大致可将其分为四个阶段:
- 1964~1990年,第一阶段,研究人脸识别面部特征,没有实现自动识别
- 1991~1997年,第二阶段,研究人工算法识别
- 1998~2014年,第三阶段,主要研究鲁棒性,如光照、姿态
- 2015年至今,第四阶段,互联网应用:技术成熟,大面积推广应用
这一技术已经让生活发生翻天覆地变化!
试想,周一早上,你通过人脸打卡机进入办公室,打开美团选好一杯热咖啡,人脸无感支付。然后你想起周末和朋友的快乐时光,习惯性打开facebook,人脸验证通过后,编辑、上传图片一气呵成,facebook也瞬间帮你@到照片中的好友。
(图源:人脸识别原理)
二、基于face_recognition实现人脸识别
如此酷炫的功能,我们也可以借助face_recognition轻松实现!
face_recognition:是世界上最简洁的人脸识别库,你可以使用Python和命令行工具提取、识别、操作人脸。 face_recognition 提供丰富的api(详见)供调用,我们借助python-flask框架,封装接口,搭建一个小型人脸识别服务器。
核心代码如下:
def faceMatch(name):
if name is None:
abort(404)
name = './uploadimg/'+name
unknown_image = face_recognition.load_image_file(name)
res = []
if unknown_image is None:
res.append(" position fail!")
else:
try:
unknown_encoding = face_recognition.face_encodings(unknown_image)[0]
WSI_MASK_PATH = './orisample/' #原始库
wsi_mask_paths = glob.glob(os.path.join(WSI_MASK_PATH, '*.jpg'))
for pic in wsi_mask_paths:
known_image = face_recognition.load_image_file(pic)
#已知人脸编码
known_encoding = face_recognition.face_encodings(known_image)[0]
#待识别图像,与源库比对
results = face_recognition.compare_faces([known_encoding], unknown_encoding, tolerance = 0.4)
if results[0] == True:
res.append(pic.split('/')[2]+" It's a picture of me!")
else:
res.append(pic.split('/')[2]+" not")
except:
res.append(" position fail!!")
return render_template('facematch.html', url=res, name=res)
代码(源码地址)解读:
- 导入face_recognition后,调用face_encodings接口获得图片编码
- 再通过compare_faces接口,依靠算法比对两者相似度,进行预判
效果展示:
以上示例,使用python-flask简单封装了face_recognition接口 完整代码
三、人脸识别原理
注:只对人脸识别应用感兴趣同学,可以跳过此章节
人脸识别,一般可分为四个步骤:
- 定位人脸
- 提取脸部特征
- 脸部特征参数化
- 比对源库作人脸辨识
3.1 定位人脸
人脸定位应用HOG算法,通过渐变替换像素,获取图片人脸主要特征。
我们首先将图片置为黑白,剔除色彩影响,然后根据像素点周围渐变趋势,用箭头标记:
(图源:人脸识别原理)
重复如此操作,最后得到箭头标记后的图像( HOG算法实现代码 ):
HOG算法中转图像的目的,是忽略图像色彩、明亮度等影响,准确定位到图片中人脸位置,为下一步提取脸部特征做好准备。
3.2 提取脸部特征
定位到人脸位置后,我们会面对一个新问题:即不同视角下(正脸、侧脸)呈现不同?在同一纬度,待识别图和源图皆为正面,那么预测会更加精准。
于是,进行简易的中转,得到待识别图的近似正脸图。
接着,我们需要提取识别图中人脸的特征。就像美术生在素描时,通常会做构图前点位设置。
(图源:CMU的Brandon Amos)
3.3 脸部特征参数化
接下来就是本文重点了!!
每一张待人脸识别的图像,会经由机器转为128位参数化标识。
那么,机器按怎样的规则做图像参数化呢?通过训练一个深度卷积神经网络,进行深度学习和训练,确定图像转128位规则。
训练方式:
- 导入已知人脸图像,得到#1
- 加载已知人的另外一张图片,得到#2
- 加载非已知人的图片,得到#3
我们不断调整算法和参数,使得#1与#2越来越接近、#1与#3越来越疏远,经过百万千万次运算,最终神经网络便能学会最优的图像参数化规则,达到人脸识别目的。
3.4 比对源库作人脸辨识
我们把得到的128位数值,与数据源库比对,找到最相似的,即完成人脸识别。通过一个简单SVM分类器,可以让比对过程,缩短到几毫秒。
四、进阶:视频打码
前有霍某,后有迪某,这可忙坏了热门综艺《披荆斩棘的GG》后期同学,这里也帮后期同学们减压,让程式自动打码吧!
我们选取一小段《披荆斩棘的GG》原视频:
打码后的视频如下:
主要借助ffmpeg、opencv实现,(完整代码来源:Jack Cui)就不用重复造轮子了:
def mask_video(input_video, output_video, mask_path='mask.jpg'):
# 打码图片
mask = cv2.imread(mask_path)
# 读取视频
cap = cv2.VideoCapture(input_video)
# 读取视频参数,fps、width、heigth
CV_CAP_PROP_FPS = 5
CV_CAP_PROP_FRAME_WIDTH = 3
CV_CAP_PROP_FRAME_HEIGHT = 4
v_fps = cap.get(CV_CAP_PROP_FPS)
v_width = cap.get(CV_CAP_PROP_FRAME_WIDTH)
v_height = cap.get(CV_CAP_PROP_FRAME_HEIGHT)
# 设置写视频参数,格式为 mp4
size = (int(v_width), int(v_height))
fourcc = cv2.VideoWriter_fourcc('m', 'p', '4', 'v')
out = cv2.VideoWriter(output_video, fourcc, v_fps, size)
# 已知人脸
known_image = face_recognition.load_image_file("lyd2.png")
# print(known_image)
biden_encoding = face_recognition.face_encodings(known_image)[0]
print(biden_encoding)
# 读取视频
cap = cv2.VideoCapture(input_video)
while(cap.isOpened()):
ret, frame = cap.read()
if ret:
# 检测人脸
face_locations = face_recognition.face_locations(frame)
# 检测每一个人脸
for (top_right_y, top_right_x, left_bottom_y, left_bottom_x) in face_locations:
unknown_image = frame[top_right_y-50:left_bottom_y +
50, left_bottom_x-50:top_right_x+50]
if unknown_image is None:
break
try:
unknown_encoding = face_recognition.face_encodings(unknown_image)[0]
except:
break
# 对比结果
results = face_recognition.compare_faces(
[biden_encoding], unknown_encoding)
# 是李云迪,就打码
if results[0] == True:
mask = cv2.resize(mask, (top_right_x-left_bottom_x, left_bottom_y-top_right_y))
frame[top_right_y:left_bottom_y,left_bottom_x:top_right_x] = mask
# 写入视频
out.write(frame)
else:
break
代码解读:
- 借助opencv,读取视频流cap = cv2.VideoCapture(input_video),获取每一帧while(cap.isOpened())
- 针对每一帧做人脸识别face_recognition.compare_faces(),若识别到目标人脸,则对每帧图像做打码cv2.resize()
- 图像流保存,逐帧写入视频out.write(frame)
- 新视频是无声的,可以通过ffmpeg转音频,再整合到一起
五、问题与方案
5.1 face_recognition对小孩和亚洲人脸辨识度较低
官方说明是缺少数据源,解决办法是扩大对应的训练库。另外,在特定人脸定位不佳,也可以针对性进行深度学习,以提升识别准确度。
5.2 视频人脸动态变化,导致打码完整度低
视频过长,对应人脸变动较大,在演示中明显发现远视角和低补光下,识别不佳,对应我们逐帧定位人脸大小,自适应打码。若想达到更好效果,人工辅助和矫正也是必不可少的。
5.3 人脸识别商业化
安防、交通、金融、楼宇是较为常见领域,但是其天然互联网属性,可以孕育出更多创造性产品,比如前一阵很火的换脸视频、宠物情绪探测器等等。随着物联网普及,相信人脸识别也会有很多有趣应用落地。
六、总结
本文通过face_recognition为大家演示了人脸识别搭建,同时介绍了背后人脸定位、特征提取、深度学习原理。最后,借助opencv通过逐帧处理,实现视频打码,让《披荆斩棘的GG》中迪某,”码“上消失。
参考资料:
face_recognition开源项目 传送门
Modern Face Recognition with Deep Learning Adam Geitgey
Pytorch 深度学习实战教程 Jack Cui
今天的文章玩转人脸识别分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/19463.html