前言
最近发现了一个好用的人脸识别python库,能够较为快速准确的识别人脸,并且能够识别出人脸的9个特征部位的特征点,包括:眉毛、眼睛、鼻子、嘴唇等,可以利用这个库结合笔者的实用工具集,加上一些逻辑运算,可以玩出各种花样。本次,我们来给人脸加上胡子、墨镜和帽子,效果如下:
基本原理
利用人脸识别库(face_recognition)逐帧识别摄像头的图像,获得人脸的左右眼眼睛,上嘴唇的特征点坐标系列,计算得到左右眼的中心,用opencv画出两个圆形,并用直线连接起来就成了一幅墨镜;再更具眼睛中心坐标在头上画椭圆就加了个帽子;胡子的画法:
利用ps画出想要的胡子形状,并保存为png透明背景格式,然后通过带alpha通道的操作,将胡子加载调整大小后,与当前的帧相叠加,就完成了初步效果。
Python源码
# -*- coding: utf-8 -*-
"""
Created on Thu Mar 31 18:12:53 2022
@author: JAMES FEI
copyright (C) 2022 FEI PANFENG, All rights reserved.
THIS SOFTEWARE, INCLUDING DOCUMENTATION,IS PROTECTED BY copYRIGHT CONTROLLED
BY FEI PANFENG ALL RIGHTS ARE RESERVED.
"""
# -*- coding: utf-8 -*-
"""
Created on Thu Mar 31 15:58:32 2022
@author: Administrator
"""
import face_recognition
import cv2
import numpy as np
video_capture = cv2.VideoCapture(0)
process_this_frame = True
#载入胡子,带透明通道
huzi = cv2.imread('huzi.png', cv2.IMREAD_UNCHANGED)
ratio=1/4
huzi = cv2.resize(huzi, (int(huzi.shape[1]*ratio),int(huzi.shape[0]*ratio)), interpolation=cv2.INTER_LINEAR)
def putonhuzi(huzi,backimg,leftup):
#print(leftup)
x1 = leftup[0]
if x1<0:
x1=0
y1 = leftup[1]
if y1<0:
y1=0
x2 = x1 + huzi.shape[1]
y2 = y1 + huzi.shape[0]
usy=huzi.shape[0]
usx=huzi.shape[1]
if x2>backimg.shape[1]:
x2=backimg.shape[1]
usx=backimg.shape[1]-x1
if y2>backimg.shape[0]:
y2=backimg.shape[1]
usy=backimg.shape[0]-y1
if backimg.shape[2] == 3:
b, g, r = cv2.split(backimg)
alpha = np.ones(b.shape, dtype=b.dtype) * 255 # 创建Alpha通道
backimg = cv2.merge((b, g, r, alpha))
alpha_huzip = huzi[:usy,:usx,3] / 255.0
alpha_huzij = 1 - alpha_huzip
for c in range(0,3):
backimg[y1:y2, x1:x2, c] = ((alpha_huzij*backimg[y1:y2,x1:x2,c]) + (alpha_huzip*huzi[:usy,:usx,c]))
return backimg[:,:,:3]
while True:
ret, frame = video_capture.read()
small_frame = cv2.resize(frame, (0, 0), fx=1/4, fy=1/4)
rgb_frame = small_frame[:, :, ::-1]
if process_this_frame:
face_landmarks_list = face_recognition.face_landmarks(rgb_frame)
for face_landmarks in face_landmarks_list:
#打印此图像中每个面部特征的位置
facial_features = [
'chin',
'left_eyebrow',
'right_eyebrow',
'nose_bridge',
'nose_tip',
'left_eye',
'right_eye',
'top_lip',
'bottom_lip'
]
lef_center_x=0
lef_center_y=0
for point in face_landmarks["left_eye"]:
lef_center_x+=point[0]*4
lef_center_y+=point[1]*4
lef_center_x=int(lef_center_x/len(face_landmarks["left_eye"]))
lef_center_y=int(lef_center_y/len(face_landmarks["left_eye"]))
cv2.circle(frame, (lef_center_x,lef_center_y), 30, (0,0,0), -1)
rig_center_x=0
rig_center_y=0
for point in face_landmarks["right_eye"]:
rig_center_x+=point[0]*4
rig_center_y+=point[1]*4
rig_center_x=int(rig_center_x/len(face_landmarks["left_eye"]))
rig_center_y=int(rig_center_y/len(face_landmarks["left_eye"]))
cv2.circle(frame, (rig_center_x,rig_center_y), 30, (0,0,0), -1)
cv2.line(frame, (rig_center_x,rig_center_y),(lef_center_x,lef_center_y), (0,0,0), 4)
cv2.ellipse(frame,(int((rig_center_x+lef_center_x)/2),int((rig_center_y+lef_center_y)/2-80)),(200,50),0,0,360, (0,0,0),-1)
cv2.ellipse(frame,(int((rig_center_x+lef_center_x)/2),int((rig_center_y+lef_center_y)/2-100)),(90,60),0,0,360, (0,0,0),-1)
top_lip_x=0
top_lip_y=0
for point in face_landmarks["top_lip"]:
top_lip_x+=point[0]*4
top_lip_y+=point[1]*4
top_lip_x= int(top_lip_x/len(face_landmarks["top_lip"]))
top_lip_y= int(top_lip_y/len(face_landmarks["top_lip"]))
ouput=putonhuzi(huzi,frame,(top_lip_x-int(huzi.shape[1]/2),top_lip_y-20))
cv2.imshow('huzi', ouput)
# 按Q退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break
video_capture.release()
cv2.destroyAllWindows()