OpenCV實(shí)現(xiàn)透視變換的示例代碼
1. 引言
今天我們將焦點(diǎn)聚焦在我在圖像處理中最喜歡的話題之一——透視變換。使用該技術(shù),可以靈活方便的實(shí)現(xiàn)各種各樣好玩的特效。
閑話少說,我們直接開始吧!
2. 單應(yīng)矩陣
我們首先展開對單應(yīng)矩陣的深入研究。作為圖像處理的基本工具,它在捕捉圖像中的幾何變換方面發(fā)揮著至關(guān)重要的作用。更具體地說,它是實(shí)現(xiàn)透視變換的秘密武器。
單應(yīng)矩陣被定義為圖像的兩個(gè)平面投影之間的映射。它由齊次坐標(biāo)空間中的3x3變換矩陣表示。這些變換可以是旋轉(zhuǎn)、平移、縮放等操作的組合。
我們用示意圖總結(jié)如下:

3. 舉個(gè)栗子
雖然上圖簡明地定義了常見的轉(zhuǎn)換,但是如果我們將其應(yīng)用到輸入和輸出為圖像操作會怎樣?根據(jù)變換,我們需要幾個(gè)點(diǎn)來計(jì)算單應(yīng)矩陣。讓我們來做吧!像往常一樣,讓我們首先導(dǎo)入必要的庫,如下:
# Import libraries from skimage.io import imread, imshow import matplotlib.pyplot as plt import numpy as np from skimage import transform
接著導(dǎo)入我們需要的測試圖像,代碼如下:
# Display the original image
image = imread('painting.png')
plt.figure(figsize=(20,20))
plt.imshow(image)
plt.title('Original Image', fontsize=20, weight='bold')
plt.axis('off')
plt.show()結(jié)果如下:

4. 計(jì)算變換矩陣
接著我們想對這幅畫有一個(gè)自上而下的視圖。我們需要計(jì)算單應(yīng)矩陣。我們必須確定這幅畫明確的角點(diǎn)。在這種情況下,我使用畫圖應(yīng)用程序來識別畫的四個(gè)角點(diǎn)坐標(biāo):
# Source points
src = np.array([879, 625, # top left
431, 2466, # bottom left
3251, 61, # top right
3416, 2767]).reshape((4, 2)) # bottom right為了執(zhí)行單應(yīng)性變換,我們需要一組與源點(diǎn)相對應(yīng)的目標(biāo)點(diǎn)。這些目標(biāo)點(diǎn)表示我們希望源點(diǎn)在輸出圖像中的位置。對于自上而下的視圖,這里我們引用源點(diǎn)的最小值和最大值x和y:
# Destination points
dst = np.array([
[np.min(src[:, 0]), np.min(src[:, 1])], # top left
[np.min(src[:, 0]), np.max(src[:, 1])], # bottom left
[np.max(src[:, 0]), np.min(src[:, 1])], # top right
[np.max(src[:, 0]), np.max(src[:, 1])], # bottom right
])接著我們用以下代碼計(jì)算單應(yīng)矩陣,如下:
tform = transform.estimate_transform('projective', src, dst)5. 透視變換
經(jīng)過上述處理,我們有了執(zhí)行透視變換所需要的單應(yīng)性矩陣,接著我們來執(zhí)行對應(yīng)的透視變換,如下:
tf_img = transform.warp(image, tform.inverse)
fig, ax = plt.subplots(figsize=(20,20))
ax.imshow(tf_img)
_ = ax.set_title('projective transformation')得到結(jié)果如下:

6. 美化顯示效果
觀察上圖,考慮到圖像外圍添加了白色像素,輸出看起來很奇怪,我們可以編輯出代碼來裁剪這些奇怪的墻和額外的像素:
# Load the image
image = imread('painting.png')
# Source points
src = np.array([879, 625, # top left
431, 2466, # bottom left
3251, 61, # top right
3416, 2767]).reshape((4, 2)) # bottom right
# Estimate the width and height from the source points
width = np.max(src[:, 0]) - np.min(src[:, 0])
height = np.max(src[:, 1]) - np.min(src[:, 1])
# Destination points (forming a box shape)
dst = np.array([
[0, 0],
[0, height],
[width, 0],
[width, height]
])
# Compute the projective transform
tform = transform.estimate_transform('projective', src, dst)
# Apply the transformation
warped_image = transform.warp(image, tform.inverse, output_shape=(height, width))
# Convert the warped image to uint8
warped_image_uint8 = (warped_image * 255).astype(np.uint8)
# Display the transformed and cropped image
plt.figure(figsize=(20,20))
plt.imshow(warped_image_uint8)
plt.title('Transformed and Cropped Image', fontsize=20, weight='bold')
plt.axis('off')
plt.show()最終的顯示效果如下:

7. 總結(jié)
經(jīng)過我們一步一步的優(yōu)化,我們最終得到了,一幅美麗而干凈的自上而下的油畫。一般來說,一旦我們有了單應(yīng)矩陣,我們也可以用它來變換一幅圖像,使其與另一幅圖像的視角對齊。這對于圖像拼接等應(yīng)用非常有用!
到此這篇關(guān)于OpenCV實(shí)現(xiàn)透視變換的示例代碼的文章就介紹到這了,更多相關(guān)OpenCV 透視變換內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python計(jì)算兩個(gè)矩形重合面積代碼實(shí)例
這篇文章主要介紹了Python 實(shí)現(xiàn)兩個(gè)矩形重合面積代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
基于OpenCV(python)的實(shí)現(xiàn)文本分割之垂直投影法
本文主要介紹了基于OpenCV(python)的實(shí)現(xiàn)文本分割之垂直投影法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08

