OpenCV實現(xiàn)常見的四種圖像幾何變換
準備圖片
選擇一張shape為(500,500,3)的梵高的《星月夜》以便示例。
1. 縮放 cv2.resize()方法
cv2.resize(src, dsize, dst=None, fx=None, fy=None, interpolation=None)
src 原圖(的數(shù)組)
dsize: 輸出圖像的大小 格式:(a,b)。
設(shè)定dsize后就無需再設(shè)置fx和fy
fx 可選參數(shù) 水平方向縮放比
fy 可選參數(shù) 垂直方向縮放比
fx和fy不同于dsize,fx和fy是各是一個比值,如設(shè)為2,則表示放大2倍,設(shè)為1/2則表示縮小到原來的1/2
import cv2 img = cv2.imread("The_Starry_Night.jpg") dst1 = cv2.resize(img, (200, 200)) dst2 = cv2.resize(img, (900, 900)) cv2.imshow("img", img) cv2.imshow("dst1", dst1) cv2.imshow("dst2", dst2) cv2.waitKey() cv2.destroyAllWindows()
執(zhí)行結(jié)果如圖所示,相比原圖,圖像得到了指定大小的縮小與放大。
使用fx和fy參數(shù),則需要手動把dsize設(shè)為None。
import cv2 img = cv2.imread("The_Starry_Night.jpg") # 將寬縮小到原來的1/3、高縮小到原來的1/2 dst3 = cv2.resize(img, None, fx=1 / 3, fy=1 / 2) # 將寬高擴大2倍 dst4 = cv2.resize(img, None, fx=2, fy=2) cv2.imshow("img", img) cv2.imshow("dst3", dst3) cv2.imshow("dst4", dst4) cv2.waitKey() cv2.destroyAllWindows()
結(jié)果呈現(xiàn):
2. 翻轉(zhuǎn) cv2.flip()方法
flip(src, flipCode, dst=None)
src 圖像(數(shù)組)
flipCode 翻轉(zhuǎn)代碼??梢允?,正數(shù),負數(shù)。0表示沿X軸(水平方向的軸)翻轉(zhuǎn)。1表示沿Y軸(豎直方向的軸)翻轉(zhuǎn)。
負數(shù)表示同時沿X軸和Y軸翻轉(zhuǎn)。
講原圖經(jīng)過著三種翻轉(zhuǎn)后,與原圖拼在一塊,呈現(xiàn)出了這種奇觀:
import cv2 img = cv2.imread("The_Starry_Night.jpg") dst1 = cv2.flip(img, 0) dst2 = cv2.flip(img, 1) dst3 = cv2.flip(img, -1) cv2.imshow("img", img) cv2.imshow("dst1", dst1) cv2.imshow("dst2", dst2) cv2.imshow("dst3", dst3) cv2.waitKey() cv2.destroyAllWindows()
將翻轉(zhuǎn)結(jié)果放在同一張畫布中
import cv2 import numpy as np img = cv2.imread("The_Starry_Night.jpg") dst1 = cv2.flip(img, 0) dst2 = cv2.flip(img, 1) dst3 = cv2.flip(img, -1) a, b, c = img.shape canvas = np.ones((2 * a, 2 * b, c), np.uint8) * 255 canvas[0:b, 0:a] = img canvas[b:2*b, 0:a] = dst1 canvas[0:b, a:2*a] = dst2 canvas[b:2*b, a:2*a] = dst3 cv2.imshow("pic", canvas) cv2.waitKey() cv2.destroyAllWindows() # 保存圖片 # cv2.imwrite("final_pic", canvas)
結(jié)果呈現(xiàn):
3. 仿射變換 warpAffine()方法
常見的仿射變換有平移,旋轉(zhuǎn)和傾斜變換。
仿射變換使用cv2.warpAffine()方法完成
warpAffine(src, M, dsize, dst=None, flags=None, borderMode=None, borderValue=None)
src 原圖
M 是一個二行三列的矩陣,也稱仿射矩陣。warpAffine方法根據(jù)此矩陣的值來變換像素的位置。
M = [[a, b, c], [d, e, f]],則像素的變換公式為:
X = x × a + y × b + c
Y = x × d + y × e + f
其中x,y指原像素的x、y軸坐標。X,Y指變換后的X,Y坐標。
dsize 輸出圖像的尺寸。(不帶放縮,增大的部分用黑色色素(0)填充)
這三個參數(shù)是常用的參數(shù)。其余參數(shù)建議使用默認值。
flags表示插入方式,borderMode是邊界類型,borderValue表示邊界值(默認0)。dst表示反射變換后輸出的圖像。
3.1 平移
以將《星月夜》向左平移50個像素,向下平移100個像素為例。
則M數(shù)組應(yīng)寫為[[1, 0, 50], [0, 1, 100]]:
import cv2 import numpy as np img = cv2.imread("The_Starry_Night.jpg") rows = len(img) cols = len(img[0]) M = np.float32([[1, 0, 50], [0, 1, 100]]) dst = cv2.warpAffine(img, M, (cols, rows)) cv2.imshow("img", img) cv2.imshow("dst", dst) cv2.waitKey() cv2.destroyAllWindows()
如圖所示,圖像按照我們的預(yù)期成功被平移。
只是這樣得到的圖像有色素損失,我們丟失了超出畫布之外的數(shù)據(jù)。
為了避免損失,可以取設(shè)置dsize參數(shù)來控制輸出圖像的大小。
修改后的代碼如下:
import cv2 import numpy as np img = cv2.imread("The_Starry_Night.jpg") rows = len(img) cols = len(img[0]) M = np.float32([[1, 0, 50], [0, 1, 100]]) dst = cv2.warpAffine(img, M, (cols+200, rows+200)) cv2.imshow("img", img) cv2.imshow("dst", dst) cv2.waitKey() cv2.destroyAllWindows()
優(yōu)化后的程序執(zhí)行效果:
3.2 旋轉(zhuǎn)
旋轉(zhuǎn)也是通過M矩陣來實現(xiàn)的,這個矩陣的運算較復(fù)雜,
OpenCV提供了getRotationMatrix2D()方法來計算旋轉(zhuǎn)操作的M矩陣
getRotationMatrix2D(center, angle, scale)
center 指旋轉(zhuǎn)中心的坐標
angle指旋轉(zhuǎn)的角度
scale值縮放的比例。(旋轉(zhuǎn)過程支持縮放)
import cv2 img = cv2.imread("The_Starry_Night.jpg") rows = len(img) cols = len(img[0]) center = (rows / 2, cols / 2) M = cv2.getRotationMatrix2D(center, 30, 0.8) dst = cv2.warpAffine(img, M, (cols, rows)) cv2.imshow("img", img) cv2.imshow("dst", dst) cv2.waitKey() cv2.destroyAllWindows()
旋轉(zhuǎn)效果如圖所示:
3.3 傾斜
OpenCV需要定位到圖像的三個點的位置來計算傾斜效果,即左上角,右上角和左下角。
圖像的傾斜也是根據(jù)M矩陣實現(xiàn),得出矩陣的運算較復(fù)雜,通過getAffineTransform 方法實現(xiàn)。
語法
getAffineTransform(src, dst)
src是原圖像的左上角,右上角和左下角三個點的坐標。三維數(shù)組格式,形如[[a, b], [c, d], [e, f]]。
dst是傾斜后這三個點預(yù)期的坐標。格式同上。
要保持左上,右下,左下三個點的順序不能亂。
以將《星月夜》保持左下角和右上角坐標不變,左上角((0,0)處)向右移動150個像素長度。
代碼如下:
import cv2 import numpy as np img = cv2.imread("The_Starry_Night.jpg") rows = len(img) cols = len(img[0]) p1 = np.array([[0, 0], [cols - 1, 0], [0, rows - 1]], dtype=np.float32) p2 = np.array([[150, 0], [cols - 1, 0], [0, rows - 1]], dtype=np.float32) M = cv2.getAffineTransform(p1, p2) dst = cv2.warpAffine(img, M, (cols, rows)) cv2.imshow('img', img) cv2.imshow('dst', dst) cv2.waitKey() cv2.destroyAllWindows()
程序執(zhí)行效果如下:
4. 透視
透視的實現(xiàn)使用的是warpPerspective()方法,而不再是用于平移、旋轉(zhuǎn)、傾斜的warpAffine()方法。
使用warpPerspective()方法也需要通過M矩陣來計算透視效果,計算透視的M矩陣可以使用getPerspectiveTransform()方法。
getPerspectiveTransform(src, dst, solveMethod=None)
該方法常用的參數(shù)有兩個,分別為原圖的四個點的坐標(scr) 和 透視后四個點的坐標(dst)。Opcv需要通過定位圖像的這四個點來計算透視效果。四個點依次為左上,右上,左下,右下。
坐標格式為二維數(shù)組格式,形如[[a, b],[c, d],[e, f],[g, h]]。
示例代碼如下:
import cv2 import numpy as np img = cv2.imread("The_Starry_Night.jpg") rows = len(img) cols = len(img[0]) # 原圖的四點坐標 p1 = np.zeros((4, 2), np.float32) p1[0] = [0, 0] p1[1] = [cols - 1, 0] p1[2] = [0, rows - 1] p1[3] = [cols - 1, rows - 1] # 透視后的四點坐標 p2 = np.zeros((4, 2), np.float32) p2[0] = [150, 0] p2[1] = [cols - 150, 0] p2[2] = [0, rows - 1] # 不變 p2[3] = [cols - 1, rows - 1] # 不變 M = cv2.getPerspectiveTransform(p1, p2) dst = cv2.warpPerspective(img, M, (cols, rows)) cv2.imshow('The_Starry_Night', img) cv2.imshow('The_Starry_Night2', dst) cv2.waitKey() cv2.destroyAllWindows()
展示原圖和透視后的圖像效果:
到此這篇關(guān)于OpenCV實現(xiàn)常見的四種圖像幾何變換的文章就介紹到這了,更多相關(guān)OpenCV圖像幾何變換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何在Win10系統(tǒng)使用Python3連接Hive
這篇文章主要介紹了如何在Win10系統(tǒng)使用Python3連接Hive,幫助大家更好的利用python讀取數(shù)據(jù),進行探索、分析和挖掘工作。感興趣的朋友可以了解下2020-10-10基于Python實現(xiàn)RLE格式分割標注文件的格式轉(zhuǎn)換
本文將以Airbus Ship Detection Challenge為例,為大家詳細講解Python實現(xiàn)RLE格式分割標注文件格式轉(zhuǎn)換的方法,感興趣的可以了解一下2022-08-08深入探究python中Pandas庫處理缺失數(shù)據(jù)和數(shù)據(jù)聚合
在本篇文章中,我們將深入探討Pandas庫中兩個重要的數(shù)據(jù)處理功能:處理缺失數(shù)據(jù)和數(shù)據(jù)聚合,文中有詳細的代碼示例,對我們的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-07-07在Python的while循環(huán)中使用else以及循環(huán)嵌套的用法
這篇文章主要介紹了在Python的while循環(huán)中使用else以及循環(huán)嵌套的用法,是Python入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-10-10Django rest framework工具包簡單用法示例
這篇文章主要介紹了Django rest framework工具包簡單用法,結(jié)合匿名訪問控制的具體實例分析了Django rest framework工具包的注冊、路由設(shè)置、視圖、權(quán)限控制、配置等相關(guān)操作技巧,需要的朋友可以參考下2018-07-07