频域滤波——快速傅里叶变换

快速傅里叶变换
1、快速傅里叶变换的算法复杂度

对于MN的二维图像来说,对其进行离散傅里叶变换时需要的运算是MNMN次乘法和加法,但是运用快速傅里叶变换的计算量是MN*logMN次乘法和加法。
对比log10000=4,10的4次方是10000,感受对数级衰减和指数级增长的明显差异。黑线是指数,绿线是对数。
在这里插入图片描述

2、快速傅里叶变换的实现思路

要想使用快速傅里叶变换需要对原图像进行扩充到适于进行DFT的最优尺寸,cv.getOptimalDFTSize() 函数可以实现图像的最优 DFT 尺寸扩充,适用于 cv.dft() 和 np.fft.fft2()。

retval=cv.getOptimalDFTSize(versize)
dft=cv.dft(src[, dst[, flags[, nonzeroRows]]])
idft=cv.idft(src[, dst[, flags[, nonzeroRows]]]) 
##最常用的形式是
cv.dft(src,flgs=cv.DFT_COMPLEX_OUTPUT)
参数说明:

src:输入图像,单通道灰度图像,使用 np.float32 格式
dst:输出图像,图像大小与 src 相同,数据类型由 flag 决定
flag:转换标识符
cv.DFT_INVERSE:用一维或二维逆变换取代默认的正向变换
cv.DFT_SCALE:缩放比例标识,根据元素数量求出缩放结果,常与DFT_INVERSE搭配使用
cv.DFT_ROWS: 对输入矩阵的每行进行正向或反向的傅里叶变换,常用于三维或高维变换等复杂操作
cv.DFT_COMPLEX_OUTPUT:对一维或二维实数数组进行正向变换,默认方法,结果是由 2个通道表示的复数阵列,第一通道是实数部分,第二通道是虚数部分
cv.DFT_REAL_OUTPUT:对一维或二维复数数组进行逆变换,结果通常是一个尺寸相同的复数矩阵

如下用快速傅里叶变换实现的代码:

import numpy as np
import matplotlib.pyplot as plt
import cv2
## 二维图像的离散傅里叶变换,opencv实现
#opencv提供了 返回结果=cv2.dft(原始图像,转换标识),
# 上述参数“原始图像”,要首先使用np.float32()函数将图像转换成np.float32格式,
# “转换标识”的值通常为“cv2.DFT_COMPLEX_OUTPUT”,用来输出一个复数阵列
#函数cv2.dft()返回的结果与使用Numpy进行傅里叶变换得到的结果是一致的,
# 但是cv2.dft()返回的值是双通道的,第1个通道是结果的实数部分,第2个通道是结果的虚数部分;但是fft=np.fft.fft2()返回值是一个复数数组;
#1、读取图像,获取图像的高、宽
img=cv2.imread("./images/CH04/woman.tif",flags=0)
#img=cv2.imread("./images/CH04/rectangle.tif",flags=0)
height,width=img.shape[:2] #获取图片的高和宽
#2、快速傅里叶变换:
#(1)获取最优DFT扩充尺寸
rPad=cv2.getOptimalDFTSize(height) #如果选取的图片尺寸是符合2**n,则最优扩充尺寸和原图像尺寸一致
cPad=cv2.getOptimalDFTSize(width) 
#(2)准备一个扩充好的全零矩阵尺寸是:rPad*cPad*2,其中每行每列中的每个元素是两个通道的(即每个元素是个二元数组)
imgPad=np.zeros((rPad,cPad,2),np.float32) 
#(3)相当于对扩充后的全零矩阵进行左上角图像填充,只对第一个通道填充是因为图像时灰度图像,只有一个通道有值
imgPad[0:height,0:width,0]=img  #边缘扩充,下侧右侧补零
#(4)进行快速傅里叶变换,实际就是对上述填充好的图像进行傅里叶变换
#注意:使用cv2.dft(原始图像,转换标识)对填充后的矩阵进行傅里叶变换,需将图像转换成np.float32格式
fdft=cv2.dft(np.float32(imgPad),flags=cv2.DFT_COMPLEX_OUTPUT)
print("img",img.shape[:2]) #原图像是512 
print("imgPad",imgPad.shape[:2]) #扩充后的尺寸还是512 
#3、傅里叶逆变换 
idft=cv2.idft(fdft) #返回的是一个rPad*cPad*2,是二通道元素
#计算idft中每个元素的模值,重建图像
idftMag=cv2.magnitude(idft[:,:,0],idft[:,:,1])
#归一化处理:将所有元素范围归到0-1之间
#normalize=lambda x:(x-x.min())/(x.max()-x.min()+1e-6)  #再让x*255 
#opencv提供了归一化函数:array = cv2.normalize(array,None,0,255,cv2.NORM_MINMAX)
idftMagNorm=cv2.normalize(idftMag,None,0,255,cv2.NORM_MINMAX)
#print(idftMag)
plt.figure(figsize=(9, 6))
#显示原图
plt.subplot(131), plt.title("origin"), plt.imshow(img)
# #显示傅里叶逆变换的
plt.subplot(132),plt.title("idftMag"),plt.imshow(idftMag,cmap="gray")
#显示逆变换后像素归一化的图像
plt.subplot(133),plt.title("idftMagNorm"),plt.imshow(idftMagNorm,cmap="gray")
plt.tight_layout()
plt.show()

运行效果如下:归一化与没有归一化好像也没有特别大的差别
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在MATLAB中,频域滤波是通过傅里叶变换将图像从空间域转换为频率域,并在频率域内对图像进行处理,最后通过傅里叶反变换将图像转换回空间域的一种图像处理方法。频域滤波可以包括低通滤波、高通滤波和同态滤波等方法。 对于频域滤波的具体步骤,首先需要进行傅里叶变换。通过调用fft2函数,可以将图像从空间域转换为频率域。然后,根据具体需求选择合适的滤波函数(如理想低通滤波器、高斯低通滤波器等)并与原始图像的频谱进行乘积运算。接着,再进行傅里叶反变换,将滤波后的频谱变换回空间域,得到最终的滤波结果。 举例来说,假设我要使用理想低通滤波器对图像进行滤波。可以按照以下步骤进行操作: 1. 读取图像并转换为灰度图像: I = imread('image.jpg'); I_gray = rgb2gray(I); 2. 将图像转换为双精度类型: I2 = im2double(I_gray); 3. 设定滤波器的行数和列数: M = 2 * size(I2, 1); N = 2 * size(I2, 2); 4. 构建频率域中的坐标网格: u = -M/2 : (M/2-1); v = -N/2 : (N/2-1); [U, V] = meshgrid(u, v); 5. 计算频率域中的距离: D = sqrt(U.^2 + V.^2); 6. 设定截至频率D0: D0 = 80; 7. 构建理想低通滤波器: H = double(D < D0); 8. 进行傅里叶变换: J = fftshift(fft2(I2, size(H, 1), size(H, 2))); 9. 对频域图像进行滤波处理: K = J .* H; 10. 进行傅里叶反变换: L = ifft2(ifftshift(K)); L = L(1:size(I2, 1), 1:size(I2, 2)); 11. 显示原始图像和滤波后的图像: figure; subplot(1, 2, 1); imshow(I2); title('原始图像'); subplot(1, 2, 2); imshow(L); title('滤波后的图像'); 通过以上步骤,我们可以使用MATLAB实现频域滤波,并对图像进行滤波处理。具体的滤波效果和滤波器的选择会根据应用需求而定。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [频域滤波(matlab)](https://blog.csdn.net/weixin_56260304/article/details/127375937)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [Matlab实现频域滤波——二维傅里叶变换、低通、高通](https://blog.csdn.net/maggieyiyi/article/details/119927638)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值