Intel RealSense depth camera D435i 数据获取时的一些坑(附,全套数据采集示例代码)

您所在的位置:网站首页 d435参数 Intel RealSense depth camera D435i 数据获取时的一些坑(附,全套数据采集示例代码)

Intel RealSense depth camera D435i 数据获取时的一些坑(附,全套数据采集示例代码)

2024-07-10 18:56| 来源: 网络整理| 查看: 265

“示例代码——通过 Intel RealSense 设备获取2D图像、3D点云等原始数据” 先放github链接:https://github.com/denkywu/intel-realsense-camera-data-collection-demo

说明如下:

 基于Intel RealSense 设备(相机)获取2D图像、3D点云等原始数据。这里对原始数据的定义为:直接通过Intel RealSense SDK 2.0从设备中获取的数据,基本没有经过其他数据后处理。已经测试(使用)过的设备,如下: Intel RealSense depth camera D435iIntel RealSense depth camera D435Intel RealSense depth camera D415理论上来说,只要支持Intel RealSense SDK 2.0的设备都可以通过该示例代码获取数据。只是要注意,某些设备可能拥有或没有某些接口。可以获取的原始数据如下: color image,2D彩色图像点云 xyztexture image,点云纹理彩色图像,与点云xyz(或者说深度图像)是对齐的点云 xyzrgb,将点云 xyz和texture image组合得到ir left image,左侧ir灰度图像ir right image,右侧ir灰度图像由于本人并不需要imu数据,所以这方面的内容目前没有涉及示例代码中,主要是实现了一个自定义类”class RealSenseData“(详见文件"realSenseData.h" 和"realSenseData.cpp"),使用该自定义类的demo(main函数)见文件"mainDemo.cpp"。示例代码中,通过配置文件"ConfigCameraRealSense.yaml"可对不同相机(比如color,depth)设置分辨率和帧率等。所以在生成了可执行文件后,需要将该文件拷贝至对应目录下,即可运行程序。数据采集自定义类class RealSenseData中的一些接口示例如下(详细内容请参见github): public: // 设备状态 bool devStart();// 设备启动 bool devStop();// 设备关闭 bool isDevConnected() const;// 设备是否连接 bool isDevReady() const;// 设备是否准备好采集数据 // 数据 cv::Mat getColorImage_2dCamera();// 2D彩色相机获取的2D彩色图像 cv::Mat getPointCloud_3dCamera();// 3D相机获取的点云xyz数据 cv::Mat getTextureImage_3dCamera();// 3D相机获取的点云纹理彩色图像 cv::Mat getIrLeftImage_3dCamera();// 3D相机获取的 IR left 图像 cv::Mat getIrRightImage_3dCamera();// 3D相机获取的 IR right 图像 // 相机内参和畸变参数 // 2D相机 cv::Matx33f getIntrinsics_2dCamera();// 2D相机-内参 cv::Matx getDistortion_2dCamera();// 2D相机-畸变参数 // 3D相机 cv::Matx33f getIntrinsics_3dCamera();// 3D相机-内参 cv::Matx getDistortion_3dCamera();// 3D相机-畸变参数 // 外参, get Depth-to-Color Extrinsics cv::Matx33f getRotation(); cv::Matx31f getTranslation(); 基于Intel RealSense depth camera D415设备,采集的一组数据示例如下:

1)2D彩色图像

2)点云xyzrgb,在CloudCompare中打开后的截图

3)点云纹理彩色图像(将2D彩色图像配准到3D点云上的结果,与深度图像是对齐的,即分辨率和点云相同)

4)IR left 灰度图像(图中暗纹就是D415在采集深度数据时发射的红外散斑)

5)IR right 灰度图像(D415是基于双目视觉Stereo+红外散斑来获取深度图像或者说点云数据的。红外散斑的红外强度是可以调节和关闭的,在SDK 2.0中有相应接口,各位感兴趣的话可以试试。该right灰度图像和上面的left是配套的)

完。

 

-------------------------------------------  分割线 -------------------------------------------

1、RealSense D435i的图像空间、相机空间的坐标系定义都与OpenCV一致,这里不再赘述(可参考我在这篇博客中对坐标系内容的描述,https://blog.csdn.net/denkywu/article/details/89850166)。

但是,我在使用其SDK中的函数 export_to_ply() 导出点云ply文件时发现了以下大坑,听我慢慢道来:

1)首先获取点云数据,以下是基本框架

rs2::pointcloud rs2_PointCloud;// Declare pointcloud object, for calculating pointclouds and texture mappings rs2::points rs2_Points; auto rs2_Frameset = pipe.wait_for_frames();// Set of time synchronized frames, one from each active stream auto rs2_ColorFrame = rs2_Frameset.get_color_frame();// get video_frame - first found color frame. auto rs2_DepthFrame = rs2_Frameset.get_depth_frame();// get depth_frame - first found depth frame. // --------------------------------------------------------------------------------- rs2_PointCloud.map_to(rs2_ColorFrame);// Tell pointcloud object to map to this frame - as texture. // 将RGB信息作为纹理与点云(深度图)匹配上 // ! 注意 ! // 要想将深度图(点云)和纹理 .map_to(),必须先进行这一步 // 然后才能进行下面的 .calculate() 计算 rs2::points // 这是我经过实验发现的,如果将先后顺序反过来,会有问题 // --------------------------------------------------------------------------------- // Generate the pointcloud and texture mappings rs2_Points = rs2_PointCloud.calculate(rs2_DepthFrame);// 获取三维点云数据

2)在获取 rs2_Points 后,可直接通过方法 export_to_ply() 导出ply文件到本地路径,例如:

rs2_Points.export_to_ply("pointCloud.ply", rs2_ColorFrame);

下面代码是官方SDK中关于该方法的说明

/** * Export current point cloud to PLY file * \param[in] string fname - file name of the PLY to be saved * \param[in] video_frame texture - the texture for the PLY. */ void export_to_ply(const std::string& fname, video_frame texture) { rs2_frame* ptr = nullptr; std::swap(texture.frame_ref, ptr); rs2_error* e = nullptr; rs2_export_to_ply(get(), fname.c_str(), ptr, &e); error::handle(e); } /** * When called on Points frame type, this method creates a ply file of the model with the given file name. * \param[in] frame Points frame * \param[in] fname The name for the ply file * \param[in] texture Texture frame * \param[out] error If non-null, receives any error that occurs during this call, otherwise, errors are ignored */ void rs2_export_to_ply(const rs2_frame* frame, const char* fname, rs2_frame* texture, rs2_error** error);

以上看起来没什么特别的,但是使用该方法导出ply文件并打开后,你会发现:任何一个点的z坐标(深度值)是负数!

经过验证后发现,官方SDK计算的深度图数据以及点云xyz信息都是没问题的(且坐标系定义和OpenCV一致)。如果自行将点云数据导出到ply文件也是没问题的。所以我认为:class points 的方法 export_to_ply() 在导出ply文件时,修改了点云xyz的坐标数值:x不变,y取反,z取反。这使得方法 export_to_ply()  导出的ply文件中点云xyz的数值在 y 和 z 坐标上与原始值相差了一个负号。

官方为何如此设置不得知,我猜测是为了ply文件打开后显示的更直观(比如在CloudCompare中打开,无需旋转,其视角就和“以相机照射方向向前看”是一致的),如果我们自行将点云数据存储并打开,是需要经过旋转才可以的。

这不是什么大问题,但是该函数并未进行说明,我认为挺坑的。一不小心,可能认为(我之前就误以为)RealSense的坐标系定义有某些特别之处。

 

2、RealSense内存泄漏问题

该问题我在github中找到了一模一样的叙述,“pointcloud processing block causing memory leak #2860”,网址https://github.com/IntelRealSense/librealsense/issues/2860

简单来说,就是把 rs2::pointcloud 放在循环中会导致内存泄漏(时间长了一定会发生。因为在每一次循环中该类生成的实例并未完全释放),解决方法就是将其放在循环以外。Mark

 

—— 后续再更新



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3