1

This is a follow-up question from this. Basically what I want to do is to simply subtract each image from the mean.

Based on this issue on GitHub and this other similar question, and also this classification example When we feed the cropped version of images to the network, we need to subtract the mean pixel using something like this:

mu = mean_file.mean(1).mean(1)

but the irony is when I want to do this:

.. = (img[:,0:224,0:224] - mu)

I get ValueError: operands could not be broadcast together with shapes (3,224,224) (3,). I'm not well-versed at Python and Numpy and can't figure out what the error message is trying to convey.

Currently, I'm cropping the mean file, which is not ideal, but is better than nothing.

.. = (img[:,0:224,0:224] - mean_image[:,0:224,0:224])
halfer
  • 19,824
  • 17
  • 99
  • 186
Hossein
  • 24,202
  • 35
  • 119
  • 224

2 Answers2

1

replace

mu = mean_file.mean(1).mean(1)

with

mu = mean_file.mean(1).mean(1)[:,None,None]

It seems like you are trying to subtract a 1D vector (shape of (3,)) from a 3D array (shape of (3,224,224)). In order to do so numpy needs to broadcast the 1D vector into the dimensions of the 3D array (much like Matlab's ). To help numpy understand what dimensions to broadcast, one needs to add singleton dimensions to the 1D vector:

mu[:,None,None]

Is now of shape (3,1,1) and this should enable numpy to perform the subtraction correctly.

Shai
  • 111,146
  • 38
  • 238
  • 371
  • Thank you very much, would you explain a bit more whats going on up there? – Hossein Jul 25 '17 at 15:28
  • by the way Now I get : ValueError: operands could not be broadcast together with shapes (3,224,224) (1,1,1,256) – Hossein Jul 25 '17 at 15:29
  • I need to add that, even if I use ` mu = np.array([ 104, 117, 123])#imagenet mean` and use mu this way, I get the same error! – Hossein Jul 25 '17 at 15:38
  • 1
    Thanks alot espacially for the nice explanation. Yet this did not solve my problem. I noticed I had to transpose my image before subtracting the mean since I was reading images off lmdb! – Hossein Jul 26 '17 at 14:41
0

I noticed since I was reading images off the lmdb, I had to do the following in order to get everything working!:

img = np.array(img.transpose(2,1,0),dtype=np.float32)
img -= mean_image[0].mean(1).mean(1)
#transpose back to the original state
img = img.transpose(2,1,0) 
Hossein
  • 24,202
  • 35
  • 119
  • 224
  • wouldn't it be better to transpose the mean once instead of the image twice? – Shai Jul 26 '17 at 16:20
  • @Shai, Thats what I thought and then tested! but that didnt work, it would fail with this error message : `ValueError: operands could not be broadcast together with shapes (3,224,224) (256,) (3,224,224)` – Hossein Jul 26 '17 at 17:27