比较两个图像并突出显示第二个图像上的差异
Compare two images and highlight differences along on the second image
下面是 python 中的当前工作代码,使用 PIL 突出显示两个图像之间的差异。但是其余的图像变黑了。
目前我想显示背景以及突出显示的图像。
有没有办法让节目的背景变浅,只突出不同之处。
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
PIL 确实有一些方便的图像处理方法,
但是当一个人想要的时候也有很多缺点
开始进行认真的图像处理 -
大多数 Python 文学会建议您切换
在你的像素数据上使用 NumPy,这会给
你完全控制 -
其他成像库,如 leptonica、gegl 和 vips
都有 Python 绑定和一系列不错的功能
图片 composition/segmentation.
在这种情况下,问题是想象一个人会如何
在图像处理程序中获得所需的输出:
你有一个黑色(或其他颜色)的阴影可以放在上面
原始图像,然后在上面粘贴第二张图像,
但使用阈值(即像素等于或
是不同的 - 所有中间值都应该四舍五入
将差异的“不同”作为第二张图片的掩码。
我修改了你的函数来创建这样的组合 -
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')
这是一个使用 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])
对于 PNG 图像,大部分 CPU 时间花在 PNG 读写上,因此 vips 仅比 PIL 解决方案快一点。
libvips 确实使用了更少的内存,尤其是对于大图像。 libvips 是一个流式库:它可以同时加载、处理和保存结果,它不需要在开始工作之前将整个图像加载到内存中。
对于 10,000 x 10,000 RGB tif,libvips 的速度大约是原来的两倍,并且需要大约 1/10 的内存。
如果您不执着于使用 Python,有一些使用 ImageMagick 的非常简单的解决方案:
“Diff” an image using ImageMagick
下面是 python 中的当前工作代码,使用 PIL 突出显示两个图像之间的差异。但是其余的图像变黑了。
目前我想显示背景以及突出显示的图像。
有没有办法让节目的背景变浅,只突出不同之处。
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
PIL 确实有一些方便的图像处理方法, 但是当一个人想要的时候也有很多缺点 开始进行认真的图像处理 -
大多数 Python 文学会建议您切换 在你的像素数据上使用 NumPy,这会给 你完全控制 - 其他成像库,如 leptonica、gegl 和 vips 都有 Python 绑定和一系列不错的功能 图片 composition/segmentation.
在这种情况下,问题是想象一个人会如何 在图像处理程序中获得所需的输出: 你有一个黑色(或其他颜色)的阴影可以放在上面 原始图像,然后在上面粘贴第二张图像, 但使用阈值(即像素等于或 是不同的 - 所有中间值都应该四舍五入 将差异的“不同”作为第二张图片的掩码。
我修改了你的函数来创建这样的组合 -
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')
这是一个使用 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])
对于 PNG 图像,大部分 CPU 时间花在 PNG 读写上,因此 vips 仅比 PIL 解决方案快一点。
libvips 确实使用了更少的内存,尤其是对于大图像。 libvips 是一个流式库:它可以同时加载、处理和保存结果,它不需要在开始工作之前将整个图像加载到内存中。
对于 10,000 x 10,000 RGB tif,libvips 的速度大约是原来的两倍,并且需要大约 1/10 的内存。
如果您不执着于使用 Python,有一些使用 ImageMagick 的非常简单的解决方案:
“Diff” an image using ImageMagick