【问题标题】:Warping Perspective using arbitary rotation angle使用任意旋转角度的翘曲透视
【发布时间】:2012-10-13 23:11:17
【问题描述】:

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

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

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

校准后我也有失真系数。如何将这些合并到代码中以改善结果?

【问题讨论】:

    标签: image-processing opencv


    【解决方案1】:

    这个答案已经晚了好几年,但在这里......

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


    记住:

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

    然而,

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

    Link to documentation

    要使用这个功能,

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

    注意事项:

    • 注意四个角的顺序。

      • 如果源坐标按顺时针顺序选取,则目标坐标也需要按顺时针顺序选取。
      • 同样,如果使用逆时针顺序,请始终如一地执行。
      • 同样,如果使用 z 顺序(左上、右上、左下、右下),请保持一致。
      • 未能始终如一地对角进行排序将生成一个矩阵,该矩阵会精确地执行点对点对应(从数学上讲),但不会生成可用的输出图像。
    • 可以任意选择目标矩形的纵横比。其实无法推导出物体在世界坐标中的“原始纵横比”,因为“这是2D单应性,不是3D”

    【讨论】:

      【解决方案2】:

      您不需要校准相机或估计相机方向(但是,后者在这种情况下非常容易:只需找到那些正交线束的消失点,然后取它们的叉积即可找到飞机正常,详见 Hartley & Zisserman 的圣经)。

      您唯一需要做的就是估计将棋盘格映射到正方形的单应性,然后将其应用于图像。

      【讨论】:

      • 这就是我想要做的:估计/构建单应性,但它​​不起作用。但我不想使用 findHomography。原因是:1)我已经知道传感器的旋转矩阵,想节省计算时间。 2)我可能很难获得对应的点(而不是我可能有圆圈的矩形)
      【解决方案3】:

      一个问题是,要乘以相机矩阵,您需要一些 z 坐标的概念。在考虑畸变系数之前,您应该首先在给定欧拉角的情况下获得基本的图像变形。查看this 答案以获得更详细的解释,并尝试复制我的结果。将图像沿 z 轴移动然后用相机矩阵投影的想法可能会令人困惑,如果其中任何部分没有意义,请告诉我。

      【讨论】:

      • Thx,它帮助我更好地理解它,但我仍然没有得到两件事:1)在#2 中是否需要'将图像居中于原点'?原点是指图像的中间? 2) '#4 将图像沿 z 轴向下移动'这是否意味着我们需要从相机到平面的距离?为什么在您的示例中使用“image.rows”作为“z”值?它只是硬编码吗?我还在 StackExchange 上阅读了“逐步相机姿势估计”,但我仍然不明白应该为“Tz”添加什么。我可以澄清我不介意矩形是否会被缩放。我只需要矩形的角度为 90 度
      • @user657429 如果您希望透视效果以图像的中心为中心,则图像需要以世界空间中的 0,0,0 为中心。在 opencv 中,原点从左上角开始。您可以像我一样手动移动它,或者乘以相机矩阵的倒数也可以,并且可能更直观。 Here是另一种解释,是不是让理论更清楚了?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多