2015-05-16 12 views
5

Dưới đây là mã làm việc hiện tại trong python sử dụng PIL để làm nổi bật sự khác biệt giữa hai hình ảnh. Nhưng phần còn lại của hình ảnh bị bôi đen.So sánh hai hình ảnh và các khác biệt nổi bật dọc theo hình ảnh thứ hai

Hiện tại tôi cũng muốn hiển thị nền cùng với hình ảnh được đánh dấu.

Có anyway tôi có thể giữ cho chương trình nền nhẹ hơn và chỉ làm nổi bật sự khác biệt.

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

Trả lời

5

PIL có một số phương pháp xử lý ảnh tiện dụng, nhưng cũng có rất nhiều thiếu sót khi ai muốn để bắt đầu thực hiện xử lý hình ảnh nghiêm trọng -

Hầu hết Python lterature sẽ đề nghị bạn chuyển sử dụng NumPy trên của bạn dữ liệu pixel, sẽ cung cấp cho bạn toàn quyền kiểm soát - Các thư viện hình ảnh khác như leptonica, gegl và vips tất cả đều có các ràng buộc Python và một dải chức năng đẹp cho thành phần/phân đoạn hình ảnh.

Trong trường hợp này, điều này là để tưởng tượng làm thế nào ai sẽ đến được kết quả mong muốn trong một chương trình xử lý ảnh: Bạn muốn có một màu đen (hoặc màu khác) bóng râm để đặt trên hình ảnh ban đầu, và trên đó, dán hình ảnh thứ hai, nhưng sử dụng ngưỡng (tức là pixel hoặc bằng là khác nhau - tất cả giá trị trung gian phải được làm tròn thành "khác biệt" của sự khác biệt làm mặt nạ cho hình ảnh thứ hai.

Tôi đã sửa đổi chức năng của bạn để tạo thành phần như vậy -

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

Cảm ơn JSbueno ..This là những gì đã được tôi đang tìm kiếm for..cheers –

+0

Oh well - các tùy chỉnh dự kiến ​​xung quanh đây là bấm vào "chấp nhận" cho câu trả lời, chứ không phải là gửi cổ vũ! :-) Dù sao cũng cảm ơn bạn. – jsbueno

+1

BTW, cho một trong những điều này chỉ cần một vài hình ảnh, và không muốn fidle với cài đặt Python - Tôi trả lời làm thế nào để samething interactivelly bằng cách sử dụng GIMP ở đây: http://graphicdesign.stackexchange.com/questions/27484/get -difference-between-two-images-as-transparent-image-in-gimp/27486 # 27486 – jsbueno

1

Dưới đây là một giải pháp sử dụng 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]) 

Với hình ảnh PNG, hầu hết thời gian CPU được chi tiêu trong PNG đọc và viết, vì vậy khách VIP là nhanh hơn so với giải pháp PIL chỉ một chút.

libvips sử dụng ít bộ nhớ hơn nhiều, đặc biệt là đối với hình ảnh lớn. libvips là một thư viện trực tuyến: nó có thể tải, xử lý và lưu kết quả tất cả cùng một lúc, nó không cần phải có toàn bộ hình ảnh được tải vào bộ nhớ trước khi nó có thể bắt đầu hoạt động.

Đối với tif 10.000 x 10.000 RGB, libvips nhanh hơn gấp đôi và cần khoảng 1/10 bộ nhớ.

Các vấn đề liên quan