项目
我正在为移动设备开发一个纹理跟踪项目。它专门跟踪平面表面,因此我一直在使用openCV的cv::FindHomography()函数来计算两个帧之间的单应性矩阵。然而,该函数运行非常缓慢,是我的流水线中的主要瓶颈。我决定使用一种可以接受单应性矩阵初始估计的算法,因为我的帧之间的单应性变化非常小。此外,我的异常值百分比非常小,因此鲁棒方法是可选的。不幸的是,据我所知,openCV没有包括可以接受初始估计的单应性矩阵查找器。但是,它确实包括solvePnP()函数,该函数需要场景的原始3D世界坐标、当前2D图像坐标、相机矩阵、畸变参数以及最重要的是一个初始估计。我正在尝试用solvePnP替换FindHomography。由于我在整个流水线中仅使用2D坐标,而solvePnP要求3D坐标,因此我正在尝试从2D->3D->3D_transform->2D_transform转换。如果给出良好的初始猜测,目前该过程比FindHomography()快6倍,但它存在问题。
问题
我在转换过程中遇到了问题。我的理论是,由于不需要相机矩阵来查找单应性,因此在这个过程中也不应该需要相机矩阵,因为最终我只需要单应性中包含的信息。我还假设,由于最终我会丢弃所有的z信息,所以如何初始化z并不重要。我的过程如下:
首先,我通过将它们的z位置设置为1来将所有初始2D坐标转换为3D坐标。我可以假设我的原始坐标位于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旋转矩阵,最后一列是平移向量。唯一的技巧是homography(2,2)对应于比例,而pnp_tran(2)对应于z轴上的运动。考虑到我将我的z坐标初始化为1,因此比例是z_translation + 1。这个过程对于6个自由度中的4个完美地工作。Translation_x、translation_x、scale和绕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,y,1 为例,其中 x > 58。结果将是 x,y,某个负数。当我将齐次坐标转换回笛卡尔坐标时,我的 x 和 y 值都会翻转符号。
所有这些都是为了说明,我现在有一个更简单的问题,我认为它可以让我解决所有问题。如何构造一个单应性,围绕 x 轴和 y 轴旋转点的某个角度?