1. 程式人生 > 其它 >7. 影象的幾何變換-cv2.resize()、cv2.warpAffine()、cv2.getRotationMatrix2D()、cv2.getAffineTransform()、透視變換

7. 影象的幾何變換-cv2.resize()、cv2.warpAffine()、cv2.getRotationMatrix2D()、cv2.getAffineTransform()、透視變換

技術標籤:opencvopencv計算機視覺python

1. 改變影象的大小-cv2.resize()

函式原型:cv2.resize(src, dst, Size, fx, fy, interpolation)

引數說明:1. src 輸入圖片 2. dst 輸出圖片 3.size 輸出圖片的大小 4. fx、fy:沿水平軸、垂直軸的縮放因子(寬度、高度) 5.插入方式,預設為INTER_LINEAR.

插入方式interpolation有以下幾種:

INTER_NEAREST

最近鄰插值

INTER_LINEAR

雙線性插值(預設設定)

INTER_AREA

使用畫素區域關係進行重取樣。

INTER_CUBIC

4x4畫素鄰域的雙三次插值

INTER_LANCZOS4

8x8畫素鄰域的Lanczos插值

程式碼如下:

def resize_demo(image):

    print("Origin size:", image.shape)
    # 第一種方法:通過fx,fy縮放因子
    res = cv.resize(image, None, fx=1, fy=3, interpolation=cv.INTER_CUBIC)  # fx寬 fy高
    print("After resize 1 size:", res.shape)
    # 第二種方法:直接設定輸出影象的尺寸,所以不用設定縮放因子
    height,width = image.shape[:2]
    res=cv.resize(image,(2*width,2*height),interpolation=cv.INTER_CUBIC)
    print("After resize 2 size:", res.shape)

    while(1):
        cv.imshow('res',res)
        cv.imshow('img',image)
        if cv.waitKey(1) & 0xFF == 27:
            break

2. 影象的偏移- cv2.warpAffine()

影象的平移也分為兩步:首先定義好影象的平移矩陣,分別指定x方向(寬)和y方向上(高)的平移量tx和ty,平移矩陣(2 X 3)的形式如下:

程式碼如下:

def move_demo(image):
    rows, cols = image.shape[:2]
    M = np.float32([[1, 0, 100], [0, 1, 50]])    # M為平移矩陣,100為寬移動的距離,50為高
    dst = cv.warpAffine(image, M, (cols, rows))  # 仿射變換函式   (cols, rows):平移後圖像的大小
    cv.imshow('image', dst)

3. 影象的旋轉- cv2.getRotationMatrix2D()

這個函式可以在任何位置進行旋轉變換,它的旋轉矩陣為:

這個函式有三個引數:旋轉中心,旋轉角度,旋轉後圖像的縮放比例。

然後再使用函式cv2.warpAffine()利用得到的M對原始影象進行變換即可。

程式碼如下:

def rotation_demo(img):
    rows, cols = img.shape[:2]
    # 將影象相對於中心旋轉90度,而不進行任何縮放。旋轉中心,角度,縮放比率
    M = cv.getRotationMatrix2D((cols / 2, rows / 2), 90, 1)
    dst = cv.warpAffine(img, M, (cols, rows))
    cv.imshow('original', img)
    cv.imshow('result', dst)
    cv.waitKey(0)
    cv.destroyAllWindows()

4. 影象的仿射變換-cv2.getAffineTransform()

仿射變換,又稱仿射對映,是指在幾何中,一個向量空間進行一次線性變換並接上一個平移,變換為另一個向量空間。仿射變換需要一個M矩陣,但是由於仿射變換比較複雜,一般直接找很難找到這個矩陣,opencv提供了根據變換前後三個點的對應關係來自動求解M的函式,這個函式就是cv2.getAffineTransform(),引數如下:

  1. src:原始影象中的三個點的座標
  2. dst:變換後的這三個點對應的座標
  3. M:根據三個對應點求出的仿射變換矩陣

然後再使用函式cv2.warpAffine()利用得到的M對原始影象進行變換即可。

程式碼如下:

def affine_demo(img):

    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')
    plt.show()

5. 透視變換-cv2.getPerspectiveTransform()、cv2.warpPerspective()

透視變換(Perspective Transformation)是將成像投影到一個新的視平面(Viewing Plane),也稱作投影對映(Projective Mapping)。

5.1cv2.getPerspectiveTransform(src, dst)

引數說明:

  • src:源影象中待測矩形的四點座標

  • sdt:目標影象中矩形的四點座標

  • 返回值:由源影象中矩形到目標影象矩形變換的矩陣 ,得到變換矩陣。

5.2cv2.warpPerspective(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)

引數說明:

  • src:輸入影象

  • M:變換矩陣

  • dsize:目標影象shape

  • flags:插值方式,interpolation方法INTER_LINEAR或INTER_NEAREST

  • borderMode:邊界補償方式,BORDER_CONSTANT or BORDER_REPLICATE

  • borderValue:邊界補償大小,常值,預設為0

  • 作用:進行透視變換。

程式碼如下:

def perspective_demo(img):

    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()