Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do convolution matrix operation in numpy?

Tags:

python

numpy

Is there a way to do convolution matrix operation using numpy?

The numpy.convolve only operates on 1D arrays, so this is not the solution.

I rather want to avoid using scipy, since it appears to be more difficult getting installed on Windows.

like image 573
EquipDev Avatar asked Apr 12 '17 15:04

EquipDev


3 Answers

You have scipy's ndimage which allows you to perform N-dimensional convolution with convolve:

from scipy.ndimage import convolve
convolve(data, kernel)

I know that you said that you want to avoid scipy... but I would advise against it. Scipy is great in so many ways. If you want to install it on windows, try Anaconda Distribution, which already comes with scipy installed.

Anaconda is a multiplatform python distribution that comes with all the essential libraries (including a lot of scientific computing libraries) preinstalled, and tools like pip or conda to install new ones. And no, they don't pay me to advertise it :/ but makes your multiplatform life much easier.

like image 115
Imanol Luengo Avatar answered Oct 28 '22 02:10

Imanol Luengo


I would highly recommend using openCV for this purpose. However in principle you can almost directly use the "pseudo-code" on the wiki-article on kernel convolution to create your own function...

ks = (kl-1)/2 ## kernels usually square with odd number of rows/columns
kl = len(kernel)
imx = len(matrix)
imy = len(matrix[0])
for i in range(imx):
  for j in range(imy):
    acc = 0
    for ki in range(kl): ##kernel is the matrix to be used
      for kj in range(kl):
        if 0 <= i-ks <= kl: ## make sure you don't get out of bound error
          acc = acc + (matrix[i-ks+ki][j-ks+kj] * kernel[ki][kj]) 
  matrix[i][j] = acc

this should in principle do the trick (but I have not yet tested it...)

I hope this is helpful.

like image 29
Chris Avatar answered Oct 28 '22 03:10

Chris


I used the example on the wikipedia article and extrapolated it for every element in the matrix:

def image_convolution(matrix, kernel):
    # assuming kernel is symmetric and odd
    k_size = len(kernel)
    m_height, m_width = matrix.shape
    padded = np.pad(matrix, (k_size-1, k_size-1))
    
    # iterates through matrix, applies kernel, and sums
    output = []
    for i in range(m_height):
        for j in range(m_width):
            output.append(np.sum(padded[i:k_size+i, j:k_size+j]*kernel))

    output=np.array(output).reshape((m_height, m_width))
    return output

padded[i:k_size+i, j:k_size+j] is a slice of the array the same size as the kernel.

Hope this is clear and helps.

like image 27
Erick Martinez Avatar answered Oct 28 '22 03:10

Erick Martinez