傅里葉變換
理論基礎
時間域與頻域相互轉換來看信號
使用Numpy實現傅里葉變換
numpy.fft.fft2
- 實現傅里葉變換
- 返回一個複數數組(complex ndarray)
numpy.fft.fftshift
- 將零頻率分量移到頻譜中心
20*np.log(np.abs(fshift))
- 設置頻譜的範圍
操作小記
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", 0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
result = 20 * np.log(np.abs(fshift))
plt.subplot(121)
plt.imshow(img, cmap='gray')
plt.title('ori')
plt.axis('off')
plt.subplot(122)
plt.imshow(result, cmap='gray')
plt.title('res')
plt.axis('off')
plt.show()
效果
注意:
- 傅里葉得到低頻、高頻信息,針對低頻、高頻處理能夠實現不同的目的
- 傅里葉過程是可逆的,圖像進過傅里葉變換、逆傅里葉變換後,能夠恢復到原始圖像
- 在頻域對圖像進行處理,在頻域的處理會反映在逆變換圖像上
numpy實現逆傅里葉變換
numpy.fft.ifft2
- 實現逆傅里葉變換,返回一個複數數組(complex ndarray)
numpy.fft.ifftshift
fftshift
函數的逆函數
iimg = np.abs(逆傅里葉變換結果)
- 設置值的範圍
操作小記
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", 0)
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('ori'), plt.axis('off')
plt.subplot(122), plt.imshow(iimg, cmap='gray')
plt.title('iimg'), plt.axis('off')
plt.show()
效果
高通濾波演示
低頻、高頻
- 低頻對應圖像內變化緩慢的灰度分量。例如,在一幅大草原的圖像中,低頻對應着廣袤的顏色趨於一致的草原
- 高頻對應圖像內變化越來越快的灰度分量,是由灰度的尖銳過渡造成的。例如,在一幅大草原的圖像中,其中獅子的邊緣等信息
- 衰減高頻而通過低頻,低頻濾波器,將模糊一幅圖像
- 衰減低頻而通過高頻,高通濾波器,將增強尖銳的細節,但是會導致圖像的對比度降低
濾波
- 接受(通過)或者拒絕一定頻率的分量
- 通過低頻的濾波器稱爲低通濾波器
- 通過高頻的濾波器稱爲高通濾波器
頻域濾波
- 修改傅里葉變換以達到特殊目的,然後計算IDFT返回到圖像域
- 特殊目的:圖像增強、圖像去噪、邊緣檢測、特徵提取、壓縮、加密等
操作小記
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", 0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
rows,cols = img.shape
crow,ccol = int(rows/2), int(cols/2)
fshift[crow-30:crow+30, ccol-30:ccol+30] = 0
ishift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ishift)
iimg = np.abs(iimg)
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('img'), plt.axis('off')
plt.subplot(122), plt.imshow(iimg, cmap='gray')
plt.title('iimg'), plt.axis('off')
plt.show()
效果
OpenCV實現傅里葉變換
返回結果=cv2.dft(原始圖像, 轉換標識)
- 返回結果
- 是雙通道的
- 第1個通道是結果的實數部分
- 第2個通道是結果的虛數部分
- 原始圖像
- 輸入圖像是首先轉換成
np.float32
格式 np.float32(img)
- 輸入圖像是首先轉換成
- 轉換標識
flags=cv2.DFT_COMPLEX_OUTPUT
- 輸出一個複數陣列
返回值=cv2.magnitude(參數1, 參數2)
:計算幅值
- 參數1:浮點型X座標值,也就是實部
- 參數2:浮點型Y座標值,也就是虛部
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", 0)
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)
res = 20 * np.log(cv2.magnitude(dftShift[:, :, 0], dftShift[:, :, 1]))
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('img'), plt.axis('off')
plt.subplot(122), plt.imshow(res, cmap='gray')
plt.title('res'), plt.axis('off')
plt.show()
效果
OpenCV實現逆傅里葉變換
返回結果=cv2.idft(原始數據)
- 返回結果:取決於原始數據的類型和大小
- 原始數據:實數或者複數均可
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", 0)
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)
ishift = np.fft.ifftshift(dftShift)
ilmg = cv2.idft(ishift)
ilmg = cv2.magnitude(ilmg[:, :, 0], ilmg[:, :, 1])
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('img'), plt.axis('off')
plt.subplot(122), plt.imshow(ilmg, cmap='gray')
plt.title('inverse'), plt.axis('off')
plt.show()
效果
低通濾波示例
操作小記
import cv2
import numpy as np
import matplotlib.pyplot as plt
img = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", 0)
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)
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
fShift = dftShift*mask
ishift = np.fft.ifftshift(fShift)
ilmg = cv2.idft(ishift)
ilmg = cv2.magnitude(ilmg[:, :, 0], ilmg[:, :, 1])
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('img'), plt.axis('off')
plt.subplot(122), plt.imshow(ilmg, cmap='gray')
plt.title('res'), plt.axis('off')
plt.show()
效果