I am using a direct convolution algorithm to compute the convolution between this image:
and this kernel:
I am using the implementation in astropy for the direct convolution.
This results in the following convolution, leaving all settings (including boundary handling) to the defaults, i.e. astropy.convolution.convolve(image,kernel):
This convolution has some puzzling artifacts. In particular, there is a 'square' pattern at an offset of about 50 pixels from the edge. It seems to me that this is due to the extent of the kernel; even though the kernel is formally 249x249 in size, most information is clearly contained within a radius of about 100 pixels -- which means that we presumably run into trouble when the kernel is applied to the edges.
Which brings me to my questions:
In CNNs, it is well-known that checkerboard artifacts are caused by two processes: forward-propagation of upsampling layers and backpropagation of convolutional layers.
The visual effect of oscillating colors or weaves to produce a grid in the appearance of a chess or checkerboard. © 2022 Cotton Incorporated.
Sub-pixel convolution [1,14] is a specific implementation of a deconvolution layer that can be interpreted as a standard convolution in low-resolution space followed by a periodic shuffling operation as shown in Figure 2.
Transposed convolutions are standard convolutions but with a modified input feature map. The stride and padding do not correspond to the number of zeros added around the image and the amount of shift in the kernel when sliding it across the input, as they would in a standard convolution operation.
Yes, this is an edge-effect issue which comes about because you have negative values in your kernel. As soon as the kernel is partially off the edge, the mean value of the kernel starts changing.
One solution would be to use boundary='fill'
and fill_value=(mean of your image)
or something along those lines. It might not completely remove these artifacts, but it ought to reduce them.
For the FFT convolution part of your question - the FFT convolution will do the same thing. However, edge padding is necessary for the FFT convolution, because otherwise the boundary will wrap. Not padding (e.g., convolve_fft(..., boundary='wrap')
) will actually get rid of your artifacts, but it will do it in a way that may surprise you, since it will be averaging pixels from the right side of the image with the left side.
astropy's convolve
and convolve_fft
both will do the same thing given the same boundary
conditions, but the naive fft convolution (i.e., conv = ifft(fft(im) * fft(kernel))
) is equivalent to using boundary='wrap'
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With