---
# System prepended metadata

title: 透視變形校正 Perspective Distortion Correction

---

# 透視變形校正 Perspective Distortion Correction
## 前言
這是中興大學資工碩士課程－影像處理的第一個作業。我個人不太喜歡這個教授的教學方式。

這裡的實作就是參考 [Jason Chen's Blog](https://jason-chen-1992.weebly.com/home/-perspective-distortion-correction) 作法，寫成 Python 版本。
他比較厲害，用 C++ 寫的，我菜雞只會用套件解方程式。

作業的目標：將變形的圖片轉成正面，就是將圖片中的四邊形指定區塊，變形成長方形狀(正面)的圖片。
## 內容

![](https://i.imgur.com/G7mjGkx.jpg)

轉換過後的圖片。

![](https://i.imgur.com/2yTw8X2.jpg)

參考網址中的定義：
$$
x_p = ax + by + cxy + d \\
y_p = ex + fy + gxy + h
$$


其中 $(height, width) = (y, x)$，$(y_p, x_p)$ 表示四邊形的四個點座標， $(y, x)$ 表示對應的長方形的點座標。因為有四個點座標，可以列出各四組方程式，可以解出係數。

化為矩陣形式 $Ax = b$ ：
$$
Ax = b \rightarrow
\begin{bmatrix}
x_1 & y_1 & x_1*y_1 & 1 & 0 & 0 & 0 & 0  \\
x_2 & y_2 & x_2*y_2 & 1 & 0 & 0 & 0 & 0  \\
x_3 & y_3 & x_3*y_3 & 1 & 0 & 0 & 0 & 0  \\
x_4 & y_4 & x_4*y_4 & 1 & 0 & 0 & 0 & 0  \\
0 & 0 & 0 & 0 & x_1 & y_1 & x_1*y_1 & 1 \\
0 & 0 & 0 & 0 & x_2 & y_2 & x_2*y_2 & 1 \\
0 & 0 & 0 & 0 & x_3 & y_3 & x_3*y_3 & 1 \\
0 & 0 & 0 & 0 & x_4 & y_4 & x_4*y_4 & 1 \\
\end{bmatrix}
%
\begin{bmatrix}
a \\
b \\
c \\ 
d \\
e \\
f \\
g \\ 
h \\
\end{bmatrix}
{=}
\begin{bmatrix}
x_{p1} \\
x_{p2} \\
x_{p3} \\
x_{p4} \\
y_{p1} \\
y_{p2} \\
y_{p3} \\
y_{p4} \\
\end{bmatrix}
$$
- $A$ 為**從正方形轉換至四邊形的座標轉換矩陣**，裡面的變數填入正方形點座標。
$x_1$ 表示正方形左上座標 $x$ 數值，$x_{p1}$ 表示對應的左上座標的 $x$ 數值，剩餘編號自行類推。
- $x$ 為想要解出的係數
- $b$ 為四邊形的座標

## 實作過程
1. 對圖片四邊形區塊找座標位置，可以使用 https://yangcha.github.io/iview/iview.html
2. 實際物品測量比例，口罩比例為 (height, width) = (19, 34)。上圖中，輸出後的圖片調整為(190, 340)
3. 建立 $A$, $b$ 矩陣
4. 使用 numpy 套件計算 $x$，程式碼為 ```x = np.linalg.solve(A, b)```
5. $x$ 為求得的係數
6. 使用 opencv 讀取目標檔案，使用 $x$ 係數計算轉換後位置
7. 輸出檔案

不要搞錯 (height, width) = (y, x) 的定義，很快就可以寫好了，就這麼簡單。

## 心得
numpy 是怎麼實作解 $Ax = b$ 的？線性代數有教但是程式碼怎麼做的就不知道了。