硬件、SDK、插件准备见这个文章:
Unity体感应用开发——Kinect V2 获取彩色摄像头数据
抠像,英文叫BackgroundRemoval。即背景移除。在SDK Browser的demo里面叫Coordinate Mapping,即坐标映射。
从名字可以看出它的目的和原理,目的就是将图像中的人物与背景分离,将人物图像剥离出来。实现的原理就是将BodyIndexImage(一个512*424的一维byte数组,512*424是Kinect深度红外摄像头的拍摄分辨率)的属于人体的点(即byte值不等于255的点)通过KinectInterop.MapDepthPointToColorCoords函数映射到ColorImage的1920*1080分辨率的坐标系中,读取它的Color32值,赋值给在KinectManager.cs中叫usersHistogramImage的变量,最终通过SetPixels32(usersHistogramImage),得到Texture2D类型的数据usersLblTex2D。这部分逻辑在KinectManager.cs的UpdateUserHistogramImage函数里面可以看到。
kinectManager.GetUsersLblTex2D()
因此只需要实例化KinectManager之后,通过上面这个函数就可以获得抠像图。也可以参考插件的BackgroundRemovalManager.cs脚本:
1 它兼容了Kinect第一代
2 自动布置了被渲染物体的scale
3 实现了对抠像玩家的甄选
4 加入了边缘腐蚀、边缘扩张、模糊的支持
我认为美中不足的是输出的图像是一个512*424像素的,比较低。我不知道RF Solution为什么一直没有修改这个点,可能对于他来说这个不那么重要。但是我的第一个抠像项目就被迫修改了这个点,在MapDepthPointToColorCoords之后,不是将Color32赋值回一个512*424的byte数组,而是修改彩色帧数据1920*1080byte数组。实现更高的抠像图分辨率,当然同时画面其实是隐约变得有些延迟的。
关于用Kinect去做抠像缺点主要表现在抠不干净,要么是边缘毛刺噪点,要么就是头发或者鞋子腐蚀掉了,主要原因是基于红外的传感技术本身的缺陷:
1 怕反光材质
2 怕黑色物体
比如黑色皮衣皮裤皮鞋,比如顶灯直照下的黑色头发,甚至我遇到过穿银色短裤(裤子的材质光滑反光)的,别说抠像效果不好了,连body basic都侦测不到这里有个人。
所以,我认为kinect抠像适合于用在交互过程中非主体的位置,就是说如果用来做拍照,抠像是交互的主体不合适。但是如果作为画面中的一个辅助图像,去为主体画面提供帮助或者营造氛围,这是可以的。因此商业尝试约2年,我从2017年开始,禁止所有kinect抠像拍照业务,务必引导客户选择绿幕抠像,除非客户能接受最差的抠像效果。