s1091444 作業3
同步發布於 https://titaliu1224.github.io/
功課要求
1. 撰寫傅利葉轉換程式 (Forward Fourier Transform and Inverse Fourier Transform) 將一張圖像轉換至頻域
2. 將頻譜大小與相位角度各以灰階256 色圖像方式呈現出
3. 呈現還原後圖像
成果
開發環境
- OS: Windows 10
- Editor: Visual Studio Code
- Language: Python 3.9.16
- OpenCV 4.53
實作
使用的 library 如下:
import cv2
import matplotlib.pyplot as plt
import numpy as np
1/ 讀取圖片並顯示
cv2.imread(file_name, cv2.IMREAD_GRAYSCALE) 會以灰階模式讀入一張圖。
2/ 調整圖像大小
DFT 在某些大小的畫布下可以計算得比較快,所以我們透過在圖片的右方與下方插入白色畫布,拓展他的尺寸。
getOptimalDFTSize() 可以幫我們取得 x 軸和 y 軸所要調整的最佳大小。
使用 np.zeros() 創建一個 dft_M * dft_N 大小的白色畫布,在畫布左上角用 original_img 覆蓋。
3/ 計算 DFT
由於 DFT 結果是複數,包含實部和虛部,所以使用二維 array planes 協助我們儲存。
利用 cv2.dft() 算 DFT 後,再使用 cv2.split() 將實部虛部兩個通道分開。
cv2.magnitude(x, y) 的原理是實部相乘 + 虛部相乘,公式為 $ dst(I) = \sqrt{x(I)^2 + y(I)^2}$ ,再來對它取 log。
# make two channel for dft (real and imaginary)
planes = [dft_A, np.zeros(dft_A.shape, np.float32)]
dft_A = cv2.merge(planes)
cv2.dft(dft_A, dft_A)
cv2.split(dft_A, planes)
#compute the magnitude
magnitude = cv2.magnitude(planes[0], planes[1])
magnitude = np.log(magnitude + 1)
4/ 平移頻譜圖
但如果把四個角的亮部移到中心,我們會更好觀察,所以剛剛那張圖我們這樣切割:
| 0 | 1 |
| 2 | 3 |
若要將亮部移動到中心位置,就必須 0、3 互換, 1、2 互換。
最後用正規化便於我們顯示灰階圖片。
5/ 相位角度圖
相位角度通常用來描述圖片的輪廓與細節,這裡直接使用 cv2.phase() 來提取相角,再用和上一步一樣的方法進行平移。
6/ 還原圖片
最後使用 DFT 得出的 dft_A 來還原圖片,使用 cv2.idft() 做反向的傅立葉轉換, cv2.split() 與 cv2.magnitude() 取得轉換後的影像, normalize 後就能以 unsigned 8 bits 的方式輸出灰階影像。

留言
張貼留言