《数字图像处理-OpenCV/Python》连载:傅里叶变换与频域滤波

发布时间:2024年01月20日

《数字图像处理-OpenCV/Python》连载:空间滤波之高斯滤波器


本书京东 优惠购书链接 https://item.jd.com/14098452.html
本书CSDN 独家连载专栏 https://blog.csdn.net/youcans/category_12418787.html

在这里插入图片描述


第 11 章 傅里叶变换与频域滤波


空间图像滤波是图像与滤波器核的卷积,而空间卷积的傅里叶变换是频域中相应变换的乘积。因此,频域图像滤波是通过频域滤波器(传递函数)与图像的傅里叶变换相乘得到的。频域中的滤波概念更加直观,滤波器设计也更容易。


本章内容概要

  • 学习二维离散傅里叶变换的实现方法,介绍快速傅里叶变换的原理。
  • 学习频域滤波的基本步骤,以及构造滤波器传递函数的基本方法。
  • 学习常用的频域滤波器,如理想滤波器、高斯滤波器、巴特沃斯滤波器。
  • 介绍低通、高通、带通、带阻滤波器的关系,构造选择性滤波器。
  • 认识和比较空间滤波与频域滤波。

11.3 频域滤波的基本步骤

傅里叶变换的目的是将图像从空间域转换到频域,在频域内进行图像处理。

空间取样和频率间隔是相互对应的,频域中的样本间隔与空间样本间隔及样本数量的乘积成反比。空间滤波器和频域滤波器也是相互对应的,二者能形成如下的傅里叶变换对。

因此,计算两个函数的空间卷积,可以直接在空间域计算,也可以在频域计算。先计算每个函数的傅里叶变换,再将两个变换相乘,最后进行傅里叶逆变换转换回空间域。

频域图像滤波首先要对原始图像 f(x,y)做傅里叶变换 F(u,v) ;然后用滤波器传递函数 H(u,v) 对傅里叶变换的频谱进行处理,做傅里叶逆变换返回空间域,得到滤波图像 g(x,y)。具体变换过程如下。

(1) 对原始图像 f(x,y) 进行傅里叶变换和中心化,得到 F(u,v) 。
(2) 将图像的傅里叶变换 F(u,v) 与滤波器传递函数 H(u,v) 相乘,得到滤波频谱 G(u,v) 。
(3) 对 G(u,v) 进行逆中心化和傅里叶逆变换,得到滤波图像 g(x,y)。

使用尺寸最优扩充的快速傅里叶变换时,还包括变换前的图像扩充和变换后的图像裁剪。


【例程1104】频域图像滤波的基本步骤

本例程以理想低通滤波器为例,示范频域图像滤波的基本步骤。

设计低通滤波器的过程,是构造二维掩模图像的过程。简单地,构造一个中心开窗的遮罩图像,在黑色图像的中心区域设有白色窗口,就构成了一个低通滤波器。


# 【1104】频域图像滤波的基本步骤
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

def ideaLPF(height, width, radius=10):  # 理想低通滤波器
    u, v = np.mgrid[-1:1:2.0/height, -1:1:2.0/width]
    Dist = cv.magnitude(u, v)
    D0 = radius/height  # 滤波器半径
    kernel = np.zeros((height, width), np.uint8)
    kernel[Dist <= D0] = 1
    return kernel

if __name__ == '__main__':
    # img = cv.imread("../images/Fig0515a.tif", flags=0)  # 读取为灰度图像
    img = cv.imread("../images/Fig1101.png", flags=0)  # 读取灰度图像
    height, width = img.shape[:2]  # (688,688)

    # (1) 对图像进行傅里叶变换,并将低频分量移动到中心
    imgFloat = img.astype(np.float32)  # 将图像转换成 float32
    dft = cv.dft(imgFloat, flags=cv.DFT_COMPLEX_OUTPUT)  # (512,512,2)
    dftShift = np.fft.fftshift(dft)  # (512,512,2)

    r = [30, 60, 90]  # 低通滤波器的半径
    plt.figure(figsize=(9, 6))
    for i in range(3):
        # (2) 构造低通滤波器
        mask = ideaLPF(height, width, r[i])  # 理想低通滤波器
        maskDual = cv.merge([mask, mask])  # 拼接为两个通道:(h,w,2)
        # maskAmp = cv.magnitude(mask, mask)  # 幅度谱

        # (3) 修改傅里叶变换实现频域图像滤波
        dftMask = dftShift * maskDual  # 两个通道分别为实部和虚部

        # (4) 逆中心化后进行傅里叶逆变换
        iShift = np.fft.ifftshift(dftMask)  # 将低频逆转换回图像四角
        iDft = cv.idft(iShift)  # 傅里叶逆变换
        iDftMag = cv.magnitude(iDft[:,:,0], iDft[:,:,1])  # 重建图像
        imgLPF = np.uint8(cv.normalize(iDftMag, None, 0, 255, cv.NORM_MINMAX))

        plt.subplot(2,3,i+1), plt.title("Mask (r={})".format(r[i]))
        plt.axis('off'), plt.imshow(mask, cmap='gray')
        plt.subplot(2,3,i+4), plt.title("LPF image (r={})".format(r[i]))
        plt.axis('off'), plt.imshow(imgLPF, cmap='gray')

    print(img.shape, dft.shape, maskDual.shape)
    plt.tight_layout()
    plt.show()

运行结果:

程序说明:

(1) OpenCV中的傅里叶变换结果保存为实部和虚部两个通道,dft的形状为(h,w,2)。因此要把单通道滤波器mask拼接为两个通道的maskDual,才能将dft与maskDual相乘。
(2) 傅里叶变换和傅里叶逆变换的结果都包括实部和虚部,使用函数cv.magnitude转换为幅度谱才能得到显示图像。
(3) 函数cv.dft的可选参数较多,在设置转换类型标志时不能省略关键字flags。
(4) 运行结果,频域滤波之理想低通滤波器如图11-2所示。从图中可以发现,低通滤波器的截止频率越小,保留的低频信息越少,滤除的高频信息越多,图像越模糊。这与空间域低通滤波的结果是一致的。
(5) 注意,滤波器传递函数与图像傅里叶变换进行乘法运算时,不能使用函数cv.multiply,因其是饱和运算。


在这里插入图片描述

图11-2 频域滤波之理想低通滤波器


版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/135705738)
Copyright 2024 youcans, XUPT
Crated:2024-01-20

《数字图像处理-OpenCV/Python》 独家连载专栏 : https://blog.csdn.net/youcans/category_12418787.html

文章来源:https://blog.csdn.net/youcans/article/details/135705738
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。