基于OpenCV创建视频会议虚拟背景
本期我们将使用Python和OpenCV为频会议创建虚拟背景。
虚拟背景是当前远程工作的员工中的热门话题之一。由于Covid-19的流行,许多人必须通过视频通话以便继续工作。很多视频会议的软件可以设置虚拟背景,以便用户建立更友好的氛围来接听这些电话。
作为一名程序员,当我们第一次使用这样的虚拟背景时自然很感兴趣。我们都想知道它是如何工作的,可以自己建立这样的虚拟背景吗?
接下来,我们将尝试使用Python和OpenCV使用计算机视觉技术构建虚拟背景的基本方法。(虽然效果并不是很好~)
介绍
我们的目的是拍摄视频,尝试弄清楚视频的背景和前景,删除背景部分,并用图片(虚拟背景)代替。因为在此项目中,我们将使用简单的方法,假设前景通常具有与背景不同的颜色。首先,让我们看看我们的工具是什么。
计算机视觉
计算机视觉是一个跨学科领域,涉及计算机如何处理和(或)理解图像和视频。说这是一个跨学科的领域,因为它借鉴了不同学科(计算机科学,代数,几何等)的许多概念,并将它们组合起来以解决许多不同而复杂的任务,例如对象跟踪,对象检测, 对象识别,图片和视频中的对象细分。
OpenCV
OpenCV是一个用于解决计算机视觉任务的库。它是开源的,可用于多种编程语言,包括Python和C ++。它具有大量的计算机视觉功能,其中一些基于数学和统计方法,而另一些则基于机器学习。
建立虚拟背景
我为此尝试的方法如下。我将显示每个步骤的代码片段,并在本文结尾处,您将获得完整的代码。
1. 导入依赖
import numpy as np
import cv2
2.从本地环境加载视频并初始化数据
ap = cv2.VideoCapture('video6.mp4')
ret = True
frameCounter = 0
previousFrame = None
nextFrame = None
iterations = 0
3.从本地环境加载替代背景图像
backgroundImage = cv2.imread("image1.jpg")
4.逐帧分割视频
while (ret):
ret, frame = cap.read()
5.每隔两帧拍摄一次
if frameCounter % 2 == 1:
nextFrame = frame
if frameCounter % 2 == 0:
frameCounter = 0
previousFrame = frame
frameCounter = frameCounter + 1
iterations = iterations + 1
6.找到两个帧之间的绝对差并将其转换为灰度->获得蒙版
if iterations > 2:
diff = cv2.absdiff(previousFrame, nextFrame)
mask = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)
每个图像都由像素组成,我们可以将其想象为具有行和列的2D矩阵,并且矩阵中的每个单元格都是图像中的像素(当然,对于彩色图像,我们拥有的尺寸比2大,但为简单起见,可以忽略)。
我们通过在第一个图像中逐个像素移动(因此在第一矩阵中一个单元一个像素)并从另一个图像中替换对应的像素(因此从另一个矩阵中替换对应的像素)来获得差异。
现在的诀窍是:如果在两帧之间,像素没有被修改,那么结果当然是0。两帧之间的像素如何变化?如果视频是完全静态的(图像中没有任何动静),则所有像素的每一帧之间的差将为0,因为没有任何更改。但是,如果某物在图像中移动,那么我们可以通过检测像素差异来识别某物在图像中的移动位置。我们可以假设,在视频会议中,移动的事物位于前台(即您),而静态部分是背景。
那么0到底有什么重要呢?图像将为每个像素显示为0的黑色,我们将利用这一优势。
7.找到蒙版中超出阈值的单元格-我选择3作为阈值,当然也可以使用不同的值。较大的值将从背景中删除更多内容,但也可能从前景中删除更多内容
th = 3
isMask = mask > th
nonMask = mask <= th
8.创建一个空白图像(每个单元格为0),其大小为两个框架中任何一个的大小
result = np.zeros_like(nextFrame, np.uint8)
9.调整背景图像的大小,使其具有与框架相同的大小
resized = cv2.resize(backgroundImage, (result.shape[1], result.shape[0]), interpolation = cv2.INTER_AREA)
10.对于蒙版中大于阈值的每个单元,请从原始帧进行复制
result[isMask] = nextFrame[isMask]000000000000
11.对于蒙版中低于阈值的每个单元,请从替代背景图像进行复制
result[nonMask] = resized[nonMask]
12.将结果框保存到本地环境
cv2.imwrite("output" + str(iterations) + ".jpg", result)
结果与结论
那么结果如何呢?老实说,我对结果感到有些失望。然后,我做了更多的研究,其原因变得更加明显。为此,您需要一种更高级的方法,并且大公司在此类问题上投入了大量资源也就不足为奇了。
这是我尝试的视频的屏幕截图。这基本上是我的手在墙前移动的视频。
虚拟背景Python和OpenCV教程-输入
这是输出图像的屏幕截图。作为背景,我在罗马尼亚的拉斯诺夫使用了我的照片。
虚拟背景Python和OpenCV教程-输出
结果并不满意,但是我们也从这个项目中学到的东西。
创建虚拟背景的其他方法
如果认为问题非常复杂,并且需要的智能水平,那么答案可能是机器学习。
已有深度学习模型可以执行此类任务。但是,这样的模型需要训练大量的数据集和大量的处理能力,在撰写本文时,我还没有这些能力做这种尝试。这种深度学习模型要解决的任务称为图像分割。
另一种方法是计算机视觉方法,用于查找相机和图像中的对象之间的距离。然后,建立一个阈值,以将前景与背景分开。之后,可以使用与移除背景相同的蒙版,并引入一个新的蒙版。
- 区块链钱包mMoney向GooglePay、Applepay发起挑战
- Model验证系统运行机制是如何实现的?
- CentOS 6.8 部署zookeeper集群
- ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidator
- 使用容器进行应用程序路由
- MVVM(Knockout.js)的新尝试:多个Page,一个ViewModel
- ASP.NET MVC以ModelValidator为核心的Model验证体系: ModelValidatorProviders
- 我所理解的RESTful Web API [设计篇]
- 黑箱难题阻碍了深度学习的普及与发展
- iOS 转场动画探究(一)
- XCode中如何使用事务
- 如何部署编译NDIS驱动的环境(内部资料)
- 深度学习的入门级装机配置推荐
- Self Host模式下的ASP. NET Web API是如何进行请求的监听与处理的?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- docker通过模板创建镜像以及容器、仓库和数据管理
- Form表单类组件与Map地图组件
- 转录组分析 | 使用Hisat2进行序列比对
- 最后一个页面:构建电影详情页面
- 安装docker以及通过容器创建镜像
- 转录组分析 | 使用trim-galore去除低质量的reads和adaptor
- 设计模式之工厂方法模式
- Ubuntu上安装TensorFlow(python2.7版)
- 转录组分析 | fastqc进行质控与结果解读
- playbook管理配置文件
- 使用playbook安装nginx
- 第五个页面:更多电影页面
- 云原生|Operator本质
- 简单使用ansible-playbook
- 设计模式之观察者模式