ArrayFire: Why doesn't convolution followed by deconvolution return the original image (not even close)

73 views Asked by At

I'm trying to perform a convolution and deconvolution using ArrayFire in C++ for an image deblurring application. For testing purposes I have a 5x5 image and a 3x3 kernel. I convolve the image using af::convolve2 and then deconvolve it using af::iterativeDeconv. However, the deconvolved values do not match the original image.

Interestingly, the mismatch is bigger when using the Landweber deconvolution algorithm as compared to the Richardson-Lucy algorithm.

Here is my code:

    // 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);

The output is:

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 

Why aren't the values in the deconvolved image matching the original image? Why is there this huge difference between Richardson-Lucy and Landweber? Clearly, I must be missing something. Any guidance in the right direction would be highly appreciated.

I've experimented with various kernels and different numbers of iterations for the deconvolution algorithms. My expectation was that the deconvolved image would more closely resemble the original image as the number of iterations increased (up to a certain number of iterations), but this is not the case.

0

There are 0 answers