2015-05-16 10 views
5

Unten ist der aktuelle Arbeitscode in Python mit PIL zum Hervorheben der Differenz zwischen den beiden Bildern. Aber der Rest der Bilder ist schwarz.Vergleichen Sie zwei Bilder und markieren Sie Unterschiede auf dem zweiten Bild

Momentan möchte ich den Hintergrund auch zusammen mit dem hervorgehobenen Bild zeigen.

Gibt es trotzdem ich kann die Show den Hintergrund heller halten und nur die Unterschiede hervorheben.

from PIL import Image, ImageChops 
point_table = ([0] + ([255] * 255)) 

def black_or_b(a, b): 
    diff = ImageChops.difference(a, b) 
    diff = diff.convert('L') 
    # diff = diff.point(point_table) 
    h,w=diff.size 
    new = diff.convert('RGB') 
    new.paste(b, mask=diff) 
    return new 

a = Image.open('i1.png') 
b = Image.open('i2.png') 
c = black_or_b(a, b) 
c.save('diff.png') 

! https://drive.google.com/file/d/0BylgVQ7RN4ZhTUtUU1hmc1FUVlE/view?usp=sharing

Antwort

5

PIL hat einige handlicher Bildmanipulationsmethoden haben, aber auch viele Nachteile, wenn man will Verarbeitung zu tun ernst Bild starten -

Die meisten Python lterature werden Sie empfehlen wechseln zu verwenden NumPy über Ihre Pixeldaten, die geben Sie volle Kontrolle - Andere Bildgebungsbibliotheken wie Leptonica, gegl und vips haben alle Python-Bindungen und eine Reihe von netten Funktion für Bildzusammensetzung/Segmentierung.

In diesem Fall ist die Sache, sich vorzustellen, wie man würde auf den gewünschten Ausgang in einem Bildbearbeitungsprogramm erhalten: Sie ein schwarzes haben würde (oder eine andere Farbe) Schatten über das Originalbild zu platzieren, und das zweite Bild über diese, Paste, aber eine Schwelle verwendet (dh ein pixel entweder gleich oder ist anders - alle Zwischenwerte auf „verschiedene gerundet werden sollte) der Differenzen als Maske auf das zweite Bild

.

Ich habe Ihre Funktion geändert, um eine solche Zusammensetzung zu erstellen -

from PIL import Image, ImageChops, ImageDraw 
point_table = ([0] + ([255] * 255)) 

def new_gray(size, color): 
    img = Image.new('L',size) 
    dr = ImageDraw.Draw(img) 
    dr.rectangle((0,0) + size, color) 
    return img 

def black_or_b(a, b, opacity=0.85): 
    diff = ImageChops.difference(a, b) 
    diff = diff.convert('L') 
    # Hack: there is no threshold in PILL, 
    # so we add the difference with itself to do 
    # a poor man's thresholding of the mask: 
    #(the values for equal pixels- 0 - don't add up) 
    thresholded_diff = diff 
    for repeat in range(3): 
     thresholded_diff = ImageChops.add(thresholded_diff, thresholded_diff) 
    h,w = size = diff.size 
    mask = new_gray(size, int(255 * (opacity))) 
    shade = new_gray(size, 0) 
    new = a.copy() 
    new.paste(shade, mask=mask) 
    # To have the original image show partially 
    # on the final result, simply put "diff" instead of thresholded_diff bellow 
    new.paste(b, mask=thresholded_diff) 
    return new 


a = Image.open('a.png') 
b = Image.open('b.png') 
c = black_or_b(a, b) 
c.save('c.png') 
+0

Dank JSbueno .this ist, was ich suchte for..cheers –

+0

Na gut - die erwartete Gewohnheit hier ist, klicken Sie auf "akzeptieren" für die Antwort, anstatt zu senden Prost! :-) Danke trotzdem. – jsbueno

+1

BTW, für jemanden, der dies nur für ein paar Bilder benötigt und nicht mit Python-Installationen umgehen möchte - ich habe hier interaktiv über GIMP geantwortet: http://graphicdesign.stackexchange.com/questions/27484/get -difference-zwischen-zwei-Bilder-als-transparent-Bild-in-Gimp/27486 # 27486 – jsbueno

1

Hier ist eine Lösung libvips mit:

import sys 

from gi.repository import Vips 

a = Vips.Image.new_from_file(sys.argv[1], access = Vips.Access.SEQUENTIAL) 
b = Vips.Image.new_from_file(sys.argv[2], access = Vips.Access.SEQUENTIAL) 

# a != b makes an N-band image with 0/255 for false/true ... we have to OR the 
# bands together to get a 1-band mask image which is true for pixels which 
# differ in any band 
mask = (a != b).bandbool("or") 

# now pick pixels from a or b with the mask ... dim false pixels down 
diff = mask.ifthenelse(a, b * 0.2) 

diff.write_to_file(sys.argv[3]) 

mit PNG-Bildern, die meist CPU-Zeit in PNG ausgegeben wird, lesen und schreiben, so vips nur ein bisschen schneller als die PIL Lösung.

libvips verwendet viel weniger Speicher, besonders für große Bilder. libvips ist eine Streaming-Bibliothek: Sie kann das Ergebnis laden, verarbeiten und gleichzeitig speichern. Es muss nicht das gesamte Bild in den Arbeitsspeicher geladen werden, bevor es mit der Arbeit beginnen kann.

Für ein 10.000 x 10.000 RGB tif, libvips ist etwa doppelt so schnell und benötigt ca. 1/10tel den Speicher.

Verwandte Themen