【问题标题】:Perspective Transform in OPENCV PYTHONOPENCV PYTHON 中的透视变换
【发布时间】:2021-01-05 08:02:25
【问题描述】:

我正在尝试对数独游戏进行透视变换。预期的转变只发生在左侧。请帮我指出我的错误。

输入图像:

预期输出图像:

我得到的输出:

使用 cv2.approxpolydp() 找到的数独谜题的角点如下:

top_left = [71,62]
top_right = [59, 418]
bottom_right = [443, 442]
bottom_left = [438, 29]

输出图像的形状为[300,300]。

对应的输出坐标为:

output_top_left = [0,0]
output_top_right = [0, 299]
output_bottom_right = [299, 299]
output_bottom_left = [299,0]

以下是我用于透视变换的代码:

#corners = [[71,62], [59, 418], [443, 442], [438, 29]]
new = np.float32([[0,0], [0,299], [299,299], [299,0]])
M = cv2.getPerspectiveTransform(np.float32(corners), new)
dst = cv2.warpPerspective(gray, M, (300,300))

生成的变换矩阵为:

[[ 9.84584842e-01  3.31882531e-02 -7.19631955e+01]
 [ 8.23993265e-02  9.16380389e-01 -6.26659363e+01]
 [ 4.58051741e-04  1.45318012e-04  1.00000000e+00]]

【问题讨论】:

    标签: python numpy opencv


    【解决方案1】:

    你的 X,Y 坐标颠倒了。 Python/OpenCV 要求将它们列为 X,Y(即使您将它们定义为 numpy 值)。您必须指定给 getPerspectiveTransform 的数组必须将它们列为 X,Y。

    输入:

    import numpy as np
    import cv2
    
    # read input
    img = cv2.imread("sudoku.jpg")
    
    # specify desired output size 
    width = 350
    height = 350
    
    # specify conjugate x,y coordinates (not y,x)
    input = np.float32([[62,71], [418,59], [442,443], [29,438]])
    output = np.float32([[0,0], [width-1,0], [width-1,height-1], [0,height-1]])
    
    # compute perspective matrix
    matrix = cv2.getPerspectiveTransform(input,output)
    
    print(matrix.shape)
    print(matrix)
    
    # do perspective transformation setting area outside input to black
    imgOutput = cv2.warpPerspective(img, matrix, (width,height), cv2.INTER_LINEAR, borderMode=cv2.BORDER_CONSTANT, borderValue=(0,0,0))
    print(imgOutput.shape)
    
    # save the warped output
    cv2.imwrite("sudoku_warped.jpg", imgOutput)
    
    # show the result
    cv2.imshow("result", imgOutput)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    结果:

    【讨论】:

    • 您好 frmw42,我们可以自动进行透视变换,以便自动检测 X、Y 坐标
    • 抱歉,我不确定我是否理解您的问题。请详细说明。
    • 如果您要问如何获取输入图像的角点,那么最简单的方法是提取轮廓并找到最大矩形的轮廓——数独谜题的轮廓。然后使用 approxPolyDP() 得到一个四边形并使用四边形的 4 个角。另一种方法是使用 SIFT 或 ORB 将拼图注册到另一个已经正面的拼图以找到相应的控制点。见docs.opencv.org/3.4/dc/dc3/tutorial_py_matcher.html
    • 如果我只想变形为目标图像的一小部分(不是矩形,而是由 4 个角定义),该怎么办?我没有看到 warpPerspective 能够接受掩码,或者 ROI 限制只能在那里执行反扭曲。如何解决这个问题?
    • 扭曲整个图像并裁剪。或者使外部透明到输入的大小并扭曲它。
    【解决方案2】:

    你应该注意:

    1. 坐标反转:宽度、高度
    2. 目标已缩放: 第一名比例:宽/高 第二名比例:高/宽
    3. 点坐标的顺序无关紧要,但源点和目标点应该相互对应。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-24
      • 1970-01-01
      • 2011-08-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多