[OpenCV基礎][Python]warpPerspective透視變換

2024/02/07閱讀時間約 7 分鐘

當我們在拍照時,有時候會期望圖像中物體是呈現我們想要的樣子,就可以利用透視變換的方式,將物體捏造成我們想要的樣子。

當我們拍攝文件或書籍時,如果有角度和距離的變化,文件可能會變形。透視變換可用於校正這種變形,使文件呈現平整的視覺效果。

cv2.warpPerspective 是 OpenCV 中的一個函數,用於進行透視變換(Perspective Transformation)。透視變換是一種將二維圖像進行轉換的方法,通常用於將視角進行調整或者校正,例如在影像處理中對於傾斜的圖像進行矯正

傾斜矯正

傾斜矯正

cv2.warpPerspective 的語法:

cv2.warpPerspective(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])
  • src:要進行透視變換的輸入圖像
  • M透視變換3x3變換矩陣
  • dsize:輸出圖像的大小,以元組(width, height)表示。

進階參數(可選擇不填,則會使用默認)

  • dst:輸出圖像,可選參數,如果未提供,則函數會創建一個與 dsize 相同大小的空白圖像。
  • flags:進行變換時的插值方法:
    cv2.INTER_NEAREST最近鄰插值,使用最近鄰的像素值進行插值,速度最快,但效果可能不夠平滑。
    cv2.INTER_LINEAR雙線性插值,使用相鄰四個像素的加權平均值,效果比最近鄰好一些,但計算成本較高。
    cv2.INTER_CUBIC雙三次插值,使用相鄰的16個像素進行插值,產生更平滑的效果,但計算成本最高。

  • borderMode:用於處理邊界模式:
    cv2.BORDER_CONSTANT常數邊界模式,邊界外的像素使用指定的常數值填充。
    cv2.BORDER_REFLECT反射邊界模式,邊界外的像素是邊界內像素的鏡像反射。
    cv2.BORDER_WRAP循環邊界模式,像素位置溢出時,回到相對應的另一邊。
  • borderMode 設定為 cv2.BORDER_CONSTANT 時:
    可以使用 borderValue 參數指定邊界常數值。這個值通常是一個顏色值,例如白色 (255, 255, 255) 或黑色 (0, 0, 0)

範例

# 指定邊界模式為 cv2.BORDER_CONSTANT,並設定邊界常數值為白色
border_mode = cv2.BORDER_CONSTANT
border_value = (255, 255, 255)

# 應用透視變換,並指定邊界模式和邊界常數值
result = cv2.warpPerspective(img, M, (img.shape[1], img.shape[0]),
borderMode=border_mode, borderValue=border_value)

透視變換的3x3變換矩陣說明:

M = | m11 m12 m13 |

| m21 m22 m23 |

| m31 m32 m33 |

m11m22是水平和垂直縮放因子,m12m21是切變因子,m13m23是平移因子,m31m32 m33 是透視因子。


程式範例

import cv2
import numpy as np

# 讀取輸入圖像
img = cv2.imread('123.JPG')

# 透視變換前的四個點,這些點可以是手動選取或使用檢測算法(例如角點檢測)
src_pts = np.array([[2700, 970], #左上
[6000, 60], #右上
[2600, 1400], #左下
[5500, 3300]], #右下
dtype=np.float32)

# 透視變換後的目標四個點
dst_pts = np.array([[100, 500], #左上
[6000, 500], #右上
[100, 3000], #左下
[6000, 3000]], #右下
dtype=np.float32)

# 計算透視變換矩陣 M
M = cv2.getPerspectiveTransform(src_pts, dst_pts)

# 應用透視變換
result = cv2.warpPerspective(img, M, (img.shape[1], img.shape[0]))

# 顯示原始圖像和變換後的圖像

cv2.imshow('Original Image', img)
cv2.imshow('Perspective Transformed Image', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

透視變換前的四個點

圖片是我大概標示,示意用,差不多位子方便理解而已。

src_pts = np.array([[2700, 970], #左上
[6000, 60], #右上
[2600, 1400], #左下
[5500, 3300]], #右下
dtype=np.float32)
透視前四個點標記位子

透視前四個點標記位子

透視變換後的目標四個點

透視變換後

透視變換後


科普名詞

透視變換:

當我們拍攝一個物體時,它可能因為角度或距離呈現變形,使得物體失真歪斜透視變換就是一種調整這種失真的方法,讓我們可以糾正或校正這些變形,使得圖像看起來更正確,更符合我們期望的形狀

數學表示方法

透視變換(Perspective Transformation)是一種非線性的幾何變換,它可以將一個二維空間中的點映射到另一個二維空間中,同時包含了線性變換(如平移、旋轉、縮放)以及透視變換

透視變換計算方式如下:

透視變換數學式

透視變換數學式

x,y是原始圖像中的座標,x′,y′,w′是變換後的座標,w 是齊次坐標中的權重(通常是1)

當齊次坐標中的 w 不等於 1 時,透視變換就會引入透視效應,從而使被變換的圖形發生變形。這是由於透視變換的特性


總結

更進階的應用是利用其他方式得到變換矩陣 M,來透視變換圖片中的物件。

可以參考我另外一篇文章,也可以利用SIFT偵測特徵點,來取得特徵物件的變換矩陣在矯正其圖像。

[OpenCV應用][Python]利用SIFT得取圖片物件旋轉角度,並旋轉回正常角度

49會員
87內容數
Python程式設計師,不是在學習就是在學習的路上
留言0
查看全部
發表第一個留言支持創作者!