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 的方式輸出灰階影像。

留言

這個網誌中的熱門文章

rzwang Homework #1

s1093350 Homework #2

s1091537 Homework #1