You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ArrayFire中卷积后反卷积无法还原原图的原因探究

图像反卷积结果偏差问题分析与解决

问题描述

使用C++ ArrayFire库开发图像去模糊应用,测试场景为5×5原图与3×3全1归一化核:

  • 通过af::convolve2完成卷积
  • 调用af::iterativeDeconv分别用Richardson-Lucy(RL)和Landweber算法反卷积
  • 结果与原图差异明显,Landweber算法偏差远大于RL;增加迭代次数未达到预期收敛效果

测试代码

// Create a simple 5x5 input image
float h_image[25] = {
    1, 1, 1, 1, 1,
    1, 2, 2, 2, 1,
    1, 2, 3, 2, 1,
    1, 2, 2, 2, 1,
    1, 1, 1, 1, 1,
};
af::array image(5, 5, h_image);

// Create a simple 3x3 kernel (normalized such that sum == 1)for convolution
float h_kernel[9] = {
    0.111, 0.111, 0.111,
    0.111, 0.111, 0.111,
    0.111, 0.111, 0.111,
};
af::array kernel(3, 3, h_kernel);

// Perform convolution
af::array convolved = af::convolve2(image, kernel);

// Perform deconvolution
float relaxation_factor = 0.64;
int num_iterations = 128;
af::array deconvolved_richardson_lucy = af::iterativeDeconv(convolved, kernel, num_iterations, relaxation_factor, AF_ITERATIVE_DECONV_RICHARDSONLUCY);
af::array deconvolved_landweber = af::iterativeDeconv(convolved, kernel, num_iterations, relaxation_factor, AF_ITERATIVE_DECONV_LANDWEBER);

// Output results
af::print("Original Image", image);
af::print("Convolved Image", convolved);
af::print("Deconvolved Image - Richardson Lucy", deconvolved_richardson_lucy);
af::print("Deconvolved Image - Landweber", deconvolved_landweber);

输出结果

Original Image
[5 5 1 1]
    1.0000     1.0000     1.0000     1.0000     1.0000 
    1.0000     2.0000     2.0000     2.0000     1.0000 
    1.0000     2.0000     3.0000     2.0000     1.0000 
    1.0000     2.0000     2.0000     2.0000     1.0000 
    1.0000     1.0000     1.0000     1.0000     1.0000 

Convolved Image
[5 5 1 1]
    0.5550     0.8880     0.9990     0.8880     0.5550 
    0.8880     1.5540     1.7760     1.5540     0.8880 
    0.9990     1.7760     2.1090     1.7760     0.9990 
    0.8880     1.5540     1.7760     1.5540     0.8880 
    0.5550     0.8880     0.9990     0.8880     0.5550 

Deconvolved Image - Richardson Lucy
[5 5 1 1]
    0.3774     0.5695     1.0053     0.5695     0.3774 
    0.5695     1.2211     2.2630     1.2211     0.5695 
    1.0053     2.2630     4.7015     2.2630     1.0053 
    0.5695     1.2211     2.2630     1.2211     0.5695 
    0.3774     0.5695     1.0053     0.5695     0.3774 

Deconvolved Image - Landweber
[5 5 1 1]
   23.2821    32.3862    71.3124    32.3862    23.2820 
   32.3862    80.7867   151.3048    80.7867    32.3862 
   71.3124   151.3049   276.6479   151.3048    71.3124 
   32.3862    80.7867   151.3048    80.7867    32.3862 
   23.2821    32.3862    71.3124    32.3862    23.2820 

问题原因分析

1. 卷积边界填充带来的误差放大

af::convolve2默认使用零填充(zero-padding),导致图像边缘区域的卷积结果与真实值偏差显著(比如原图左上角1,卷积后得到0.555,是因为边缘只有5个像素被核覆盖,其余4个是0)。反卷积本身是病态问题,这种边界误差会被迭代过程不断放大,Landweber算法对这类误差的敏感度远高于RL算法,直接导致结果发散。

2. Landweber算法参数设置不合理

Landweber算法收敛的前提是松弛因子小于2/L(L为卷积算子的最大特征值)。对于全1归一化核,L=1(核的和为1,对应最大特征值),理论上松弛因子应小于2,但实际中过大的松弛因子(如0.64)加上128次迭代,会导致算法偏离收敛方向,最终数值爆炸。

3. 核的精度不足

手动设置的0.111与真实值1/9≈0.111111...存在精度误差,卷积后会引入微小偏差,在反卷积的迭代过程中被累积放大。

4. 反卷积的固有病态性

反卷积是典型的不适定问题,即使无噪声,微小的输入误差(如边界填充、核精度)也会被迭代过程放大,导致结果偏离原图。

解决建议

1. 调整边界填充模式

将卷积和反卷积的边界模式改为对称填充(AF_PAD_SYM)或复制填充(AF_PAD_REPLICATE),减少边缘区域的不连续性误差:

// 卷积时指定边界模式
af::array convolved = af::convolve2(image, kernel, AF_CONV_DEFAULT, AF_PAD_SYM);

2. 优化Landweber算法参数

  • 降低松弛因子:比如设置为0.1,避免迭代发散
  • 减少迭代次数:从128次降至10-20次,观察收敛情况
float relaxation_factor = 0.1;
int num_iterations = 15;
af::array deconvolved_landweber = af::iterativeDeconv(convolved, kernel, num_iterations, relaxation_factor, AF_ITERATIVE_DECONV_LANDWEBER);

3. 提高核的精度

使用精确的归一化值代替手动输入的0.111:

float h_kernel[9];
float kernel_val = 1.0f / 9.0f;
std::fill(h_kernel, h_kernel+9, kernel_val);
af::array kernel(3, 3, h_kernel);

4. 加入正则化约束

对于RL算法,可通过调整松弛因子实现隐式正则化;Landweber可考虑使用带正则化的版本,或在迭代过程中加入梯度裁剪,抑制误差放大。

内容的提问来源于stack exchange,提问作者speca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 01:15:56