首页 文章

Kinect深度图像

提问于
浏览
8

在我的应用程序中,我得到的深度框架类似于从深度基础样本中检索到的深度框架 . 我不明白的是,为什么图像中存在离散的水平?我不知道我称之为深度值的这些突然变化 . 很明显,我右手的一半都是黑色的,我的左手似乎分为3个这样的等级 . 这是什么以及如何删除它?

Kinect Depth Basics Sample http://i46.tinypic.com/2hwekxd.jpg

当我运行KinectExplorer示例应用程序时,我获得如下深度 . 这是我想从原始深度数据生成的深度图像 .

Kinect Explorer http://i50.tinypic.com/2rwx1z5.jpg

我正在使用Microsoft Kinect SDK(v1.6)NuiApi和OpenCV . 我有以下代码:

BYTE *pBuffer = (BYTE*)depthLockedRect.pBits; //pointer to data having 8-bit jump
USHORT *depthBuffer = (USHORT*) pBuffer; //pointer to data having 16-bit jump
int cn = 4;
this->depthFinal = cv::Mat::zeros(depthHeight,depthWidth,CV_8UC4); //8bit 4 channel
for(int i=0;i<this->depthFinal.rows;i++){
   for(int j=0;j<this->depthFinal.cols;j++){
      USHORT realdepth = ((*depthBuffer)&0x0fff); //Taking 12LSBs for depth
      BYTE intensity = (BYTE)((255*realdepth)/0x0fff); //Scaling to 255 scale grayscale
      this->depthFinal.data[i*this->depthFinal.cols*cn + j*cn + 0] = intensity;
      this->depthFinal.data[i*this->depthFinal.cols*cn + j*cn + 1] = intensity;
      this->depthFinal.data[i*this->depthFinal.cols*cn + j*cn + 2] = intensity;
      depthBuffer++;
   }
}

4 回答

  • 0

    您看到的条纹是由 %256 操作引起的 wrapping 深度值引起的 . 而不是应用导致波段出现的模运算( %256 ),重新映射整个范围内的深度值,例如:

    BYTE intensity = depth == 0 || depth > 4095 ? 0 : 255 - (BYTE)(((float)depth / 4095.0f) * 255.0f);
    

    如果您的最大深度为2048,请将2095替换为2047 .

    更多指针:

    • Kinect可能会返回11位值(0-2047),但您只使用8位(0-255) .

    • 新的Kinect版本似乎返回12位值(0-4096)
      在Kinect资源管理器源代码中

    • ,有一个名为 DepthColorizer.cs 的文件,其中大部分魔法似乎都在发生 . 我相信这段代码使kinect资源管理器中的深度值如此平滑 - 但我可能错了 .

  • 0

    我在处理涉及深度图可视化的项目时遇到了同样的问题 . 但是我使用OpenNI SDK和OpenCV而不是Kinect SDK库 . 问题是一样的,因此解决方案对我来说就像对我一样 .

    正如您在问题的先前答案中所提到的,Kinect深度图是11位(0-2047) . 而在示例中,使用8位数据类型 .

    我在我的代码中做的就是将深度图获取到16位Mat,然后使用 convertTo 函数中的缩放选项将其转换为8位uchar Mat,用于 Mat

    首先,我初始化 Mat 以获取深度数据

    Mat depthMat16UC1(XN_VGA_Y_RES, XN_VGA_X_RES, CV_16UC1);
    

    这里 XN_VGA_Y_RES, XN_VGA_X_RES 定义了获取的深度图的分辨率 .

    我这样做的代码如下:

    depthMat16UC1.data = ((uchar*)depthMD.Data());
    depthMat16UC1.convertTo(depthMat8UC1, CV_8U, 0.05f); 
    imshow("Depth Image", depthMat8UC1);
    

    depthMD 是包含从Kinect传感器检索的数据的元数据 .

    我希望这能以某种方式帮助你 .

  • 5

    深度图像数据的可视化具有粗略的级别(在您的代码示例中为0到255),但实际深度图像数据是0到2047之间的数字 . 当然,仍然谨慎,但不是如此粗略的单位选择用来描绘它们的颜色 .

  • 1

    kinect v2可以看到8米深度(但精度超过4.5减少) . 它开始大约0.4米 . 因此,需要将一个数字8000表示为一种颜色 . 一种方法是使用RGB颜色只是一个数字 . 然后你可以存储一个像255x255x255像素的数字 . 或者如果你有不同的颜色格式,那么它会有所不同 . 在255x255x255最大数量中存储8000将产生一定量的R G B,并且这会产生这种条带效应 .

    但是你可以将8000或者减去一个数字,或者删除超过一定值 .

相关问题