不用@微信官方了,Python20行自动戴帽!
这两天被朋友圈里@微信官方要求戴帽的消息刷屏了,会玩的都悄咪咪地用美图秀秀一类的app给自己头像p一顶然后可高兴地表示“哎呀好神奇hhhh”,呆萌的当然就一直等啊等。作为一名坚信“用技术解决需求”的萌新,在这个无聊的周末尝试用python来搞一波事情。
主要思路
准备两张图,一张头像,一张帽子。先祭出人脸识别定位头像中的人脸,给出人脸像素坐标;再根据这个坐标确定帽子放置的坐标;最后将两张图片拼接后输出。(需要注意的是,帽子是不规则图像,除了主体外背景应该是透明的,因此必须是四通道png格式)。gakki酱亲自演示如下:
问题展开
人脸识别怎么搞定?(重新造轮子?不存在的,这辈子都不可能造轮子的)。Github上一个开源的python人脸识别库face_recognition双手奉上,据说识别率99.38%(顶瓜瓜啊!)。通过安装这个库就可以调用人脸检测器。
确定了帽子的放置位置,怎么拼接图层?这个属于基本的图像操作,python提供了PIL(Python Image Lib)这么一个库来进行图像处理,具体操作请看后面的代码。
库的安装
我的环境是Ubuntu 16.04+Python2.7.12。使用Window,Mac OS和Python3的同学也可以参考,都是类似的。
face_recognition这个库比较事儿,安装前需要依次安装boost(boost_python),cmake,dlib这几个依赖和库,中间出现任何问题都可以通过Google解决(懒得写 -.. -)。安装完所有的依赖后,使用命令:
pip install face_recognition
pip install pillow#PIL库
完成后就可以在你的python脚本里import face_recognition和PIL了。
代码分析
Talk is cheap, show me the code。直接上代码:
1. from PIL import Image
2. import face_recognition
3 img_path = raw_input("image path:")
4. image = face_recognition.load_image_file(img_path)
5. face_locations = face_recognition.face_locations(image)
6. print("Found {} face(s) in this photograph.".format(len(face_locations)))
第1、2行导入PIL库中的Image模块和face_recognition库。第3行,等待用户输入头像图片的路径。第4行,把路径所指的图像数据读入image中。第5行,调用face_locations处理image中的图像数据,对图片中的人脸进行识别定位,定位后的得到的像素坐标数据放在face_locations里。第6行在shell里输出图片里识别到的人脸的个数。
7. human_img = Image.open(img_path)
8. human_img = human_img.convert("RGBA")
9. hat_img = Image.open("./hat.png")
10. hat_img = hat_img.convert("RGBA")
第7、8行,把路径所指的图像数据读入human_img中,并转换为四通道RGBA模式。9、10行读入帽子图像并做相同处理。
11. for face_location in face_locations:
12. top, right, bottom, left = face_location
13. top -= 10
14. print("A face is located at pixel location Top: {}, Left: {}, Bottom: {}, Right: {}".format(top, left, bottom, right))
15. head_h = bottom-top#hight of head
16. head_l = right-left#length of head
17. hat_img = hat_img.resize( (head_l,head_h) )#convert size of hat
18. hat_region = hat_img
19. human_region = ( left, top-head_h, right, top )
20. human_img.paste(hat_region, human_region,mask=hat_img)
21. human_img.show()
如果一张图里有多张人脸,face_recognition.face_locations(image)会返回每张人脸的位置信息,存放在一个list里。
因此第11行是遍历face_locations里的每张人脸的数据。第12行解包一个人脸像素坐标数据,得到top,right,bottom,left分别为示意图中的y1,x2,y2,x1。第13行,为啥y1要减10个像素?因为人脸识别得到的y1最多到你额头的位置,所以再把这个坐标往上提一提帽子才戴得更自然。第14行输出坐标数据方便调试。第15、16行计算人脸的高度和宽度。第17行使用resize()根据人脸的大小调整帽子的大小,因为图像中的人脸有大有小,调整后看起来更和谐。第18行,将帽子图像作为顶部图层图像。第19行,确定底部图层(头像图片)被覆盖的区域(就是帽子放置区域)。第20行,把顶部图层与底部图层拼接(不太明白的看下图)。
然后一个循环结束,亦即完成图片中一个人的戴帽操作,接着进行下个人的戴帽,直到所有人都戴上了帽子。最后21行,完成输出~
更多测试结果~
- im4java + imagemagic 搭建一个图片处理服务
- # Java 一步一步实现高逼格的字符串替换工具(二)
- 专题 | Python编写渗透工具学习笔记二
- Java 一步一步实现高逼格的字符串替换工具(一)
- Python编写渗透工具学习笔记一 | 0x05抓取应用的banner --推断服务
- Logback 简明使用手册
- Python编写渗透工具学习笔记一 | 0x06 Zip包破解程序
- Java 并发排序
- Python编写渗透工具学习笔记一 | 0x07 Python实现键盘记录器
- Python编写渗透工具学习笔记一 | 0x08字典生成程序
- 漫步VR——Unity语音聊天室开发
- Python编写渗透工具学习笔记一 | 0x01 目录扫描程序
- JDK容器学习之HashMap (一) : 底层存储结构分析
- Python编写渗透工具学习笔记一 | 0x02实现一个反弹shell
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 3分钟短文 | Laravel 日志全程记录 SQL 查询语句,要改写底层?
- MySQL InnoDB表空间加密
- 微信小程序自动化测试最佳实践(附 Python 源码)
- 3分钟短文 | MySQL在分组时,把多列合并为一个字段!
- Redis Linux系统参数最佳配置
- 实现Promise其它API
- 使用sysbench进行压测 Part1 sysbench安装
- Java并发编程(07):Fork/Join框架机制详解
- PostgreSQL Pgbouncer 到底怎么使用,疗效有多大
- 微信练手小程序源码 - 日历(含各种功能组件)
- Redis 5.0.8安装
- Redis 主从搭建
- Redis 5.0.8 主从+哨兵的搭建
- ammo.js-bullet物理引擎碰撞检测
- TKE上动态部署jenkins slaves