如何用人脸识别自动给头像添加口罩及护目镜
给头像添加口罩及护目镜
项目地址:https://github.com/Evilran/add-mask-and-goggle
写在前面
武汉爆发了2020新型冠狀病毒肺炎,大家都纷纷戴上了口罩以预防被传染。朋友圈也不例外,许多用户都为自己的头像戴上了口罩,但是p图调整口罩的位置浪费了大家很多时间。那么我们如何通过人脸识别自动给头像添加口罩及护目镜呢?
此项目使用人脸识别自动给头像添加口罩及护目镜,仅为呼吁大家积极佩戴口罩及护目镜,为武汉及奋斗在第一线的医护人员加油!
依赖🐍
在开始前,我们需要在python3上安装以下几个包:
- numpy==1.17.4
- Flask>=1.0.0
- requests==2.22.0
- opencv-python==4.0.0.21
- dlib==19.17.99
Flask为我们的项目提供了一个简单的Web服务器,dlib用以识别人脸及嘴唇和眼睛的部位(提供了口罩所在的位置),opencv库可以把口罩素材添加到人脸的嘴唇部位上,护目镜添加到人脸的眼部。
搭建Web服务器
首先,引入flask库并构造主页面:
- from flask import Flask
- from flask import request
- from flask import render_template
- @app.route('/', methods=['GET', 'POST'])
- def index():
- return render_template('index.html')
- ----------------------
- if __name__ == '__main__':
- app.run()
需要注意的是,我们的服务器上只允许上传图片类型的文件,并且不缓存图片(用户可以选择其他的口罩重新制作),所以我们要进行如下配置:
- app = Flask(__name__)
- # 取消图片缓存
- app.config['SEND_FILE_MAX_AGE_DEFAULT'] = timedelta(seconds=1)
- ALLOWED_EXTENSIONS = set(['bmp', 'png', 'jpg', 'jpeg'])
- UPLOAD_FOLDER=r'./cache/'
- app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
- def allowed_file(filename):
- return '.' in filename and \
- filename.rsplit('.', 1)[1] in ALLOWED_EXTENSIONS
我们的Web服务器上包含有两个路由:
- /url /add
url 是粘贴图片的地址,服务器会自动下载图片,add 则为用户手动上传图片 (如果只需用户手动上传图片,不需要引入requests库)
add 路由的函数代码如下:
- @app.route('/add', methods=['GET', 'POST'])
- def search():
- if request.method == 'POST':
- file = request.files['image']
- mode = (int)(request.form['mask'])
- isGoggle = request.form.get('goggle')
- if file and allowed_file(file.filename):
- path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
- file.save(path)
- output = add(path, file.filename, mode, isGoggle)
- return render_template('index.html', outputoutput = output)
- else:
- return render_template('index.html', alert = '文件类型必须是图片!')
- else:
- return render_template('index.html')
接着我们配置好 templates 里的 index.html 文件,详细代码请移步 Github 项目。
人脸识别
好了,到这里我们已经成功配置好Web服务器了,接着我们开始写后端处理图片的代码。我们引入 dlib 和 opencv 库:
- import cv2
- import dlib
- import numpy as np
- import os
利用已经训练好的 Dlib 正向人脸检测器 detector = dlib.get_frontal_face_detector() 进行人脸检测,并用 'models/shapepredictor68facelandmarks.dat' 进行 人脸嘴部 20 个特征点坐标( 40 维特征)的提取:
- def get_mouth(img):
- img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
- detector = dlib.get_frontal_face_detector()
- predictor = dlib.shape_predictor('models/shape_predictor_68_face_landmarks.dat')
- faces = detector(img_gray, 0)
- for k, d in enumerate(faces):
- x = []
- y = []
- # 人脸大小的高度
- height = d.bottom() - d.top()
- # 人脸大小的宽度
- width = d.right() - d.left()
- shape = predictor(img_gray, d)
- # 49-68 为嘴唇部分
- for i in range(48, 68):
- x.append(shape.part(i).x)
- y.append(shape.part(i).y)
- # 根据人脸的大小扩大嘴唇对应口罩的区域
- y_max = (int)(max(y) + height / 3)
- y_min = (int)(min(y) - height / 3)
- x_max = (int)(max(x) + width / 3)
- x_min = (int)(min(x) - width / 3)
- size = ((x_max-x_min),(y_max-y_min))
- return x_min, x_max, y_min, y_max, size
同样的道理,我们进行 人脸眼部特征 的提取:
- def get_eye(img):
- img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
- detector = dlib.get_frontal_face_detector()
- predictor = dlib.shape_predictor('models/shape_predictor_68_face_landmarks.dat')
- faces = detector(img_gray, 0)
- for k, d in enumerate(faces):
- x = []
- y = []
- height = d.bottom() - d.top()
- width = d.right() - d.left()
- shape = predictor(img_gray, d)
- for i in range(36, 48):
- x.append(shape.part(i).x)
- y.append(shape.part(i).y)
- y_max = (int)(max(y) + height / 3)
- y_min = (int)(min(y) - height / 3)
- x_max = (int)(max(x) + width / 3)
- x_min = (int)(min(x) - width / 3)
- size = ((x_max-x_min),(y_max-y_min))
- return x_min, x_max, y_min, y_max, size
识别出嘴唇和眼睛的位置后,我们通过 opencv 处理背景透明的口罩和护目镜素材 ,把背景变成白色:
- img2 = cv2.imread('masks/goggle.png', cv2.IMREAD_UNCHANGED)
- img2 = cv2.resize(img2,size)
- alpha_channel = img2[:, :, 3]
- _, mask = cv2.threshold(alpha_channel, 220, 255, cv2.THRESH_BINARY)
- color = img2[:, :, :3]
- img2 = cv2.bitwise_not(cv2.bitwise_not(color, maskmask=mask))
然后进行图像融合,把口罩及护目镜添加到我们刚刚得到的嘴唇位置和眼睛位置:
- x_min, x_max, y_min, y_max, size = get_eye(img1)
- rows,cols,channels = img2.shape
- roi = img1[y_min: y_min + rows, x_min:x_min + cols]
- img2gray = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY)
- ret, mask = cv2.threshold(img2gray, 254, 255, cv2.THRESH_BINARY)
- mask_inv = cv2.bitwise_not(mask)
- img1_bg = cv2.bitwise_and(roi,roi,maskmask = mask)
- img2_fg = cv2.bitwise_and(img2,img2,mask = mask_inv)
- dst = cv2.add(img1_bg,img2_fg)
- img1[y_min: y_min + rows, x_min:x_min + cols] = dst
到这里,我们人脸识别添加口罩及护目镜的代码就已经成功完成了。
演示😷
项目完成后,
仅需一个命令即可简单地运行Web服务器:
- $ python3 server.py
然后访问:127.0.0.1:5000(端口 5000).
这里支持两种模式,一种是输入URL地址,另外一种是直接上传图片:
目前口罩支持以下几种类型:
举个栗子🌰
原图:
添加口罩及护目镜:
原图:
添加口罩:
感谢🙏
感谢奋斗在第一线的医护人员,感谢春运中的逆行者!


更多资讯推荐
- “刷脸”不再是玩笑,戴上口罩也可以“不失灵”
-
近年来,随着人工智能、大数据、云计算等技术的迅速发展,人脸识别技术取得了长足的进步并且在众多场景中得以成功应用,“刷脸”成为了这几年的热门话题。
佚名 · 2021-02-20 10:56:30
- 真会玩,程序员用AI认双胞胎儿子!“这个树莓派版人脸识别系统,没我认得准”
-
本文介绍了外国程序员使用软件利用AI系统Raspberry Pi识别双胞胎儿子的实验,并试图探究在面部识别方面,机器的发展是否已经超过人类大脑。
佚名 · 2021-02-15 16:30:35
- 人脸识别技术的应用风险和法律规制
-
人脸识别技术是根据人的脸部特征信息加以身份识别的一种先进识别技术。因其无感性、便利性和准确性而广泛应用,不过近年来也引发一些法律问题,法律如何加以妥当规制值得深入研究。
中国社会科学网 · 2021-02-03 17:11:06
- 你的照片被多少面部识别系统「偷偷」用过?是时候用工具查一查了
-
在这个数据「泛滥」的时代,你的隐私数据到底被多少机构「花式」使用了?国外的研究人员开发一款名叫Exposing.AI的工具,可以帮人们获知自己的人脸数据被各种面部识别系统使用的情况,并经常能获得令人出乎意料的结果。
佚名 · 2021-02-03 15:29:44
- 什么是人脸识别?你真的了解人脸识别技术吗?
-
由于人工智能的发展,近年来,基于海量数据的人脸识别技术被广泛应用于各个领域。火车、地铁通道、人脸通道、微邮服务、一些工作人员测绘设施等都是人脸识别技术的特殊应用。本节简单介绍一下人脸识别的好处和一些典型应用领域。
每日精彩科技 · 2021-02-03 14:43:40
- 三分钟带你入门人脸识别
-
人脸识别是AI研究带给世界的众多奇迹之一。对于许多技术人员来说,这是一个充满好奇的话题-他们希望对事物的工作方式有基本的了解。让我们潜入主题,看看事情如何运作。
佚名 · 2021-02-03 14:31:53
- 面部解锁时,手机是怎么“认出”你的?人脸识别了解下
-
“刷脸”是这几年的一个热门话题,在现实生活中也随处可见,那么,人脸识别在技术上究竟是如何实现的呢?它与人工智能又有怎样的关联?本文详细的介绍了人脸识别的相关知识。
史淑荣 · 2021-02-03 11:50:05
- 格灵深瞳:人脸识别最新进展以及工业级大规模人脸识别实践探讨
-
人脸识别已经成为成为计算机视觉领域最热门的应用之一,很多刚入门的 AI 新手都或多或少接触过人脸识别的相关知识,但是纸上得来终觉浅,在实际应用中,往往会遇到各种各样的问题,比如如何保证不同环境下人脸识别的准确率,极端环境下如何进行人脸识别等等。
张德兵 · 2021-02-03 11:26:20