(转载请注明出处)
使用SDK: Kinect for Windows SDK v2.0 1409
这节算是补充节吧,以3D方式显示深度帧,SDK更新的则在后面的章节说明.
之前想错了,以为每帧显示所谓的点云,GPU负担很大,
背景每帧都要传送 500 * 400 * 3 * 4 , 才2M的数据,之前估计错了。
3D接口依然是D3D11,这次简单多了,顺带复习一下吧
要点:
0. 初始化.. 仅仅需要:
IKinectSensor(使用 GetDefaultKinectSensor)
IDepthFrameReader(使用 IKinectSensor::get_DepthFrameSource 与 IDepthFrameSource::OpenReader)
ICoordinateMapper(使用 IKinectSensor::get_CoordinateMapper)
1. 轮询模式, 因为基于等待垂直同步
使用IDepthFrameReader::AcquireLatestFrame进行轮询
2. 数据获取
使用IDepthFrame所带的一抹多方法进行数据获取
3. 坐标映射
使用ICoordinateMapper::MapDepthFrameToCameraSpace,将深度数据映射到相机坐标空间。
4. 渲染规则
仅仅是渲染点,所以使用简单的VS-PS模式即可,VS计算坐标,PS计算颜色。
可视化算法,不同与2D的算法,这次,我们将深度值的0.4~4.5映射到波长的400~700(大致即可)
也就是彩虹的颜色啦
所以,PS的代码就是这样
// PS 输入 <-> VS 输出 struct PSInput { float4 position : SV_POSITION; float4 raw_position: POSITION; }; // 光谱颜色 float4 spectral_color(float l){ float t; float4 color = float4(0, 0, 0, 1); // R if ((l >= 400.0) && (l < 410.0)) { t = (l - 400.0) / (410.0 - 400.0); color.x = +(0.33*t) - (0.20*t*t); } else if ((l >= 410.0) && (l < 475.0)) { t = (l - 410.0) / (475.0 - 410.0); color.x = 0.14 - (0.13*t*t); } else if ((l >= 545.0) && (l < 595.0)) { t = (l - 545.0) / (595.0 - 545.0); color.x = +(1.98*t) - (t*t); } else if ((l >= 595.0) && (l < 650.0)) { t = (l - 595.0) / (650.0 - 595.0); color.x = 0.98 + (0.06*t) - (0.40*t*t); } else if ((l >= 650.0) && (l < 700.0)) { t = (l - 650.0) / (700.0 - 650.0); color.x = 0.65 - (0.84*t) + (0.20*t*t); } // G if ((l >= 415.0) && (l < 475.0)) { t = (l - 415.0) / (475.0 - 415.0); color.y = +(0.80*t*t); } else if ((l >= 475.0) && (l < 590.0)) { t = (l - 475.0) / (590.0 - 475.0); color.y = 0.8 + (0.76*t) - (0.80*t*t); } else if ((l >= 585.0) && (l < 639.0)) { t = (l - 585.0) / (639.0 - 585.0); color.y = 0.84 - (0.84*t); } // B if ((l >= 400.0) && (l < 475.0)) { t = (l - 400.0) / (475.0 - 400.0); color.y = +(2.20*t) - (1.50*t*t); } else if ((l >= 475.0) && (l < 560.0)) { t = (l - 475.0) / (560.0 - 475.0); color.y = 0.7 - (t)+(0.30*t*t); } return color; } // Shader 入口 float4 main(PSInput input) : SV_TARGET{ float4 judgment = float4(0.4, 4.5, 400, 700); if ((input.raw_position.z >= judgment.x) && (input.raw_position.z <= judgment.y)){ // 将 0.4~4.5映射到 400~700 // 73.1707 = (judgment.w-judgment.z)*(judgment.y-judgment.x) return spectral_color(judgment.w - (input.raw_position.z - judgment.x) * 73.1707f) * 2.f; } return float4(0, 0, 0, 1); }
最后乘上2是为了提高亮度.
VS就不贴了。
每次询问道深度数据就映射到相机坐标空间,再送到GPU。
每帧渲染这些顶点即可,可谓简单。
这就是成品了:
代码下载地址:点击这里
对了,上传后才发现,这次不需要复制文件,所以自定义生成步骤那里是多余的