I am trying to perform 2D matrix processing (convolution) by applying a kernel/filter to a large matrix. There is a built-in function convolve that can perform convolution. It offers three different types of convolution, namely circular, open and filter. It looks like filter is what I am looking for, but it isn't.
Let's consider two matrices:
# "large" matrix
(largemx <- matrix(1:16, nrow=4, byrow = T))
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 8
[3,] 9 10 11 12
[4,] 13 14 15 16
# kernel
(kernel <- rbind(1,c(1, 0, 1), 1))
[,1] [,2] [,3]
[1,] 1 1 1
[2,] 1 0 1
[3,] 1 1 1
This is what I am getting with the filter argument (a vector of 8 elements):
convolve(largemx, kernel, type="f")
[1] 61 63 65 67 69 71 73 75
With type="open" the output is a vector of 17 elements:
convolve(largemx, kernel, type="o")
[1] 1 6 15 28 29 31 37 47 61 63 65 67 69 71 73 75 72 65 54 39 40 36 28 16
The circular type convolution requires the kernel to be the same size as the matrix and the output is a matrix too:
(cbind(rbind(kernel,0),0) -> kernelc)
[,1] [,2] [,3] [,4]
[1,] 1 1 1 0
[2,] 1 0 1 0
[3,] 1 1 1 0
[4,] 0 0 0 0
convolve(largemx, kernelc, type="c")
[,1] [,2] [,3] [,4]
[1,] 48 56 52 52
[2,] 80 88 84 84
[3,] 64 72 68 68
[4,] 64 72 68 68
Below follows the desired output. I would very much appreciate if someone could clarify whether any of those types of convolution could be used for the task and maybe explain how the calculations are performed.
[,1] [,2] [,3] [,4]
[1,] 13 22 27 18
[2,] 28 48 56 37
[3,] 48 80 88 57
[4,] 33 58 63 38
Inspired by this question on CGCC
imagine::convolution2D(rbind(0, cbind(0,largemx, 0), 0), kernel)