【问题标题】:Project coordinate system onto angled planar surface in image将坐标系投影到图像中的倾斜平面上
【发布时间】:2020-11-04 07:59:52
【问题描述】:

我想定义一个投影到图像内某个平面上的坐标系。我只需要一些关于如何实现这一点的提示和想法,不一定是代码,但一切都值得赞赏!如果提供了代码,在以 Python 为语言的 OpenCV 中将是首选。

示例:我有一张从某些角度看的桌子图像。我使用放置在桌面上的棋盘图案拍摄了 N 张校准图像。我们可以想象它是一个平面的斯诺克台球桌。我已经计算了内在/外在校准矩阵、单应矩阵,我可以将图像投影到我的桌面上——一切都很好。但是现在我想在桌面上创建一个坐标系。如果我知道桌面的尺寸是 1 米乘 2 米,我想要一个我可以说的函数:给我图像中对应于点的 2d 像素坐标(x=0.75 米,y=1.65 米) 在桌面表面上。我希望原点从桌面的左上角开始,但这应该只是翻译问题。我如何才能使这个坐标系和相应的功能“使用”它?

我提出了两种可能的方法,但似乎都非常无效,我相信必须存在一种更有效、更稳健的方法。

1:在我的校准过程中,我在桌面上放置了 N 个不同的校准图案图像。这给了我 N 个局部坐标系,一个用于每个校准模式。由于每个校准图案都留在桌面上,因此 x 轴和 y 轴将始终位于同一平面上。使用this OpenCV 指南我可以绘制沿着桌面平面的轴,每个点都匹配为棋盘格的大小,所以我有一个工作公制转换米到像素。最大的问题是,如果棋盘边缘不平行于桌子边缘,那么我的坐标系就会错位。另一个问题是,通过有 N 个小坐标系,我必须选择任意一个,然后手动找到其对应的平移到左上桌面位置,并围绕 origo 旋转以重新对齐轴。这使得解决方案非常手动,并且难以动态化。最终,只需在像素值中定义 4 个手动识别的表格边缘,然后需要任何派生值,例如单应矩阵、旋转矩阵、平移矩阵等。

2:我可以生成坐标网格的图像,然后将此图像网格投影到我的桌面图像上。该技术类似于this。然后我会扩充我的原始桌面图像以包含一个已正确转换的网格(即靠近相机的网格坐标方块大于更远的网格坐标方块)。然而,这并不能让我从绘制的网格中提取坐标。如果我可以投影一个网格而不是图像,那么这将是一个非常简单的解决方案。据我在 OpenCV 文档中看到的,这是不可能的。

【问题讨论】:

    标签: opencv computer-vision augmented-reality homography projective-geometry


    【解决方案1】:

    配方形式:

    • 通过任何必要的方式(例如单击并收集鼠标单击坐标)在图像中识别所需原点的图像位置。

    • 以相同的方式识别所需 X 轴上的一个点和所需 Y 轴上的一个点。

    • 将这些像素反向投影到世界坐标中的光线中,使用在校准期间获得的任何一种坐标变换(也称为外部参数)作为“世界”。我们把它的旋转矩阵和相对于相机的平移分别称为Rc0, Tc0

    • 将光线与 XY 世界平面(== 放置在桌子上的校准目标的平面)相交,获得 3D 点 Ot、Xt 和 Yt。

    • 计算向量xt = (Xt - Ot) / np.linalg.norm(Xt - Ot)yt = (Yt - Ot) / np.linalg.norm(Yt - Ot)

    • 使用 Gram 方法对它们进行正交化:yt = yt - yt.dot(xt) * xt; yt = yt / np.linalg.norm(yt)

    • 计算第三个轴:zt = np.cross(xy, yt)

    • 三元组(xt, yt, zt) 是您想要的坐标系,以Ot 为中心。矩阵R0t = np.hstack((xt, yt, zt)) 是从那个坐标系到世界坐标系的旋转。

    • 新帧到相机的坐标变换为Rct = Rc0.dot(R0t), Tt = Ot

    【讨论】:

    • 非常感谢您提供非常详细的回答。我已经成功地实现了这种方法,而且它也很直观。抱歉回复慢了。我接受了你的好回答!
    猜你喜欢
    • 1970-01-01
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多