在OpenCV中我們經常會用到圖像的縮放,旋轉以及平移,比如有的時候我們想對一類圖片進行操作,這個時候我們就需要對這一類的圖片進行尺寸統一,在以后深度學習的學習中,我們也會發現,對於數據集的訓練,它們的數據集樣本通常都是尺寸統一的。
縮放
在OpenCV中,使用函數cv2.resize()實現對圖像的縮放 語法格式為:
dst = cv2.resize( src, dsize[ ,fx[, fy[ ,interpolation]]])
(1) src:原圖片
(2)dsize:縮放圖片尺寸,如果dsize=0,默認計算方式如下dsize=Size(round(fx∗src.cols),round(fy∗src.rows))
(3)fx fy和dsize不能同時為0 fx,fy分別是在x,y軸上的縮放系數,默認取0時,fx=(double)dsize.width/src.cols ,fy=(double)dsize.height/src.cols,默認參數為0可以不寫如里面
(4)interpolation :差值方式使用默認即可 默認的是INTER_LINEAR - a bilinear interpolation (used by default)現行差值:
我們習慣的坐標表示 是 先 x 橫坐標,再 y 縱坐標。在圖像處理中,這種慣性思維經常情況下是錯誤的。
因為在計算機中,圖像是以矩陣的形式保存的,先行后列。所以,一張 寬×高×顏色通道=480×256×3 的圖片會保存在一個 256×480×3 的三維張量中。圖像處理時也是按照這種思想進行計算的(其中就包括 OpenCV 下的圖像處理),即 高×寬×顏色通道。
但是問題來了,cv2.resize這個API卻是個小例外。因為它的參數輸入卻是 寬×高×顏色通道。
我們來看代碼:
import cv2 pic = cv2.imread("cat.jpg") cv2.imshow("org",pic) pic = cv2.resize(pic, (400, 400), interpolation=cv2.INTER_CUBIC) cv2.imshow('res', pic) cv2.waitKey(0) cv2.destroyAllWindows()
先看原圖效果:
再看縮放之后的效果:
我們發現,用這種方法縮小之后的寬高比跟原圖並非一樣,現在我們可以進行代碼的改進:
import cv2 pic = cv2.imread("cat.jpg") cv2.imshow("org",pic) pic = cv2.resize(pic, (0, 0), fx=0.5, fy=0.5, interpolation=cv2.INTER_NEAREST) cv2.imshow('res', pic) cv2.waitKey(0) cv2.destroyAllWindows()
我們直接來看縮放之后的圖像:
在這里,如果我們不直接指定縮放后大小,則通過fx和fy直接指定縮放比例,0.5則長寬都為原來一半。
旋轉
OpenCV中對圖像的旋轉主要是先通過getRotationMatrix2D函數得到圖像的旋轉矩陣,然后再通過仿射變換函數warpAffine得到旋轉后的圖像。
我們看一下函數:
cv2.getRotationMatrix2D(center, angle, scale)
· center 旋轉中心點 (cx, cy) 你可以隨意指定
· angle 旋轉的角度 單位是角度 逆時針方向為正方向 , 角度為正值代表逆時針。
· scale 縮放倍數. 值等於1.0代表尺寸不變
該函數返回的就是仿射變換矩陣M,之后我們將這個仿射變換的矩陣傳入到下一個函數:
cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) → dst
src - 輸入圖像。
M - 變換矩陣。
dsize - 輸出圖像的大小。
flags - 插值方法的組合(int 類型!)
borderMode - 邊界像素模式(int 類型!)
borderValue - 邊界填充值; 默認情況下,它為0。
現在我們來講述一下圖像旋轉的原理:
我們根據公式:
可以得出:
所以對應的變換矩陣為:
我們來看代碼:
import cv2 img = cv2.imread("cat.jpg") rows,cols = img.shape[:2] M = cv2.getRotationMatrix2D((cols/2,rows/2),90,1) dst = cv2.warpAffine(img,M,(cols,rows)) cv2.imshow('res', dst) cv2.waitKey(0) cv2.destroyAllWindows()
旋轉之后的效果:
圖像平移
圖像的平移實際上就是矩陣的移動,它是最簡單的一種空間變換,其表達式為:
其中(b0,b1) 是偏移量。
舉個例子,如果是向右平移10個像素, 向下平移30個像素的話, 那么變換矩陣M:
我們來看源碼:
import cv2 import numpy as np img = cv2.imread('cat.jpg') height,width,channel = img.shape # 聲明變換矩陣 向右平移10個像素, 向下平移30個像素 M = np.float32([[1, 0, 10], [0, 1, 30]]) # 進行2D 仿射變換 shifted = cv2.warpAffine(img, M, (width, height)) cv2.imshow('res', shifted) cv2.waitKey(0) cv2.destroyAllWindows()
效果演示:
如若需要修改平移的方位,只需要改動矩陣的值就可以。