【Python自动戴圣诞帽】01 熟悉face_recognition库

近两三年每次一到圣诞节,朋友圈里面就各类“@微信官方 给我一顶圣诞帽”。先不说微信官方到底给没给,本着“求人不如求己”的想法,此次咱们来用Python写一个自动戴圣诞帽的脚本。html

缘起

每到圣诞节,朋友圈就会变得热闹起来。你们都争先恐后向微信官方讨要圣诞帽:python

你还别说,微信官方真还圆了各位网友的愿望:git

且不说有没有人信,这波网友的演技绝对是满分。github

注:本节图片来自新浪新闻->重庆商报在2017年12月23日 12:35的 文章,若有侵权请联系删除。shell

简要分析

本着“本身动手,丰衣足食”的精神,打算本身撸一个戴圣诞帽的脚本,毕竟微信官方要照顾这么多人的须要,着实挺忙的。微信

那么,要把一顶圣诞帽自动戴到头像(这里只考虑头像包含人脸的状况)的正确位置,须要怎样作呢?markdown

下面是我认为的步骤:学习

  1. 获取头像定位人脸
  2. 获取人脸关键点
  3. 获取合适的圣诞帽位置
  4. 调整圣诞帽大小
  5. 合成头像

人脸检测

要定位人脸就不得不说到人脸检测技术了。spa

人脸检测和识别的研究一直很火热,成熟的落地应用也很是多。多数地方坐火车能够刷脸进站,甚至有些地方在付钱的时候某付宝还支持刷脸付款。code

与此同时,不少研究人员开源了本身的代码库供学习者参考。

本文采用的就是号称世界上最简洁的人脸识别库——face_recognition库。

熟悉face_recognition

face_recognition的人脸识别基于业内领先的深度学习模型,在Labeled Faces in the Wild人脸数据集下有高达99.38%的准确率,惟一美中不足的是对小孩和亚洲人脸的识别准确率尚待提高。在实际使用中,人脸检测的效果还受脸部的光照以及遮挡等的影响,但无妨咱们作研究。

最近有一部很火的电视剧《庆余年》,咱们就拿这部剧中的人物来作实验。

下面是《庆余年》的剧照或是宣传照,真的是俊男美女呀:

在这里提一下安装方法。因为face_recognition库依赖的dlib包须要编译,懒得麻烦的同窗能够直接下载已经编译好了的.whl文件用pip命令安装,或者在公众号后台回复face_recognition获取。安装命令以下:

pip install dlib-****.whl
复制代码

人脸位置检测

既然是号称世界上最简洁的人脸识别库,代码必然很简洁。

首先天然是引入相关的包:

import face_recognition
import cv2
复制代码

而后用face_recognition来读取有人脸的图片:

image = face_recognition.load_image_file('your-path-to-face')
复制代码

关键代码来了:

face_locations = face_recognition.face_locations(image)
复制代码

对,你没看错,这一句话就检测到了图片中全部的人脸。简单的处理一下,在检测到脸的地方画一个框:

for top, right, bottom, left in face_locations:
    cv2.rectangle(image, (left, top), (right, bottom), (0, 0, 255), 2)
    face_locations = face_recognition.face_locations(image)
cv2.imshow('rects_face', image[:,:,::-1])
cv2.waitKey(0)
复制代码

细心的读者可能会注意到image[:,:,::-1]。缘由是读取图片时,普通的方法通常是按照RGB的顺序排列,而OpenCV中则是以BGR的顺序排列,因此须要在最后一个维度使用::-1的方式进行倒序处理。

下面是人脸识别的结果:

是否是很简单,加上包引入以及显示的代码总共才9行。

人脸关键点检测

仔细观察检测到的脸部,会发现框住的位置都比较宽泛,没办法比较紧密的贴合脸部,这样后面戴圣诞帽会很难作。不过好在face_recognition库还为咱们提供了人脸关键点检测功能,能够告诉咱们五官的详细坐标。

在获取坐标以前,仍是须要先检测到人脸代码与上面相似:

image = face_recognition.load_image_file(face)
face_locations = face_recognition.face_locations(image)
face_landmarks = face_recognition.face_landmarks(image, face_locations)
复制代码

仍是一句代码解决问题。face_landmarks里面存储的即是五官详细位置。以“范闲”为例,face_landmarks的具体信息以下:

[{
	'chin': [(148, 100), (149, 117), (152, 133), (155, 148), (161, 163), (169, 177), (178, 189), (190, 198), (203, 200), (216, 198), (226, 189), (235, 178), (244, 165), (250, 151), (254, 136), (257, 120), (259, 104)],
	'left_eyebrow': [(162, 105), (172, 103), (182, 106), (191, 109), (202, 112)],
	'right_eyebrow': [(213, 114), (222, 110), (231, 106), (241, 103), (250, 106)],
	'nose_bridge': [(206, 121), (206, 131), (206, 141), (206, 151)],
	'nose_tip': [(195, 156), (200, 157), (206, 159), (211, 157), (216, 155)],
	'left_eye': [(173, 118), (179, 117), (187, 117), (192, 121), (185, 123), (178, 122)],
	'right_eye': [(220, 122), (226, 118), (233, 117), (239, 119), (234, 123), (227, 123)],
	'top_lip': [(187, 174), (194, 171), (201, 169), (206, 171), (211, 169), (216, 171), (223, 173), (220, 174), (211, 174), (205, 175), (200, 174), (191, 174)],
	'bottom_lip': [(223, 173), (216, 180), (210, 184), (205, 185), (200, 184), (193, 181), (187, 174), (191, 174), (200, 175), (205, 176), (211, 175), (220, 174)]
}]
复制代码

总共72个关键点,其中左右眉毛各5个、左右眼睛各6个、鼻子5个、鼻梁4个、上下嘴唇各12个和脸颊17个。

跟前面同样,为了直观的观察,用代码将这些点画出来,代码以下:

for each in face_landmarks:
    for i in each.keys():
        for any in each[i]:
            points_face = cv2.circle(points_face, any, 3, (0,0,255), -1)
复制代码

结果以下:

有了这些关键点,咱们就比较容易的定位圣诞帽的位置了。

下期预告

上面提到的这些都是face_recognition库提供的最基础的功能,face_recognition库还有更多更好玩的地方。下期咱们会再简单介绍其余功能,而后实现咱们的自动戴帽脚本,敬请期待~

后记

无论写什么,但愿能跟更多人沟通,有问题或者需求随时欢迎交流。

我全部的项目源码都会放在下面的github仓库里面,有须要能够参考,有问题欢迎指正,谢谢!

https://github.com/TitusWongCN/WeChatSubscriptionArticles
复制代码

下面是个人公众号,有兴趣能够扫一下:

相关文章
相关标签/搜索