我想定义一个投影到图像中某个平面上的坐标系。我只需要一些关于如何实现这一点的提示和想法,不一定是代码,但一切都很感激!如果提供了代码,那么在OpenCV中最好使用Python作为语言。
示例:我有一张从某些角度看的桌子的图片。我已经使用放置在桌面上的棋盘图案拍摄了N张校准图像。我们可以想象它是一张平的台球桌。我已经计算了内在/外在校准矩阵,一个单应矩阵,我可以将图像投影到我的桌面表面上——一切都很好。但是现在我想在桌面上创建一个坐标系。如果我知道桌面的尺寸是1米乘2米,我想要一个函数,我可以说:给我图像中对应于桌面表面上的点(x=0.75米,y=1.65米(的二维像素坐标。我希望原点从桌面的左上角开始,但这应该只是翻译的问题。我怎么能使这个坐标系和相应的函数成为;使用";它
我已经提出了两种潜在的方法,但都似乎非常无效,我相信必须存在一种更有效、更稳健的方法。
1:在我的校准过程中,我在桌面上放置了N张不同的校准图案图像。这给了我N个局部坐标系,每个校准模式一个。由于每个校准图案都留在桌面上,因此x轴和y轴将始终位于同一平面上。使用这个OpenCV指南,我可以绘制沿着桌面平面的轴,每个点都匹配为棋盘正方形的大小,所以我有一个将米转换为像素的工作度量。最大的问题是,如果棋盘边与桌子边不平行,那么我的坐标系就会错位。另一个问题是,通过使用N个小坐标系,我必须选择一个任意的坐标系,然后手动找到其对应的平移到桌面左上角的位置,并绕origo旋转以重新对齐轴。这使得解决方案非常手动,并且很难动态化。最终,最好只在像素值中定义4个手动识别的表边缘,然后需要任何导出的值,如单应矩阵、旋转矩阵、平移矩阵等。
2:我可以生成坐标网格的图像,然后将该图像网格投影到桌面图像上。这项技术与此类似。然后,我会增强我的原始桌面图像,以包含一个经过正确转换的网格(即,离相机较近的网格坐标正方形比离相机较远的网格坐标方形大(。然而,这并不能使我从绘制的网格中提取坐标。如果我可以投影一个网格来代替图像,那么这将是一个非常简单的解决方案。据我在OpenCV文档中看到的,这是不可能的。
以配方形式:
-
在图像中,通过任何必要的手段(例如点击和收集鼠标点击坐标(,确定所需原点的图像位置。
-
以相同的方式识别所需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