深度值没有意义 R200 相机

Depth Values Don't Make Sense R200 Camera

我是 运行 在这里找到的教程:https://software.intel.com/en-us/articles/using-librealsense-and-opencv-to-stream-rgb-and-depth-data

它使用以下行从 r200 获取深度值:

   cv::Mat depth16( _depth_intrin.height, _depth_intrin.width, CV_16U,(uchar *)_rs_camera.get_frame_data( rs::stream::depth ) );
   cv::Mat depth8u = depth16;
   depth8u.convertTo( depth8u, CV_8UC1, 255.0/1000 );
   imshow( WINDOW_DEPTH, depth8u );

输出图像流为:

https://imgur.com/EmdhFNk

您也可以看到彩色图像。我还在底部放了一个卷尺,最远可达 3.5m(r200 的范围应该达到 3.5m)

颜色到底为什么是二进制的?我试过添加不同的彩色图像,但它似乎根本不是深度值。同样,即使距离从 1m 到 5m 不远,地板始终是黑色也是没有意义的。为什么所有物体都是白色的? table和沙发的距离明显不同

我该如何改进?我知道您可以从 r200 获得良好的深度值,就像我在示例中得到的那样。请参阅 (http://docs.ros.org/kinetic/api/librealsense/html/cpp-capture_8cpp_source.html),但这些使用 glfw 而不是 OpenCV。我想知道为什么深度值在转换后如此奇怪。

理想情况下,我想生成深度值并过滤掉 1m 到 2m 范围之外的任何值。谢谢!

编辑:正如@MSalters 所指出的,我的回答的前半部分是错误的,这是由于我误读了 OP 的代码。下半部分包含正确答案。

如果你的深度范围是1-3.5m,单位是毫米(1000mm-3500mm);将结果除以 1000 将得到 1.0-3.5 范围内的数据。但是,您的源数据是 16 位无符号类型,不能表示十进制或浮点值,只能表示整数,因此您的值会被截断为 {0,1,2,3} 之一。您 可能 convertTo 中解决这个问题,因为它可能会在内部编组类型,但这是一个潜在的错误来源。

但是还有第二个问题... CV_8U 是一个 8 位无符号字符,它也只能表示整数值,这次的范围是 0-255。由于您的数据可以在 0...3500 范围内,通过像您在示例中所做的那样乘以 0.255,任何超过 1000 毫米深度的值都会导致超过 255 的值,因此会在那里被截断。

您可以使用 cv::normalize 函数,使用 NORM_MINMAX 归一化类型将数据归一化为 0...255,而不是像上面那样转换原始深度图像范围。您也可以将目标图像格式设置为 CV_8U。

这可能只适用于可视化,因为它会受到源数据输入范围的影响。相反,如果您知道最大值为 3500,最小值为 0,则将源图像除以 3500,然后乘以 255。也就是说,在可能的情况下,最好将其保留为 16 位格式,以便深度分辨率。