实时面具覆盖人脸小程序
这个实时面具覆盖人脸的小程序参考了http://datahonor.com/2017/05/18/实时视频中面具覆盖的实现/中的处理思路,在此基础上做了一些改动,应用了python-opencv及其中的人脸识别模块。
因为这里用到的人脸识别比较粗糙,返回的是一个包含脸部的矩形框,所以只能做到简单的覆盖,效果并不精细。
import cv2 as cv
import numpy as np
faceCascade = cv.CascadeClassifier('classify/haarcascade_frontalface_default.xml')
# 读取面具图像
faceMask = cv.imread("data/maskFace1.jpg")
# 打开摄像头
cap = cv.VideoCapture(0)
# 开始处理图像
while True:
ret, img = cap.read()
scalingFactor = 0.75
# 重置输入图像大小
frame = cv.resize(img,None,fx = scalingFactor, fy = scalingFactor, interpolation = cv.INTER_AREA)
# 彩色转灰度图像
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
# 直方图均衡化
frameGray = cv.equalizeHist(gray)
# 检测脸部,该函数在输入图像的不同尺度中检测物体
faces = faceCascade.detectMultiScale(frameGray, 1.3, 5)
for i in range(0, len(faces)):
for (x1, y1, w1, h1) in faces:
# 自定义参数,使面具适合脸
x = x1 - int(0.1 * w1)
y = y1 - int(0.0 * h1)
w = int(1.1 * w1)
h = int(1.1 * h1)
try:
FaceMaskSmall = cv.resize(faceMask, (w, h), interpolation=cv.INTER_AREA)
# roi确定了面具所在人脸图像上的位置
roi = frame[y: y+h, x: x+w]
# 面具图转换为灰度图
gray = cv.cvtColor(FaceMaskSmall, cv.COLOR_BGR2GRAY)
# 对面具图阈值分割得到mask1,也就是面具图的背景(0~50部分)
# 保留mask1部分的roi
ret, mask1 = cv.threshold(gray, 50, 255, cv.THRESH_BINARY_INV)
fg1 = cv.bitwise_and(roi, roi, mask=mask1)
# 对面具图阈值分割得到面具的前景部分(50~255部分)
ret, mask2 = cv.threshold(gray, 50, 255, cv.THRESH_BINARY)
# 保留面具图像的面具部分
fg2 = cv.bitwise_and(FaceMaskSmall, FaceMaskSmall, mask=mask2)
# 图像叠加
roi[:] = cv.add(fg1, fg2)
except:
continue
# 设置退出循环条件
if cv.waitKey(1) & 0xFF == ord('q'):
break
cv.imshow("Frame", frame)
# 退出程序
cv.waitKey(0)
cap.release()
cv.destroyAllWindows()
处理结果的视频截图如下图所示: