1.前言

影像處理通常分為空間域處理與頻率域處理。傅立葉轉換是頻率域影像處理中常見的方法之一。關於傅立葉轉換的原理介紹,請參考<從傅立葉轉換到訊號處理>。

透過傅立葉轉換,我們可以依據需求,設計高通濾波器或低通濾波器來進行影像處理。


1.1.高通濾波器與低通濾波器

  • 低通濾波器,讓低頻訊號通過,會使影像模糊。
  • 高通濾波器,讓高頻訊號通過,會增強影像中尖銳的細節,導致影像對比度降低。


何謂低頻訊號呢? 何謂高頻訊號呢?

  • 低頻訊號對應影像內變化緩慢的灰階分量。以草原中獅子圖為例,低頻訊號對應顏色趨於一致的草原。
  • 高頻訊號對應影像內變化越來越快的灰階分量。以草原中獅子圖為例,高頻訊號對應獅子的邊緣等資訊。


2.程式實作

實現傅立葉轉換的模組,numpy和opencv都有內建相應模組,可彈性使用。

相關用法與結果呈現如下:

2.1. numpy傅立葉轉換

<來源:Greatway9999>


import numpy as np

import cv2

import matplotlib.pyplot as plt


img = cv2.imread('Lenna.jpg', cv2.IMREAD_GRAYSCALE)


#傅立葉轉換

f = np.fft.fft2(img)

fshift = np.fft.fftshift(f)


magnitude_spectrum = 20*np.log(np.abs(fshift)) #將值轉換成0~255間


#繪圖

plt.subplot(121)

plt.imshow(img, cmap='gray')

plt.title('original')

plt.axis('off')

plt.subplot(122)

plt.imshow(magnitude_spectrum, cmap='gray')

plt.title('result')

plt.axis('off')

plt.show()


2.2.傅立葉逆轉換

<來源:Greatway9999>


import numpy as np

import cv2

import matplotlib.pyplot as plt


img = cv2.imread('Lenna.jpg', cv2.IMREAD_GRAYSCALE)

f = np.fft.fft2(img)

fshift = np.fft.fftshift(f)

ishift = np.fft.ifftshift(fshift)

iimg = np.fft.ifft2(ishift)

iimg = np.abs(iimg)


plt.subplot(121)

plt.imshow(img, cmap='gray')

plt.title('original')

plt.axis('off')

plt.subplot(122)

plt.imshow(iimg, cmap='gray')

plt.title('iimg')

plt.axis('off')

plt.show()


2.3. numpy 高通濾波器實作

<來源:Greatway9999>


import numpy as np

import cv2

import matplotlib.pyplot as plt


img = cv2.imread('Lenna.jpg', cv2.IMREAD_GRAYSCALE)


# Step1 傅立葉轉換

f = np.fft.fft2(img)

fshift = np.fft.fftshift(f)


#Step2 將低頻分量值歸0

rows, cols = img.shape

crow, ccol = int(rows/2), int(cols/2) #找影像中心

fshift[crow-30:crow+30, ccol-30:ccol+30] = 0 #將低頻分量值歸0


# Step3 逆傅立葉轉換

ishift = np.fft.ifftshift(fshift)

iimg = np.fft.ifft2(ishift)

iimg = np.abs(iimg)


plt.subplot(121)

plt.imshow(img, cmap='gray')

plt.title('original')

plt.axis('off')

plt.subplot(122)

plt.imshow(iimg, cmap='gray')

plt.title('iimg')

plt.axis('off')

plt.show()


2.4.OpenCV的傅立葉轉換

<來源:Greatway9999>


# 重點:將影像轉換成 np.float32格式

import numpy as np

import cv2

import matplotlib.pyplot as plt


img = cv2.imread('Lenna.jpg', cv2.IMREAD_GRAYSCALE)


f = np.fft.fft2(img)

fshift = np.fft.fftshift(f)


dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT)

dftshift = np.fft.fftshift(dft)

result = 20*np.log(cv2.magnitude(dftshift[:,:,0], dftshift[:,:,1]))


plt.subplot(121)

plt.imshow(img, cmap='gray')

plt.title('original')

plt.axis('off')

plt.subplot(122)

plt.imshow(result, cmap='gray')

plt.title('result')

plt.axis('off')

plt.show()


2.5.OpenCV的低通濾波器實作

<來源:Greatway9999>

import numpy as np

import cv2

import matplotlib.pyplot as plt


img = cv2.imread('Lenna.jpg', cv2.IMREAD_GRAYSCALE)

# Step1 傅立葉轉換

dft = cv2.dft(np.float32(img), flags = cv2.DFT_COMPLEX_OUTPUT)

dftshift = np.fft.fftshift(dft)


#Step2 將高頻濾掉,只讓低頻通過。透過遮罩方式進行

rows, cols = img.shape

crow, ccol = int(rows/2), int(cols/2) #找影像中心

mask = np.zeros((rows, cols, 2), np.uint8) #建立遮罩

mask[crow-30:crow+30, ccol-30:ccol+30] = 1 #將指定區域的值設為1

fShift = dftshift * mask #將高頻濾掉,保留低頻


# Step3 逆傅立葉轉換

ishift = np.fft.ifftshift(fShift)

iImg = cv2.idft(ishift)

iImg = cv2.magnitude(iImg[:,:,0], iImg[:,:,1])


plt.subplot(121)

plt.imshow(img, cmap='gray')

plt.title('original')

plt.axis('off')

plt.subplot(122)

plt.imshow(iImg, cmap='gray')

plt.title('iImg')

plt.axis('off')

plt.show()


---

參考資料:


#傅立葉轉換 #逆傅立葉轉換 #高通濾波 #低通濾波

0 留言