zoukankan      html  css  js  c++  java
  • OpenCV-Python 图像的几何变换 | 十四

    目标

    • 学习将不同的几何变换应用到图像上,如平移、旋转、仿射变换等。
    • 你会看到这些函数: cv.getPerspectiveTransform

    变换

    OpenCV提供了两个转换函数cv.warpAffinecv.warpPerspective,您可以使用它们进行各种转换。cv.warpAffine采用2x3转换矩阵,而cv.warpPerspective采用3x3转换矩阵作为输入。

    缩放

    缩放只是调整图像的大小。为此,OpenCV带有一个函数cv.resize()。图像的大小可以手动指定,也可以指定缩放比例。也可使用不同的插值方法。首选的插值方法是cv.INTER_AREA用于缩小,cv.INTER_CUBIC(慢)和cv.INTER_LINEAR用于缩放。默认情况下,出于所有调整大小的目的,使用的插值方法为cv.INTER_LINEAR。您可以使用以下方法调整输入图像的大小:

    import numpy as np
    import cv2 as cv
    img = cv.imread('messi5.jpg')
    res = cv.resize(img,None,fx=2, fy=2, interpolation = cv.INTER_CUBIC)
    #或者
    height, width = img.shape[:2]
    res = cv.resize(img,(2*width, 2*height), interpolation = cv.INTER_CUBIC)
    

    平移

    平移是物体位置的移动。如果您知道在(x,y)方向上的位移,则将其设为(txt_x,tyt_y),你可以创建转换矩阵Mmathbf{M},如下所示:

    M=[10tx01ty] M = egin{bmatrix} 1 & 0 & t_x \ 0 & 1 & t_y end{bmatrix}

    您可以将其放入np.float32类型的Numpy数组中,并将其传递给cv.warpAffine函数。参见下面偏移为(100, 50)的示例:

    import numpy as np
    import cv2 as cv
    img = cv.imread('messi5.jpg',0)
    rows,cols = img.shape
    M = np.float32([[1,0,100],[0,1,50]])
    dst = cv.warpAffine(img,M,(cols,rows))
    cv.imshow('img',dst)
    cv.waitKey(0)
    cv.destroyAllWindows()
    

    警告

    cv.warpAffine函数的第三个参数是输出图像的大小,其形式应为(width,height)。记住width =列数,height =行数。

    你将看到下面的结果:

    旋转

    图像旋转角度为θθ是通过以下形式的变换矩阵实现的:

    M=[cosθsinθsinθcosθ] M = egin{bmatrix} cos heta & -sin heta \ sin heta & cos heta end{bmatrix}

    但是OpenCV提供了可缩放的旋转以及可调整的旋转中心,因此您可以在自己喜欢的任何位置旋转。修改后的变换矩阵为

    [αβ(1α)center.xβcenter.yβαβcenter.x(1α)center.y] egin{bmatrix} alpha & eta & (1- alpha ) cdot center.x - eta cdot center.y \ - eta & alpha & eta cdot center.x (1- alpha ) cdot center.y end{bmatrix}

    其中:

    α=scalecosθ,β=scalesinθ egin{array}{l} alpha = scale cdot cos heta , \ eta = scale cdot sin heta end{array}

    为了找到此转换矩阵,OpenCV提供了一个函数cv.getRotationMatrix2D。请检查以下示例,该示例将图像相对于中心旋转90度而没有任何缩放比例。

    img = cv.imread('messi5.jpg',0)
    rows,cols = img.shape
    # cols-1 和 rows-1 是坐标限制
    M = cv.getRotationMatrix2D(((cols-1)/2.0,(rows-1)/2.0),90,1)
    dst = cv.warpAffine(img,M,(cols,rows))
    

    查看结果:

    仿射变换

    在仿射变换中,原始图像中的所有平行线在输出图像中仍将平行。为了找到变换矩阵,我们需要输入图像中的三个点及其在输出图像中的对应位置。然后cv.getAffineTransform将创建一个2x3矩阵,该矩阵将传递给cv.warpAffine

    查看以下示例,并查看我选择的点(以绿色标记):

    img = cv.imread('drawing.png')
    rows,cols,ch = img.shape
    pts1 = np.float32([[50,50],[200,50],[50,200]])
    pts2 = np.float32([[10,100],[200,50],[100,250]])
    M = cv.getAffineTransform(pts1,pts2)
    dst = cv.warpAffine(img,M,(cols,rows))
    plt.subplot(121),plt.imshow(img),plt.title('Input')
    plt.subplot(122),plt.imshow(dst),plt.title('Output')
    

    查看结果:

    透视变换

    对于透视变换,您需要3x3变换矩阵。即使在转换后,直线也将保持直线。要找到此变换矩阵,您需要在输入图像上有4个点,在输出图像上需要相应的点。在这四个点中,其中三个不应共线。然后可以通过函数cv.getPerspectiveTransform找到变换矩阵。然后将cv.warpPerspective应用于此3x3转换矩阵。

    请参见下面的代码:

    img = cv.imread('sudoku.png')
    rows,cols,ch = img.shape
    pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
    pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
    M = cv.getPerspectiveTransform(pts1,pts2)
    dst = cv.warpPerspective(img,M,(300,300))
    plt.subplot(121),plt.imshow(img),plt.title('Input')
    plt.subplot(122),plt.imshow(dst),plt.title('Output')
    plt.show()
    

    结果:

    其他资源

    1. “Computer Vision: Algorithms and Applications”, Richard Szeliski

    欢迎关注磐创博客资源汇总站:
    http://docs.panchuang.net/

    欢迎关注PyTorch官方中文教程站:
    http://pytorch.panchuang.net/

    OpenCV中文官方文档:
    http://woshicver.com/

  • 相关阅读:
    day15
    day13
    day12
    使用modelsim直接仿真IP(FIFO)
    整理:FPGA选型
    Quartus 中调用modelsim的流程及*.vt或*.vht自动生成
    quartus ip核破解
    LDO ,开关电源DC-DC的优缺点
    硬件工程师面试经历2015---笔试篇
    出色的硬件工程师必备的几项“硬”实力
  • 原文地址:https://www.cnblogs.com/panchuangai/p/12567917.html
Copyright © 2011-2022 走看看