2015-05-16 8 views
5

Poniżej znajduje się bieżący działający kod w Pythonie za pomocą PIL dla podświetlenia różnicy między dwoma obrazami. Ale reszta zdjęć jest czarna.Porównaj dwa obrazy i wyróżnij różnice wzdłuż drugiego obrazu

Obecnie chcę pokazać tło wraz z podświetlonym obrazem.

Czy mogę mimo to utrzymać tło w tle i po prostu wyróżnić różnice.

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

Odpowiedz

5

PIL ma kilka przydatnych metod manipulacji obrazem, ale także wiele niedociągnięć, gdy ktoś chce zacząć robić poważne przetwarzanie obrazu -

Większość Python lterature wam polecić, aby przełączyć używać NumPy na swoje Dane pikselowe, które dają pełną kontrolę - masz pełną kontrolę - Inne biblioteki obrazowania, takie jak leptonica, gegl i vips wszystkie mają powiązania Python i zakres fajnej funkcji dla kompozycji obrazu/segmentacji.

W tym przypadku jest to sobie wyobrazić, jak można by dostać się do żądanego wyjścia w programie do obróbki zdjęć: że masz czarny (lub innego koloru) cień do umieszczenia na oryginalnego obrazu, a na tym wkleić drugiego obrazu, że stosuje się próg (czyli pikseli albo jest równa lub jest inny - wszystkie wartości pośrednie powinny być zaokrąglone do „różnych) z różnic jako maska ​​do drugiego obrazu

.

Zmodyfikowałem twoją funkcję, by stworzyć taką kompozycję -

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

Dzięki JSbueno ..This to co szukałem for..cheers –

+0

No cóż - oczekiwanym zwyczajem jest kliknięcie "zaakceptuj" dla odpowiedzi, zamiast wysyłania okrzyków! :-) Dzięki i tak. – jsbueno

+1

BTW, dla kogoś, kto potrzebuje tego tylko dla kilku obrazów i nie chce się fidować z instalacjami w Pythonie - odpowiedziałem na pytanie, jak do interaktywnego używania sampingu za pomocą GIMP: http://graphicdesign.stackexchange.com/questions/27484/get -difference-between-two-images-as-transparent-image-in-gimp/27486 # 27486 – jsbueno

1

Oto rozwiązanie przy użyciu libvips:

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]) 

Z obrazów PNG, większość czasu procesora spędza w PNG czytać i pisać, więc vips jest tylko nieco szybciej niż roztwór PIL.

Libvips zużywa o wiele mniej pamięci, szczególnie w przypadku dużych obrazów. libvips to biblioteka strumieniowania: może załadować, przetworzyć i zapisać wynik w tym samym czasie, nie musi mieć całego obrazu załadowanego do pamięci, zanim będzie mogła rozpocząć pracę.

Dla tiff 10,000 x 10,000 RGB, libvips jest około dwa razy szybsze i potrzebuje około 1/10 pamięci.