圖像幾何變換
圖像縮放
圖像縮放隻是調整圖像的大小,為此, OpenCV 為我們提供了一個函數 cv.resize() ,原函數如下:
resize(src, dsize, dst=None, fx=None, fy=None, interpolation=None)
src 表示的是輸入圖像,而 dsize 代表的是輸出圖像的大小,如果為 0 ,則:
dsize=Size(round(fxsrc.cols),round(fysrc.rows))
dsize 和 fx 、 fy 不能同時為 0 。
fx 、fy 是沿 x 軸和 y 軸的縮放系數,預設取 0 時,算法如下:
fx=(double)dsize.width/src.cols
fy=(double)dsize.height/src.rows
最後一個參數 interpolation 表示插值方式:
INTER_NEAREST – 最近鄰插值
INTER_LINEAR – 線性插值(預設)
INTER_AREA – 區域插值
INTER_CUBIC – 三次樣條插值
INTER_LANCZOS4 – Lanczos插值
示例:
import cv2 as cv
#讀取圖檔
src = cv.imread('data.jpg')
print(src.shape)
#圖像縮放
result = cv.resize(src, (300, 150))
print(result.shape)
#顯示圖像
cv.imshow("src", src)
cv.imshow("result", result)
#等待顯示
cv.waitKey()
cv.destroyAllWindows()
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0gTMx81dsQWZ4lmZf1GLlpXazVmcvwFciV2dsQXYtJ3bm9CX9s2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xCMy81dvRWYoNHLwEzX5xCMx8FesU2cfdGLwMzX0xiRGZkRGZ0Xy9GbvNGLpZTY1EmMZVDUSFTU4VFRR9Fd4VGdsYTMfVmepNHLrJXYtJXZ0F2dvwVZnFWbp1zczV2YvJHctM3cv1Ce-cmbw5CMwEDM0IzYjRTNhNjYyQjYyYzX0MDO1YTMzIzLcZDMyIDMy8CXn9Gbi9CXzV2Zh1WavwVbvNmLvR3YxUjLyM3Lc9CX6MHc0RHaiojIsJye.png)
需要注意的是,這裡的 (300, 150) 設定的是 dsize 的列數為 300 ,行數為 150 。
同理,我們可以通過設定一個比例進行縮放,可以是等比例縮放,也可以是不等比例縮放,下面是等比例縮放的示例:
import cv2 as cv
# 設定比例
scale = 0.5
#讀取圖檔
src = cv.imread('data.jpg')
rows, cols = src.shape[:2]
#圖像縮放
result = cv.resize(src, ((int(cols * scale), int(rows * scale))))
print(result.shape)
#顯示圖像
cv.imshow("src", src)
cv.imshow("result", result)
#等待顯示
cv.waitKey()
cv.destroyAllWindows()
除了可通過設定 dszie 對圖像進行縮放,我們還可以通過設定 fx 和 fy 對圖像進行縮放:
import cv2 as cv
#讀取圖檔
src = cv.imread('data.jpg')
print(src.shape)
#圖像縮放
result = cv.resize(src, None, fx=0.5, fy=0.5)
print(result.shape)
#顯示圖像
cv.imshow("src", src)
cv.imshow("result", result)
#等待顯示
cv.waitKey()
cv.destroyAllWindows()
圖像平移
圖像平移是通過仿射函數 warpAffine() 來實作的,原函數如下:
warpAffine(src, M, dsize, dst=None, flags=None,borderMode=None, borderValue=None)
在圖像平移中我們會用到前三個參數:
- 需要變換的原始圖像
- 移動矩陣M
- 變換的圖像大小(如果這個大小不和原始圖像大小相同,那麼函數會自動通過插值來調整像素間的關系)。
圖像的平移是沿着 x 方向移動 tx 距離, y 方向移動 ty 距離,那麼需要構造移動矩陣:
這裡不妨各位建立一些矩陣來乘以這個M看看😂。
import cv2 as cv
import numpy as np
#讀取圖檔
src = cv.imread('data.jpg')
rows, cols = src.shape[:2]
# 定義移動距離
tx = 50
ty = 100
# 生成 M 矩陣
affine = np.float32([[1, 0, tx], [0, 1, ty]])
dst = cv.warpAffine(src, affine, (cols, rows))
# 顯示圖像
cv.imshow('src', src)
cv.imshow("dst", dst)
# 等待顯示
cv.waitKey(0)
cv.destroyAllWindows()
圖像旋轉
圖像旋轉主要調用 getRotationMatrix2D() 函數和 warpAffine() 函數實作,繞圖像的某一個中心點旋轉,具體如下:
- M = cv2.getRotationMatrix2D((cols/2, rows/2), 30, 1)
參數分别為:旋轉中心、旋轉度數、scale
- rotated = cv2.warpAffine(src, M, (cols, rows))
參數分别為:原始圖像、旋轉參數、原始圖像寬高
圖像旋轉:設( x0 , y0 )是旋轉後的坐标,( x , y )是旋轉前的坐标,( m , n )是旋轉中心, a 是旋轉的角度(順時針),( left , top )是旋轉後圖像的左上角坐标,則公式如下:
python具體實作如下:
import cv2 as cv
#讀取圖檔
src = cv.imread('data.jpg')
# 原圖的高、寬
rows, cols = src.shape[:2]
# 繞圖像的中心旋轉
# 參數:旋轉中心 旋轉度數 scale
M = cv.getRotationMatrix2D((cols/2, rows/2), 90, 1)
#
dst = cv.warpAffine(src, M, (cols, rows))
# 顯示圖像
cv.imshow("src", src)
cv.imshow("dst", dst)
# 等待顯示
cv.waitKey()
cv.destroyAllWindows()
圖像翻轉
圖像翻轉在 OpenCV 中調用函數 flip() 實作,原函數如下:
flip(src, flipCode, dst=None)
- src:原始圖像。
- flipCode:翻轉方向,如果 flipCode 為 0 ,則以 X 軸為對稱軸翻轉,如果 fliipCode >0 則以 Y 軸為對稱軸翻轉,如果 flipCode < 0 則在 X 軸、 Y 軸方向同時翻轉。
import cv2 as cv
import matplotlib.pyplot as plt
# 讀取圖檔 由 GBR 轉 RGB
img = cv.imread('data.jpg')
src = cv.cvtColor(img, cv.COLOR_BGR2RGB)
# 圖像翻轉
img1 = cv.flip(src, 0)
img2 = cv.flip(src, 1)
img3 = cv.flip(src, -1)
# plt 顯示圖形
titles = ['Source', 'Ima1', 'Ima2', 'Ima3']
images = [src, img1, img2, img3]
for i in range(4):
plt.subplot(2, 2, i + 1)
plt.imshow(images[i])
plt.title(titles[i])
plt.xticks([])
plt.yticks([])
plt.show()