views:

239

answers:

4

I'm using numpy to build pixel arrays. An 800x600 image is an 3-dimensional array of uint8, 800x600x3. I also have a similar array with a fixed pattern (a checkerboard, see here). I have another array, 800x600 of mask values. Where the mask is zero, I want to copy the pattern pixel to the image pixel. Where the mask is not zero, I want to leave the image pixel alone.

>>> image.shape
(800, 600, 3)
>>> chex.shape
(800, 600, 3)
>>> mask.shape
(800, 600)

This feels like it should work:

image[mask == 0,...] = chex

but gives "ValueError: array is not broadcastable to correct shape".

What do I use to copy chex pixels to image pixels where mask is zero?

A: 

Try:

image[mask[:] == 0,...] = chex[mask[:] == 0,...]
ezod
"ValueError: array is not broadcastable to correct shape"
Ned Batchelder
A: 

This is not an answer to your question as posed, but in the Python Image Library (PIL), I think the function Image.composite does what you want.

Jive Dadson
+3  A: 
idx=(mask==0)
image[idx]=chex[idx]

Note that image has shape (800,600,3), while idx has shape (800,600). The rules for indexing state

if the selection tuple is smaller than n, then as many : objects as needed are added to the end of the selection tuple so that the modified selection tuple has length N.

Thus indexing arrays have a sort of broadcasting ability of their own. idx's shape gets promoted to (800,600,:)

unutbu
A: 

I used arrays of 8x6x3, 8x6x3, and 8x6 to represent your image array, checker array, and mask array respectively.

# first create mini-versions of your arrays:
mask = NP.random.random_integers(0, 1, 48).reshape(8, 6)
img = NP.random.random_integers(3, 9, 8*6*3).reshape(8, 6, 3)
chk = NP.ones((8, 6, 3))

# all the work done in these two lines
mask = mask[:,:,NP.newaxis]
res = NP.where(mask==0, chk, img)
doug