14-傅里葉變換的代碼實現


一、numpy實現傅里葉變換和逆傅里葉變換

1.numpy實現傅里葉變換
numpy.fft.fft2
實現傅里葉變換,返回一個復數數組(complex ndarray),也就是頻譜圖像
numpy.fft.fftshift
將零頻率分量移到頻譜中心(將左上角的低頻區域,移到中心位置)

 20*np.log(np.abs(fshift))
設置頻譜的范圍。可以理解為,之前通過傅里葉變換得到復數的數組,是不能通過圖像的方法展示出來的,需要轉換為灰度圖像(映射到[0,255]區間)

需要注意的是
1> 傅里葉得到低頻、高頻信息,針對低頻、高頻處理能夠實現不同的目的
2> 傅里葉過程是可逆的,圖像經過傅里葉變換、逆傅里葉變換后,能夠恢復到原始圖像
3> 在頻域對圖像進行處理,在頻域的處理會反映在逆變換圖像上

# 將繪制的圖顯示在窗口
%matplotlib qt5

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread(r"image\lena.bmp",cv2.IMREAD_GRAYSCALE)

# 傅里葉變換
f = np.fft.fft2(img)
# 移動中心位置
fshift = np.fft.fftshift(f)
# 調整值范圍
result = 20*np.log(np.abs(fshift))

plt.subplot(1,2,1)
plt.imshow(img,cmap=plt.cm.gray)
plt.title("original")
plt.axis("off")

plt.subplot(1,2,2)
plt.imshow(result,cmap=plt.cm.gray)
plt.title("result")
plt.axis("off")

plt.show()

傅里葉變換的頻譜圖像:

 

2.numpy實現逆傅里葉變換
numpy.fft.ifft2
實現逆傅里葉變換,返回一個復數數組(complex ndarray)
numpy.fft.ifftshift
fftshift函數的逆函數,將中心位置的低頻,重新移到左上角
iimg = np.abs(逆傅里葉變化結果)
設置值的范圍,映射到[0,255]區間

# 將繪制的圖顯示在窗口
%matplotlib qt5

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread(r"image\boat.bmp",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(1,2,1)
plt.imshow(img,cmap=plt.cm.gray)
plt.title("original")
plt.axis("off")

plt.subplot(1,2,2)
plt.imshow(iimg,cmap=plt.cm.gray)
plt.title("iimg")
plt.axis("off")

plt.show()

將一副圖像,進行傅里葉變換和逆傅里葉變換后,進行對比(一樣的)

實例:通過numpy實現高通濾波,保留圖像的邊緣信息

獲取圖像的形狀
rows,cols = img.shape
獲取圖像的中心點
crow,ccol = int(rows/2),int(cols/2)
將頻譜圖像的中心區域(低頻區域)設置為0(黑色)
fshift[crow-30:crow+30,ccol-30:ccol+30] = 0

# 將繪制的圖顯示在窗口
%matplotlib qt5

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread(r"image\boat.bmp",cv2.IMREAD_GRAYSCALE)

# 傅里葉變換
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(1,2,1)
plt.imshow(img,cmap=plt.cm.gray)
plt.title("original")
plt.axis("off")

plt.subplot(1,2,2)
plt.imshow(iimg,cmap=plt.cm.gray)
plt.title("iimg")
plt.axis("off")

plt.show()

使用numpy實現高通濾波的實驗結果:

 二、opencv實現傅里葉變換和逆傅里葉變換

1.opencv實現傅里葉變換

返回結果 = cv2.dft(原始圖像,轉換標識)
1> 返回結果:是雙通道的,第一個通道是結果的實數部分,第二個通道是結果的虛數部分
2> 原始圖像:輸入圖像要首先轉換成np.float32(img)格式
3> 轉換標識:flags = cv2.DFT_COMPLEX_OUTPUT,輸出一個復數陣列

numpy.fft.fftshift
將零頻率分量移到頻譜中心(將左上角的低頻區域,移到中心位置)

調整頻譜的范圍,將上面頻譜圖像的復數數組,轉換為可以顯示的灰度圖像(映射到[0,255]區間)
返回值 = 20*np.log(cv2.magnitude(參數1,參數2))
1> 參數1:浮點型X坐標值,也就是實部
2> 參數2:浮點型Y坐標值,也就是虛部

# 將繪制的圖顯示在窗口
%matplotlib qt5

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread(r"image\lena.bmp",cv2.IMREAD_GRAYSCALE)

# 傅里葉變換
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(1,2,1)
plt.imshow(img,cmap=plt.cm.gray)
plt.title("original")
plt.axis("off")

plt.subplot(1,2,2)
plt.imshow(result,cmap=plt.cm.gray)
plt.title("result")
plt.axis("off")

plt.show()

傅里葉變換的頻譜圖像:

2.opencv實現逆傅里葉變換
返回結果 = cv2.idft(原始數據)
1> 返回結果:取決於原始數據的類型和大小
2> 原始數據:實數或者復數均可

numpy.fft.ifftshift
fftshift函數的逆函數,將中心位置的低頻,重新移到左上角

調整頻譜的范圍,映射到[0,255]區間
返回值 = cv2.magnitude(參數1,參數2)
1> 參數1:浮點型X坐標值,也就是實部
2> 參數2:浮點型Y坐標值,也就是虛部

 

# 將繪制的圖顯示在窗口
%matplotlib qt5

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread(r"image\lena.bmp",cv2.IMREAD_GRAYSCALE)

# 傅里葉變換
dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT)
dftShift = np.fft.fftshift(dft)

# 逆傅里葉變換
ishift = np.fft.ifftshift(dftShift)
iimg = cv2.idft(ishift)
iimg = cv2.magnitude(iimg[:,:,0],iimg[:,:,1])

plt.subplot(1,2,1)
plt.imshow(img,cmap=plt.cm.gray)
plt.title("original")
plt.axis("off")

plt.subplot(1,2,2)
plt.imshow(iimg,cmap=plt.cm.gray)
plt.title("inverse")
plt.axis("off")

plt.show()

將一副圖像,進行傅里葉變換和逆傅里葉變換后,進行對比(一樣的)

 實例:通過opencv實現低通濾波,模糊一副圖像

 獲取圖像的形狀
rows,cols = img.shape
獲取圖像的中心點
crow,ccol = int(rows/2),int(cols/2)
生成一個原圖像大小的全零矩陣(黑色)
mask = np.zeros((rows,cols,2),np.uint8),這里的(rows,cols,2)是因為dftShift頻譜圖像的形狀是(rows,cols,2),雙通道的
將全零矩陣(黑色)的中心區域設置為1(白色),也就是mask矩陣
mask[crow-30:crow+30,ccol-30:ccol+30] = 1
頻譜圖像 = 原頻譜圖像 * mask矩陣
fShift = dftShift*mask

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread(r"image\lena.bmp",cv2.IMREAD_GRAYSCALE)

# 傅里葉變換
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-50:crow+50,ccol-50:ccol+50] = 1
fShift = dftShift*mask

# 逆傅里葉變換
ishift = np.fft.ifftshift(fShift)
iimg = cv2.idft(ishift)
iimg = cv2.magnitude(iimg[:,:,0],iimg[:,:,1])

plt.subplot(1,2,1)
plt.imshow(img,cmap=plt.cm.gray)
plt.title("original")
plt.axis("off")

plt.subplot(1,2,2)
plt.imshow(iimg,cmap=plt.cm.gray)
plt.title("inverse")
plt.axis("off")

plt.show()

使用opencv實現高通濾波的實驗結果:

 

拓展:什么什么是低頻、高頻

低頻:
1> 低頻對應圖像內變化緩慢的灰度分量。例如,在一副大草原的圖像中,低頻對應着廣袤的顏色趨於一致的草原
2> 衰減高頻而通過低頻,低通濾波器,將模糊一副圖像
高頻:
1> 高頻對應圖像內變化越來越快的灰度分量,是由灰度的尖銳過度造成的。例如,在一副大草原圖像中,其中獅子的邊緣等信息
2> 衰減低頻而通過高頻,高通濾波器,將增強尖銳的細節,但是會導致圖像的對比圖降低

 

什么是濾波

1> 接受(通過)或拒絕一定頻率的分量
2> 通過低頻的濾波器稱為低通濾波器
3> 通過高頻的濾波器稱為高通濾波器

 

頻域濾波

修改傅里葉變換的低頻或者高頻信息,以達到特殊目的,然后計算IDFT(逆傅里葉變換)返回到圖像域。特殊目的通常是圖像增強、圖像去噪、邊緣檢測、特征提取、壓縮、加密等

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM