0、概述
python练习用代码。使用电脑摄像头录视频,实时识别人脸,并为头像上覆盖一个圣诞帽。
使用cv2包。包括人脸识别和图像覆盖的方法。
效果如图:(随便网上找了个照片)
1、图像覆盖函数
cv2自带的addweighted图像叠加方法不能很好地处理图片的透明度。
这里手动处理,根据png图像的alpha通道值计算图像覆盖。
def mask_img(front, back, y_offset=0, x_offset=0):
"""
图像覆盖函数,并且根据alpha通道的透明度计算。
:param front: 前景图,cv2.imread类型
:param back: 背景图,cv2.imread类型
:param y_offset: y偏移量
:param x_offset: x偏移量
:return: 无return,在front参数上生效
"""
y1, y2 = y_offset, y_offset + front.shape[0]
x1, x2 = x_offset, x_offset + front.shape[1]
alpha_front = front[:, :, 3] / 255.0
alpha_back = 1.0 - alpha_front
# 3个颜色通道,分别根据透明度覆盖
for color in range(0, 3):
front[y1:y2, x1:x2, color] = (alpha_front * front[:, :, color] + alpha_back * back[y1:y2, x1:x2, color])
2、人脸识别
cv2官方的人脸识别分类器就足够好用了。
根据人脸识别的结果,在适当的位置覆盖上圣诞帽图像。
import cv2
if __name__ == '__main__':
face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') # 读入cv2的官方的人脸识别分类器
cap = cv2.VideoCapture(0) # 加载电脑摄像头
# 读取帽子图像。cv2.IMREAD_UNCHANGED参数使可以保留png图像的alpha通道(透明度0-255)
hatImg = cv2.imread('hat.png', cv2.IMREAD_UNCHANGED)
while (True):
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
if len(faces) > 0:
for face_x, face_y, face_w, face_h in faces:
# 为人脸识别结果加上框框,方便调试用的
# frame = cv2.rectangle(frame, (face_x, face_y), (face_x + face_w, face_y + face_h), (255, 0, 0), 2)
# 根据人脸大小和位置,确定帽子的位置和大小。参数要根据帽子图手动调整
hat_x = int(face_x + face_w * 0.3)
hat_y = int(face_y - face_h * 0.5)
hat_w = int(face_w * 1)
hat_h = int(face_h * 1)
# 调整帽子图的尺寸
hatImg_resize = cv2.resize(hatImg, (hat_w, hat_h), interpolation=cv2.INTER_LINEAR)
rows, cols, channels = hatImg_resize.shape
# 使用上述的自定义函数做图像覆盖,覆盖后的图像保存在hatImg_resize
mask_img(hatImg_resize, frame[hat_y:hat_y + rows, hat_x:hat_x + cols])
for color in range(0, 3):
# 把原图像的修改为覆盖后图像
frame[hat_y:hat_y + rows, hat_x:hat_x + cols, color] = hatImg_resize[:, :, color]
cv2.imshow('face', frame)
# 按q退出
if cv2.waitKey(15) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
3、资源下载
圣诞帽图:hat.png
cv2的人脸识别分类器:haarcascade_frontalface_default

文章评论
哈哈哈哈哈哈哈谢谢!我在想后面再写点啥……
高产!