1

I have a single image of shape img.shape = (500, 439, 3)

The convolution function is

def convolution(image, kernel, stride=1, pad=0):

    n_h, n_w, _ = image.shape

    f = kernel.shape[0]
    kernel = np.repeat(kernel[None,:], 3, axis=0)

    n_H = int(((n_h + (2*pad) - f) / stride) + 1)
    n_W = int(((n_w + (2*pad) - f) / stride) + 1)
    n_C = 1

    out = np.zeros((n_H, n_W, n_C))

    for h in range(n_H):
        vert_start = h*stride
        vert_end = h*stride + f

        for w in range(n_W):
            horiz_start = w*stride
            horiz_end = w*stride + f

            for c in range(n_C):
                a_slice_prev = image[vert_start:vert_end,
                                     horiz_start:horiz_end, :]

                s = np.multiply(a_slice_prev, kernel)
                out[h, w, c] = np.sum(s, dtype=float)

    return out

I want to see the image after any kernel/filter applied to the image, so I got the following

img = plt.imread('cat.png')
kernel = np.arange(25).reshape((5, 5))
out2 = convolution(img, kernel)
plt.imshow(out2)
plt.show()

I get

s = np.multiply(a_slice_prev, kernel)

ValueError: operands could not be broadcast together with shapes (5,5,3) (3,5,5)

Community
  • 1
  • 1
PolarBear10
  • 2,065
  • 7
  • 24
  • 55
  • You can do this simply with pytorch.Implementation here https://stackoverflow.com/a/62678843/5484902 – Gal_M Jul 02 '20 at 07:19

2 Answers2

2

np.multiply is doing an elementwise multiplication. However, your arguments do not have matching dimensions. You could transpose your kernel or image with this to ensure it can work:

kernel = kernel.transpose()

You could do this prior to your np.multiply call.

relh
  • 146
  • 1
  • 6
  • I quickly updated my question to illustrate what I got, it seems that the ouput gets a CYAN overlay, is the logic of the convolution correct ? – PolarBear10 Feb 10 '20 at 21:23
  • I just realized I had to change the plot to `plt.imshow(np.squeeze(out2))` to actually plot it – PolarBear10 Feb 10 '20 at 21:40
0

ValueError: operands could not be broadcast together with shapes (5,5,3) (3,5,5)

Since, Convolution is element-wise multiplication, your shapes should be (5,5,3) for the image region and (5,5,3) for the kernel, thus repeat your kernel like this:

kernel = np.arange(25).reshape((5, 5, 1))
kernel = np.repeat(kernel, 3, axis=2)
trsvchn
  • 8,033
  • 3
  • 23
  • 30