# Why does ImageDeconvolve not restore this image?

The ImageDeconvolve documentation page has many examples where ImageDeconvolve restores blurred images almost perfectly. I assume that the source images were prepared so as to make this possible.

Why does deconvolution fail so badly in this example then? How should one perform the convolution so that deconvolution can succeed?

im = ExampleData[{"TestImage", "Couple2"}]


ImageDeconvolve[ImageConvolve[im, GaussianMatrix[10]], GaussianMatrix[10]]


Update

George Varnavides shows in a comment that convolution must be performance with Padding -> "Reversed". This restores the image:

ImageDeconvolve[
GaussianMatrix[10]]


There is also a note under Details for ImageDeconvolve:

Note that ImageDeconvolve and ImageConvolve use different default settings for Padding.

There are some remaining mysteries though:

• ImageDeconvolve accepts all documented Padding settings, in the sense that it will not show an error messages when these are provided, but it will if I use a different string. However, its output is precisely the same regardless of this setting. Is this expected?

{a1, a2, a3, a4} = ImageDeconvolve[
GaussianMatrix[10], Padding -> #] & /@ {"Fixed", "Periodic",
"Reflected", "Reversed"}

Equal @@ {a1, a2, a3, a4}
(* True *)

• Is there any hope for deconvolving an image prepared with ImageConvolve and Padding -> "Fixed" or Padding -> 0.5 or Padding -> "Relfected", etc.?

• Look at the last example under Properties & Relations. Seems like you need Padding->"Reversed" in your ImageConvolve call. Jun 23 at 13:19
• @GeorgeVarnavides Thanks for the pointer! Jun 23 at 13:33
• The Gaussian matrix span should be linked to the frequency to be recovered. High frequency, low Gaussian matrix span. See Shannon theory. Jun 23 at 16:37

The answer is that you are asking too much of deconvolution. The following code shows images blurred and refocused with different degrees of blurring.

Do[blur = ImageConvolve[im, GaussianMatrix[n]];
focused = ImageDeconvolve[blur, GaussianMatrix[n]];
CellPrint[{blur, focused}], {n, 2, 6, 2}]


Mathematically, it is informative to consider the convolution in the frequency domain, where it becomes multiplication by a frequency mask. The Gaussian filter mask drops nearly to zero at high frequencies. Recovering these by deconvolution involves dividing by these near zero values. However, the values in the spectrum of the blurred image will be dominated by rounding errors at high frequencies. Consequently, as blurring increases the reconstructed image becomes dominated by reconstruction errors. You can clearly see the periodic nature of these.

Deconvolution cannot recover features that have been lost, but it can certainly degrade the image in trying. With a radius of 2 there is some recovery, but at larger radii, artefacts dominate.

Note that to be practically useful, deconvolution needs to be robust to e.g. addition of noise, minor differences in the point spread function.

If you exactly reverse the convolution process, you may manage to get unrepresentatively good results. This is what happens (I think) if you exactly match Padding and other options.

Update

An important factor is what happens at the edges of the image. Ideally, we might hope that edge effects would be limited to a small area near the edge. When the image is blurred, information is spread into pixels outside the image (which are then discarded).

We can see that with large filter radii, reconstruction is highly non-local. Consider the alternating bright/dark strip at the top of the image. Reconstruction errors line up with these in vertical stripes. The error effects are non-local.

Further Update

I think we can see the importance of edge effects by cropping the blurred image prior to deconvolution. In the examples shown below, we remove 1 pixel from each side. The result (with a large radius) is that deconvolution fails completely.

Do[blur = ImageConvolve[im, GaussianMatrix[n], Padding -> "Reversed"];
crop = ImageCrop[blur, ImageDimensions[blur] - 2];
focused = ImageDeconvolve[blur, GaussianMatrix[n]];
focusedcrop = ImageDeconvolve[crop, GaussianMatrix[n]];
s = " Radius " <> IntegerString[n];
CellPrint[{"Blurred" <> s, blur, "Cropped" <> s, crop,
"Focused" <> s, focused, "Cropped & Focused" <> s,
focusedcrop}], {n, 2, 10, 2}]


We can also see that reconstruction is not robust to additive noise. Here I add barely perceptible Gaussian noise, but the reconstruction is severely degraded.

Do[blur =
noisy = ImageEffect[blur, {"GaussianNoise", 0.01}];
focused = ImageDeconvolve[blur, GaussianMatrix[n]];
noisyfocused = ImageDeconvolve[noisy, GaussianMatrix[n]];
s = " Radius " <> IntegerString[n];
CellPrint[{"Blurred" <> s, blur, "Noisy" <> s, noisy,
"Focused" <> s, focused, "Noisy & Focused" <> s,
noisyfocused}], {n, 2, 10, 2}]


Conclusion

The Mathematica documentation is severely misleading. The deconvolution examples show correction of blurring that is not remotely achievable under real-world conditions.

• It seems to me that it is what you say under "Update" that is the most relevant Jun 24 at 13:05