图像合成

实现思路

通过背景建模的方法,对源图像中的动态人物前景进行分割,再将目标图像作为背景,进行合成操作,获得一个可用的合成影像。

实现步骤如下。

使用BackgroundSubtractorMOG2进行背景分割

BackgroundSubtractorMOG2是一个以高斯混合模型为基础的背景前景分割算法,

混合高斯模型

分布概率是K个高斯分布的和,每个高斯分布有属于自己的 \(\mu\) 和 \(\sigma\) 参数,以及对应的权重参数,权重值必须为正数,所有权重的和必须等于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 np
import cv2
import 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')
# 形态学操作需要使用
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:
break
out.release()
camera.release()
cap.release()
cv2.destroyAllWindows()

使用OpenCV进行简单的人像分割与合成的更多相关文章

  1. OpenCV 编程简单介绍(矩阵/图像/视频的基本读写操作)

    PS. 因为csdn博客文章长度有限制,本文有部分内容被截掉了.在OpenCV中文站点的wiki上有可读性更好.而且是完整的版本号,欢迎浏览. OpenCV Wiki :<OpenCV 编程简单 ...

  2. SQL点滴3—一个简单的字符串分割函数

    原文:SQL点滴3-一个简单的字符串分割函数 偶然在电脑里看到以前保存的这个函数,是将一个单独字符串切分成一组字符串,这里分隔符是英文逗号“,”  遇到其他情况只要稍加修改就好了 CREATE FUN ...

  3. Android上掌纹识别第一步:基于OpenCV的6种肤色分割 源码和效果图

    Android上掌纹识别第一步:基于OpenCV的6种肤色分割 源码和效果图 分类: OpenCV图像处理2013-02-21 21:35 6459人阅读 评论(8) 收藏 举报   原文链接  ht ...

  4. c# 利用百度图像处理【人像分割】一键抠图

    百度AI开放平台-人像分割: http://ai.baidu.com/tech/body/seg 注意本文后面的话,百度这个技术效果太差劲了,国外这 https://www.remove.bg/ 个比 ...

  5. 18、OpenCV Python 简单实现一个图片生成(类似抖音生成字母人像)

    __author__ = "WSX" import cv2 as cv import numpy as np def local_threshold(img): #局部阈值 gra ...

  6. Python + opencv 实现图片文字的分割

    实现步骤: 1.通过水平投影对图形进行水平分割,获取每一行的图像: 2.通过垂直投影对分割的每一行图像进行垂直分割,最终确定每一个字符的坐标位置,分割出每一个字符: 先简单介绍一下投影法:分别在水平和 ...

  7. 基于Opencv的简单图像处理

    实验环境 本实验均在笔记本电脑完成,电脑的配置如表1所示: 系统 Windows 10 家庭版 处理器 英特尔 Core i5-6200 @ 2.30GHz 双核 主板 宏碁 Zoro_SL 内存 1 ...

  8. vs2012配置opencv及简单测试

    为visual studio2012搭建openCV平台,实现打开图片. 实现步骤: 1.1.配置环境变量 基于win7操作系统的环境配置步骤: 1.1.1 计算机—>属性—>更改设置—& ...

  9. OpenCV —— 图像局部与部分分割(一)

    背景减除 一旦背景模型建立,将背景模型和当前的图像进行比较,然后减去这些已知的背景信息,则剩下的目标物大致就是所求的前景目标了 缺点 —— 该方法基于一个不长成立的假设:所有像素点是独立的 场景建模 ...

随机推荐

  1. 敏捷开发 | DSDM 在非 IT 领域也同样适用?

    动态系统开发方法(Dynamic Systems Development Method:DSDM)是在快速应用程序开发(RAD)方法的基础上改进的.作为敏捷方法论的一种,DSDM方法倡导以业务为核心, ...

  2. Robot Framework+adb框架自动化测试Android设备案例⑷——L2层关键字

    一.EMMC测试套件 L2层关键字.robot *** Settings *** Resource ../L3公共层.robot *** Keywords *** 一般录影文件列表(EMMC) ${f ...

  3. Mysql为什么使用b+树,而不是b树、AVL树或红黑树?

    首先,我们应该考虑一个问题,数据库在磁盘中是怎样存储的?(答案写在下一篇文章中) b树.b+树.AVL树.红黑树的区别很大.虽然都可以提高搜索性能,但是作用方式不同. 通常文件和数据库都存储在磁盘,如 ...

  4. 精尽Spring MVC源码分析 - MultipartResolver 组件

    该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...

  5. 软件工程与UML的第一次课

    | 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/fzzcxy/2018SE1 | | 这个作业要求在哪里 | https://edu.cnblogs.com ...

  6. Taro 周报 #7: 收获「e代驾」案例,发布 v2.2.16 和 v3.2.0-canary.2

    Taro 周报 2020 年 12 月 05 日 - 2020 年 12 月 12 日 ,更多的Taro周报点击 Taro 大事件 58 技术发布文章<开源 | Taro 3 支持 React ...

  7. Application Data in Docker 笔记

    Application Data in Docker By default all files created inside a container are stored on a writable ...

  8. 太酷炫了!!我会Python 导包八种方法,你呢?

    1. 直接 import 人尽皆知的方法,直接导入即可 >>> import os >>> os.getcwd() '/home/wangbm'复制代码 与此类似的 ...

  9. Qt学习笔记-了解信号与槽-自定义信号-自定义槽

    信号与槽是连接不同控件直接的渠道. 这里以Horizontal Slider和Dial两个控件举例. 目的是在改变滑条的数值时,Dial也随之响应. 首先添加两个控件. 然后按快捷键F4进入控件编辑模 ...

  10. Win10下mysql5.5和mysql8.0.19共存

    Win10下mysql5.5和mysql8.0.19共存 需求:由于之前做的项目用的是mysql5.5,而新接的项目指定用mysql8,需要myql5..5和8同时存在运行. 前提:电脑已经安装mys ...