带垂直周期噪声的圆形图像FFT修复:边界伪影消除方案咨询
圆形图像FFT去垂直噪声时边界水波问题的解决方案
问题概述
使用FFT结合垂直硬掩码消除圆形图像的垂直周期噪声时,圆形边界处出现明显的水波状振铃效应,严重影响修复效果。以下是复现问题的代码及图像:
复现代码
import numpy as np from skimage import data, color, transform, draw # 生成垂直周期噪声 vnoise = np.linspace(1, 100, 100).reshape(-1, 1) vnoise = np.tile(vnoise, (30, 3000)) # 加载并预处理背景图像 astro = data.astronaut() astro = color.rgb2gray(astro) astro = transform.resize(astro, (3000, 3000)) # 创建圆形掩码 cen = (1500, 1500) radii = 1500 circle = np.zeros_like(astro) rr, cc = draw.disk(cen, radii, shape=astro.shape) circle[rr, cc] = 1 # 生成含噪声的圆形图像 coeff = 0.01 output = astro + coeff * vnoise output *= circle # 现有FFT滤波流程 image = output.copy().astype(np.complex128) fimg = np.fft.fftshift(np.fft.fft2(image)) # 垂直硬掩码 vf = np.ones_like(image) center = 1500 vf[:center-10, center-10:center+10] = 0 vf[center+10:, center-10:center+10] = 0 # 逆FFT fimg = fimg * vf ifimg = np.fft.ifft2(np.fft.ifftshift(fimg)) ifimg = np.real(ifimg)
相关图像
- 无噪声原始图像:

- 含噪声退化图像:

- 滤波后带水波效应的图像:

解决方法
1. 圆形区域加窗函数,平滑边界突变
振铃效应的根源是圆形掩码内外的像素值阶跃(内部是图像,外部是0)。在FFT前对圆形区域内的图像施加汉宁窗,让边界像素值平滑过渡到0:
# 生成径向汉宁窗 y, x = np.ogrid[:3000, :3000] dist_from_center = np.sqrt((x - cen[0])**2 + (y - cen[1])**2) window = np.zeros_like(astro) # 仅在圆形区域内应用窗函数 window[rr, cc] = np.hanning(2*radii)[radii - dist_from_center[rr, cc].astype(int)] # 对图像加窗后再做FFT windowed_img = output * window # 后续FFT/逆FFT流程不变,输入替换为windowed_img
2. 用软掩码替代硬掩码,避免频率域阶跃
硬掩码在频率域是矩形突变,会引入振铃。改用高斯软掩码,让目标频率区域的滤波效果平滑过渡:
# 生成高斯软掩码 vf = np.ones_like(image) center = 1500 # 垂直方向的高斯衰减曲线 y = np.arange(3000) gauss = np.exp(-((y - center)**2)/(2*(50)**2)) # 标准差50可根据噪声频率调整 # 仅在中心垂直条带区域应用衰减 vf[:, center-10:center+10] = gauss[:, None]
3. 提取圆形区域单独处理,隔离边界影响
把圆形区域裁剪成独立的矩形子图,处理完成后再放回原图像,避免与背景0值的交互:
# 提取圆形区域的最小外接矩形 min_r, max_r = rr.min(), rr.max() min_c, max_c = cc.min(), cc.max() crop_img = output[min_r:max_r, min_c:max_c] crop_circle = circle[min_r:max_r, min_c:max_c] # 对裁剪子图做FFT滤波 fimg_crop = np.fft.fftshift(np.fft.fft2(crop_img)) center_crop = (max_r - min_r) // 2 vf_crop = np.ones_like(crop_img) vf_crop[:center_crop-10, center_crop-10:center_crop+10] = 0 vf_crop[center_crop+10:, center_crop-10:center_crop+10] = 0 ifimg_crop = np.real(np.fft.ifft2(np.fft.ifftshift(fimg_crop * vf_crop))) # 将处理后的子图放回原图像 result = output.copy() result[min_r:max_r, min_c:max_c] = ifimg_crop * crop_circle
4. 使用Wiener滤波,兼顾噪声抑制与细节保留
Wiener滤波是一种自适应滤波方法,能有效减少振铃效应,同时保留图像细节:
from scipy.signal import wiener # 对圆形区域内的图像应用Wiener滤波 masked_img = output * circle filtered_img = wiener(masked_img, mysize=5) # 窗口大小可调整 result = filtered_img * circle
内容的提问来源于stack exchange,提问作者Kevin
相关产品推荐
相关产品推荐

