【opencv学习】【傅里叶变换】【高通滤波器和低通滤波器】

本文探讨了如何使用OpenCV进行图像的傅立叶变换(DFT),实现低通和高通滤波,通过实际操作展示了滤波效果对图像细节和模糊度的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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


# 展示图像,封装成函数
def cv_show_image(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)  # 等待时间,单位是毫秒,0代表任意键终止
    cv2.destroyAllWindows()

# 高频:图像灰度变化剧烈的部分,一般是边界点
# 低频:图像像素变化变化缓慢的部分

# 高通滤波:只保留高频成分,会使得图像细节增强
# 低通滤波:只保留低频成分,会使得图像变得模糊

# 1. cv2.dft(img, cv2.DFT_COMPLEX_OUTPUT) 进行傅里叶变化
# 参数说明: img表示输入的图片, cv2.DFT_COMPLEX_OUTPUT表示进行傅里叶变化的方法
#
# 2. np.fft.fftshift(img)  将图像中的低频部分移动到图像的中心
# 参数说明:img表示输入的图片
#
# 3. cv2.magnitude(x, y) 将sqrt(x^2 + y^2) 计算矩阵维度的平方根
# 参数说明:需要进行x和y平方的数
#
# 4.np.fft.ifftshift(img) # 进图像的低频和高频部分移动到图像原来的位置
# 参数说明:img表示输入的图片
#
# 5.cv2.idft(img) # 进行傅里叶的逆变化
# 参数说明:img表示经过傅里叶变化后的图片


# =============================================================================
# 图像的DFT
# =============================================================================

img = cv2.imread('images/naruto.jpg', cv2.IMREAD_GRAYSCALE)  # 读取灰度图,DFT是对一个通道计算的
img_float32 = np.float32(img)  # 转成浮点数的,方便DFT计算

# 进行DFT计算
# 但是结果是双通道的,有实部和虚部,无法直接展示,需要转换成图像格式(像素值是0~255)才能展示
dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)
print(dft.shape)
dft_shift = np.fft.fftshift(dft)  # 将低频的值集中到图像的中间位置,拼接好图像
print(dft_shift.shape)

# 在转成能灰度表示的图像形式,DFT的计算结果是双通道的,是实部和虚部
magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))

plt.subplot(1, 2, 1), plt.imshow(img, 'gray')
plt.title('input image'), plt.xticks([]), plt.yticks([])
plt.subplot(1, 2, 2), plt.imshow(magnitude_spectrum, 'gray')
plt.title('magnitude_spectrum image'), plt.xticks([]), plt.yticks([])
plt.show()


# =============================================================================
# 低通滤波器,高通滤波器
# =============================================================================
img = cv2.imread('images/naruto.jpg', cv2.IMREAD_GRAYSCALE)  # 读取灰度图,DFT是对一个通道计算的
img_float32 = np.float32(img)  # 转成浮点数的,方便DFT计算

# 进行DFT计算
# 但是结果是双通道的,有实部和虚部,无法直接展示,需要转换成图像格式(像素值是0~255)才能展示
dft = cv2.dft(img_float32, flags=cv2.DFT_COMPLEX_OUTPUT)
print(dft.shape)
dft_shift = np.fft.fftshift(dft)  # 将低频的值集中到图像的中间位置,拼接好图像
print(dft_shift.shape)

# ============================

# 计算图像的row和col size,以及中心点的位置
rows, cols = img.shape
center_x, center_y = int(rows / 2), int(cols / 2)
mask_len = 50

# 低通滤波器:将高频部分全部过滤,就是远离中心的频率全部掩盖
# 先做个掩码mask,中心部分通过
mask_low = np.zeros((rows, cols, 2), np.uint8)
mask_low[center_x - mask_len: center_x + mask_len, center_y - mask_len: center_y + mask_len] = 1

# 低通滤波器:将低频部分全部过滤,就是中心附近的频率全部掩盖
# 先做个掩码mask,中心部分抑制
mask_high = np.ones((rows, cols, 2), np.uint8)
mask_high[center_x - mask_len: center_x + mask_len, center_y - mask_len: center_y + mask_len] = 0

# IDFT 运用低通滤波器
fshift_low = dft_shift * mask_low  # 进行掩码运算后,得到了过滤后的低通分量
f_ishift_low = np.fft.ifftshift(fshift_low)  # 逆转换,进图像的低频和高频部分移动到图像原来的位置
idft_img_low = cv2.idft(f_ishift_low)  # 逆 DFT
idft_img_low = cv2.magnitude(idft_img_low[:, :, 0], idft_img_low[:, :, 1])  # 求加和平方根

# IDFT 运用高通滤波器
fshift_high = dft_shift * mask_high  # 进行掩码运算后,得到了过滤后的高通分量
f_ishift_high = np.fft.ifftshift(fshift_high)  # 逆转换,进图像的低频和高频部分移动到图像原来的位置
idft_img_high = cv2.idft(f_ishift_high)  # 逆 DFT
idft_img_high = cv2.magnitude(idft_img_high[:, :, 0], idft_img_high[:, :, 1])  # 求加和平方根

plt.subplot(131), plt.imshow(img, cmap='gray'), plt.title('src img')
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴
plt.subplot(132)
plt.imshow(idft_img_low, cmap='gray'), plt.title('low pass img')
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴
plt.subplot(133)
plt.imshow(idft_img_high, cmap='gray'), plt.title('high pass img')
plt.xticks([]), plt.yticks([])  # 隐藏坐标轴
plt.show()

图像和DFT后的结果
请添加图片描述
低通和高通的结果
请添加图片描述

<think>好的,我需要帮助用户在OpenCV中实现傅里叶变换以及低通高通滤波的应用。首先,我得回忆一下傅里叶变换的基本概念在图像处理中的作用。傅里叶变换能将图像从空间域转换到频率域,这样在频率域中进行滤波操作会更方便。低频对应图像的平滑部分(比如轮廓),而高频对应细节边缘,所以低通滤波可以模糊图像,高通滤波可以增强边缘。 接下来,我需要结合用户提供的引用内容。引用[1]提到OpenCVNumpy中的傅里叶变换,引用[2][3]解释了低通高通滤波的效果及频率域中心化的重要性,引用[4]提到了一些滤波器的设置。这些信息需要整合到步骤中。 首先,步骤应该是加载图像并转为灰度图,然后进行傅里叶变换。根据引用[3],需要使用np.fft.fftshift来将低频移到中心。然后创建低通高通滤波器,应用滤波,再进行逆变换回到空间域。 需要注意正确使用NumpyOpenCV的函数。比如,OpenCVdft函数可能返回双通道(实部虚部),而Numpy的FFT处理可能需要不同的步骤。另外,滤波器的创建部分,低通是中心区域保留,周围置零;高通则相反,中心置零,周围保留。 在代码示例中,可能需要使用cv2.dftcv2.idft,同时结合Numpy的fft模块。需要确保数据类型正确,比如转换为浮点数,进行归一化等。滤波器的掩模创建部分,可能需要用圆形或矩形区域,根据引用来选择合适的形状,比如理想滤波器或高斯滤波器。 还要考虑到用户可能需要完整的示例代码,包括读取图像、处理、显示结果等步骤。需要解释每个步骤的作用,比如为什么需要灰度图,为什么要进行频谱中心化,滤波器如何影响频率成分等。 最后,生成相关问题,需要基于用户提供的引用回答内容,比如不同滤波器的比较、带通滤波的实现,或者傅里叶变换的应用场景。 检查是否有遗漏的步骤,比如归一化、显示频谱图等,确保代码能够运行并达到预期效果。同时,确保引用正确,比如引用[3]关于fftshift的使用,引用[2]关于低通滤波的效果。</think>### OpenCV实现傅里叶变换滤波的示例教程 #### 1. 傅里叶变换实现 **步骤1:加载图像并转换格式** ```python import cv2 import numpy as np import matplotlib.pyplot as plt # 读取图像并转为灰度图 img = cv2.imread('input.jpg', 0) rows, cols = img.shape ``` **步骤2:执行傅里叶变换** ```python # 转为浮点类型并扩展为双通道(实部+虚部) dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT) dft_shift = np.fft.fftshift(dft) # 将低频移至中心[^3] # 计算幅度谱(用于可视化) magnitude = 20 * np.log(cv2.magnitude(dft_shift[:,:,0], dft_shift[:,:,1])) ``` #### 2. 低通滤波(模糊轮廓) **创建圆形掩模保留中心低频** ```python mask_low = np.zeros((rows, cols, 2), np.uint8) center = (rows//2, cols//2) radius = 30 cv2.circle(mask_low, center, radius, (1,1), -1) # 中心圆形区域保留[^2] # 应用滤波并逆变换 dft_filtered_low = dft_shift * mask_low img_low = cv2.idft(np.fft.ifftshift(dft_filtered_low), flags=cv2.DFT_REAL_OUTPUT) ``` #### 3. 高通滤波(增强边缘) **创建掩模抑制中心低频** ```python mask_high = np.ones((rows, cols, 2), np.uint8) cv2.circle(mask_high, center, radius, (0,0), -1) # 中心置零 dft_filtered_high = dft_shift * mask_high img_high = cv2.idft(np.fft.ifftshift(dft_filtered_high), flags=cv2.DFT_REAL_OUTPUT) ``` #### 4. 结果可视化 ```python plt.subplot(131), plt.imshow(img, cmap='gray'), plt.title('原始图像') plt.subplot(132), plt.imshow(img_low, cmap='gray'), plt.title('低通滤波后') plt.subplot(133), plt.imshow(img_high, cmap='gray'), plt.title('高通滤波后') plt.show() ``` --- ### 关键原理说明 - **低频保留**:低通滤波通过抑制高频信号(如边缘噪声),保留图像主体轮廓 - **高频增强**:高通滤波通过抑制低频信号(如平滑区域),突出细节特征 - **频谱中心化**:`np.fft.fftshift`用于将低频分量移至图像中心,便于滤波器设计 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值