【问题标题】:How can I transform an image using matrices R and T (extrinsic parameters matrices) in opencv?如何在opencv中使用矩阵R和T(外部参数矩阵)转换图像?
【发布时间】:2012-10-17 12:35:30
【问题描述】:

我有一个旋转平移矩阵 [R T] (3x4)。

opencv中是否有执行[R T]描述的旋转平移的函数?

【问题讨论】:

  • 是的,但你也需要你的内在参数,你有吗?您还需要对图像的初始位置做出一些假设,但通常这不是问题。
  • 是的,我有内在参数。
  • 下一个问题,你的 R 和 T 矩阵相对于什么?相机的原始位置?世界空间中的某个位置?等等。
  • 世界空间中的一个位置,特别是地板。
  • 好的,这应该是最后一个问题了。你知道相机现在在哪里,即 R 和 T。如果你想将地板的图像从一个角度扭曲到另一个角度,你需要知道当第一张图像出现时相机的 R 和 T 是什么采取。然后你可以找出它们之间的 R 和 T 等。拍照时你知道 R 和 T 吗?

标签: opencv camera-calibration projective-geometry


【解决方案1】:

我认为这个问题的很多解决方案都做出了隐藏的假设。我将尝试快速总结一下我对这个问题的看法(过去我不得不考虑很多)。两个图像之间的变形是一个二维过程,由称为单应性的 3x3 矩阵完成。你所拥有的是一个 3x4 矩阵,它定义了一个 3 维的变换。您可以通过将图像视为 3 维空间中的平面来在两者之间进行转换。然后,诀窍是确定图像平面在世界空间中的初始位置。然后,您可以使用相机内在矩阵变换其位置并将其投影到新的图像平面上。

第一步是确定初始图像在世界空间中的位置,注意这不必与初始 R 和 T 矩阵指定的相同。那些在世界坐标中,我们说的是那个世界创建的图像,图像中的所有对象都被压平成一个平面。这里最简单的决定是将图像设置在 z 轴上的固定位移并且不旋转。从这一点开始,我将假设没有轮换。如果您想查看一般情况,我可以提供它,但它稍微复杂一些。

接下来,您可以在 3d 空间中定义两个图像之间的变换。由于您有两个关于同一原点的变换,因此从 [A] 到 [B] 的变换与从 [A] 到原点的变换相同,然后是从原点到 [B] 的变换。你可以通过

transform = [B]*inverse([A])

现在从概念上讲,您需要做的是拍摄第一张图像,将其像素投影到 3d 空间中图像的几何解释上,然后通过上述变换在 3d 空间中变换这些像素,然后将它们投影回新的带有相机矩阵的 2d 图像。这些步骤需要组合成一个 3x3 矩阵。

cv::Matx33f convert_3x4_to_3x3(cv::Matx34f pose, cv::Matx33f camera_mat, float zpos)
{   
//converted condenses the 3x4 matrix which transforms a point in world space 
//to a 3x3 matrix which transforms a point in world space.  Instead of 
//multiplying pose by a 4x1 3d homogeneous vector, by specifying that the
//incoming 3d vectors will ALWAYS have a z coordinate of zpos, one can instead 
//multiply converted by a homogeneous 2d vector and get the same output for x and y.

cv::Matx33f converted(pose(0,0),pose(0,1),pose(0,2)*zpos+pose(0,3),
                      pose(1,0),pose(1,1),pose(1,2)*zpos+pose(1,3),
                      pose(2,0),pose(2,1),pose(2,2)*zpos+pose(2,3));

//This matrix will take a homogeneous 2d coordinate and "projects" it onto a 
//flat plane at zpos.  The x and y components of the incoming homogeneous 2d 
//coordinate will be correct, the z component is dropped.  
cv::Matx33f projected(1,0,0,
                      0,1,0,
                      0,0,zpos);
projected = projected*camera_mat.inv();

//now we have the pieces.  A matrix which can take an incoming 2d point, and 
//convert it into a pseudo 3d point (x and y correspond to 3d, z is unused) 
//and a matrix which can take our pseudo 3d point and transform it correctly.  
//Now we just need to turn our transformed pseudo 3d point back into a 2d point 
//in our new image, to do that simply multiply by the camera matrix.

return camera_mat*converted*projected;
}

这可能是一个比您要寻找的更复杂的答案,但我希望它能让您了解您在问什么。这可能非常令人困惑,我很快就对它的某些部分进行了研究,请随时要求澄清。如果您需要解决方案在不假设初始图像没有旋转的情况下工作,请告诉我,我只是不想让它变得比需要的更复杂。

【讨论】:

  • 我一直在尝试遵循您的答案,因为我正在尝试做类似的事情,也许您可​​以提供帮助。您的函数pose和camera_mat的输入?这些到底是什么? Carlo 提到他对两个相机都有内在和外在矩阵(我也是)你如何将视图 1 中的 (x,y) 点映射到视图 2 中相应的 (x,y) 点?您是否只需将从您的函数返回的 3x3 矩阵乘以视图 1 中的 (x,y) 点?
  • @LukeZammit 要转换点,您需要将点 (x,y) 转换为 3 向量 [x,y,1] 并乘以 3x3 矩阵。 Camera_mat 是一个相机内在矩阵。您可以在线找到有关内在矩阵如何工作的解释,但从概念上讲,它代表相机的焦距。姿势是您想在“3d 空间”中应用到您的图像的变换,如果您还有问题,请告诉我
猜你喜欢
  • 1970-01-01
  • 2012-09-18
  • 1970-01-01
  • 1970-01-01
  • 2014-04-13
  • 2017-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多