日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

图像傅里叶变换--OpenCV

發布時間:2023/12/29 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图像傅里叶变换--OpenCV 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

傅里葉變換

? ? 傅里葉變換主要是將時間域上的信號轉變為頻率域上的信號,用來進行圖像降噪,圖像增強等處理。

? ? 對于數字圖像這種離散的信號,頻率大小表示信號變換的劇烈程度或者說信號變化的快慢。頻率越大,變換越劇烈,頻率越小,信號越平緩,對應到的圖像中,高頻信號往往是圖像中的邊緣信號和噪聲信號,而低頻信號包含圖像變化頻繁的圖像輪廓及背景燈信號。

? ? 故傅里葉變換的結果圖像中,中心的圖像表示低頻信號,邊緣的圖像代表高頻圖像,需要注意的是,原圖像和傅里葉變換結果的圖像不是一一對應的。

dft = cv.dft(np.float32(img), flags=cv.DFT_COMPLEX_OUTPUT) dft_shift = np.fft.fftshift(dft) magnitude_spectrum = 20 * np.log(cv.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))

? ? np.fft.fftshift()用于將FFT變換之后的頻譜顯示范圍從[0, N]變為:[-N/2, N/2-1](N為偶數)? 或者[-(N-1)/2, (N-1)/2](N為奇數),這一步的目的是在后續畫頻域圖時候,能將低頻部分移到中心,在使用IDFT時也需要進行這個操作。

第三句話用于計算傅里葉變換結果的幅值,Magnitude()函數的原理:

其中根號下為虛部與實部。20lg(x)是常用描述頻域的單位,故此次做這個處理。

import numpy as np import cv2 as cv from matplotlib import pyplot as pltimg = cv.imread(r'XXXXX') img = cv2.cv2.cvtColor(img, cv.COLOR_BGR2GRAY) dft = cv.dft(np.float32(img), flags=cv.DFT_COMPLEX_OUTPUT) dft_shift = np.fft.fftshift(dft) magnitude_spectrum = 20 * np.log(cv.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1])) plt.subplot(121), plt.imshow(img, cmap='gray') plt.title('Input Image'), plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(magnitude_spectrum, cmap='gray') plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([]) plt.show()

?

?從圖中可以看出,中心部分較亮,四周部分較暗,這說明圖像的低頻部分較多,高頻部分較少,這符合正常圖像的情況。

利用傅里葉變換可以完成許多操作,例如我們只提取低頻部分,然后利用反FFT重構圖像,完成模糊操作:

利用傅里葉變換進行操作:

實質上是先得到原圖像的FFT,再截取FFT圖像中的低頻部分,再IFFT得到圖像,完成模糊。

import cv2.cv2 import numpy as np import cv2 as cv from matplotlib import pyplot as pltimg = cv.imread(r'XXXXXX') img = cv2.cv2.cvtColor(img, cv.COLOR_BGR2GRAY) dft = cv.dft(np.float32(img), flags=cv.DFT_COMPLEX_OUTPUT) dft_shift = np.fft.fftshift(dft) magnitude_spectrum = 20 * np.log(cv.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))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 = dft_shift*mask f_ishift = np.fft.ifftshift(fshift)img_back = cv.idft(f_ishift) img_back = cv.magnitude(img_back[:,:,0],img_back[:,:,1])plt.subplot(121),plt.imshow(img, cmap = 'gray') plt.title('Input Image'), plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(img_back, cmap = 'gray') plt.title('Vague'), plt.xticks([]), plt.yticks([]) plt.show()

?

?同理可得,我們也可以得到高頻部分,很顯然,高頻部分即為邊緣:

import cv2.cv2 import numpy as np import cv2 as cv from matplotlib import pyplot as pltimg = cv.imread(r'XXXX') img = cv2.cv2.cvtColor(img, cv.COLOR_BGR2GRAY) dft = cv.dft(np.float32(img), flags=cv.DFT_COMPLEX_OUTPUT) dft_shift = np.fft.fftshift(dft) magnitude_spectrum = 20 * np.log(cv.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))rows, cols = img.shape crow,ccol = int(rows/2) , int(cols/2) mask = np.ones((rows,cols,2),np.uint8) mask[crow-30:crow+30, ccol-30:ccol+30] = 0 fshift = dft_shift*mask f_ishift = np.fft.ifftshift(fshift)img_back = cv.idft(f_ishift) img_back = cv.magnitude(img_back[:,:,0],img_back[:,:,1])plt.subplot(121),plt.imshow(img, cmap = 'gray') plt.title('Input Image'), plt.xticks([]), plt.yticks([]) plt.subplot(122),plt.imshow(img_back, cmap = 'gray') plt.title('Vague'), plt.xticks([]), plt.yticks([]) plt.show()dft1 = cv.dft(np.float32(img_back), flags=cv.DFT_COMPLEX_OUTPUT) dft_shift1 = np.fft.fftshift(dft1) magnitude_spectrum1 = 20 * np.log(cv.magnitude(dft_shift1[:, :, 0], dft_shift1[:, :, 1])) plt.subplot(121), plt.imshow(magnitude_spectrum, cmap='gray') plt.title('Input Image'), plt.xticks([]), plt.yticks([]) plt.subplot(122), plt.imshow(magnitude_spectrum1, cmap='gray') plt.title('Vague'), plt.xticks([]), plt.yticks([]) plt.show()

?

? ? ?這里有應該問題,為什么得到邊界圖像的FFT圖像仍然是中心較亮,四周較暗的模式呢?

? ? ?其實很容易想明白,這個FFT圖像還是由boundary原圖像得到的,對于傅里葉變換來說,考慮的是整幅圖像,而boundary原圖像中,黑色部分占大部分,這又構成低頻部分!

傅里葉變換優化

? ? 由于傅里葉變換的數學特性,其對圖像的長與寬有一個喜好,我們可以根據cv.getOptimalDFTSize()函數來找到這個最優的尺寸,需要注意的是,得到的尺寸是在原有尺寸的基礎上進行微量改變的。

img = cv.imread(r'XXXX') img = cv2.cv2.cvtColor(img, cv.COLOR_BGR2GRAY) rows,cols = img.shape print("{} {}".format(rows,cols)) nrows = cv.getOptimalDFTSize(rows) ncols = cv.getOptimalDFTSize(cols) print("{} {}".format(nrows,ncols))1050 750 1080 750

可以看到,函數對我們的尺寸提出了改變。

那我們要怎么利用這個改變呢?有一個簡單的方法,即可以創造一些邊框來對圖像進行微量擴充:

right = ncols - cols bottom = nrows - rows img = cv.copyMakeBorder(img,0,bottom,0,right,cv.BORDER_CONSTANT, value = 0)

其實實質上,拉普拉斯變化,sobel算子,scharr算子,高斯變化都可以利用傅里葉變換來解釋,但此處不再贅述。

總結

以上是生活随笔為你收集整理的图像傅里叶变换--OpenCV的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。