(拉普拉斯金字塔算法)
怎么玩穿越?从楼梯上摔下?被车撞?被雷电劈?太危险鸟!最新穿越方式:一台 Kinect 即可。
去年上半年开发了一个Kinect项目,这是一个类似于虚拟演播室的项目,它使用 Kinect 实时捕捉图像,将人物抠出来,然后与图像、其它视频或其它程序里的内容实时合成。
过完年了,与对方约定的保密期也过去了,且撰文总结一下,谈谈开发这个项目过程中的体会。
先上图,去年夏天拍的。
在这张图的电脑屏幕上有一个睿智的中年大叔,哦……这不是我,这是魔兽世界里大名鼎鼎的青铜龙王诺兹多姆。走在最前方那个让诺兹多姆仰望、让战五渣侧目、让绿龙女王害羞、让红龙女王情不自禁、把萨尔气得跳了大漩涡的英俊潇洒的人类大帅哥才是我。
好一副穿越的场景。这个场景怎么来的呢?
主角就是Kinect。具体步骤为:
(1)人物站在房间中做动作;
(2)Kinect 找到人物的景深图和彩图,配准后,将人物抠出来;
(3)对抠出来的图进行处理,让它变得稳定平滑;
(4)后台解码待合成的视频,将抠图与视频进行图像融合,然后一帧、一帧的在屏幕上显示;
(5)这个照片是手中拿的IPad实时拍下来的。
来段新录制的视频(由于是一边跑程序一边录制的,看起来比较卡。实际情况比这流畅,大概能到每秒10帧。我的显卡比较烂,换好显卡更流畅):
(萨尔你这么苦大仇深的看着我干啥?)
项目总结:
(1)Kinect 的景深图非常的不稳定。如何让它稳定的贴合人体的边缘是个非常困难的事情。虽然做了一定的工作,效果只能说是可接受,而并不完美。
(2)抠出来的图不能直接贴上去,而要使用图像融合技术让边缘过度尽量自然。常见的图像融合方法有拉普拉斯融合和泊松融合。这里借 XXX Tech 博客里的的一张图来说明,直接贴图、泊松融合和拉普拉斯融合的对比。
为性能起见,我采用的是拉普拉斯融合。泊松融合太复杂了,直接放弃。后来又发现了更好的高性能算法,鉴于当时效果对方已经满意了,就没具体实现。
(3)性能!性能!
整个项目一大半时间在优化性能。因为要实时视频解码,要实时从Kinect处拿到彩色图片和景深图片,实时配准,实时稳定边缘,实时图像融合,以上操作最少要达到每秒十几帧,因此需要极度的压榨性能。压榨到什么程度呢?压榨到CPU和图像尺寸近似的情况下,我用C#写的拉普拉斯混合性能是别人论文中VC版本性能的几十倍(不是说C#比VC快,优化的是拉普拉斯混合算法本身),以至于只用C#单线程就实现了640×480大小的拉普拉斯混合。后来,对方要做1280×960分辨率的,C#歇菜了,直接上了CUDA。
Kinect感想:
(1)Kinect为我们提供了一个非常经济的获得景深图、骨骼图的设备;
(2)除了游戏外,使用这套设备我们可以做很多事情,比如,能自动跟踪垃圾的垃圾桶,试衣服,以及本文讲的这个可用于虚拟演播室。
发挥想象力吧,想象你K歌的时候,Kinect把你融合进大屏幕中,就像你本人在舞台上一样,这种震撼和体验。
想象轻易的穿越进各种各样的视频之中,想象可以轻松的拍摄各种场景照片 ……
Kinect 为我们打开了第一步,也仅仅只是第一步,要用它做些事情,只会Kinect SDK的话走不远。
以Kinect试衣服为例子。
从上面这图,可以看到它采用的只是单纯贴图技术,且贴的不紧。
为什么贴的不紧?
——没准确找到人物的轮廓。
为什么没有准确找到人物的轮廓?
——Kinect的景深图不稳定。
怎么能找到准确的轮廓?
——这就复杂了。我预感需要三个一起用上才行:Kinect自带的景深图,自然抠图技术和前景/背景建模。三个用上后估计能够得到准确的人物轮廓。
找到准确的轮廓后可以做什么?
——可以换背景,换场景。
这是锦上添花。
——那么,或许可以结合计算机动画和图像变形技术,做关节动画,这样你做动作,服装也会跟着你做动作,尤其是有袖子的服装。
只会Kinect,上面这些都做不了。要用Kinect开发现实应用,重点在Kinect之外。