3

该项目

我正在为移动设备开发纹理跟踪项目。它专门跟踪平面,所以我一直在使用 openCV 的 cv::FindHomography() 来计算两帧之间的单应性。然而,该功能运行非常缓慢,是我管道中的主要瓶颈。我决定可以对单应性进行初始估计的算法运行得更快,因为我在帧之间的单应性变化非常小。此外,我的异常值百分比非常小,因此稳健的方法是可选的。不幸的是,据我所知,open CV 不包括进行初步估计的单应性查找器。然而,它确实包含solvePnP(),它获取场景的原始3d 世界坐标、当前2d 图像坐标、相机矩阵、失真参数,最重要的是初始估计。我正在尝试用solvePnP替换FindHomography。由于我在整个管道中仅使用 2d 坐标,并且 solvePnP 要求提供 3d 坐标,因此我试图从 2d->3d->3d_transform->2d_transform 移动。现在,如果给定一个好的初始猜测,但它有问题,该过程的运行速度比 FindHomography() 快 6 倍。

问题

我的转换方式有问题。我的理论是,由于不需要相机矩阵来找到单应性,因此此过程不需要它,因为我只想要最终包含在单应性中的信息。我还假设,由于我最终丢弃了所有 z 信息,因此我如何初始化 z 应该无关紧要。我的流程如下

首先,我将所有初始 2d 坐标转换为 3d,方法是给它们 1 的 az pos。我可以假设我的原始坐标平放在 xy 平面上。然后

cv::Mat rot_mat; //3x3 rotation matrix
cv::Mat pnp_rot; //3x1 rotation vector
cv::Mat pnp_tran; //3x1 translation vector
cv::Matx33f camera_matrix(1,0,0,
                          0,1,0,
                          0,0,1);
cv::Matx41f dist(0,0,0,0);
cv::solvePnP(original_cord, current_cord, camera_matrix, dist, pnp_rot, pnp_tran,true);

//Rodrigues converts from a rotation vector to a rotation matrix
cv::Rodrigues(pnp_rot, rot_mat);
cv::Matx33f homography(rot_mat(0,0),rot_mat(0,1),pnp_tran(0),
                       rot_mat(1,0),rot_mat(1,1),pnp_tran(1),
                       rot_mat(2,0),rot_mat(2,1),pnp_tran(2)+1);

此处转换为单应性很简单。单应性的前两列来自 3x3 旋转矩阵,最后一列是平移向量。一个技巧是单应性(2,2) 对应于比例,而 pnp_tran(2) 对应于 z 轴上的移动。鉴于我将 z 坐标初始化为 1,比例为 z_translation + 1。此过程适用于 6 个自由度中的 4 个。Translation_x、translation_x、缩放和围绕 z 的旋转都有效。然而,关于 x 和 y 的旋转显示出明显的错误。我相信这是由于在 z = 1 处初始化了我的点,但我不知道如何解决它。

问题

我假设我可以通过使用伪造的相机矩阵和初始 z 坐标从 solvePnP 中获得良好的结果吗?如果是这样,我应该如何设置我的相机矩阵和 z 坐标以使 x 和 y 旋转工作?此外,如果有人知道我在哪里可以获得一个单应性查找算法,该算法需要初始猜测并且只能在 2d 中工作,或者有关编写我自己的技术的信息,这将非常有帮助。一旦我开始工作,我很可能会朝着这个方向前进。

更新

我自己构建了一个测试程序,它采用单应性,从该单应性生成一组共面点,然后通过solvePnP运行这些点以恢复指定的单应性。在这样做的过程中,我意识到我从根本上误解了单应性是如何构建的某些部分。我一直假设单应性构造如下。

hom(0,2) = x translation
hom(1,2) = y translation
hom(2,2) = scale, I can divide the entire matrix by this to normalize

我假设的前两列是 3x3 旋转矩阵的前两列。这基本上相当于进行 3x4 变换并丢弃列 (2)。然而,我发现这不是真的。向我展示我的方式错误的测试用例试图制作一个单应性,它将点围绕 y 轴旋转一些小角度。

//rotate by .0175 rad about y axis
rot_mat = (1,0,.0174,
           0,1,0,
      -.0174,0,1);
//my conversion method to make this a homography gives

homography = (1,0,0,
              0,1,0,
         -.0174,0,1);

上面的单应性根本不起作用。以 x > 58 的点 x,y,1 为例。结果将是 x,y,some_negative_number。当我从齐次坐标转换回笛卡尔坐标时,我的 x 和 y 值都会翻转符号。

也就是说,我现在有一个更简单的问题,我认为它可以让我解决所有问题。如何构建一个单应性,将点围绕 x 和 y 轴旋转某个角度?

4

1 回答 1

3

单应性不是简单的平移或旋转矩阵。目的是将直线映射到直线,而不是将单个点映射到其他点。他们考虑了透视矩阵来实现这一点,并在此处进行了解释

Hence, homography matrices cannot be easily decomposed, but there are (complicated) ways to do so shown here. This may help you extract rotations and translations out of it.

This should help you better understand a homography, but the rest I am unfamiliar with.

于 2012-11-26T16:11:12.523 回答