3.2 Python图像的频域图像增强-高通和低通滤波器

3.2 Python图像的频域图像增强-高通和低通滤波器

1 算法原理

高通和低通滤波器(分别考虑:理想滤波器、巴特沃斯滤波器,指数滤波器)

1.1理想滤波器

顾名思义,高通滤波器为:让高频信息通过,过滤低频信息;低通滤波相反。低频滤波器,顾名思义,就是过滤掉或者大幅度衰减图像的高频成分,让图像的低频成分通过。低频滤波器可以平滑图像,虑去图像的噪声。而与此相反的高频滤波器,则是过滤低频成分,通过高频成分,可以达到锐化图像的目的。理想低通滤波器的滤波非常尖锐,而高斯低通滤波器的滤波则非常平滑。

Butterworth 低通滤波器则介于两者之间,当 Butterworth 低通滤波器的阶数较高时,接近于理想低通滤波器,阶数较低时,则接近于高斯低通滤波器。理想低通滤波器在以原点为圆心、D0 为半径的园内,通过所有的频率,而在圆外截所有的频率。(圆心的频率最低,为变换的直流(dc)分量)。理想的低通滤波器模板为:

image-20210710093153441

其中,D0 表示通带半径,D(u,v)是到频谱中心的距离(欧式距离),计算

公式如下:

image-20210710093207531

M 和 N 表示频谱图像的大小,(M/2,N/2)即为频谱中心。理想的高通滤波器与此相反,1 减去低通滤波模板即可。

1.2巴特沃斯滤波器

巴特沃斯低通滤波器公式:

image-20210710093422377

D0 为截至频率距原点的距离,D(u,v)是点(u,v)距原点的距离不同于 ILPF,BLPF 变换函数在通带与被滤除的频率之间没有明显的截断。当 D(u,v)=D0 时,H(u,v)=0.5(最大值是 1,当 D(u,v)=0)。随着次数的增加,振铃现象会越来越明显。巴特沃斯高通滤波器的形状与巴特沃斯低通滤波器的形状相反,因为高低频率间平滑过渡,因此振铃现象不明显。

巴特沃斯高通滤波器公式:

image-20210710093432531

在公式中,D(u,v)代表频域当中,点(u,v)到中心点的距离,所以中心点也就是 (M/2,N/2),M 和 N 代表图像的长和宽,那么 D(u,v)就可以用下面的式子来表示了:

image-20210710093500790

而 D0 就是截止距离了,就相当于在频域当中画一个圈,对圈内或者圈外保留就可以达到所谓的低通和高通了,这个 D0 就相当于一维当中的截止频率。

1.3指数滤波器

指数低通滤波器公式为:

image-20210710093602091

指数高通滤波器公式为:

image-20210710093615489

2 代码

运行代码说明

1.要改变代码中的图片地址(地址不能有中文)

更改put(path)函数中的路径put(r'../image/image1.jpg')

2.注意最后的plt.savefig('1.new.jpg')是保存plt图像,如果不使用可以注释掉

import os

import numpy as np
import cv2
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 理想低通滤波器
def LowPassFilter(img):
    """
    理想低通滤波器
    """
    # 傅里叶变换
    dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
    fshift = 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 - 20:crow + 20, ccol - 20:ccol + 20] = 1

    # 掩膜图像和频谱图像乘积
    f = fshift * mask

    # 傅里叶逆变换
    ishift = np.fft.ifftshift(f)
    iimg = cv2.idft(ishift)
    res = cv2.magnitude(iimg[:, :, 0], iimg[:, :, 1])
    return res


# 理想高通滤波器
def HighPassFilter(img):
    """
    理想高通滤波器
    """
    # 傅里叶变换
    f = np.fft.fft2(img)
    fshift = np.fft.fftshift(f)

    # 设置高通滤波器
    rows, cols = img.shape
    crow, ccol = int(rows / 2), int(cols / 2)
    fshift[crow - 2:crow + 2, ccol - 2:ccol + 2] = 0

    # 傅里叶逆变换
    ishift = np.fft.ifftshift(fshift)
    iimg = np.fft.ifft2(ishift)
    iimg = np.abs(iimg)
    return iimg


# 巴特沃斯低通滤波器
def ButterworthLowPassFilter(image, d, n, s1):
    """
    Butterworth低通滤波器
    """
    f = np.fft.fft2(image)
    fshift = np.fft.fftshift(f)

    def make_transform_matrix(d):
        transform_matrix = np.zeros(image.shape)
        center_point = tuple(map(lambda x: (x - 1) / 2, s1.shape))
        for i in range(transform_matrix.shape[0]):
            for j in range(transform_matrix.shape[1]):

                def cal_distance(pa, pb):
                    from math import sqrt

                    dis = sqrt((pa[0] - pb[0]) ** 2 + (pa[1] - pb[1]) ** 2)
                    return dis
                dis = cal_distance(center_point, (i, j))
                transform_matrix[i, j] = 1 / (1 + (dis / d) ** (2 * n))
        return transform_matrix


    d_matrix = make_transform_matrix(d)
    new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * d_matrix)))
    return new_img


# 巴特沃斯高通滤波器
def ButterworthHighPassFilter(image, d, n, s1):
    """
    Butterworth高通滤波器
    """
    f = np.fft.fft2(image)
    fshift = np.fft.fftshift(f)

    def make_transform_matrix(d):
        transform_matrix = np.zeros(image.shape)
        center_point = tuple(map(lambda x: (x - 1) / 2, s1.shape))
        for i in range(transform_matrix.shape[0]):
            for j in range(transform_matrix.shape[1]):

                def cal_distance(pa, pb):
                    from math import sqrt

                    dis = sqrt((pa[0] - pb[0]) ** 2 + (pa[1] - pb[1]) ** 2)
                    return dis

                dis = cal_distance(center_point, (i, j))
                transform_matrix[i, j] = 1 / (1 + (d / dis) ** (2 * n))
        return transform_matrix


    d_matrix = make_transform_matrix(d)
    new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * d_matrix)))
    return new_img

# 指数滤波器
def filter(img, D0, W=None, N=2, type='lp', filter='exponential'):
    '''
    频域滤波器
    Args:
        img: 灰度图片
        D0: 截止频率
        W: 带宽
        N: butterworth和指数滤波器的阶数
        type: lp, hp, bp, bs即低通、高通、带通、带阻
    Returns:
        imgback:滤波后的图像
    '''

    # 离散傅里叶变换
    dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
    # 中心化
    dtf_shift = np.fft.fftshift(dft)

    rows, cols = img.shape
    crow, ccol = int(rows / 2), int(cols / 2)  # 计算频谱中心
    mask = np.ones((rows, cols, 2))  # 生成rows行cols列的2纬矩阵
    for i in range(rows):
        for j in range(cols):
            D = np.sqrt((i - crow) ** 2 + (j - ccol) ** 2)
            if (filter.lower() == 'exponential'):  # 指数滤波器
                if (type == 'lp'):
                    mask[i, j] = np.exp(-(D / D0) ** (2 * N))
                elif (type == 'hp'):
                    mask[i, j] = np.exp(-(D0 / D) ** (2 * N))
                elif (type == 'bs'):
                    mask[i, j] = np.exp(-(D * W / (D ** 2 - D0 ** 2)) ** (2 * N))
                elif (type == 'bp'):
                    mask[i, j] = np.exp(-((D ** 2 - D0 ** 2) / D * W) ** (2 * N))
                else:
                    assert ('type error')

    fshift = dtf_shift * mask

    f_ishift = np.fft.ifftshift(fshift)
    img_back = cv2.idft(f_ishift)
    img_back = cv2.magnitude(img_back[:, :, 0], img_back[:, :, 1])  # 计算像素梯度的绝对值
    img_back = np.abs(img_back)
    img_back = (img_back - np.amin(img_back)) / (np.amax(img_back) - np.amin(img_back))

    return img_back

def put(path):
    img = cv2.imread(path, 1)
    # img = cv2.imread(os.path.join(base, path), 1)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    f = np.fft.fft2(img)
    fshift = np.fft.fftshift(f)
    # 取绝对值后将复数变化为实数 # 取对数的目的是将数据变换到0~255
    s1 = np.log(np.abs(fshift))

    # 用以中文显示
    plt.subplot(331)
    plt.axis('off')
    plt.title('原始图像')
    plt.imshow(img, cmap='gray')

    plt.subplot(332)
    plt.axis('off')
    plt.title('理想低通20')
    res1 = LowPassFilter(img)
    plt.imshow(res1, cmap='gray')

    plt.subplot(333)
    plt.axis('off')
    plt.title('理想高通2')
    res2 = HighPassFilter(img)
    plt.imshow(res2, cmap='gray')

    plt.subplot(334)
    plt.axis('off')
    plt.title('原始图像')
    plt.imshow(img, cmap='gray')

    plt.subplot(335)
    plt.axis('off')
    plt.title('巴特沃斯低通20')
    butter_10_1 = ButterworthLowPassFilter(img, 20, 1, s1)
    plt.imshow(butter_10_1, cmap='gray')

    plt.subplot(336)
    plt.axis('off')
    plt.title('巴特沃斯高通2')
    butter_2_1_1 = ButterworthHighPassFilter(img, 2, 1, s1)
    plt.imshow(butter_2_1_1, cmap='gray')

    plt.subplot(337)
    plt.axis('off')
    plt.title('指数原始图像')
    plt.imshow(img, cmap='gray')

    plt.subplot(338)
    plt.axis('off')
    plt.title('指数低通图像20')
    img_back = filter(img, 30, type='lp')
    plt.imshow(img_back, cmap='gray')

    plt.subplot(339)
    plt.axis('off')
    plt.title('指数高通图像2')
    img_back = filter(img, 2, type='hp')
    plt.imshow(img_back, cmap='gray')

    # plt.savefig('2.new.jpg')
    plt.show()

# 处理函数,要传入路径
put(r'../image/image3.jpg')

3 效果

image-20210710093939373

image-20210710094002933

  • 12
    点赞
  • 109
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
好的,我可以为您介绍一下频域图像处理高通滤波和低通滤波的基本概念和Python实现。 频域图像处理是指将图像从空间域(即像素的位置和灰度值)转换到频率域(即图像的频谱和幅度谱)进行处理的方法。频域图像处理基于傅里叶变换(FFT)和傅里叶反变换(IFFT)实现。在频域中,可以使用不同类型的滤波器对图像进行处理,包括高通滤波和低通滤波。高通滤波器可以用来增强图像的边缘和细节,而低通滤波器则可以用来平滑图像并消除噪声。 在Python中,可以使用NumPy和OpenCV库来实现频域图像处理和滤波。以下是高通滤波和低通滤波的Python代码示例: 高通滤波: ``` python import cv2 import numpy as np # 读取图像 img = cv2.imread('image.jpg', 0) rows, cols = img.shape # 构建高通滤波器 kernel = np.array([[-1,-1,-1],[-1,9,-1],[-1,-1,-1]]) # 傅里叶变换 f = np.fft.fft2(img) fshift = np.fft.fftshift(f) # 滤波 filtered = fshift * kernel f_ishift = np.fft.ifftshift(filtered) img_back = np.fft.ifft2(f_ishift) img_back = np.abs(img_back) # 显示图像 cv2.imshow('Original Image', img) cv2.imshow('High Pass Filtered Image', img_back) cv2.waitKey() cv2.destroyAllWindows() ``` 低通滤波: ``` python import cv2 import numpy as np # 读取图像 img = cv2.imread('image.jpg', 0) rows, cols = img.shape # 构建低通滤波器 kernel = np.ones((5,5),np.float32)/25 # 傅里叶变换 f = np.fft.fft2(img) fshift = np.fft.fftshift(f) # 滤波 filtered = fshift * kernel f_ishift = np.fft.ifftshift(filtered) img_back = np.fft.ifft2(f_ishift) img_back = np.abs(img_back) # 显示图像 cv2.imshow('Original Image', img) cv2.imshow('Low Pass Filtered Image', img_back) cv2.waitKey() cv2.destroyAllWindows() ``` 在这些代码中,我们首先读取输入图像,然后使用NumPy库进行傅里叶变换。然后,我们构建了一个高通低通滤波器,将其应用于频率域的图像,然后使用反傅里叶变换将图像转换回空间域,并显示结果。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值