[Python影象處理] 六.影象縮放、影象旋轉、影象翻轉與影象平移

Eastmount發表於2018-09-06

該系列文章是講解Python OpenCV影象處理知識,前期主要講解影象入門、OpenCV基礎用法,中期講解影象處理的各種演算法,包括影象銳化運算元、影象增強技術、影象分割等,後期結合深度學習研究影象識別、影象分類應用。希望文章對您有所幫助,如果有不足之處,還請海涵~

同時推薦作者的C++影象系列知識:
[數字影象處理] 一.MFC詳解顯示BMP格式圖片
[數字影象處理] 二.MFC單文件分割視窗顯示圖片
[數字影象處理] 三.MFC實現影象灰度、取樣和量化功能詳解
[數字影象處理] 四.MFC對話方塊繪製灰度直方圖
[數字影象處理] 五.MFC影象點運算之灰度線性變化、灰度非線性變化、閾值化和均衡化處理詳解
[數字影象處理] 六.MFC空間幾何變換之影象平移、映象、旋轉、縮放詳解
[數字影象處理] 七.MFC影象增強之影象普通平滑、高斯平滑、Laplacian、Sobel、Prewitt銳化詳解

前文參考:
[Python影象處理] 一.影象處理基礎知識及OpenCV入門函式
[Python影象處理] 二.OpenCV+Numpy庫讀取與修改畫素
[Python影象處理] 三.獲取影象屬性、興趣ROI區域及通道處理
[Python影象處理] 四.影象平滑之均值濾波、方框濾波、高斯濾波及中值濾波
[Python影象處理] 五.影象融合、加法運算及影象型別轉換

本篇文章主要講解Python呼叫OpenCV實現影象位移操作、旋轉和翻轉效果,包括四部分知識:影象縮放、影象旋轉、影象翻轉、影象平移。全文均是基礎知識,希望對您有所幫助。
1.影象縮放
2.影象旋轉
3.影象翻轉
4.影象平移

PS:文章參考自己以前系列影象處理文章及OpenCV庫函式,同時部分參考網易雲視訊,推薦大家去學習。同時,本篇文章涉及到《計算機圖形學》基礎知識,請大家下來補充。
推薦原理文章:OpenCV2:影象的幾何變換,平移、映象、縮放、旋轉

PSS:2019年1~2月作者參加了CSDN2018年部落格評選,希望您能投出寶貴的一票。我是59號,Eastmount,楊秀璋。投票地址:https://bss.csdn.net/m/topic/blog_star2018/index

[Python影象處理] 六.影象縮放、影象旋轉、影象翻轉與影象平移
五年來寫了314篇部落格,12個專欄,是真的熱愛分享,熱愛CSDN這個平臺,也想幫助更多的人,專欄包括Python、資料探勘、網路爬蟲、影象處理、C#、Android等。現在也當了兩年老師,更是覺得有義務教好每一個學生,讓貴州學子好好寫點程式碼,學點技術,"師者,傳到授業解惑也",提前祝大家新年快樂。2019我們攜手共進,為愛而生。

一.影象縮放

影象縮放主要呼叫resize()函式實現,具體如下:
result = cv2.resize(src, dsize[, result[. fx[, fy[, interpolation]]]])
其中src表示原始影象,dsize表示縮放大小,fx和fy也可以表示縮放大小倍數,他們兩個(dsize或fx\fy)設定一個即可實現影象縮放。例如:

  1. result = cv2.resize(src, (160,160))
  2. result = cv2.resize(src, None, fx=0.5, fy=0.5)

影象縮放:設(x0, y0)是縮放後的座標,(x, y)是縮放前的座標,sx、sy為縮放因子,則公式如下:
(1)[x0y01]=[xy1][sx000sy0001] \left[ \begin{matrix} x_0 & y_0 & 1 \end{matrix} \right] =\left[ \begin{matrix} x & y & 1 \end{matrix} \right] \left[ \begin{matrix} sx & 0 & 0 \\ 0 & sy & 0 \\ 0 & 0 & 1 \end{matrix} \right] \tag{1}

程式碼示例如下所示:

#encoding:utf-8
import cv2  
import numpy as np  
 
#讀取圖片
src = cv2.imread('test.jpg')

#影象縮放
result = cv2.resize(src, (200,100))
print result.shape

#顯示影象
cv2.imshow("src", src)
cv2.imshow("result", result)

#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()

輸出結果如下圖所示,影象縮小為(200,100)畫素。

[Python影象處理] 六.影象縮放、影象旋轉、影象翻轉與影象平移

需要注意的是,程式碼中 cv2.resize(src, (200,100)) 設定的dsize是列數為200,行數為100。
同樣,可以獲取原始影象畫素再乘以縮放係數進行影象變換,程式碼如下所示。

#encoding:utf-8
import cv2  
import numpy as np  
 
#讀取圖片
src = cv2.imread('test.jpg')
rows, cols = src.shape[:2]
print rows, cols

#影象縮放 dsize(列,行)
result = cv2.resize(src, (int(cols*0.6), int(rows*1.2)))

#顯示影象
cv2.imshow("src", src)
cv2.imshow("result", result)

#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()

輸出結果如下圖所示:

[Python影象處理] 六.影象縮放、影象旋轉、影象翻轉與影象平移

最後講解(fx,fy)縮放倍數的方法對影象進行放大或縮小。

#encoding:utf-8
import cv2  
import numpy as np  
 
#讀取圖片
src = cv2.imread('test.jpg')
rows, cols = src.shape[:2]
print rows, cols

#影象縮放
result = cv2.resize(src, None, fx=0.3, fy=0.3)

#顯示影象
cv2.imshow("src", src)
cv2.imshow("result", result)

#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()

最後輸出的結果如下圖所示,這是按例比0.3*0.3縮小的。

[Python影象處理] 六.影象縮放、影象旋轉、影象翻轉與影象平移


二、影象旋轉

影象旋轉主要呼叫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)是旋轉後影象的左上角座標,則公式如下:
(1)[x0y01]=[xy1][100010mn1][cosasina0sinacosa0001][100010lefttop1] \left[ \begin{matrix} x_0 & y_0 & 1 \end{matrix} \right] = \left[ \begin{matrix} x & y & 1 \end{matrix} \right] \left[ \begin{matrix} 1 & 0 & 0 \\ 0 & -1 & 0 \\ -m & n & 1 \end{matrix} \right] \left[ \begin{matrix} cosa & -sina & 0 \\ sina & cosa & 0 \\ 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} 1 & 0 & 0 \\ 0 & -1 & 0 \\ left & top & 1 \end{matrix} \right] \tag{1}

程式碼如下所示:

#encoding:utf-8
import cv2  
import numpy as np  
 
#讀取圖片
src = cv2.imread('test.jpg')

#原圖的高、寬 以及通道數
rows, cols, channel = src.shape

#繞影象的中心旋轉
#引數:旋轉中心 旋轉度數 scale
M = cv2.getRotationMatrix2D((cols/2, rows/2), 30, 1)
#引數:原始影象 旋轉引數 元素影象寬高
rotated = cv2.warpAffine(src, M, (cols, rows))

#顯示影象
cv2.imshow("src", src)
cv2.imshow("rotated", rotated)

#等待顯示
cv2.waitKey(0)
cv2.destroyAllWindows()

輸出結果如下圖所示:

[Python影象處理] 六.影象縮放、影象旋轉、影象翻轉與影象平移

如果設定-90度,則核心程式碼和影象如下所示。
M = cv2.getRotationMatrix2D((cols/2, rows/2), -90, 1)
rotated = cv2.warpAffine(src, M, (cols, rows))

[Python影象處理] 六.影象縮放、影象旋轉、影象翻轉與影象平移


三、影象翻轉

影象翻轉在OpenCV中呼叫函式flip()實現,原型如下:
dst = cv2.flip(src, flipCode)
其中src表示原始影象,flipCode表示翻轉方向,如果flipCode為0,則以X軸為對稱軸翻轉,如果fliipCode>0則以Y軸為對稱軸翻轉,如果flipCode<0則在X軸、Y軸方向同時翻轉。

程式碼如下所示:

#encoding:utf-8
import cv2  
import numpy as np
import matplotlib.pyplot as plt
 
#讀取圖片
img = cv2.imread('test.jpg')
src = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)

#影象翻轉
#0以X軸為對稱軸翻轉 >0以Y軸為對稱軸翻轉 <0X軸Y軸翻轉
img1 = cv2.flip(src, 0)
img2 = cv2.flip(src, 1)
img3 = cv2.flip(src, -1)

#顯示圖形
titles = ['Source', 'Image1', 'Image2', 'Image3']  
images = [src, img1, img2, img3]  
for i in xrange(4):  
   plt.subplot(2,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()  

輸出結果如下圖所示:

[Python影象處理] 六.影象縮放、影象旋轉、影象翻轉與影象平移


四、影象平移

影象平移:設(x0, y0)是縮放後的座標,(x, y)是縮放前的座標,dx、dy為偏移量,則公式如下:
(3)[x0y01]=[xy1][100010dxdy1] \left[ \begin{matrix} x_0 &amp; y_0 &amp; 1 \end{matrix} \right] =\left[ \begin{matrix} x &amp; y &amp; 1 \end{matrix} \right] \left[ \begin{matrix} 1 &amp; 0 &amp; 0 \\ 0 &amp; 1 &amp; 0 \\ dx &amp; dy &amp; 1 \end{matrix} \right] \tag{3}

影象平移首先定義平移矩陣M,再呼叫warpAffine()函式實現平移,核心函式如下:
M = np.float32([[1, 0, x], [0, 1, y]])
shifted = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))

完整程式碼如下所示:

#encoding:utf-8
import cv2  
import numpy as np
import matplotlib.pyplot as plt
 
#讀取圖片
img = cv2.imread('test.jpg')
image = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)

#影象平移 下、上、右、左平移
M = np.float32([[1, 0, 0], [0, 1, 100]])
img1 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))

M = np.float32([[1, 0, 0], [0, 1, -100]])
img2 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))

M = np.float32([[1, 0, 100], [0, 1, 0]])
img3 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))

M = np.float32([[1, 0, -100], [0, 1, 0]])
img4 = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))

#顯示圖形
titles = [ 'Image1', 'Image2', 'Image3', 'Image4']  
images = [img1, img2, img3, img4]  
for i in xrange(4):  
   plt.subplot(2,2,i+1), plt.imshow(images[i], 'gray')  
   plt.title(titles[i])  
   plt.xticks([]),plt.yticks([])  
plt.show()  

輸出結果如下圖所示:

[Python影象處理] 六.影象縮放、影象旋轉、影象翻轉與影象平移

三尺講臺,三寸舌,
三千桃李,三杆筆。
再累再苦,站在講臺前就是最美的自己,幾個月的煩惱和憂愁都已消失,真的好享受這種狀態,彷彿散著光芒,終於給低年級的同學上課了越早培養程式設計興趣越好,恨不能傾囊相授。
即使當一輩子的教書匠,平平淡淡也喜歡,而且總感覺給學生講課遠不是課酬和職稱所能比擬,這就是所謂的事業,所謂的愛好。
希望文章對大家有所幫助,如果有錯誤或不足之處,還請海涵。 準備出去休回家了,好好享受最美時光。
(By:Eastmount 2018-09-06 早10點 https://blog.csdn.net/Eastmount/)

相關文章