Kinect for Windows SDK v2.0 开发笔记 (十七) 深度帧3D



(转载请注明出处)

使用SDK: Kinect for Windows SDK v2.0 1409

这节算是补充节吧,以3D方式显示深度帧,SDK更新的则在后面的章节说明.

之前想错了,以为每帧显示所谓的点云,GPU负担很大,

背景每帧都要传送 500 * 400 * 3 * 4 , 才2M的数据,之前估计错了。Kinect for Windows SDK v2.0 开发笔记 (十七) 深度帧3D


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(大致即可)

Kinect for Windows SDK v2.0 开发笔记 (十七) 深度帧3D

     也就是彩虹的颜色啦

   所以,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。

每帧渲染这些顶点即可,可谓简单。


这就是成品了:

Kinect for Windows SDK v2.0 开发笔记 (十七) 深度帧3D

代码下载地址:点击这里


对了,上传后才发现,这次不需要复制文件,所以自定义生成步骤那里是多余的

Kinect for Windows SDK v2.0 开发笔记 (十七) 深度帧3D

上一篇:C#计算某一些任务的执行时间(消耗时间)


下一篇:拥抱新的.Net开发框架,WPF开发者如何向.Net迁移