Convolution artifacts

I use the direct convolution algorithm to calculate the convolution between this image:

enter image description here

and this is the core:

enter image description here

I use astropy implementation for direct convolution.

This leads to the following convolution, leaving all settings (including border processing) with default values, i.e. astropy.convolution.convolve (image, kernel):

enter image description here

There are some mysterious artifacts in this bundle. In particular, there is a “square” pattern with an offset of about 50 pixels from the edge. It seems to me that this is due to the size of the kernel; even if the kernel formally has a size of 249x249, most of the information is clearly contained in a radius of about 100 pixels, which means that we are presumably faced with problems when the kernel is applied to the edges.

Which brings me to my questions:

  • Is this hypothesis correct - that it really is a problem with the edge?
  • How do I solve this? I don’t know how to justify the use of various treatments (zero filling, interpolation, packaging, ...) I’m sure that different cases require different solutions, but I’m not sure how to solve it ...
  • Just ... trying to understand the difference between using a direct algorithm and convolution FFT. If the core and the image are equally large, zero addition is not required for FT convolution; no edge effects were detected. For the direct method, you will inadvertently have some edge processing ... are there any results, even equivalent ones? Because, in principle, only their performance should be different, right?
+5
source share
1 answer

Yes, this is an edge effect problem that arises from the fact that you have negative values ​​in your kernel. As soon as the core partially leaves the edge, the average value of the core begins to change.

One solution would be to use boundary='fill' and fill_value=(mean of your image) or something similar to these lines. This may not completely remove these artifacts, but this should reduce them.

For the FFT convolution part of your question, the FFT convolution will do the same. However, edge striping is required for FFT convolution, because otherwise the boundary will be completed. Not padding (e.g. convolve_fft(..., boundary='wrap') ) will actually save you from your artifacts, but it will do it in a way that may surprise you, since it will average the pixels on the right side of the image on the left side .

astropy convolve and convolve_fft will both do the same under the same boundary conditions, but a naive fft convolution (i.e. conv = ifft(fft(im) * fft(kernel)) ) is equivalent to using boundary='wrap' .

+7
source

Source: https://habr.com/ru/post/1238511/


All Articles