Python 绕相机轴旋转图像
Python Rotate image about camera axis
假设我有一张图像,它是在对某些原始图像应用单应变换 H 后获得的。未显示原始图像。对原图应用单应性H的结果是这张图:
我想将这张图片绕一个合适的轴旋转 30 度(可能是相机所在的位置,如果有的话)以获得这张图片:
如果我不知道相机参数,如何使用 python 应用此旋转变换?我只能指定我想要旋转图像的度数和我想要旋转的近似轴。另外,如何使用 H 和旋转变换推导出原始图像(单应性之前)和最终旋转图像之间的单应性 H'?
要应用单应性,我建议使用 OpenCV,更具体地说是 warpPerspective
函数 https://docs.opencv.org/3.0-beta/modules/imgproc/doc/geometric_transformations.html#warpperspective
因为我们说的是纯旋转,没有相机平移,你确实可以只用单应性来产生对应于这个旋转的图像。但是要找到作为轴方向和旋转角度函数的单应性参数,您需要知道相机的内在参数,主要是焦距。
如果你有相机模型,你可以计算出方程,但另一种获得单应矩阵的方法是计算变换后的目标点坐标,然后使用 findHomography
函数.或者你可以找到匹配点,然后计算单应性。
如果您没有相机型号和旋转参数,或者两张图像中的匹配点,您无能为力,您需要其中任何一个来找出单应性。您可以尝试猜测相机型号。你掌握的具体信息是什么?
一个有趣的问题。为了帮助解释我的解决方案,我将定义一些符号:
- I1:原图。
- I2:将 I1 进行 H 变换后的图像。
- I3:通过 3D 相机旋转 R(您自己设置)变换 I2 得到的图像。
- I2对应的未知相机本征矩阵K
因为你的相机在旋转而不是平移,你可以通过使用相应的单应性矩阵。因此,您无需尝试以 3D 方式重建场景来合成这些视图。
现在我假设我们有 K 的估计值,并给出从 I1 到 I3 的单应性方程。这回答了你问题的最后一部分。最后我会给出一个很好的方法来估计K。然后你就拥有了你所需要的一切。
设p=(px,py)为I1中的二维点。我们用向量 p=(px,py,1) 在齐次坐标中定义这个点。同样设点q=(qx,qy,1)为点p在I3中的位置。将 p 变换为 q 的单应矩阵 H' 由 H' 给出 = K R inv(K) H。对于您指定的任何 R,您将使用它来计算 H' 然后您可以使用例如扭曲 I1 来合成新视图OpenCV 的 warpPerspective 函数。
推导。我们首先应用 H 将点放入 I2。接下来我们通过 inv(K) 将点转换到它在 3D 相机坐标中的位置。然后我们应用旋转 R,最后用 K 投影回图像。如果您不确定是否要像这样应用投影变换,那么我强烈建议您深入阅读 Hartley 和 Zisserman 的著作《多视图几何》。
计算K。为此,我提出了一个使用自由女神像的巧妙策略。具体来说,请注意她站在一个平台上,我假设它是方形的。这就是绝招!现在我们将使用正方形进行粗略的相机校准。我假设没有镜头畸变,并且 K 的简化形式为 K = [f,0,cx;0,f, cy;0,0,1]。这意味着宽高比为 1(数码相机通常大致如此)并且主点位于图像的中心:cx=w/2 和 cy=h/2 其中 w 和 h 是宽度和图像的高度分别。尝试估计镜头畸变和更复杂的 K 矩阵将非常困难。镜头失真似乎并不明显,因为木头的边缘在图像中大致都是直的,因此可以忽略不计。
所以现在我们要计算 f。这将使用基于平面的相机校准来完成。著名的参考文献是 Zhang:A Flexible New Technique for Camera Calibration,位于 https://www.microsoft.com/en-us/research/publication/a-flexible-new-technique-for-camera-calibration/
这样做的方法是首先单击 I2 中雕像平面的四个可见角的四个角(见附图)。我们称这些为 p1 p2 p3 和 p4,从左下角开始顺时针旋转。然后,您可以使用 OpenCV 的相机校准方法从这 4 个角点获得 K 的估计值。重要的是,我们之所以能够这样做,是因为我们知道平台是方形的。为了更深入地了解基于平面的校准,我建议阅读张的论文。如果您遇到困难,我可以在几分钟内自己完成并发送 K 矩阵。
最后一点,此方法的一个细微变化是使用原始图像进行校准(假设您仍然拥有原始图像)。原因是H 会扭曲I2,使其纵横比不接近1,主点不在图像中心附近。如果您使用原始图像进行校准(我们称矩阵为 K1),那么您将使用 K = H K1.
假设我有一张图像,它是在对某些原始图像应用单应变换 H 后获得的。未显示原始图像。对原图应用单应性H的结果是这张图:
我想将这张图片绕一个合适的轴旋转 30 度(可能是相机所在的位置,如果有的话)以获得这张图片:
如果我不知道相机参数,如何使用 python 应用此旋转变换?我只能指定我想要旋转图像的度数和我想要旋转的近似轴。另外,如何使用 H 和旋转变换推导出原始图像(单应性之前)和最终旋转图像之间的单应性 H'?
要应用单应性,我建议使用 OpenCV,更具体地说是 warpPerspective
函数 https://docs.opencv.org/3.0-beta/modules/imgproc/doc/geometric_transformations.html#warpperspective
因为我们说的是纯旋转,没有相机平移,你确实可以只用单应性来产生对应于这个旋转的图像。但是要找到作为轴方向和旋转角度函数的单应性参数,您需要知道相机的内在参数,主要是焦距。
如果你有相机模型,你可以计算出方程,但另一种获得单应矩阵的方法是计算变换后的目标点坐标,然后使用 findHomography
函数.或者你可以找到匹配点,然后计算单应性。
如果您没有相机型号和旋转参数,或者两张图像中的匹配点,您无能为力,您需要其中任何一个来找出单应性。您可以尝试猜测相机型号。你掌握的具体信息是什么?
一个有趣的问题。为了帮助解释我的解决方案,我将定义一些符号:
- I1:原图。
- I2:将 I1 进行 H 变换后的图像。
- I3:通过 3D 相机旋转 R(您自己设置)变换 I2 得到的图像。
- I2对应的未知相机本征矩阵K
因为你的相机在旋转而不是平移,你可以通过使用相应的单应性矩阵。因此,您无需尝试以 3D 方式重建场景来合成这些视图。
现在我假设我们有 K 的估计值,并给出从 I1 到 I3 的单应性方程。这回答了你问题的最后一部分。最后我会给出一个很好的方法来估计K。然后你就拥有了你所需要的一切。
设p=(px,py)为I1中的二维点。我们用向量 p=(px,py,1) 在齐次坐标中定义这个点。同样设点q=(qx,qy,1)为点p在I3中的位置。将 p 变换为 q 的单应矩阵 H' 由 H' 给出 = K R inv(K) H。对于您指定的任何 R,您将使用它来计算 H' 然后您可以使用例如扭曲 I1 来合成新视图OpenCV 的 warpPerspective 函数。
推导。我们首先应用 H 将点放入 I2。接下来我们通过 inv(K) 将点转换到它在 3D 相机坐标中的位置。然后我们应用旋转 R,最后用 K 投影回图像。如果您不确定是否要像这样应用投影变换,那么我强烈建议您深入阅读 Hartley 和 Zisserman 的著作《多视图几何》。
计算K。为此,我提出了一个使用自由女神像的巧妙策略。具体来说,请注意她站在一个平台上,我假设它是方形的。这就是绝招!现在我们将使用正方形进行粗略的相机校准。我假设没有镜头畸变,并且 K 的简化形式为 K = [f,0,cx;0,f, cy;0,0,1]。这意味着宽高比为 1(数码相机通常大致如此)并且主点位于图像的中心:cx=w/2 和 cy=h/2 其中 w 和 h 是宽度和图像的高度分别。尝试估计镜头畸变和更复杂的 K 矩阵将非常困难。镜头失真似乎并不明显,因为木头的边缘在图像中大致都是直的,因此可以忽略不计。
所以现在我们要计算 f。这将使用基于平面的相机校准来完成。著名的参考文献是 Zhang:A Flexible New Technique for Camera Calibration,位于 https://www.microsoft.com/en-us/research/publication/a-flexible-new-technique-for-camera-calibration/
这样做的方法是首先单击 I2 中雕像平面的四个可见角的四个角(见附图)。我们称这些为 p1 p2 p3 和 p4,从左下角开始顺时针旋转。然后,您可以使用 OpenCV 的相机校准方法从这 4 个角点获得 K 的估计值。重要的是,我们之所以能够这样做,是因为我们知道平台是方形的。为了更深入地了解基于平面的校准,我建议阅读张的论文。如果您遇到困难,我可以在几分钟内自己完成并发送 K 矩阵。
最后一点,此方法的一个细微变化是使用原始图像进行校准(假设您仍然拥有原始图像)。原因是H 会扭曲I2,使其纵横比不接近1,主点不在图像中心附近。如果您使用原始图像进行校准(我们称矩阵为 K1),那么您将使用 K = H K1.