利用傅里叶变换获取低频和高频部分图像

该博客介绍了如何通过傅里叶变换和滤波器在频域中分离图像的低频和高频部分。首先,将图像转换为单通道浮点数并进行傅里叶变换。然后,利用高斯滤波器和圆形滤波器来选择性地保留或过滤掉高频和低频信息。具体而言,低频部分通过中心区域的滤波,而高频部分则通过边缘区域的滤波。最后,通过逆傅里叶变换恢复图像并将其转换回uint8格式。文章还讨论了滤波器选择对图像质量的影响,如振铃效应,并提供了相关代码实现。
摘要由CSDN通过智能技术生成

1、高频、低频图像的获取

步骤:

  • 图像转换为单通道、浮点数
  • 傅里叶变换
  • 傅里叶平移:使低分集中在中间
  • 制作mask,过滤出低频、高频
  • 逆傅里叶平移
  • 逆傅里叶变换
  • 计算绝对值,恢复至[0,255],uint8

2、滤波器(mask)的选择

  • 振铃效应
    在时域中使用矩形函数的滤波器会导致在频域中的涟波,其原因就如同Sinc滤波器(在频域中为矩形函数)在时域中产生的涟波一样;在这两个例子中,矩形函数的傅立叶变换就是Sinc函数

3、code

# -*- coding: utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt


def gaussian_filter_high_f(fshift, D):
    # 获取索引矩阵及中心点坐标
    h, w = fshift.shape
    x, y = np.mgrid[0:h, 0:w]
    center = (int((h - 1) / 2), int((w - 1) / 2))

    # 计算中心距离矩阵
    dis_square = (x - center[0]) ** 2 + (y - center[1]) ** 2

    # 计算变换矩阵
    template = np.exp(- dis_square / (2 * D ** 2))

    return template * fshift

def gaussian_filter_low_f(fshift, D):
    # 获取索引矩阵及中心点坐标
    h, w = fshift.shape
    x, y = np.mgrid[0:h, 0:w]
    center = (int((h - 1) / 2), int((w - 1) / 2))

    # 计算中心距离矩阵
    dis_square = (x - center[0]) ** 2 + (y - center[1]) ** 2

    # 计算变换矩阵
    template = 1 - np.exp(- dis_square / (2 * D ** 2)) # 高斯过滤器

    return template * fshift

def circle_filter_high_f(fshift, radius_ratio):
    """
    过滤掉除了中心区域外的高频信息
    """
    # 1, 生成圆形过滤器, 圆内值1, 其他部分为0的过滤器, 过滤
    template = np.zeros(fshift.shape, np.uint8)
    crow, ccol = int(fshift.shape[0] / 2), int(fshift.shape[1] / 2)  # 圆心
    radius = int(radius_ratio * img.shape[0] / 2)
    if len(img.shape) == 3:
        cv2.circle(template, (crow, ccol), radius, (1, 1, 1), -1)
    else:
        cv2.circle(template, (crow, ccol), radius, 1, -1)
    # 2, 过滤掉除了中心区域外的高频信息
    return template * fshift


def circle_filter_low_f(fshift, radius_ratio):
    """
    去除中心区域低频信息
    """
    # 1 生成圆形过滤器, 圆内值0, 其他部分为1的过滤器, 过滤
    filter_img = np.ones(fshift.shape, np.uint8)
    crow, col = int(fshift.shape[0] / 2), int(fshift.shape[1] / 2)
    radius = int(radius_ratio * img.shape[0] / 2)
    if len(img.shape) == 3:
        cv2.circle(filter_img, (crow, col), radius, (0, 0, 0), -1)
    else:
        cv2.circle(filter_img, (crow, col), radius, 0, -1)
    # 2 过滤中心低频部分的信息
    return filter_img * fshift


def ifft(fshift):
    """
    傅里叶逆变换
    """
    ishift = np.fft.ifftshift(fshift)  # 把低频部分sift回左上角
    iimg = np.fft.ifftn(ishift)  # 出来的是复数,无法显示
    iimg = np.abs(iimg)  # 返回复数的模
    return iimg

def get_low_high_f(img, radius_ratio, D):
    """
    获取低频和高频部分图像
    """
    # 傅里叶变换
    # np.fft.fftn
    f = np.fft.fftn(img)  # Compute the N-dimensional discrete Fourier Transform. 零频率分量位于频谱图像的左上角
    fshift = np.fft.fftshift(f)  # 零频率分量会被移到频域图像的中心位置,即低频

    # 获取低频和高频部分
    hight_parts_fshift = circle_filter_low_f(fshift.copy(), radius_ratio=radius_ratio)  # 过滤掉中心低频
    low_parts_fshift = circle_filter_high_f(fshift.copy(), radius_ratio=radius_ratio)
    hight_parts_fshift =  gaussian_filter_low_f(fshift.copy(), D=D)
    low_parts_fshift = gaussian_filter_high_f(fshift.copy(), D=D)

    low_parts_img = ifft(low_parts_fshift)  # 先sift回来,再反傅里叶变换
    high_parts_img = ifft(hight_parts_fshift)

    # 显示原始图像和高通滤波处理图像
    img_new_low = (low_parts_img - np.amin(low_parts_img)) / (np.amax(low_parts_img) - np.amin(low_parts_img) + 0.00001)
    img_new_high = (high_parts_img - np.amin(high_parts_img) + 0.00001) / (
                np.amax(high_parts_img) - np.amin(high_parts_img) + 0.00001)

    # uint8
    img_new_low = np.array(img_new_low * 255, np.uint8)
    img_new_high = np.array(img_new_high * 255, np.uint8)
    return img_new_low, img_new_high


# 频域中使用高斯滤波器能更好的减少振铃效应
if __name__ == '__main__':
    radius_ratio = 0.5  # 圆形过滤器的半径:ratio * w/2
    D = 50              # 高斯过滤器的截止频率:2 5 10 20 50 ,越小越模糊信息越少
    img = cv2.imread('butterfly2.png', cv2.IMREAD_GRAYSCALE)
    low_freq_part_img, high_freq_part_img = get_low_high_f(img, radius_ratio=radius_ratio, D=D)  # multi channel or single

    plt.subplot(131), plt.imshow(img, 'gray'), plt.title('Original Image')
    plt.axis('off')
    plt.subplot(132), plt.imshow(low_freq_part_img, 'gray'), plt.title('low_freq_img')
    plt.axis('off')
    plt.subplot(133), plt.imshow(high_freq_part_img, 'gray'), plt.title('high_freq_img')
    plt.axis('off')
    plt.show()

4、参考链接

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值