c++ - 深度值没有意义 R200 相机

标签 c++ computer-vision realsense

我正在运行此处找到的教程: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。我想知道为什么深度值在转换后如此奇怪。

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

最佳答案

编辑:正如@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 位格式,以便深度分辨率。

关于c++ - 深度值没有意义 R200 相机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52693955/

相关文章:

opencv - 用于跟踪除 Windows Kinect 人体手势之外的其他对象的 API 可用性

python - TypeError : mat data type = 17 is not supported, 使用 realsense d435 显示红外数据

c++ - 函数原型(prototype)和函数实现签名不一致地使用 const 可以吗?

c++ - GCC 内联汇编错误 : block assembly operand not recognized

c++ - 使用运算符大小初始化数组?

machine-learning - 在计算机视觉中使用形状描述符检测对象类别

Python文件使用OpenCV写入所有边界框坐标

c++ - 通过结构将动态数组传递给 pthreads

c++ - 英特尔实感 3D 相机 (SR300) 的 pmdGet3DCoordinates 相当于什么?

c++ - 如何在英特尔实感(Visual C++)中保存图像