Chrispresso
Chrispresso

Reputation: 4081

Numpy using where with varying array sizes

So I have two PIL images of RGBA. What I want to do is find all locations where the RGB values are the same and alpha is 255. It looks like this:

from PIL import Image
import numpy as np
img1 = np.array(Image.open(/path/to/img1).convert('RGBA'), float).reshape(32,32,4)
img2 = np.array(Image.open(/path/to/img2).convert('RGBA'), float).reshape(32,32,4)

# Checks to see if RGB of img1 == RGB of img2 in all locations that A=255
np.where((img1[:,:,:-1] == img2[:,:,:-1]) &\ # RGB check
         (img1[:,:,3] == 255)) # Alpha check

But this results in operands could not be broadcast together with shapes (32,32,3) (32,32).
I didn't think I was trying to broadcast them together, I just wanted to find the indeces, which I guess in turn broadcasts them in this statement. Is there another way to do this, or a way to not broadcast unequal shapes?

Upvotes: 1

Views: 54

Answers (1)

unutbu
unutbu

Reputation: 880289

Use .all(axis=-1) to find locations where all three RGB values are equal:

np.where((img1[..., :-1] == img2[..., :-1]).all(axis=-1) 
         & (img1[..., 3] == 255)) 

As mgilson points out, (img1[..., :-1] == img2[..., :-1]) has shape (32, 32, 3). Calling .all(axis-1) reduces the last axis to a scalar boolean value, so

(img1[..., :-1] == img2[..., :-1]).all(axis=-1) 

has shape (32, 32). This matches the shape of (img1[..., 3] == 255), so these boolean arrays can be combined with the bitwise-and operator, &.

Upvotes: 3

Related Questions