基於Python實現圖像的傅裡葉變換

前言

首先是本文總體代碼,改一下圖像的讀取路徑就可以運行瞭,但我還是建議大傢先看後面的步驟一行行敲代碼,這樣效果更好:

"""
Author:XiaoMa
date:2021/11/7
"""
import cv2
import matplotlib.pyplot as plt
import numpy as np
 
#讀取圖像信息
from numpy.fft import ifftshift
 
img0 = cv2.imread("E:\From Zhihu\For the desk\cvthirteen2.jpg")
img1 = cv2.resize(img0, dsize = None, fx = 0.5, fy = 0.5)
img2 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)               #轉化為灰度圖
h, w = img1.shape[:2]
print(h, w)
cv2.namedWindow("W0")
cv2.imshow("W0", img2)
cv2.waitKey(delay = 0)
#將圖像轉化到頻域內並繪制頻譜圖
##numpy實現
plt.rcParams['font.family'] = 'SimHei'       #將全局中文字體改為黑體
f = np.fft.fft2(img2)
fshift = np.fft.fftshift(f)   #將0頻率分量移動到圖像的中心
magnitude_spectrum0 = 20*np.log(np.abs(fshift))
#傅裡葉逆變換
#Numpy實現
ifshift = np.fft.ifftshift(fshift)
# 將復數轉為浮點數進行傅裡葉頻譜圖顯示
ifimg = np.log(np.abs(ifshift))
if_img = np.fft.ifft2(ifshift)
origin_img = np.abs(if_img)
imggroup = [img2, magnitude_spectrum0, ifimg, origin_img]
titles0 = ['原始圖像', '經過移動後的頻譜圖', '逆變換得到的頻譜圖', '逆變換得到的原圖']
for i in range(4):
    plt.subplot(2, 2, i + 1)
    plt.xticks([])                               #除去刻度線
    plt.yticks([])
    plt.title(titles0[i])
    plt.imshow(imggroup[i], cmap = 'gray')
plt.show()
##OpenCV實現
dft = cv2.dft(np.float32(img2), flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
magnitude_spectrum1 = 20*np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))
plt.subplot(121), plt.imshow(img2, cmap = 'gray')
plt.title('原圖'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(magnitude_spectrum1, cmap = 'gray')
plt.title('頻譜圖'), plt.xticks([]), plt.yticks([])
plt.show()

(1)基本概念

一般我們觀察信號是直接在時域內(聲音信號)或者空間內(圖像)對其進行分析,這樣雖然符合常理,但信號中的一些有用的條件就不會被我們考慮進去,從而達不到分析的效果,所以我們要將信號轉化到其他的一些變換域中進行分析。

(2)讀取圖像信息

本系列文章經典操作:

"""
Author:XiaoMa
date:2021/11/7
"""
import cv2
import matplotlib.pyplot as plt
import numpy as np
 
#讀取圖像信息
img0 = cv2.imread("E:\From Zhihu\For the desk\cvthirteen2.jpg")
img1 = cv2.resize(img0, dsize = None, fx = 0.5, fy = 0.5)
img2 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)               #轉化為灰度圖
h, w = img1.shape[:2]
print(h, w)
cv2.namedWindow("W0")
cv2.imshow("W0", img1)
cv2.waitKey(delay = 0)

得到圖像信息如下:

540 960 

1. 傅裡葉變換

代碼參考:OpenCV官網

(1)基本概念

當我們描述一段聲音時,我們不僅會說它的音量的大小如何,還有可能會說它的頻率是高的還是低的,那麼我們該怎麼理解頻率這個概念呢?以前學習三角函數時我們被告知每一個正弦信號有它的固定的頻率,就是它的周期的倒數。那麼什麼是頻域呢?我們也接觸過其他形狀的波形,比如方波、三角波等等,而這些不同形狀的波呢,就是用一個個頻率不相同的正弦波組成的,如果我們將那些不同頻率的正弦波按照它們的頻率大小排列起來,就得到瞭一個頻率軸(這是一維的),然後我們將各個頻率對應的幅度值給它們對應起來(就像xoy平面一樣)得到的二維的平面,就是頻域瞭。傅裡葉變換就是將信號從時域轉化到頻域的一個工具。對於傅裡葉變換中的的理解可以參考下面的圖片:

當然如果你想更加深入的瞭解傅裡葉變換,你可以按照圖片上的水印去搜索,他那裡講的非常清晰。 

(2)numpy實現

#將圖像轉化到頻域內並繪制頻譜圖
plt.rcParams['font.family'] = 'SimHei'       #將全局中文字體改為黑體
f = np.fft.fft2(img2)
fshift = np.fft.fftshift(f)       #將0頻率分量移動到中心
magnitude_spectrum = 20*np.log(np.abs(fshift))
plt.xticks([])                               #除去刻度線
plt.yticks([])
plt.title("頻譜圖")
plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.show()

(3)OpevCV實現 

#OpenCV實現
dft = cv2.dft(np.float32(img2), flags = cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
magnitude_spectrum1 = 20*np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))
plt.subplot(121), plt.imshow(img2, cmap = 'gray')
plt.title('原圖'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(magnitude_spectrum1, cmap = 'gray')
plt.title('頻譜圖'), plt.xticks([]), plt.yticks([])
plt.show()

2. 傅裡葉逆變換

(1)基本概念

前面提到,經過傅裡葉變換圖像可以轉化到頻域內,那麼經過傅裡葉逆變換,圖像肯定能從頻域內轉化到時域中,所以傅裡葉逆變換就是將信號從頻域轉化到時域的工具。

(2)代碼實現

此處的代碼接上面的使用 Numpy 進行傅裡葉變換

#傅裡葉逆變換
#Numpy實現
ifshift = np.fft.ifftshift(fshift)
# 將復數轉為浮點數進行傅裡葉頻譜圖顯示
ifimg = np.log(np.abs(ifshift))
if_img = np.fft.ifft2(ifshift)
origin_img = np.abs(if_img)
imggroup = [img2, magnitude_spectrum0, ifimg, origin_img]
titles0 = ['原始圖像', '經過移動後的頻譜圖', '逆變換得到的頻譜圖', '逆變換得到的原圖']
for i in range(4):
    plt.subplot(2, 2, i + 1)
    plt.xticks([])                               #除去刻度線
    plt.yticks([])
    plt.title(titles0[i])
    plt.imshow(imggroup[i], cmap = 'gray')
plt.show()

到此這篇關於基於Python實現圖像的傅裡葉變換的文章就介紹到這瞭,更多相關Python圖像傅裡葉變換內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: