通过 TouchDesigner 提取 Kinect2 的点云信息

在TouchDesigner(之后称为TD)中提取Kinect2的点云这个效果在很早之前就已经实现了。TD的灵活之处不再赘述,如果需要将大量点云(准确来讲这个案例有1920*1080=2,073,600个点)超过2M的点的深度和颜色渲染出来并到达每秒超过30帧的速度,目前我想到的方法有且只有使用TD中的GLSL shader。GLSL的优势就是在于直接使用GUP并行处理所有的点,所以在这种应用中速度要比CUP快上成千上万倍。大概方向讲清楚了,先上个图看看效果。

 

从kinect方面我们需要两个图像信息,第一个是深度图,之后我们会使用这个深度图的颜色值来确定每个点的位置。另一个是颜色图也就是我们传统的视频画面,使用这个视频信息之后我们把每个像素点的颜色值传递到每个点上,让点云不仅有深度值也有颜色值。

在GLSL中我们同时需要使用vertex shader和fragmentshader,在vertex shader中把点云的深度位置确定好,再传递到fragment shader中把视频的颜色信息给点云。

 

vertex shader中读取深度图中每个像素的深度信息,将其传给已经创建好的grid的每一个点上,也就是说事先我们已经做好了一个1920*1080的grid。

//in vertex shader

uniform sampler2D sPointTex; uniform sampler2D sColorTex; uniform vec4 uPointRes;
out Vertex { vec4 color; }vVert; void main() { int id = gl_VertexID; vec2 posUV; posUV.t = id / int(uPointRes.p); posUV.s = id - (posUV.t * int(uPointRes.q)); posUV.t += 1; posUV *= uPointRes.st; vec4 newPos = texture(sPointTex, posUV); newPos.z *= -1; newPos.z += 2; vVert.color = texture(sColorTex, posUV); vec4 worldSpaceVert =TDDeform(newPos); vec4 camSpaceVert = uTDMat.cam * worldSpaceVert;
//if(newPos.z < -0){ // gl_PointSize = 1; //}else{ // gl_PointSize = 0.0; //} gl_Position = TDCamToProj(camSpaceVert); }

sPointTex 是深度贴图的采样,sColorTex 是颜色信息的采样。通过grid上每个点的ID来确定该点是在哪一行哪一列,让后确定该点在画幅中uv位置,使用这个uv位置从采样中拿到深度信息和颜色信息,深度信息直接应用到点的z轴上,颜色信息记录下来并传递给fragment shader。 注释掉的这段是应用在把背景信息隔离掉的。

在fragment shader中就容易多了,应为我们已经知道颜色值了,只需要赋值给最终的颜色变量上就好了。

//in fragment shader
in
Vertex { vec4 color; }vVert; // Output variable for the color layout(location = 0) out vec4 fragColor; void main() { fragColor[0] = vVert.color;
for (int i = 1; i < TD_NUM_COLOR_BUFFERS; i++) { fragColor[i] = vec4(0.0); } }

posted @ 2015-05-31 08:48  嘉豪一点点  阅读(4480)  评论(0编辑  收藏  举报