一、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(逆傅里葉變換)返回到圖像域。特殊目的通常是圖像增強、圖像去噪、邊緣檢測、特征提取、壓縮、加密等