![](/img/trans.png)
[英]Getting Color and Depth Frames from Kinect Version 2 Simultaneously in C++
[英]Kinect SDK: align depth and color frames
我正在使用Kinect传感器,我正在尝试对齐深度和颜色框架,以便我可以将它们保存为彼此“适合”的图像。 我花了很多时间浏览msdn论坛和Kinect SDK的适度文档,我完全无处可去。
基于这个答案: Kinect:从RGB坐标转换为深度坐标
我有以下函数,其中depthData
和colorData
是从NUI_LOCKED_RECT.pBits
获得的,而mappedData
是包含新颜色框架的输出,映射到深度坐标:
bool mapColorFrameToDepthFrame(unsigned char *depthData, unsigned char* colorData, unsigned char* mappedData)
{
INuiCoordinateMapper* coordMapper;
// Get coordinate mapper
m_pSensor->NuiGetCoordinateMapper(&coordMapper);
NUI_DEPTH_IMAGE_POINT* depthPoints = new NUI_DEPTH_IMAGE_POINT[640 * 480];
HRESULT result = coordMapper->MapColorFrameToDepthFrame(NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, NUI_IMAGE_RESOLUTION_640x480, 640 * 480, reinterpret_cast<NUI_DEPTH_IMAGE_PIXEL*>(depthData), 640 * 480, depthPoints);
if (FAILED(result))
{
return false;
}
int pos = 0;
int* colorRun = reinterpret_cast<int*>(colorData);
int* mappedRun = reinterpret_cast<int*>(mappedData);
// For each pixel of new color frame
for (int i = 0; i < 640 * 480; ++i)
{
// Find the corresponding pixel in original color frame from depthPoints
pos = (depthPoints[i].y * 640) + depthPoints[i].x;
// Set pixel value if it's within frame boundaries
if (pos < 640 * 480)
{
mappedRun[i] = colorRun[pos];
}
}
return true;
}
我在运行此代码时获得的是一个未更改的颜色框架,其中删除了(白色)所有像素,其中depthFrame没有信息。
在OpenNI框架中有一个选项调用注册。
IMAGE_REGISTRATION_DEPTH_TO_IMAGE - 深度图像被转换为具有与RGB图像相同的明显有利位置。
OpenNI 2.0和Nite 2.0非常适合捕获Kinect信息,还有很多教程。
你可以看看这个:
OpenNi在SimplerViewer中有一个合并深度和颜色的例子,你也可以看看并尝试一下。
我认为你应该调用MapDepthFrameToColorFrame来解决MapColorFrameToDepthFrame问题。
吸烟枪就是这行代码:
mappedRun[i] = colorRun[pos];
从pos
读取并写入i
是向后的,因为pos = depthPoints[i]
表示对应于i
处的颜色坐标的深度坐标。 您实际上想要迭代编写所有深度坐标并从相应颜色坐标处的输入颜色图像读取。
我认为在你的代码中有不同的不正确的行。
对于每个值,使用两个字节来存储深度数据,这意味着您应该用于深度数据的指针的正确类型是unsigned short 。
第二点是从我所理解的,你想要将深度框架映射到颜色框架,因此你必须从kinect sdk调用的正确函数是MapDepthFrameToColorFrame而不是MapColorFrameToDepthFrame。
最后,函数将返回一个点的映射,对于位置[i]的每个深度数据,你有位置x和位置y,应该映射该点。
. 为此,您 。
所以你的功能应该修改如下:
/** Method used to build a depth map aligned to color frame
@param [in] depthData : pointer to your data;
@param [out] mappedData : pointer to your aligned depth map;
@return true if is all ok : false whene something wrong
*/
bool DeviceManager::mapColorFrameToDepthFrame(unsigned short *depthData, unsigned short* mappedData){
INuiCoordinateMapper* coordMapper;
NUI_COLOR_IMAGE_POINT* colorPoints = new NUI_COLOR_IMAGE_POINT[640 * 480]; //color points
NUI_DEPTH_IMAGE_PIXEL* depthPoints = new NUI_DEPTH_IMAGE_PIXEL[640 * 480]; // depth pixel
/** BE sURE THAT YOU ARE WORKING WITH THE RIGHT HEIGHT AND WIDTH*/
unsigned long refWidth = 0;
unsigned long refHeight = 0;
NuiImageResolutionToSize( NUI_IMAGE_RESOLUTION_640x480, refWidth, refHeight );
int width = static_cast<int>( refWidth ); //get the image width in a right way
int height = static_cast<int>( refHeight ); //get the image height in a right way
m_pSensor>NuiGetCoordinateMapper(&coordMapper); // get the coord mapper
//Map your frame;
HRESULT result = coordMapper->MapDepthFrameToColorFrame( NUI_IMAGE_RESOLUTION_640x480, width * height, depthPoints, NUI_IMAGE_TYPE_COLOR, NUI_IMAGE_RESOLUTION_640x480, width * height, colorPoints );
if (FAILED(result))
return false;
// apply map in terms of x and y (image coordinates);
for (int i = 0; i < width * height; i++)
if (colorPoints[i].x >0 && colorPoints[i].x < width && colorPoints[i].y>0 && colorPoints[i].y < height)
*(mappedData + colorPoints[i].x + colorPoints[i].y*width) = *(depthData + i );
// free your memory!!!
delete colorPoints;
delete depthPoints;
return true;
}
确保已正确初始化mappedData,例如,如下所示。
mappedData = (USHORT*)calloc(width*height, sizeof(ushort));
请记住,kinect sdk不提供颜色和深度数据之间的精确对齐功能。
如果要在两个图像之间进行精确对齐,则应使用校准模型。 在这种情况下,我建议您使用基于Heikkilä校准模型的Kinect校准工具箱。
您可以在以下链接中找到它:
http://www.ee.oulu.fi/~dherrera/kinect/ 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.