《數(shù)字圖像處理-OpenCV/Python》連載(41)圖像的旋轉(zhuǎn)
本書京東優(yōu)惠購書鏈接:https://item.jd.com/14098452.html
本書CSDN獨(dú)家連載專欄:https://blog.csdn.net/youcans/category_12418787.html
第 6 章 圖像的幾何變換
幾何變換分為等距變換、相似變換、仿射變換和投影變換,是指對圖像的位置、大小、形狀和投影進(jìn)行變換,將圖像從原始平面投影到新的視平面。OpenCV圖像的幾何變換,本質(zhì)上是將一個多維數(shù)組通過映射關(guān)系轉(zhuǎn)換為另一個多維數(shù)組。
本章內(nèi)容概要
- 介紹仿射變換,學(xué)習(xí)使用仿射變換矩陣實(shí)現(xiàn)圖像的仿射變換。
- 學(xué)習(xí)使用函數(shù)實(shí)現(xiàn)圖像的平移、縮放、旋轉(zhuǎn)、翻轉(zhuǎn)和斜切。
- 介紹投影變換,學(xué)習(xí)使用投影變換矩陣實(shí)現(xiàn)圖像的投影變換。
- 介紹圖像的重映射,學(xué)習(xí)使用映射函數(shù)實(shí)現(xiàn)圖像的自定義變換和動態(tài)變換。
6.1 圖像的旋轉(zhuǎn)
旋轉(zhuǎn)變換屬于等距變換,變換后圖像的長度和面積不變。
圖像以左上角(0,0)為旋轉(zhuǎn)中心、以旋轉(zhuǎn)角度 θ 順時針旋轉(zhuǎn),可以構(gòu)造旋轉(zhuǎn)變換矩陣 MAR,通過函數(shù) cv.warpAffine 計算旋轉(zhuǎn)變換圖像。
[ x ~ y ~ 1 ] = M A R [ x y 1 ] , M A R = [ c o s θ ? s i n θ 0 s i n θ c o s θ 0 0 0 1 ] \begin{bmatrix} \tilde{x}\\ \tilde{y}\\ 1 \end{bmatrix} = M_{AR} \begin{bmatrix} x\\ y\\ 1 \end{bmatrix} ,\hspace{1em} M_{AR} = \begin{bmatrix} cos \theta &-sin \theta &0\\ sin \theta &cos \theta &0\\ 0 &0 &1 \end{bmatrix} ?x~y~?1? ?=MAR? ?xy1? ?,MAR?= ?cosθsinθ0??sinθcosθ0?001? ?
圖像以任意點(diǎn)(x,y)為旋轉(zhuǎn)中心、以旋轉(zhuǎn)角度 順時針旋轉(zhuǎn),可以先將原點(diǎn)平移到旋轉(zhuǎn)中心(x,y),再對原點(diǎn)進(jìn)行旋轉(zhuǎn)處理,最后反向平移回坐標(biāo)原點(diǎn)。
OpenCV中的函數(shù)cv.getRotationMatrix2D可以計算以任意點(diǎn)為中心的旋轉(zhuǎn)變換矩陣。
函數(shù)原型
cv.getRotationMatrix2D(center, angle, scale) → M
函數(shù)cv.getRotationMatrix2D能根據(jù)旋轉(zhuǎn)中心和旋轉(zhuǎn)角度計算旋轉(zhuǎn)變換矩陣M:
M = [ α β ( 1 ? α ) x ? β y ? β α β x + ( 1 ? α ) y ] M = \begin{bmatrix} \alpha & \beta &(1-\alpha)x-\beta y\\ -\beta &\alpha &\beta x +(1-\alpha) y \end{bmatrix} M=[α?β?βα?(1?α)x?βyβx+(1?α)y?]
參數(shù)說明
- center:旋轉(zhuǎn)中心坐標(biāo),格式為元組(x,y)。
- angle:旋轉(zhuǎn)角度,角度制,以逆時針方向旋轉(zhuǎn)。
- scale:縮放系數(shù),是浮點(diǎn)型數(shù)據(jù)。
- M:旋轉(zhuǎn)變換矩陣,是形狀為(2,3)、類型為np.float32的Numpy數(shù)組。
注意問題
-
(1)函數(shù)可以直接獲取以任意點(diǎn)為中心的旋轉(zhuǎn)變換矩陣,不需要額外進(jìn)行平移變換。
-
(2) 如果旋轉(zhuǎn)圖像的尺寸與原始圖像的尺寸相同,則四角的像素會被切除(見圖6-3(2))。為了保留原始圖像的內(nèi)容,需要在旋轉(zhuǎn)的同時對圖像進(jìn)行縮放,或?qū)⑿D(zhuǎn)圖像的尺寸調(diào)整為:
W
r
o
t
=
w
c
o
s
θ
+
h
s
i
n
θ
H
r
o
t
=
h
c
o
s
θ
+
w
s
i
n
θ
W_{rot} = w cos \theta+ h sin \theta \\ H_{rot} = h cos \theta+ w sin \theta
Wrot?=wcosθ+hsinθHrot?=hcosθ+wsinθ
式中,w、h分別為原始圖像的寬度與高度; 、 分別為旋轉(zhuǎn)圖像的寬度與高度。
- (3) 縮放系數(shù)scale在旋轉(zhuǎn)的同時能進(jìn)行縮放,但水平、垂直方向必須使用相同的縮放比例。
函數(shù)cv.rotate用于直角旋轉(zhuǎn),旋轉(zhuǎn)角度為90度、180度或270度。該方法通過矩陣轉(zhuǎn)置實(shí)現(xiàn),運(yùn)行速度極快。
函數(shù)原型
cv.rotate(src, rotateCode[, dst]) → dst
參數(shù)說明
- src:輸入圖像,是Numpy數(shù)組。
- dst:輸出圖像,類型與src相同,圖像尺寸由旋轉(zhuǎn)角度確定。
- rotateCode:旋轉(zhuǎn)標(biāo)志符。
- ROTATE_90_CLOCKWISE:順時針旋轉(zhuǎn)90度。
- ROTATE_180:順時針旋轉(zhuǎn)180度。
- ROTATE_90_COUNTERCLOCKWISE:順時針旋轉(zhuǎn)270度。
注意問題
旋轉(zhuǎn)角度為180度時,輸出圖像的尺寸與輸入圖像的尺寸相同;旋轉(zhuǎn)角度為90度或180度時,輸出圖像的高度和寬度分別等于輸入圖像的寬度和高度。
【例程0603】圖像的旋轉(zhuǎn)
本例程介紹以原點(diǎn)為旋轉(zhuǎn)中心、以任意點(diǎn)為旋轉(zhuǎn)中心旋轉(zhuǎn)圖像,以及圖像的直角旋轉(zhuǎn)。
# 【0603】圖像的旋轉(zhuǎn)
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
if __name__ == '__main__':
img = cv.imread("../images/Fig0301.png") # 讀取彩色圖像(BGR)
height, width = img.shape[:2] # 圖像的高度和寬度
# (1) 以原點(diǎn)為旋轉(zhuǎn)中心
x0, y0 = 0, 0 # 以左上角頂點(diǎn) (0,0) 作為旋轉(zhuǎn)中心
theta, scale = 30, 1.0 # 逆時針旋轉(zhuǎn) 30 度,縮放系數(shù) 1.0
MAR0 = cv.getRotationMatrix2D((x0,y0), theta, scale) # 旋轉(zhuǎn)變換矩陣
imgRot1 = cv.warpAffine(img, MAR0, (width, height))
# (2) 以任意點(diǎn)為旋轉(zhuǎn)中心
x0, y0 = width//2, height//2 # 以圖像中心作為旋轉(zhuǎn)中心
angle = theta * np.pi/180 # 弧度->角度
wRot = int(width * np.cos(angle) + height * np.sin(angle)) # 調(diào)整寬度
hRot = int(height * np.cos(angle) + width * np.sin(angle)) # 調(diào)整高度
scale = width/wRot # 根據(jù) wRot 調(diào)整縮放系數(shù)
MAR1 = cv.getRotationMatrix2D((x0,y0), theta, 1.0) # 逆時針旋轉(zhuǎn) 30 度,縮放系數(shù) 1.0
MAR2 = cv.getRotationMatrix2D((x0,y0), theta, scale) # 逆時針旋轉(zhuǎn) 30 度,縮放比例 scale
imgRot2 = cv.warpAffine(img, MAR1, (height, width), borderValue=(255,255,255)) # 白色填充
imgRot3 = cv.warpAffine(img, MAR2, (height, width)) # 調(diào)整縮放系數(shù),以保留原始圖像的內(nèi)容
print(img.shape, imgRot2.shape, imgRot3.shape, scale)
# (3) 圖像的直角旋轉(zhuǎn)
imgRot90 = cv.rotate(img, cv.ROTATE_90_CLOCKWISE) # 順時針旋轉(zhuǎn) 90度
imgRot180 = cv.rotate(img, cv.ROTATE_180) # 順時針旋轉(zhuǎn) 180度
imgRot270 = cv.rotate(img, cv.ROTATE_90_COUNTERCLOCKWISE) # 順時針旋轉(zhuǎn) 270度
plt.figure(figsize=(9, 6))
plt.subplot(231), plt.title("1.Rotate around the origin"), plt.axis('off')
plt.imshow(cv.cvtColor(imgRot1, cv.COLOR_BGR2RGB))
plt.subplot(232), plt.title("2.Rotate around the center"), plt.axis('off')
plt.imshow(cv.cvtColor(imgRot2, cv.COLOR_BGR2RGB))
plt.subplot(233), plt.title("3.Rotate and resize"), plt.axis('off')
plt.imshow(cv.cvtColor(imgRot3, cv.COLOR_BGR2RGB))
plt.subplot(234), plt.title("4.Rotate 90 degrees"), plt.axis('off')
plt.imshow(cv.cvtColor(imgRot90, cv.COLOR_BGR2RGB))
plt.subplot(235), plt.title("5.Rotate 180 degrees"), plt.axis('off')
plt.imshow(cv.cvtColor(imgRot180, cv.COLOR_BGR2RGB))
plt.subplot(236), plt.title("6.Rotate 270 degrees"), plt.axis('off')
plt.imshow(cv.cvtColor(imgRot270, cv.COLOR_BGR2RGB))
plt.tight_layout()
plt.show()
程序說明:
運(yùn)行結(jié)果,圖像的旋轉(zhuǎn)如圖6-3所示。
(1) 圖6-3(1)~(3)用函數(shù)cv.getRotationMatrix2D計算旋轉(zhuǎn)變換矩陣后,通過函數(shù)cv.warpAffine計算旋轉(zhuǎn)變換圖像。圖6-3(1)以圖像原點(diǎn),即左上角為中心旋轉(zhuǎn),圖6-3(2)和圖6-3(3)圍繞圖像中心點(diǎn)旋轉(zhuǎn)變換。
(2) 圖像尺寸不變,中心旋轉(zhuǎn)后四角像素被切除(見圖6-3(2))。在計算旋轉(zhuǎn)變換矩陣時使用了縮放系數(shù),使旋轉(zhuǎn)圖像保留了原始圖像的內(nèi)容(見圖6-3(3))。
(3) 圖6-3(4)~(6)所示都是直角旋轉(zhuǎn),使用函數(shù)cv.rotate通過矩陣轉(zhuǎn)置實(shí)現(xiàn)。
*圖6-3 圖像的旋轉(zhuǎn)
版權(quán)聲明:
youcans@xupt 原創(chuàng)作品,轉(zhuǎn)載必須標(biāo)注原文鏈接:(https://blog.csdn.net/youcans/article/details/134317103)
Copyright 2023 youcans, XUPT
Crated:2023-11-11文章來源:http://www.zghlxwxcb.cn/news/detail-751393.html
歡迎關(guān)注本書CSDN獨(dú)家連載專欄
《數(shù)字圖像處理-OpenCV/Python》連載: https://blog.csdn.net/youcans/category_12418787.html文章來源地址http://www.zghlxwxcb.cn/news/detail-751393.html
到了這里,關(guān)于《數(shù)字圖像處理-OpenCV/Python》連載(41)圖像的旋轉(zhuǎn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!