图像合成
实现思路
通过背景建模的⽅法,对源图像中的动态⼈物前景进⾏分割,再将⽬标图像作为背景,进⾏合成操作,获得⼀个可⽤的合成影像。实现步骤如下。
使⽤BackgroundSubtractorMOG2进⾏背景分割
BackgroundSubtractorMOG2是⼀个以⾼斯混合模型为基础的背景前景分割算法,混合⾼斯模型
分布概率是K个⾼斯分布的和,每个⾼斯分布有属于⾃⼰的 µ 和 σ 参数,以及对应的权重参数,权重值必须为正数,所有权重的和必须等于1,以确保公式给出数值是合理的概率密度值。换句话说如果我们把该公式对应的输⼊空间合并起来,结果将等于1。
回到原算法,它的⼀个特点是它为每⼀个像素选择⼀个合适数⽬的⾼斯分布。基于⾼斯模型的期望和标准差来判断混合⾼斯模型模型中的哪个⾼斯模型更有可能对应这个像素点,如果不符合就会被判定为前景。
使⽤⼈像识别填充⾯部信息
创建级联分类器
face_cascade = cv2.CascadeClassifier()face_cascade.load(
'/usr/local/anaconda3/envs/OpenCV/lib/python3.8/site-packages/cv2/data/haarcascade_frontalface_default.xml')
使⽤OpenCV⾃带的级联分类器,加载OpenCV的基础⼈像识别数据。识别源图像中的⼈像
faces = face_cascade.detectMultiScale(gray, 1.3, 5)使⽤形态学填充分割出来的前景
# 形态学开运算去噪点
fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel)for i in range(15):
fgmask = cv2.dilate(fgmask, kernel, iterations=1)
通过开操作去掉前景图像数组中的噪点,然后重复进⾏膨胀,填充前景轮廓。
将⼈像与⽬标背景进⾏合成
def resolve(o_img, mask, faces): if len(faces) == 0: return
(x, y, w, h) = faces[0]
rgb_mask_front = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR) rgb_mask_front = cv2.bitwise_not(rgb_mask_front)
cv2.circle(rgb_mask_front, (int(x + w / 2), int(y + h / 2)), int((w + h) / 4), (0, 0, 0), thickness=-1) o_img = cv2.subtract(o_img, rgb_mask_front) return o_img
将分割出来的部分取反再与源图像进⾏减操作,相当于⽤⼀个Mask从原图中抠出⼀部分。再与背景进⾏加操作
out = resolve(frame, fgmask, faces)out = cv2.add(out, c_frame)
代码实现
import numpy as npimport cv2import os
# 经典的测试视频
camera = cv2.VideoCapture('./source/background_test2.avi')cap = cv2.VideoCapture('./source/camera_test2.avi')face_cascade = cv2.CascadeClassifier()face_cascade.load(
os.getcwd()+'/source/haarcascade_frontalface_default.xml')# 形态学操作需要使⽤
Processing math: 100%
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))# 创建混合⾼斯模型⽤于背景建模
fgbg = cv2.createBackgroundSubtractorMOG2(detectShadows=False)
def resolve(o_img, mask, faces): if len(faces) == 0: return
(x, y, w, h) = faces[0]
rgb_mask_front = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR) rgb_mask_front = cv2.bitwise_not(rgb_mask_front)
cv2.circle(rgb_mask_front, (int(x + w / 2), int(y + h / 2)), int((w + h) / 4), (0, 0, 0), thickness=-1) o_img = cv2.subtract(o_img, rgb_mask_front) return o_img
while True:
ret, frame = cap.read()
c_ret, c_frame = camera.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
fgmask = fgbg.apply(frame) # 形态学开运算去噪点
fgmask = cv2.morphologyEx(fgmask, cv2.MORPH_OPEN, kernel) gray_camera = cv2.cvtColor(c_frame, cv2.COLOR_BGR2GRAY) for i in range(15):
fgmask = cv2.dilate(fgmask, kernel, iterations=1) faces = face_cascade.detectMultiScale(gray, 1.3, 5) out = resolve(frame, fgmask, faces) out = cv2.add(out, c_frame) cv2.imshow('Result', out) cv2.imshow('Mask', fgmask) k = cv2.waitKey(150) & 0xff if k == 27: breakout.release()camera.release()cap.release()
cv2.destroyAllWindows()
因篇幅问题不能全部显示,请点此查看更多更全内容