skimage unsupervised_wiener传max_num_iter参数报错排查
问题现象
- 使用scikit-image的
restoration.unsupervised_wiener开展图像复原实验时,简单构造测试场景下算法运行正常,结果符合预期;切换到复杂数据集后,复原结果出现明显条纹伪影,像素值出现-1、1这类超出常规范围的极端异常值。 - 为排查异常尝试调整算法参数时,传入
max_num_iter参数触发报错:unsupervised_wiener() got an unexpected keyword argument 'max_num_iter'。先后切换scikit-image 0.19.3、0.19.2版本,该报错始终存在;传入官方0.19.x版本API文档标注的其他可选参数时,也会触发同类参数不识别报错。
可复现测试代码
测试逻辑为构造模拟扫描图像与点扩散函数,通过2D卷积生成退化图像,再调用无监督维纳反卷积尝试复原:
import numpy as np import matplotlib.pyplot as plt from skimage import color, data, restoration import pickle rng = np.random.default_rng() from scipy.signal import convolve2d as conv2 scan = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0.5, 0.5, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0.5, 1, 0.5, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0.5, 1, 0.5, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0.5, 1, 0.5, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0.5, 0.5, 0.5, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ]) print(scan.shape) psf = np.array([ [1, 1, 1, 1, 1], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [1, 1, 1, 1, 1] ]) psf = psf/(np.sum(psf)) print(psf) scan_conv = conv2(scan, psf, 'same') deconvolved1, _ = restoration.unsupervised_wiener(scan_conv, psf, max_num_iter=10) fig, ax = plt.subplots(nrows=1, ncols=3, figsize=(8, 5), sharex=True, sharey=True) ax[0].imshow(scan, vmin=scan.min(), vmax=1) ax[0].axis('off') ax[0].set_title('Data') ax[1].imshow(scan_conv) ax[1].axis('off') ax[1].set_title('Data_distorted') ax[2].imshow(deconvolved1) ax[2].axis('off') ax[2].set_title('restoration1') fig.tight_layout() plt.show()
问题原因与解决方法
- 参数不识别问题:0.19.x版本的
unsupervised_wiener迭代次数参数名为n_iter,并非旧版本/文档笔误标注的max_num_iter,参数名不匹配是报错的核心原因。不要依赖文档标注的参数名,可直接在代码中运行以下命令查看当前环境下函数的真实参数列表,避免版本差异、安装源差异导致的参数不匹配:import inspect print(inspect.signature(restoration.unsupervised_wiener)) - 条纹伪影与像素异常值问题:
- 无监督维纳反卷积属于迭代类病态逆问题求解,默认迭代次数较少时参数未收敛,高频分量估计偏差会产生明显振铃条纹,将迭代次数设置为100~300次可显著改善收敛效果
- 输入图像需提前归一化到[0,1]数值区间,数值范围不匹配会导致噪声功率估计偏差,产生溢出的异常像素值
- 点扩散函数(PSF)的形状、尺寸与实际退化过程不匹配是振铃伪影的最常见诱因,需尽可能校准PSF的精度
- 得到复原结果后可对像素值做截断,消除数值求解过程中产生的极端异常值:
deconvolved_res = np.clip(deconvolved_res, scan_conv.min(), scan_conv.max())
内容的提问来源于stack exchange,提问作者Bende
相关产品推荐
相关产品推荐

