圖像幾何變換
1.圖像仿射變換
圖像仿射變換又稱為圖像仿射映射境钟,是指在幾何中,一個向量空間進行一次線性變換并接上一個平移倔幼,變換為另一個向量空間饲齐。通常圖像的旋轉(zhuǎn)加上拉升就是圖像仿射變換,仿射變換需要一個M矩陣實現(xiàn)腐魂,但是由于仿射變換比較復(fù)雜帐偎,很難找到這個M矩陣.
OpenCV提供了根據(jù)變換前后三個點的對應(yīng)關(guān)系來求解M的函數(shù)
M = cv2.getAffineTransform(pos1,pos2)
- pos1表示變換前的位置
- pos2表示變換后的位置
cv2.warpAffine(src, M, (cols, rows))
- src表示原始圖像
- M表示仿射變換矩陣
- (rows,cols)表示變換后的圖像大小,rows表示行數(shù)蛔屹,cols表示列數(shù)
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 讀取圖片
src = cv2.imread('data/test1.jpg')
# 獲取圖像大小
rows, cols = src.shape[:2]
# 設(shè)置圖像仿射變換矩陣
pos1 = np.float32([[50,50], [200,50], [50,200]])
pos2 = np.float32([[10,100], [200,50], [100,250]])
M = cv2.getAffineTransform(pos1, pos2)
# 圖像仿射變換
result = cv2.warpAffine(src, M, (cols, rows))
# 顯示結(jié)果
titles = ['src', 'result']
images = [src, result]
plt.figure(figsize=(10, 4))
for i in range(2):
plt.subplot(1, 2, i + 1)
plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
2.圖像透視變換
圖像透視變換(Perspective Transformation)的本質(zhì)是將圖像投影到一個新的視平面削樊,同理OpenCV通過函數(shù)cv2.getPerspectiveTransform(pos1,pos2)構(gòu)造矩陣M,其中pos1和pos2分別表示變換前后的4個點對應(yīng)位置兔毒。得到M后在通過函數(shù)cv2.warpPerspective(src,M,(cols,rows))進行透視變換
M = cv2.getPerspectiveTransform(pos1, pos2)
- pos1表示透視變換前的4個點對應(yīng)位置
- pos2表示透視變換后的4個點對應(yīng)位置
cv2.warpPerspective(src,M,(cols,rows))
- src表示原始圖像
- M表示仿射變換矩陣
- (rows,cols)表示變換后的圖像大小漫贞,rows表示行數(shù),cols表示列數(shù)
import cv2
import numpy as np
import matplotlib.pyplot as plt
#讀取圖片
src = cv2.imread('data/test1.jpg')
#獲取圖像大小
rows, cols = src.shape[:2]
#設(shè)置圖像透視變換矩陣
pos1 = np.float32([[114, 82], [287, 156], [8, 322], [216, 333]])
pos2 = np.float32([[0, 0], [188, 0], [0, 262], [188, 262]])
M = cv2.getPerspectiveTransform(pos1, pos2)
#圖像透視變換
result = cv2.warpPerspective(src, M, (190, 272))
#顯示結(jié)果
titles = ['src', 'result']
images = [src, result]
plt.figure(figsize=(10, 4))
for i in range(2):
plt.subplot(1, 2, i + 1)
plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
## 基于圖像透視變換的圖像校正
import cv2
import numpy as np
import matplotlib.pyplot as plt
#讀取圖片
src = cv2.imread('data/test9.jpg')
#獲取圖像大小
rows, cols = src.shape[:2]
#將源圖像高斯模糊
img = cv2.GaussianBlur(src, (3,3), 0)
#進行灰度化處理
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#邊緣檢測(檢測出圖像的邊緣信息)
edges = cv2.Canny(gray,50,250,apertureSize = 3)
#通過霍夫變換得到A4紙邊緣
lines = cv2.HoughLinesP(edges,1,np.pi/180,50,minLineLength=90,maxLineGap=10)
#下面輸出的四個點分別為四個頂點
# for x1,y1,x2,y2 in lines[0]:
# print(x1,y1),(x2,y2)
# for x1,y1,x2,y2 in lines[1]:
# print(x1,y1),(x2,y2)
#繪制邊緣
for x1,y1,x2,y2 in lines[0]:
cv2.line(gray, (x1,y1), (x2,y2), (0,0,255), 1)
#根據(jù)四個頂點設(shè)置圖像透視變換矩陣
pos1 = np.float32([[114, 82], [287, 156], [8, 322], [216, 333]])
pos2 = np.float32([[0, 0], [188, 0], [0, 262], [188, 262]])
M = cv2.getPerspectiveTransform(pos1, pos2)
#圖像透視變換
result = cv2.warpPerspective(src, M, (190, 272))
#顯示結(jié)果
titles = ['src', 'edges', 'result']
images = [src, edges, result]
plt.figure(figsize=(10, 5))
for i in range(3):
plt.subplot(1, 3, i + 1)
plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
# 圖像幾何變換各操作實例
import cv2
import numpy as np
import matplotlib.pyplot as plt
#讀取圖片
img = cv2.imread('data/test3.jpg')
image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
#圖像平移矩陣
M = np.float32([[1, 0, 80], [0, 1, 30]])
rows, cols = image.shape[:2]
img1 = cv2.warpAffine(image, M, (cols, rows))
#圖像縮小
img2 = cv2.resize(image, (200, 100))
#圖像放大
img3 = cv2.resize(image, None, fx=1.1, fy=1.1)
#繞圖像的中心旋轉(zhuǎn)
#源圖像的高育叁、寬 以及通道數(shù)
rows, cols, channel = image.shape
#函數(shù)參數(shù):旋轉(zhuǎn)中心 旋轉(zhuǎn)度數(shù) scale
M = cv2.getRotationMatrix2D((cols / 2, rows / 2), 30, 1)
#函數(shù)參數(shù):原始圖像 旋轉(zhuǎn)參數(shù) 元素圖像寬高
img4 = cv2.warpAffine(image, M, (cols, rows))
#圖像翻轉(zhuǎn)
img5 = cv2.flip(image, 0) #參數(shù)=0以X軸為對稱軸翻轉(zhuǎn)
img6 = cv2.flip(image, 1) #參數(shù)>0以Y軸為對稱軸翻轉(zhuǎn)
#圖像的仿射
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
pts2 = np.float32([[10, 100], [200, 50], [100, 250]])
M = cv2.getAffineTransform(pts1, pts2)
img7 = cv2.warpAffine(image, M, (rows, cols))
#圖像的透射
pts1 = np.float32([[56, 65], [238, 52], [28, 237], [239, 240]])
pts2 = np.float32([[0, 0], [200, 0], [0, 200], [200, 200]])
M = cv2.getPerspectiveTransform(pts1, pts2)
img8 = cv2.warpPerspective(image, M, (200, 200))
#循環(huán)顯示圖形
titles = [
'source', 'shift', 'reduction', 'enlarge', 'rotation', 'flipX', 'flipY',
'affine', 'transmission'
]
images = [image, img1, img2, img3, img4, img5, img6, img7, img8]
plt.figure(figsize=(10,10))
for i in range(9):
plt.subplot(3, 3, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()