使用任意旋转角度的翘曲透视

时间:2012-10-23 22:25:39

标签: image-processing opencv

我有一个从某个角度拍摄的棋盘图像。现在我想扭曲视角,使棋盘图像再次看起来好像是从上面直接拍摄的。

我知道我可以尝试使用' findHomography'匹配点之间,但我想避免它,并使用例如来自移动传感器的旋转数据我自己建立单应矩阵。我校准了相机以获得内在参数。然后让我们说下面的图像是围绕x轴以~60度角拍摄的。我认为我所要做的就是将相机矩阵与旋转矩阵相乘以获得单应矩阵。我尝试使用以下代码,但看起来我没有正确理解某些内容,因为它没有按预期工作(结果图像完全是黑色或白色。

enter image description here

import cv2
import numpy as np
import math 



camera_matrix = np.array([[ 5.7415988502105745e+02, 0., 2.3986181527877352e+02],
                           [0., 5.7473682183375217e+02, 3.1723734404756237e+02], 
                           [0., 0., 1.]])

distortion_coefficients = np.array([ 1.8662919398453856e-01, -7.9649812697463640e-01,
   1.8178068172317731e-03, -2.4296638847737923e-03,
   7.0519002388825025e-01 ])

theta = math.radians(60)

rotx = np.array([[1, 0, 0],
               [0, math.cos(theta), -math.sin(theta)],
               [0, math.sin(theta), math.cos(theta)]])   



homography = np.dot(camera_matrix, rotx)


im = cv2.imread('data/chess1.jpg')
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)

im_warped = cv2.warpPerspective(gray, homography, (480, 640), flags=cv2.WARP_INVERSE_MAP)
cv2.imshow('image', im_warped)
cv2.waitKey()
pass

校准后我也有失真系数。如何将这些内容纳入代码以改善结果?

3 个答案:

答案 0 :(得分:2)

这个答案已经过了好几年了,但现在却是......

(免责声明:我在这个答案中使用的术语可能不准确或不正确。请从其他更可信的来源查看此主题。)


记住:

  • 因为您只有一个图像(视图),所以您只能计算2D单应性(一个2D视图和另一个2D视图之间的透视对应关系),而不是完整的3D单应性。
  • 因此,对于3D单应性(旋转矩阵,平移矩阵,焦距等)的直观理解是 不可用 给您。
  • 我们所说的是,对于2D单应性,你 无法将3x3矩阵分解为 ,就像3D单应性这样的直观组件。
  • 你有一个矩阵 - (这是几个你不知道的矩阵的产物) - 就是这样。

然而,

OpenCV提供了一个getPerspectiveTransform函数,它解决了3x3透视矩阵(使用同质坐标系)在两个平面四边形之间的二维单应性。

Link to documentation

要使用此功能,

  • 找到图像上棋盘的四个角。这些将是您的源坐标。
  • 提供您选择的四个矩形角。这些将是您的目的地坐标。
  • 将源坐标和目标坐标传递到getPerspectiveTransform以生成一个3x3矩阵,该矩阵能够将棋盘扭曲为直立矩形。

要记住的注意事项:

  • 记住四个角落的顺序。

    • 如果按顺时针顺序拾取源坐标,则还需要按顺时针顺序拾取目标。
    • 同样,如果使用逆时针顺序,请一致地执行此操作。
    • 同样,如果使用z顺序(左上角,右上角,左下角,右下角),请一致地执行此操作。
    • 未能一致地对角落进行排序将生成一个矩阵,该矩阵精确地执行点对点对应(数学上讲),但不会生成可用的输出图像。
  • 目标矩形的宽高比可以任意选择。事实上,不可能在世界坐标中推断出对象的“原始宽高比”,因为“这是2D单应性,而不是3D”

答案 1 :(得分:1)

一个问题是,要乘以相机矩阵,您需要一些z坐标的概念。在考虑失真系数之前,应该先考虑Euler角度,然后再进行基本的图像变形。请查看this答案,了解更详细的解释并尝试复制我的结果。将图像向下移动z轴然后用相机矩阵投影的想法可能令人困惑,让我知道它的任何部分是否有意义。

答案 2 :(得分:0)

你不需要校准相机也不需要估计相机的方向(后者,在这种情况下,这将是非常容易的:只需找到那些正交线束的消失点,并采取他们的交叉产品找到垂直于飞机,详见Hartley& Zisserman的圣经)。

您唯一需要做的就是估算将检查器映射到正方形的单应性,然后将其应用于图像。