基于Python实现人脸自动戴口罩系统


Posted in Python onFebruary 06, 2020

1、项目背景

2019年新型冠状病毒感染的肺炎疫情发生以来,牵动人心,举国哀痛,口罩、酒精、消毒液奇货可居。

基于Python实现人脸自动戴口罩系统

抢不到口罩,怎么办?作为技术人今天分享如何使用Python实现自动戴口罩系统,来安慰自己,系统效果如下所示:

基于Python实现人脸自动戴口罩系统

本系统的实现原理是借助 Dlib模块的Landmark人脸68个关键点检测库轻松识别出人脸五官数据,根据这些数据,确定嘴唇部分的位置数据(48点~67点位置),根据检测到嘴部的尺寸和方向,借助PLL模块调整口罩的尺寸和方向,实现将口罩放在图像的适当位置。

基于Python实现人脸自动戴口罩系统

2、页面设计

 基于tkinter模块实现GUI设计,可载入人物图像,选择四种类型口罩(这里的口罩是处理好的图片),展示佩戴好口罩的效果,操作完成退出系统,效果如下所示:

基于Python实现人脸自动戴口罩系统

页面布局实现代码如下所示:

def __init__(self):
 self.root = tk.Tk()
 self.root.title('基于Pyhon的人脸自动戴口罩系统')
 self.root.geometry('1200x500')
 self.path1_ = None
 self.path2_ = None
 self.seg_img_path = None
 self.mask = None
 self.label_Img_seg = None
 decoration = PIL.Image.open('./pic/bg.png').resize((1200, 500))
 render = ImageTk.PhotoImage(decoration)
 img = tk.Label(image=render)
 img.image = render
 img.place(x=0, y=0)
 # 原图1的展示
 tk.Button(self.root, text="打开头像", command=self.show_original1_pic).place(x=50, y=120)
 tk.Button(self.root, text="退出软件", command=quit).place(x=900, y=40)
 tk.Label(self.root, text="头像", font=10).place(x=280, y=120)
 self.cv_orinial1 = tk.Canvas(self.root, bg='white', width=270, height=270)
 self.cv_orinial1.create_rectangle(8, 8, 260, 260, width=1, outline='red')
 self.cv_orinial1.place(x=180, y=150)
 self.label_Img_original1 = tk.Label(self.root)
 self.label_Img_original1.place(x=180, y=150)
 tk.Label(self.root,text="选择口罩",font=10).place(x=600,y=120)
 first_pic = Image.open("./pic/Mask.png")
 first_pic = first_pic.resize((60, 60), Image.ANTIALIAS)
 first_pic = ImageTk.PhotoImage(first_pic)
 self.first = tk.Label(self.root, image=first_pic)
 self.first.place(x=600,y=160, width=60, height=60)
 self.first.bind("<Button-1>", self.mask0)
 second_pic = Image.open("./pic/Mask1.png")
 second_pic = second_pic.resize((60, 60), Image.ANTIALIAS)
 second_pic = ImageTk.PhotoImage(second_pic)
 self.second_pic = tk.Label(self.root, image=second_pic)
 self.second_pic.place(x=600, y=230, width=60, height=60)
 self.second_pic.bind("<Button-1>", self.mask1)
 third_pic = Image.open("./pic/Mask3.png")
 third_pic = third_pic.resize((60, 60), Image.ANTIALIAS)
 third_pic = ImageTk.PhotoImage(third_pic)
 self.third_pic = tk.Label(self.root, image=third_pic)
 self.third_pic.place(x=600, y=300, width=60, height=60)
 self.third_pic.bind("<Button-1>", self.mask3)
 forth_pic = Image.open("./pic/Mask4.png")
 forth_pic = forth_pic.resize((60, 60), Image.ANTIALIAS)
 forth_pic = ImageTk.PhotoImage(forth_pic)
 self.forth_pic = tk.Label(self.root, image=forth_pic)
 self.forth_pic.place(x=600, y=370, width=60, height=60)
 self.forth_pic.bind("<Button-1>", self.mask4)
 tk.Label(self.root, text="佩戴效果", font=10).place(x=920, y=120)
 self.cv_seg = tk.Canvas(self.root, bg='white', width=270, height=270)
 self.cv_seg.create_rectangle(8, 8, 260, 260, width=1, outline='red')
 self.cv_seg.place(x=820, y=150)
 self.label_Img_seg = tk.Label(self.root)
 self.label_Img_seg.place(x=820, y=150)
 self.root.mainloop()

载入人物图像,实现代码如下所示:

# 原图1展示
 def show_original1_pic(self):
 self.path1_ = askopenfilename(title='选择文件')
 print(self.path1_)
 self.Img = PIL.Image.open(r'{}'.format(self.path1_))
 Img = self.Img.resize((270,270),PIL.Image.ANTIALIAS) # 调整图片大小至256x256
 img_png_original = ImageTk.PhotoImage(Img)
 self.label_Img_original1.config(image=img_png_original)
 self.label_Img_original1.image = img_png_original # keep a reference
 self.cv_orinial1.create_image(5, 5,anchor='nw', image=img_png_original)

人脸戴口罩展示,实现代码如下所示

# 人脸戴口罩效果展示
 def show_morpher_pic(self):
 img1 = cv2.imread(self.path1_)
 x_min, x_max, y_min, y_max, size = self.get_mouth(img1)
 adding = self.mask.resize(size)
 im = Image.fromarray(img1[:, :, ::-1]) # 切换RGB格式
 # 在合适位置添加头发图片
 im.paste(adding, (int(x_min), int(y_min)), adding)
 # im.show()
 save_path = self.path1_.split('.')[0]+'_result.jpg'
 im.save(save_path)
 Img = im.resize((270, 270), PIL.Image.ANTIALIAS) # 调整图片大小至270x270
 img_png_seg = ImageTk.PhotoImage(Img)
 self.label_Img_seg.config(image=img_png_seg)
 self.label_Img_seg.image = img_png_seg # keep a reference

导入四种口罩图像,实现代码如下所示:   

def mask0(self, event):
 self.mask = Image.open('pic/mask.png')
 self.show_morpher_pic()
 def mask1(self, event):
 self.mask = Image.open('pic/mask1.png')
 self.show_morpher_pic()
 def mask3(self, event):
 self.mask = Image.open('pic/mask3.png')
 self.show_morpher_pic()
 def mask4(self, event):
 self.mask = Image.open('pic/mask4.png')
 self.show_morpher_pic()

3、器官识别

页面功能实现后就是依托Dlib库实现人脸器官关键点的识别,分析出嘴部位置及尺寸,这里为了方便各位直观了解,写了一个测试Demo,将人物脸部关键点都显示出来,代码如下所示:

#coding=utf-8
#图片检测 - Dlib版本
import cv2
import dlib
import time
t=time.time()
path = "./pic/im.jpg"
img = cv2.imread(path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 
#人脸分类器
detector = dlib.get_frontal_face_detector()
# 获取人脸检测器
predictor = dlib.shape_predictor(
 "./shape_predictor_68_face_landmarks.dat"
)
dets = detector(gray, 1)
for face in dets:
 shape = predictor(img, face) # 寻找人脸的68个标定点
 # 遍历所有点,打印出其坐标,并圈出来
 for pt in shape.parts():
 pt_pos = (pt.x, pt.y)
 cv2.circle(img, pt_pos, 1, (0, 255, 0), 2)
 cv2.imshow("image", img)
print('所用时间为{}'.format(time.time()-t))
cv2.waitKey(0)
#cv2.destroyAllWindows()
time.sleep(5)

效果如下所示: 

基于Python实现人脸自动戴口罩系统

在本系统中这些关键点无需绘制显示,直接使用就可以,实现代码如下所示:

def get_mouth(self, img):
 img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
 detector = dlib.get_frontal_face_detector()
 predictor = dlib.shape_predictor('./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)
 # 48-67 为嘴唇部分
 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

4、退出系统

退出系统非常简单,一行Demo即可实现,如下所示:

def quit(self):
 self.root.destroy()

总结

以上所述是小编给大家介绍的基于Python实现人脸自动戴口罩系统,希望对大家有所帮助!

Python 相关文章推荐
Tornado Web服务器多进程启动的2个方法
Aug 04 Python
python出现&quot;IndentationError: unexpected indent&quot;错误解决办法
Oct 15 Python
python版大富翁源代码分享
Nov 19 Python
Linux下通过python获取本机ip方法示例
Sep 06 Python
python编写猜数字小游戏
Oct 06 Python
python add_argument()用法解析
Jan 29 Python
基于Python 的语音重采样函数解析
Jul 06 Python
使用python编写一个语音朗读闹钟功能的示例代码
Jul 14 Python
Python无损压缩图片的示例代码
Aug 06 Python
python爬虫中的url下载器用法详解
Nov 30 Python
Python经典五人分鱼实例讲解
Jan 04 Python
python requests库的使用
Jan 06 Python
python时间日期操作方法实例小结
Feb 06 #Python
python通过matplotlib生成复合饼图
Feb 06 #Python
tensorflow 初始化未初始化的变量实例
Feb 06 #Python
python中count函数简单的实例讲解
Feb 06 #Python
tensorflow之变量初始化(tf.Variable)使用详解
Feb 06 #Python
使用TensorFlow搭建一个全连接神经网络教程
Feb 06 #Python
详解python 降级到3.6终极解决方案
Feb 06 #Python
You might like
php的declare控制符和ticks教程(附示例)
2014/03/21 PHP
使用phpexcel类实现excel导入mysql数据库功能(实例代码)
2016/05/12 PHP
Yii2如何批量添加数据
2016/05/17 PHP
Javascript中eval函数的使用方法与示例
2007/04/09 Javascript
模拟多级复选框效果的jquery代码
2013/08/13 Javascript
使用jQuery异步加载 JavaScript脚本解决方案
2014/04/20 Javascript
基于JavaScript实现图片点击弹出窗口而不是保存
2016/02/06 Javascript
JavaScript常用本地对象小结
2016/03/28 Javascript
异步加载JS、CSS代码(推荐)
2016/06/15 Javascript
easyUI实现(alert)提示框自动关闭的实例代码
2016/11/07 Javascript
JS键盘版计算器的制作方法
2016/12/03 Javascript
微信小程序 wx.uploadFile在安卓手机上面the same task is working问题解决
2016/12/14 Javascript
jQuery如何跳转到另一个网页 就这么简单
2016/12/28 Javascript
原生JavaScript来实现对dom元素class的操作方法(推荐)
2017/08/16 Javascript
面包屑导航详解
2017/12/07 Javascript
简单的Vue SSR的示例代码
2018/01/12 Javascript
说说Vuex的getters属性的具体用法
2019/04/15 Javascript
vue中的面包屑导航组件实例代码
2019/07/01 Javascript
Javascript Dom元素获取和添加详解
2019/09/24 Javascript
python获取文件版本信息、公司名和产品名的方法
2014/10/05 Python
Python3.6.x中内置函数总结及讲解
2019/02/22 Python
Pytorch释放显存占用方式
2020/01/13 Python
python给视频添加背景音乐并改变音量的具体方法
2020/07/19 Python
公认8个效率最高的爬虫框架
2020/07/28 Python
英国剑桥包中文官网:The Cambridge Satchel Company中国
2018/11/06 全球购物
元旦晚会上单位领导演讲稿
2014/01/05 职场文书
红领巾心向党演讲稿
2014/09/10 职场文书
工作疏忽检讨书500字
2014/10/26 职场文书
2015幼儿园庆元旦活动方案
2014/12/09 职场文书
岳麓书院导游词
2015/02/03 职场文书
上下班时间调整通知
2015/04/23 职场文书
考试没考好检讨书
2015/05/06 职场文书
2015年税务稽查工作总结
2015/05/26 职场文书
小学语文的各类谚语(70首)
2019/08/15 职场文书
JS异步堆栈追踪之为什么await胜过Promise
2021/04/28 Javascript
如何利用Python实现一个论文降重工具
2021/07/09 Python