2016-05-20 13 views
1

So habe ich zwei PIL Bilder von RGBA. Was ich tun möchte, ist es, alle Orte zu finden, wo die RGB-Werte gleich sind und Alpha ist 255. Es sieht wie folgt aus:Numpy mit wo mit verschiedenen Array-Größen

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 

Aber dies führt zu operands could not be broadcast together with shapes (32,32,3) (32,32).
Ich dachte nicht, dass ich versuchte, sie zusammen zu übertragen, ich wollte nur die Indices finden, die ich wiederum in dieser Aussage ausstrahlt. Gibt es eine andere Möglichkeit, dies zu tun, oder eine Möglichkeit, ungleiche Formen nicht zu übertragen?

+1

'img1 [:,:,: -1]' Ergebnisse in Form einer Anordnung von '32, 32, 3'. 'img1 [:,:, 3]' ergibt ein Array mit der Form '32, 32'. – mgilson

+0

@mgilson ja ich weiß. Aber ist das, was ich versuche zu erreichen, klar? Ich dachte das obige würde funktionieren, weil ich dachte "np.where" würde mehrere "where" Anweisungen erlauben, nicht zusammen übertragen – ZWiki

+0

Und um auf etwas Stil hinzuweisen, ist die '\' for line Fortsetzung hier unnötig. Python verkettet Zeilen, die sich in nicht geschlossenen Klammern, Klammern oder Klammern befinden (wie es hier der Fall ist). In der Tat empfiehlt PEP 8 (der "offizielle" Styleguide), Klammern zu verwenden, um Zeilen fortzusetzen und _never_ die '\' für Zeilenfortsetzung zu verwenden. – mgilson

Antwort

3

Verwenden .all(axis=-1) Orte zu finden, wo alle drei RGB-Werte gleich sind:

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

Als mgilson points out hat (img1[..., :-1] == img2[..., :-1])(32, 32, 3) zu formen. Der Aufruf .all(axis-1) reduziert die letzte Achse auf einen Skalar Booleschen Wert, so

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

(32, 32) Form hat. Dies entspricht der Form (img1[..., 3] == 255), so dass diese booleschen Arrays mit bitwise-and operator, & kombiniert werden können.

+2

+1 Ich denke, dass die Reduzierung entlang der letzten Achse das ist, was OP verlangt. Ich frage mich, ob OP sicherstellen will, dass die Alpha-Werte auch gleich sind ... (In diesem Fall vereinfacht es sich zu '(img1 == img2) .all (axis = -1) 'ohne die Ellipse) – mgilson

+0

Awesome! Genau das wollte ich. Und ja @mgilson konnte ich auch hinzufügen, um den Alpha-Check zu bekommen. Vielen Dank! – ZWiki

+0

Ich werde auch darauf hinweisen, dass '&' ist _nicht_ der logische und Operator (obwohl es häufig als solcher verwendet wird). Es ist der _binary_ '&' -Operator, der speziell dafür vorgesehen ist, ein Array von logischen Daten zurückzugeben, wenn sowohl die rechte als auch die linke Seite logische Arrays sind. Für _logical_ und, habe ich immer empfohlen, 'np.logical_and' zu verwenden (was nicht die Präzedenzfälle hat, die der' & 'Operator hat, die Leute beißen, die versuchen, es zu benutzen) ... – mgilson