当前位置: 首页 > 科技观察

如何使用人脸识别自动为头像添加口罩和护目镜

时间:2023-03-21 20:37:00 科技观察

为头像添加口罩和护目镜项目地址:https://github.com/Evilran/add-mask-and-goggle大家都戴口罩防止传播的冠状病毒。朋友圈也不例外。很多用户给自己的头像戴上了面具,但是调整面具在p图中的位置浪费了大家很多时间。那么我们如何通过人脸识别自动为头像添加口罩和护目镜呢?本项目利用人脸识别自动为头像添加口罩和护目镜,只为呼吁大家积极佩戴口罩和护目镜,为武汉加油,为奋战在一线的医护人员加油!依赖性🐍在开始之前,我们需要在python3上安装以下包:numpy==1.17.4Flask>=1.0.0requests==2.22.0opencv-python==4.0.0.21dlib==19.17.99Flask提供了一个简单的web服务器对于我们的项目,dlib用于识别人脸、嘴唇和眼睛(提供蒙版的位置),opencv库可以将蒙版材质添加到人脸的嘴唇上。脸部眼睛上加了护目镜。搭建web服务器首先导入flask库,构建主页面:fromflaskimportFlaskfromflaskimportrequestfromflaskimportrender_template@app.route('/',methods=['GET','POST'])defindex():returnrender_template('index.html')-------------------if__name__=='__main__':app.run()需要注意的是只允许上传图片类型的文件我们的服务器,并没有缓存图片(用户可以选择其他mask来重制),所以我们需要配置如下: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_FOLDERdefalowed_file(filename):return'.'infilenameand\filename.rsplit('.',1)[1]inALLOWED_EXTENSIONS我们的web服务器包含两条路由:/url/addurl是粘贴图片的地址,服务器会自动下载图片,add是用户手动上传图片(如果只有用户需要手动上传图片,不导入requests库)添加路由的函数代码如下:@app.route('/add',methods=['GET','POST'])defsearch():ifrequest.method=='POST':file=request.files['image']mode=(int)(request.form['mask'])isGoggle=request.form.get('goggle')iffileandallowed_file(file.filename):路径=os.path.join(app.config['UPLOAD_FOLDER'],file.filename)file.save(path)output=add(path,file.filename,mode,isGoggle)returnrender_template('index.html',outputoutput=output)else:returnrender_template('index.html',alert='file类型必须是图片!')else:returnrender_template('index.html')然后我们在模板中配置index.html文件。详细代码请移步Github项目人脸识别。到这里我们已经成功配置好了Web服务器,接下来我们开始写后端处理图片的代码。我们导入dlib和opencv库:importcv2importdlibimportnumpyasnpiimportos使用训练好的Dlib前向人脸检测器detector=dlib.get_frontal_face_detector()进行人脸检测,人脸和嘴巴的20个特征点坐标(40-维度特征)提取:defget_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(=deimg_gray,0)fork,dinenumerate(faces):x=[]y=[]#facesize的高度height=d.bottom()-d.top()#facesize的宽度width=d.right()-d.left()shape=predictor(img_gray,d)#49-68是唇部foriinrange(48,68):x.append(shape.part(i).x)y.append(shape.part(i).y)#根据脸的大小扩大mask对应的嘴唇面积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))returnx_min,x_max,y_min,y_max,和size一样,我们提取人脸和眼睛特征:defget_eye(img):img_gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)detector=dlib.get_frontal_face_detector()预测器=dlib.shape_predictor('models/shape_predictor_68_face_landmarks.dat')faces=detector(img_gray,0)fork,dinenumerate(faces):x=[]y=[]height=d.bottom()-d.top()宽度=d.right()-d.left()shape=predictor(img_gray,d)foriinrange(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))returnx_min,x_max,y_min,y_max,size确定了嘴唇和眼睛的位置后,我们处理背景通过opencvmask和goggles材质的透明度,将背景更改为白色: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))然后图像融合,把mask和goggles加到我们刚刚得到的唇位和眼位:x_min,x_max,y_min,y_max,size=get_眼睛(img1)行,列,通道=img2.shaperoi=img1[y_min:y_min+行,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到这里,我们就成功完成了人脸识别添加口罩和护目镜的代码演示😷一个命令可以简单地运行网络服务器:$python3server.py然后访问:127.0.0.1:5000(端口5000)。这里支持两种模式,一种是输入url地址,另一种是直接上传图片:currentmask支持以下类型:举个栗子🌰原图:加口罩和护目镜:原图:加口罩:谢谢🙏感谢奋战在一线的医护人员,感谢春运中的逆行者!