使用单应性围绕x / y轴旋转

时间:2012-07-23 16:02:59

标签: c++ opencv computer-vision transform affinetransform

项目

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

问题

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

首先,我将所有初始的2d坐标转换为3d,给它们的z pos为1.我可以假设我的原始坐标平躺在x-y平面上。然后

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个。有关z的Translation_x,translation_x,scale和rotation都可以正常工作。然而,关于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,y,1,其中x> 1。 58.结果将是x,y,some_negative_number。当我从齐次坐标转换回笛卡儿时,我的x和y值都会翻转符号。

所有这一切,我现在有一个更简单的问题,我认为这会让我解决所有问题。如何构建一个旋转点绕x轴和y轴旋转一定角度的单应性?

1 个答案:

答案 0 :(得分:3)

Homographies不是简单的平移或旋转矩阵。目的是将直线映射到直线而不是将单个点映射到其他点。他们考虑了透视矩阵来实现这一点并解释here

因此,单应性矩阵不容易分解,但有(复杂)方法这样做here。这可以帮助您从中提取旋转和翻译。

这可以帮助你更好地理解单应性,但其余的我不熟悉。