前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >基于OpenCV创建视频会议虚拟背景

基于OpenCV创建视频会议虚拟背景

作者头像
小白学视觉
发布于 2020-09-22 07:21:18
发布于 2020-09-22 07:21:18
3.6K00
代码可运行
举报
运行总次数:0
代码可运行

本期我们将使用Python和OpenCV为频会议创建虚拟背景。

虚拟背景是当前远程工作的员工中的热门话题之一。由于Covid-19的流行,许多人必须通过视频通话以便继续工作。很多视频会议的软件可以设置虚拟背景,以便用户建立更友好的氛围来接听这些电话。

作为一名程序员,当我们第一次使用这样的虚拟背景时自然很感兴趣。我们都想知道它是如何工作的,可以自己建立这样的虚拟背景吗?

接下来,我们将尝试使用PythonOpenCV使用计算机视觉技术构建虚拟背景的基本方法。(虽然效果并不是很好~)

介绍

我们的目的是拍摄视频,尝试弄清楚视频的背景和前景,删除背景部分,并用图片(虚拟背景)代替。因为在此项目中,我们将使用简单的方法,假设前景通常具有与背景不同的颜色。首先,让我们看看我们的工具是什么。

计算机视觉

计算机视觉是一个跨学科领域,涉及计算机如何处理和(或)理解图像和视频。说这是一个跨学科的领域,因为它借鉴了不同学科(计算机科学,代数,几何等)的许多概念,并将它们组合起来以解决许多不同而复杂的任务,例如对象跟踪对象检测, 对象识别,图片和视频中的对象细分

OpenCV

OpenCV是一个用于解决计算机视觉任务的库。它是开源的,可用于多种编程语言,包括Python和C ++。它具有大量的计算机视觉功能,其中一些基于数学和统计方法,而另一些则基于机器学习

建立虚拟背景

我为此尝试的方法如下。我将显示每个步骤的代码片段,并在本文结尾处,您将获得完整的代码。

1. 导入依赖

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import numpy as np
import cv2

2.从本地环境加载视频并初始化数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ap = cv2.VideoCapture('video6.mp4')
ret = True
frameCounter = 0
previousFrame = None
nextFrame = None
iterations = 0

3.从本地环境加载替代背景图像

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
backgroundImage = cv2.imread("image1.jpg")

4.逐帧分割视频

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
while (ret):
ret, frame = cap.read()

5.每隔两帧拍摄一次

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if frameCounter % 2 == 1:
           nextFrame = frame        
if frameCounter % 2 == 0:
           frameCounter = 0
           previousFrame = frame       
frameCounter = frameCounter + 1
           iterations = iterations + 1

6.找到两个帧之间的绝对差并将其转换为灰度->获得蒙版

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if iterations > 2:
  diff = cv2.absdiff(previousFrame, nextFrame)
  mask = cv2.cvtColor(diff, cv2.COLOR_BGR2GRAY)

每个图像都由像素组成,我们可以将其想象为具有行和列的2D矩阵,并且矩阵中的每个单元格都是图像中的像素(当然,对于彩色图像,我们拥有的尺寸比2大,但为简单起见,可以忽略)。

我们通过在第一个图像中逐个像素移动(因此在第一矩阵中一个单元一个像素)并从另一个图像中替换对应的像素(因此从另一个矩阵中替换对应的像素)来获得差异。

现在的诀窍是:如果在两帧之间,像素没有被修改,那么结果当然是0两帧之间的像素如何变化?如果视频是完全静态的(图像中没有任何动静),则所有像素的每一帧之间的差将为0,因为没有任何更改。但是,如果某物在图像中移动,那么我们可以通过检测像素差异来识别某物在图像中的移动位置。我们可以假设,在视频会议中,移动的事物位于前台(即您),而静态部分是背景。

那么0到底有什么重要呢?图像将为每个像素显示为0的黑色,我们将利用这一优势。

7.找到蒙版中超出阈值的单元格-我选择3作为阈值,当然也可以使用不同的值。较大的值将从背景中删除更多内容,但也可能从前景中删除更多内容

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
th = 3
isMask = mask > th
nonMask = mask <= th

8.创建一个空白图像(每个单元格为0),其大小为两个框架中任何一个的大小

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
result = np.zeros_like(nextFrame, np.uint8)

9.调整背景图像的大小,使其具有与框架相同的大小

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
resized = cv2.resize(backgroundImage, (result.shape[1], result.shape[0]), interpolation = cv2.INTER_AREA)

10.对于蒙版中大于阈值的每个单元,请从原始帧进行复制

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
result[isMask] = nextFrame[isMask]000000000000

11.对于蒙版中低于阈值的每个单元,请从替代背景图像进行复制

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
result[nonMask] = resized[nonMask]

12.将结果框保存到本地环境

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cv2.imwrite("output" + str(iterations) + ".jpg", result)

结果与结论

那么结果如何呢?老实说,我对结果感到有些失望。然后,我做了更多的研究,其原因变得更加明显。为此,您需要一种更高级的方法,并且大公司在此类问题上投入了大量资源也就不足为奇了。

这是我尝试的视频的屏幕截图。这基本上是我的手在墙前移动的视频。

虚拟背景Python和OpenCV教程-输入

这是输出图像的屏幕截图。作为背景,我在罗马尼亚的拉斯诺夫使用了我的照片。

虚拟背景Python和OpenCV教程-输出

结果并不满意,但是我们也从这个项目中学到的东西。

创建虚拟背景的其他方法

如果认为问题非常复杂,并且需要的智能水平,那么答案可能是机器学习。

已有深度学习模型可以执行此类任务。但是,这样的模型需要训练大量的数据集和大量的处理能力,在撰写本文时,我还没有这些能力做这种尝试。这种深度学习模型要解决的任务称为图像分割

另一种方法是计算机视觉方法,用于查找相机和图像中的对象之间的距离。然后,建立一个阈值,以将前景与背景分开。之后,可以使用与移除背景相同的蒙版,并引入一个新的蒙版。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小白学视觉 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
vim常用命令总结
文本的选择,对于编辑器来说,是很基本的东西,也经常被用到,总结如下: v    从光标当前位置开始,光标所经过的地方会被选中,再按一下v结束。  V    从光标当前行开始,光标经过的行都会被选中,再按一下V结束。  Ctrl + v   从光标当前位置开始,选中光标起点和终点所构成的矩形区域,再按一下Ctrl + v结束。  ggVG 选中全部的文本, 其中gg为跳到行首,V选中整行,G末尾
阳光岛主
2019/02/19
1.4K0
vim实用指南(一)
Vim是从 vi 发展出来的和 Emacs 并列成为类 Unix 系统用户最喜欢的编辑器。Vim 的可配置性非常强,各种插件、语法高亮配色方案等多不胜数,无论作为代码编辑器或是文稿撰写工具都非常给力。
用户8639654
2021/08/19
9450
vim基本命令
最实用的几个: 0(数字0)移动到本行第一个字符上  移动到行尾 。 3 移动到下面3行的行尾 gg 移动到文件头。 =  [[ G(shift + g) 移动到文件尾。 =  ]] /text  查
不吃西红柿
2022/07/29
1.4K0
vim常用命令(命令模式、末行模式)
以下是vim操作一些基础的命令,分为两种模式总结整理,分别为命令模式、末行模式,建议读者学习的同时能配合实际的操作,这样会记得更加牢固。
秃头哥编程
2019/08/13
2.5K0
学会这21条,你离Vim大神就不远了
导语:作者本人是 Vim 的重度使用者,就因为喜欢上这种双手不离键盘就可以操控一切的feel,Vim 可以让人对文本的操作更加精准、高效。对于未使用过 Vim 的朋友来说,可能还无法体会到这种感觉。由于使用 Vim 有一定的学习成本,只有做到非常熟练的程度才能感受到它带来的快捷。
AI科技大本营
2019/08/20
1.8K0
学会这21条,你离Vim大神就不远了
【总结】vim命令使用总结,该来的还是躲不掉啊晕
曾经我也天真的觉得如今很多软件都可以充当文本编辑器,像vim上手这么麻烦的可以替代
自学气象人
2023/06/20
7510
【总结】vim命令使用总结,该来的还是躲不掉啊晕
介绍下vim的基本使用
用过 Linux 系统的朋友一定都或多或少知道 vim ,很多人对这款编辑器的第一印象一定是反人类,可能你不小心进去 vim 的话就不知道怎么退出来了,因此,自从我知道 Ubuntu 图形界面自带 gedit 编辑器时,我就立下 flag 这辈子绝对不用 vim ,可是 flag 这东西不就是用来倒的嘛,最近在 WSL 里面折腾,没有 gedit ,只好学习 vim ,这不, vim 真香!所以嘛,做技术的人还是不要把话说得太绝对,这样只会让人家觉得你很狭隘,一件事物的流行肯定有他的道理,不要固步自封,还是要多去了解一下自己不知道的事务,就像我之前也说过这辈子都不会学 Java 和 PHP ,我自己打脸吧(逃
棒棒鸡不棒
2022/09/01
1.2K0
介绍下vim的基本使用
vim 使用教程
定义映射模式时,我们可以使用nmap、imap、vmap来定义映射仅在normal、insert、visual模式有效
暮雨
2018/10/09
3.1K0
vim 使用教程
138 条 Vim 命令、操作、快捷键全集
作者:perlman 命令历史 以:和/开头的命令都有历史纪录,可以首先键入:或/然后按上下箭头来选择某个历史命令。 启动vim 在命令行窗口中输入以下命令即可 vim 直接启动vim vim filename 打开vim并创建名为filename的文件 文件命令 打开单个文件 vim file 同时打开多个文件 vim file1 file2 file3 ... 在vim窗口中打开一个新文件 :open file 在新窗口中打开文件 :split file 切换到下一个文件 :bn 切换到上一个文件 :
小小科
2018/06/20
1.4K0
学习vim有这一篇就足够了
vi/vim 的重要性不言而喻,比如登录服务器操作。那么如何掌握呢?看这一篇足矣。更多精彩文章请关注公众号『Pythonnote』或者『全栈技术精选』
小闫同学啊
2020/07/10
1.1K0
vim常用命令总结[通俗易懂]
在命令状态下对当前行用== (连按=两次), 或对多行用n==(n是自然数)表示自动缩进从当前行起的下面n行。你可以试试把代码缩进任意打乱再用n==排版,相当于一般IDE里的code format。使用gg=G可对整篇代码进行排版。
全栈程序员站长
2022/09/06
15.8K0
vim常用命令总结[通俗易懂]
Vim 基本配置和经常使用的命令
vim 的优点纯文字编辑和 Linux 完美的融合提供了命令行。只能假设 ssh 至server进行操作,那么这样的情况就仅仅能使用 vim 了。vim 也是最为强大的通用文本编辑器之中的一个,对于须要编辑不同文本的情景,vim 也是相当有优势的。所以,熟练掌握一下 vim 的基本使用还是非常有必要的。
全栈程序员站长
2022/07/06
1.3K0
Vim学习笔记上篇
在普通模式中,用的编辑器命令,比如移动光标,删除文本等等。这也是Vim启动后的默认模式。这正好和许多新用户期待的操作方式相反(大多数编辑器默认模式为插入模式)。 Vim强大的编辑能来自于其普通模式命令。普通模式命令往往需要一个操作符结尾。例如普通模式命令dd删除当前行,但是第一个”d”的后面可以跟另外的移动命令来代替第二个d,比如用移动到下一行的”j”键就可以删除当前行和下一行。另外还可以指定命令重复次数,2dd(重复dd两次),和dj的效果是一样的。用户学习了各种各样的文本间移动/跳转的命令和其他的普通模式的编辑命令,并且能够灵活组合使用的话,能够比那些没有模式的编辑器更加高效地进行文本编辑。 在普通模式中,有很多方法可以进入插入模式。比较普通的方式是按a(append/追加)键或者i(insert/插入)键。
InitCool
2020/04/29
6450
【最简单的vim教程】vim学习笔记-基础操作
Vim基础操作 说明 C-字母 = Ctrl + 字母 char = 任意字符 开始编辑 insert 按键 功能 说明 i(I) insert 当前位置插入(当前行前) a(A) append 当前字符后面插入(当前行后) o(O) open a line below 当前行的下面(当前行上面) 模式 模式 功能 说明 普通模式(ESC) normal 操作和移动 插入模式(i,a,o) insert 编辑 命令模式(:) command 执行命令 可视模式(v,V,C-v) visual 选择 可视
huanhao
2020/04/09
5800
Mac之vim普通命令使用
稍微解释一下,当在normal模式下输入:qx后,你对文本的所有编辑动作将会被记录下来,再次输入q即退出了记录模
用户3621210
2020/09/08
6.4K1
Linux基础_vim命令
使用过LINUX操作系统的人应该都知道vim命令可以编写文本,对于没有接触过的同学通过以下介绍就可以轻松学会vim命令的使用方法。
全栈程序员站长
2022/07/25
5.2K0
Linux基础_vim命令
vim 学习笔记(四)—— 常用命令汇总
在命令状态下对当前行用== (连按=两次), 或对多行用n==(n是自然数)表示自动缩进从当前行起的下面n行。你可以试试把代码缩进任意打乱再用n==排版,相当于一般IDE里的code format。使用gg=G可对整篇代码进行排版。
为为为什么
2022/08/05
1.8K0
vim 学习笔记(四)—— 常用命令汇总
Vim 快捷命令
本文由 Alone88 创作,采用 知识共享署名4.0 国际许可协议进行许可 本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名 最后编辑时间为: Aug 31, 2018 at 07:48 pm
Alone88
2019/10/22
8260
VIM常用命令
1. 首先按esc进入命令行模式下,按下Ctrl + v,进入列(也叫区块)模式;
浩Coding
2022/01/18
15.4K0
linux之vi,vim命令
表示当前行的下一行的行尾b按照单词向前移动 字首e按照单词向后移动 字尾w按照单词向后移至次一个字首H移动到屏幕最上 非空白字M移动到屏幕中央 非空白字L移动到屏幕最下 非空白字G移动到文档最后一行gg移动到文档第一行v进入光标模式,配合移动键选中多行Ctrl+f向下翻页Ctrl+b向上翻页u撤销上一次操作``回到上次编辑的位置dw删除这个单词后面的内容dd删除光标当前行dG删除光标后的全部文字d$删除本行光标后面的内容d0删除本行光标前面的内容y复制当前行,会复制换行符yy复制当前行的内容yyp复制当前行到下一行,此复制不会放到剪切板中nyy复制当前开始的 n 行p,P,.粘贴ddp当前行和下一行互换位置J合并行Ctrl+r重复上一次动作Ctrl+z暂停并退出ZZ保存离开xp交换字符后面的交换到前面~更换当前光标位置的大小写,并光标移动到本行右一个位置,直到无法移动
入门笔记
2022/06/02
22.3K0
相关推荐
vim常用命令总结
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档