如何用极客范儿打造一个HTC Vive虚拟演播室?(下)
雷锋网按:作者王锐,VR行业资深从业者,写过不少广受欢迎的VR好文,有兴趣可移步其 专栏 。本文是 《如何用极客范儿打造一个HTC Vive虚拟演播室?(上)》 的下篇,文章将继续讲述,如何动手打造HTC Vive虚拟演播?
|
实时绿幕场景的搭建
购买和搭建抠像拍摄的环境并不是多么复杂的事情, 选择质量较好,不易起皱的绿色(蓝色)背景布 ,用背景架支起后应当有良好的下垂感。而延伸到地面的部分要处理起来可能更为麻烦一些,因为演员的运动很难保证不会把地上的幕布弄皱,尤其是美丽的女主角可能穿了高跟鞋,或者需要在场景里来一段即兴街舞的时候。这种时候也可以考虑使用抠像地胶,它更适用于直接在平整地面上进行铺设,并且可以稳定放置一些抠像网格定位用的标记点。
更为专业的布置就 需要抠像摄影棚 ,用柔光箱来做整体的立体布光,并且尽可能避免演员身上出现明显的投影,以及因为服饰和道具的高亮材质而产生反射光点。这些都可能对未来的实际拍摄和叠加工作产生影响。
当然笔者的工作环境并不会那么理想,或者说因为受到场地条件,资金,非专业性,以及自己屌丝的背影等因素所限,最后能够为这个标题搭建出的拍摄场景只是区区如下图而已。没错,连美丽的女演员都请不起,只好用一只熊猫玩偶来充数了……
不过这并不妨碍我们对实时抠像方法的实验。也就是说,我们期望将正在拍摄的视频内容即时转换为扣去了背景色的画面(只剩下孤零零的小熊猫自己),然后传输到一个简单的类似三维游戏的场景当中,进行叠加,从而呈现出现实角色身处虚拟世界的情景—— 如果把这里的小熊猫替换成一位头戴HTC VIVE头盔进行虚拟游戏的朋友 ,而这个游戏场景又恰恰就是他正在体验的场景的话,那么就如本文开头所述的那样,可以做到一种理想的VR游戏第三人称视角直播的效果了。
把当前拍摄的画面输出到用于抠像和叠加的PC电脑也许并不是什么难事,至少我们有多种途径可以选择: 手机拍摄可以通过App转换到Live Stream的视频流,单反和摄像机的话可以直接通过视频采集卡输入,更专业一点还可以用到Decklink的专业采集和转换设备 。当然了,如果手头有专业控台的话,大可不必考虑笔者后面要描述的复杂抠像过程,直接启用控台的Chroma Keying功能即可。不过这种硬件直接抠像的实现方案往往可供调节的参数繁多,操作复杂,并且价格极为昂贵,并非笔者之流所能及了。
如果拍摄的内容并不需要实时传输的话,整套流程也不需要如此复杂。比如我们可以把视频文件直接导入到After Effects或者NUKE这样的后期软件,然后直接做抠像参数的精细调节和输出即可。不过这显然不适用于直播的场合,因此也不在我们的考虑之列。
| 实时抠像算法的实现
实时抠像的一个重要的中间产物,叫做Matte。 它通常是一幅黑白图像,其中黑色区域表示完全被扣去,而白色区域表示完全被保留,中间色(灰色)的区域则会在叠加之后呈现出半透明的效果。
上图就是刚才的小熊猫经过处理后得到的Matte图结果,虽然因为环境本身的影响以及算法的不完善性,这张图看起来还有明显的边缘瑕疵,并不能尽如人意。但是如果我们 将它与虚拟场景的画面叠加 的话,应当已经可以得到一个正确混合的效果了。当然了,这是下一步要考虑的问题,我们首先要知道的是,如何得到这样一幅Matte图。这里业界通常的做法有两种,其一名为 Luma Keying(亮度抠像) 。
Luma Keying的基本原理是通过图像的亮度(luminance,明暗)来区分和构建Matte。而对于某一个RGB像素点的亮度,我们可以简单地通过下面的公式来表达:
Lum = 0.29 * R + 0.59 * G + 0.12 * B
之后我们可以根据一个固定的阈值来划分黑色和白色,低于这个阈值的颜色为黑色(扣去颜色),而高于这个阈值的颜色为白色。这样的分类方法显然是粗暴的,一个更为合理一些的方案是设定一个阈值的[min, max]区间,小于最小值min的亮度值输出黑色,大于最大值max的亮度值输出白色,而中间值输出0-1区间的灰色值。实际过程中这个阈值范围是要根据输入画面来做调整的,而这种方案本身也并非针对绿幕或者蓝幕场景,而是更适用于较暗的背景颜色与较亮的前景人物,因此并不在我们计划采用之列。
另一种做法名为Chroma Keying(色度抠像) 。我们假设RGB颜色是一个三维空间的坐标系统的话,那么每一个像素点都可以被认为是这个坐标系中的一个向量。因此,我们可以认为两个相近的颜色在这个颜色空间(color space)中距离更近——那么对于绿幕抠像的需求而言,就可以转化成“计算RGB像素点与绿色像素的距离,并且扣去更接近绿色的颜色”这样一个更有逻辑性的要求了。至于如何判断这个抠像的阈值,我们也完全可以借鉴之前的做法,采用一个手动调节的[min, max]区间来完成Matte(黑色,白色和中间色)的输出。
(Via wikipedia.org )
这种方法理论上适合任何色键(也就是绿色或者蓝色,当然也可以是其它颜色)的抠像处理,是否一定是基于RGB颜色空间,则要多少商榷一番。有些算法会选择HSV颜色空间(即Hue-Saturation-Value,色调-饱和度-明度)来进行当前像素向量与目标向量之间距离的计算,这种方式对于颜色的直观特性也许会有更为清晰的表达。
笔者通过GPU编程的方法实现了上述的Chroma Keying方案,并且使用简单的UI界面来做快速的参数调节。当然了,为了确保更好的输出效果和稳定性,我们多少还要在抠像算法的基础上做一些功能的增补, 比如输出图像的饱和度和对比度调节,以及Matte边缘的模糊处理等等 。基本的实现效果如下:
实际上现在的Matte图已经可以和任何一个背景视频直接进行叠加了,即使它们的内容之间并没有什么直接的联系;而如果这个背景视频恰恰就是我们需要的虚拟场景画面,并且虚拟摄像机的姿态设置已经与真实相机做到了一致,那么我们几乎就可以认为这一艰巨的任务已经接近完成了!在此之前,一个简单叠加输出的效果如下:
现在,我们下一步的目标就是星辰大海,哦不,应该说是 混合现实(Mixed Reality)输出方法 的实现。
| 混合现实,就在眼前
显然,因为有了Matte作为遮罩图存在,我们已经可以将外部输入的实际摄像机画面与虚拟场景进行叠加,扣去绿色背景并保留前景的角色。而因为虚拟摄像机与实际的VIVE手柄之间实现了姿态的联动,我们也可以保证摄像机视场角和姿态的一致性。看起来万事俱备,但是有一个问题却依然值得我们考虑,那就是景物之间的互相遮挡。
一个最简单的应用如下图所示,我们的角色要放置到这个小街道的中心位置,当虚拟摄像机与角色之间不存在任何遮挡的时候,这看起来毫无问题。但是一旦有虚拟的房屋出现在视野中,挡在了角色的前面,事情恐怕就会变得棘手起来。
没错,因为我们只是用Matte遮罩图将实际画面与虚拟场景的输出结果做了2D的叠加,并不会考虑到虚拟场景本身的深度遮挡问题,因此小熊猫会永远处于画面的最上层,就仿佛它是粘在观看者的眼镜片上,而非真的和街道房屋处于同一个场景当中。
这当然不是我们想要的结果,不过想针对这个问题实现一个通用的解决方案也不是一件容易的事情。因为我们 并不能获得实际相机拍摄画面的深度信息,也就无法预知它与虚拟场景之间的深度关系 。如果使用带有深度信息的摄像设备,例如双目立体摄像机,或者Kinect之类的RGBD相机,那么前者的问题是价格昂贵;后者的问题是分辨率粗糙,深度信息在物体边缘的可信度很低,因而造成图像叠加的结果产生很不稳定的毛边。如果是制作一般的体感游戏,那么这无伤大雅;如果是要输出虚拟演播室的视频图像的话,那么这样的画质显然是无法接受的。
(Via codeproject.com )
听起来让人沮丧,不过在实际工程中,我们总有更为简单的方法来解决问题。
最直接有效的做法莫过于:对真人角色在直播时的走位做出提示,比如放一台小型的输出画面监视器在他能够看到的地方,让他尽可能避开所有影响到遮挡关系的虚拟物体。
当然有的时候我们就是希望虚拟场景的某些物体遮挡住真人主角们,比如虚拟世界的花瓶,石柱,虚构生物,或者一些特效效果。这个时候我们就需要手动设置这些虚拟物体为“前景”物体,也就是说,它们的渲染总是会在真实角色之前。而其它的虚拟场景,例如地面和远处的建筑,则总是处于“背景”上。这样就构成了一个前景-中景-背景组成的画面层次,如图所示:
当然了,随着真实摄像机和虚拟摄像机的运动,原本处于前景的虚拟物体可能会变化到主角身后,变成了背景;原本是背景的物体也可能转到主角身前,将他遮挡在后面。如果有这种复杂的需求,那么就需要在直播进行过程中手动切换每个虚拟物体的“前景/背景”标签,并且切换动作一定要及时和准确,以免发生穿帮。当然了,所谓的“前景-中景-背景”这三个深度层次还可以进一步扩展,衍生出更多层次和更为复杂的遮挡关系。不过那样负责切换的工作人员估计也是要骂娘的节奏就是了。
那么是否存在某种自动切换虚拟物体遮挡层次的方法呢?
回答是肯定的。如果我们能够知道真实角色在虚拟场景中的详细XYZ位置的话,也就可以知道他在虚拟场景中对应的位置,进而知道渲染输出的结果中,我们的角色应当处于什么样的深度层次上,从而自动计算虚拟物体与角色之间的遮挡关系。对于传统的虚拟演播室应用来说,可能的方法包括:在头顶阵列布置红外摄像机矩阵,识别主角身上的红外放射源并进而判断他在空间的位置;或者在绿幕环境中使用同样色键,但是明暗不同的胶带粘贴出大小不一的网格,然后判断角色与网格之间的位置关系来完成跟踪和深度的识别。
不过对于HTC VIVE的使用者来说,这却成了一个天然的福音。因为VIVE头盔本来就可以记录自身在空间的位置和姿态,这样玩家和场景之间的遮挡关系问题,也就迎刃而解了。
不过,对于更为复杂的画面叠加要求,目前的技术手段往往还是无能为力的——比如多个角色在虚拟场景里进行复杂的互动,或者让真实角色准确地陷入到虚拟的席梦思床里,或者环抱一个虚拟布娃娃——这种时候再复杂的层次关系,或者再准确的独立深度信息跟踪,都无法妥善解决这类问题。如果这是一部制作精良的大商业电影,那么后期制作的工作人员只好熬夜加班逐帧修图,哭着把任务完成;如果这是实时直播中的需求,那么还是保持清醒,实事求是吧……
幸好,无论是基于HTC VIVE的真正演播室搭建,还是在本文的简陋示例中,我们都不需要考虑上述的复杂情况。既然已经解决了如此多的问题,那就让我们炫耀一下,然后休息,休息就好。
雷锋网 (搜索“雷锋网”公众号关注) 注:作者王锐,雷锋网独家约稿文章,转载请联系授权,不得删减内容。
相关VR课程力荐:
1、 如何用极客范儿打造一个HTC Vive虚拟演播室?(上)
2、 如何用极客范儿做一款VR头盔?不是插个手机的那种
3、 开发一款像Hololens这样的产品需要学习哪些技术?