opencv-python-學習筆記九(圖像幾何轉換)


opencv提供了2個轉換函數,可以對圖像進行任意轉換。

cv.warpAffine和cv.warpPerspective.第一種采取2*3的矩陣作為輸入。第二種采取3*3的矩陣作為輸入。

1.縮放

函數:

cv.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]])

參數:

src:輸入圖像

dsize:目標尺寸,整形,非0

dst:目標圖像,大小為dsize,或由src.size()計算而來

fx:水平軸縮放比例,非0

fy:垂直軸縮放比例,非0

interpolation:插值算法,分為以下幾種

INTER_NEAREST 
Python: cv.INTER_NEAREST

nearest neighbor interpolation最鄰近插值

INTER_LINEAR 
Python: cv.INTER_LINEAR

bilinear interpolation雙線性插值

INTER_CUBIC 
Python: cv.INTER_CUBIC

bicubic interpolation雙三次插值

INTER_AREA 
Python: cv.INTER_AREA

resampling using pixel area relation. It may be a preferred method for image decimation, as it gives moire'-free results. But when the image is zoomed, it is similar to the INTER_NEAREST method.基於局部像素的重采樣

INTER_LANCZOS4 
Python: cv.INTER_LANCZOS4

Lanczos interpolation over 8x8 neighborhood.基於8x8像素鄰域的Lanczos插值

INTER_LINEAR_EXACT 
Python: cv.INTER_LINEAR_EXACT

Bit exact bilinear interpolation.位精確雙線性插值

INTER_MAX 
Python: cv.INTER_MAX

mask for interpolation codes.插補碼掩碼

WARP_FILL_OUTLIERS 
Python: cv.WARP_FILL_OUTLIERS

flag, fills all of the destination image pixels. If some of them correspond to outliers in the source image, they are set to zero

WARP_INVERSE_MAP 
Python: cv.WARP_INVERSE_MAP

flag, inverse transformation

For example, linearPolar or logPolar transforms:

  • flag is not set: dst(ρ,ϕ)=src(x,y)
  • flag is set: dst(x,y)=src(ρ,ϕ)

舉例

import numpy as np
import cv2 as cv


src = cv.imread('4.jpg')
# method 1
res1 = cv.resize(src, None, fx=1.2, fy=1.2, interpolation=cv.INTER_CUBIC)
# method 2 直接設置輸出尺寸
height, width = src.shape[:2]  # 獲得原尺寸
res2 = cv.resize(src, (int(0.5*width), int(0.5*height)),interpolation=cv.INTER_CUBIC)
while(1):
    cv.imshow("src", src)
    cv.imshow("res1", res1)
    cv.imshow("res2", res2)
    if cv.waitKey(1) & 0xFF == 27:
        break
cv.destroyAllWindows()

 

平移

平移是物體的移動,如果知道物體平移的坐標(tx,ty),可以創建如下變換矩陣

將其放入類型為np.float32的數組中,將M矩陣賦值給 cv.warpAffine() 函數。即可實現平移

函數

dst=cv.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])

參數:

src 輸入圖像
dst 與src同類型的輸出圖像
M 2×3 的變換矩陣
dsize 輸出圖像尺寸大小
flags combination of interpolation methods (see InterpolationFlags) and the optional flag WARP_INVERSE_MAP that means that M is the inverse transformation ( dstsrc ).插值矩陣,上一章的表。
borderMode 邊界像素模式,默認為BORDER_CONSTANT ,邊界按常數填充
borderValue 邊界填充值; 默認為0,所以默認情況下填充為黑色

特別注意:dsize參數是指輸出圖像的寬高,即對應圖像的列,行。

舉例

import numpy as np
import cv2 as cv


img = cv.imread('4.jpg', 0)
rows, cols = img.shape
M = np.float32([[1, 0, 300], [0, 1, 50]])
dst
= cv.warpAffine(img, M, (cols, rows)) cv.imshow('img', dst) cv.waitKey(0) cv.destroyAllWindows()

旋轉

平移和旋轉都是仿射變換的特例,所用函數都是cv2.warpAffine,只是轉換矩陣M有所不同。

圖像旋轉θ度是由變換矩陣  M 得到的

 

但是opencv改進了這個矩陣,如下圖。使得提供了縮放旋轉與可調的旋轉中心。

     

上述矩陣表示繞 center.x,center.y 旋轉 θ度

 

 函數:

  retval=cv.getRotationMatrix2D(center, angle, scale)獲取變換矩陣M

 參數:

center 旋轉中心
angle Rotation angle in degrees. Positive values mean counter-clockwise rotation (the coordinate origin is assumed to be the top-left corner).旋轉角度,角度為正則表示逆時針旋轉
scale 旋轉后的縮放系數

舉例:

import numpy as np
import cv2 as cv


src = cv.imread('4.jpg', 0)
rows, cols = src.shape
# 旋轉中心  旋轉角度  縮放系數
M = cv.getRotationMatrix2D(((cols-1) / 2.0,(rows-1)/2.0), 90,1)
# 原圖像 變換矩陣 輸出圖像尺寸中心
dst = cv.warpAffine(src, M, (cols, rows))

while(1):
    cv.imshow('src', src)
    cv.imshow('dst', dst)
    if cv.waitKey(1) & 0xFF == 27:
        break
cv.destroyAllWindows()

 

仿射變換

在仿射變換中,原圖像中的所有平行線在輸出圖像中仍然是平行的,直線仍然是直線,為了找到變換矩陣,我們需要從輸入圖像中選取三個點,以及它們在輸出圖像中的對應位置。利用 cv.getAffineTransform創建一個2*3 的變換矩陣,賦值給cv.warpAffine

函數

retval=cv.getAffineTransform(src, dst),獲取仿射矩陣M

參數:

src Coordinates of triangle vertices in the source image.原圖中3個點所組成的矩陣,數據類型為np.float32
dst Coordinates of the corresponding triangle vertices in the destination image.目標圖中對應的3個點所組成的矩陣,數據類型為np.float32                                                         

舉例

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt


img = cv.imread('4.jpg')
rows, cols, ch = img.shape
#原圖3個點的矩陣
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])

#輸出圖3個點的矩陣
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()

 

透視變換

透視變換。需要一個3*3的變換矩陣,直線在變換之后仍然是直線,但不能保證平行。為了找到這個變換矩陣,我們需要輸入圖像的4個點和對應的輸出圖像的點。在4個點中,其中的任意三個點不能連成直線,然后利用 cv.getPerspectiveTransform函數求出變換矩陣最后3*3的變換矩陣作為函數 cv.warpPerspective 的輸入,進行變換

 函數:

retval=cv.getPerspectiveTransform(src, dst[, solveMethod])獲取轉換矩陣M

參數:

src 原圖像四邊形頂點坐標,數據類型為np.float32                                                                                                       
dst 目標圖像對應四邊形頂點坐標,數據類型為np.float32
solveMethod DecompTypes

dst=cv.warpPerspective(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])

參數:

src 輸入圖像
dst 和src具有相同類型具有dsize大小的輸出圖像
M 3×3 變換矩陣
dsize 輸出圖像大小
flags 插值方法,見頁首                                                                                                    
borderMode pixel extrapolation method (BORDER_CONSTANT or BORDER_REPLICATE).邊界像素模式,默認為BORDER_CONSTANT
borderValue 邊界填充值; 默認為0,所以默認情況下填充為黑色

舉例:

import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt


img = cv.imread('4.jpg')
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()

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM