近两三年每次一到圣诞节,朋友圈里面就各类“@微信官方 给我一顶圣诞帽”。先不说微信官方到底给没给,本着“求人不如求己”的想法,此次咱们来用
Python
写一个自动戴圣诞帽的脚本。html
每到圣诞节,朋友圈就会变得热闹起来。你们都争先恐后向微信官方讨要圣诞帽:python
你还别说,微信官方真还圆了各位网友的愿望:git
且不说有没有人信,这波网友的演技绝对是满分。github
注:本节图片来自新浪新闻->重庆商报在
2017年12月23日 12:35
的 文章,若有侵权请联系删除。shell
本着“本身动手,丰衣足食”的精神,打算本身撸一个戴圣诞帽的脚本,毕竟微信官方要照顾这么多人的须要,着实挺忙的。微信
那么,要把一顶圣诞帽自动戴到头像(这里只考虑头像包含人脸的状况)的正确位置,须要怎样作呢?markdown
下面是我认为的步骤:学习
要定位人脸就不得不说到人脸检测技术了。spa
人脸检测和识别的研究一直很火热,成熟的落地应用也很是多。多数地方坐火车能够刷脸进站,甚至有些地方在付钱的时候某付宝还支持刷脸付款。code
与此同时,不少研究人员开源了本身的代码库供学习者参考。
本文采用的就是号称世界上最简洁的人脸识别库——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]
。缘由是读取图片时,普通的方法通常是按照R
、G
、B
的顺序排列,而OpenCV
中则是以B
、G
、R
的顺序排列,因此须要在最后一个维度使用::-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
复制代码
下面是个人公众号,有兴趣能够扫一下: