从 (x,y) 像素坐标获取 3D 世界坐标

Getting 3D world coordinate from (x,y) pixel coordinates

我是 ROS/Gazebo 世界的新手;这可能是一个简单的问题,但我找不到好的答案。

我在 Gazebo 场景中有一个模拟深度相机 (Kinect)。经过一些阐述,我在像素坐标中得到了 RGB 图像中的一个兴趣点,我想在世界坐标系中检索它的 3D 坐标。 我不明白该怎么做。

我已尝试补偿 CameraInfo 消息给出的失真。我尝试将 PointCloud 与 pcl 库一起使用,将点检索为 cloud.at(x,y).

这两种情况都是坐标不对(我在程序给出的坐标中放了一个小球体,看看对不对)。

我们将不胜感激。非常感谢。

编辑: 从 PointCloud 开始,我尝试通过以下方式找到点的坐标:

point = cloud.at(xInPixel, yInPixel);
point.x = point.x + cameraPos.x;
point.y = point.y + cameraPos.y;
point.z = point.z - cameraPos.z;

但是我得到的 x,y,z 坐标 point.x 似乎不正确。 相机的俯仰角为 pi/2,因此指向地面。 我显然遗漏了一些东西。

我假设您已经看过 kinect 的凉亭示例 (brief, full)。您可以获得作为主题的原始图像、原始深度和计算的点云(通过在配置中设置它们):

<imageTopicName>/camera/color/image_raw</imageTopicName>
<cameraInfoTopicName>/camera/color/camera_info</cameraInfoTopicName>
<depthImageTopicName>/camera/depth/image_raw</depthImageTopicName>
<depthImageCameraInfoTopicName>/camera/dept/camera_info</depthImageCameraInfoTopicName>
<pointCloudTopicName>/camera/depth/points</pointCloudTopicName>

除非您需要使用 image_raw 为 rgb 和深度帧做自己的事情(ex ML over rgb frame & find corresponding depth point via camera_infos),点云主题应该足够了- 它与 c++ 中的 pcl 点云相同,如果你包含正确的 headers.

编辑(回应): ros中有个神奇的东西叫tf/tf2。如果您查看 msg.header.frame_id,您的点云会显示类似 "camera" 的内容,表明它在相机框架中。 tf,就像ros中的消息系统一样,发生在后台,但是它looks/listens用于从一个参考系到另一个参考系的转换。然后,您可以 transform/query 另一帧中的数据。例如,如果相机安装在机器人的旋转位置,您可以在启动文件中指定静态转换。看起来您正在尝试自己进行转换,但您可以让 tf 为您完成;这使您可以轻松找出点在 world/map 框架、robot/base_link 框架或 actuator/camera/etc 框架中的位置。

我还会查看这些 ros wiki 问题,这些问题演示了几种不同的方法,具体取决于您的需要:ex1, ex2, ex3