为什么这个预测是错误的?

信息处理 计算机视觉 投影 几何学
2022-01-26 20:12:13

我试图弄清楚为什么 3D 立方体没有投影在图像中的正确位置。

我从原点的相机和以(0,0,1)世界坐标为中心的立方体开始:

正面

R然后我围绕 Y 轴创建 45 度的 3D 旋转:

(0.707106781, 0, 0.707106781,
0, 1, 0,
-0.707106781, 0, 0.707106781)

我将相机设置为使用旋转R^-1,并进行平移R * (0,0,1)(这些是相机到世界的转换)。相机应该围绕立方体逆时针旋转 45 度(我可以确认我0.707106781在 x 和 z 上进行了平移)。

在这一点上,我希望看到具有相同比例的立方体,仍然居中,并且其中一个边缘位于图像的中间。但这就是我得到的:

边 45

我用来投影 3d 点的过程X是(伪代码):

  • 带入相机坐标:Xc = R^-1 * X - R^1 * translation
  • 转换为图像坐标:x = Xc * focal length / Xc.z + principal point

我从各种来源阅读了理论,似乎我正在遵守规则。

这只是人工数据,不知道焦距和主点会不会有影响?我究竟做错了什么?为什么立方体不居中?

编辑:

我像这样构造立方体(有重复的顶点,因为我需要它们来画线):

  cv::Matx31d center(0,0,1);
  double delta = 0.2;

  std::vector<cv::Matx31d> volumeCorners = {
    // back
    (center + cv::Matx31d(-delta, delta, delta)),
    (center + cv::Matx31d(delta, delta, delta)),

    (center + cv::Matx31d(delta, delta, delta)),
    (center + cv::Matx31d(delta, -delta, delta)),

    (center + cv::Matx31d(delta, -delta, delta)),
    (center + cv::Matx31d(-delta, -delta, delta)),

    (center + cv::Matx31d(-delta, -delta, delta)),
    (center + cv::Matx31d(-delta, delta, delta)),

    // right
    (center + cv::Matx31d(delta, delta, delta)),
    (center + cv::Matx31d(delta, delta, -delta)),

    (center + cv::Matx31d(delta, delta, -delta)),
    (center + cv::Matx31d(delta, -delta, -delta)),

    (center + cv::Matx31d(delta, -delta, -delta)),
    (center + cv::Matx31d(delta, -delta, delta)),

    // front
    (center + cv::Matx31d(delta, delta, -delta)),
    (center + cv::Matx31d(-delta, delta, -delta)),

    (center + cv::Matx31d(-delta, -delta, -delta)),
    (center + cv::Matx31d(delta, -delta, -delta)),

    (center + cv::Matx31d(-delta, -delta, -delta)),
    (center + cv::Matx31d(-delta, delta, -delta)),

    // left
    (center + cv::Matx31d(-delta, delta, -delta)),
    (center + cv::Matx31d(-delta, delta, delta)),

    (center + cv::Matx31d(-delta, -delta, delta)),
    (center + cv::Matx31d(-delta, -delta, -delta)),
  };

我使用右手坐标系,y 轴指向下方,用于世界和相机坐标,而图像的原点位于左上角。

1个回答

我的翻译应该描述了围绕立方体中心的旋转,但这是错误的。我将其更改为:

rotate45 * (translation - center) + center

我把立方体放在中间,角度是正确的。