Pet*_*son 39 python linux image
试图解决防止上传重复图像的问题.
我有两个JPG.看着它们,我可以看到它们实际上是相同的.但由于某种原因,它们具有不同的文件大小(一个是从备份中提取的,另一个是另一个上载),因此它们具有不同的md5校验和.
我怎样才能有效和自信地比较两个图像,就像人类能够看到它们完全相同?
示例:http://static.peterbe.com/a.jpg和http://static.peterbe.com/b.jpg
更新
我写了这个脚本:
import math, operator
from PIL import Image
def compare(file1, file2):
image1 = Image.open(file1)
image2 = Image.open(file2)
h1 = image1.histogram()
h2 = image2.histogram()
rms = math.sqrt(reduce(operator.add,
map(lambda a,b: (a-b)**2, h1, h2))/len(h1))
return rms
if __name__=='__main__':
import sys
file1, file2 = sys.argv[1:]
print compare(file1, file2)
Run Code Online (Sandbox Code Playgroud)
然后我下载了两个视觉上相同的图像并运行脚本.输出:
58.9830484122
Run Code Online (Sandbox Code Playgroud)
谁能告诉我一个合适的截止点应该是什么?
更新II
a.jpg和b.jpg之间的区别在于第二个用PIL保存了:
b=Image.open('a.jpg')
b.save(open('b.jpg','wb'))
Run Code Online (Sandbox Code Playgroud)
这显然适用于一些非常轻质的修改.我现在已经解决了我的问题,将相同的PIL保存应用到正在上传的文件而不用它做任何事情它现在可以工作了!
Aut*_*ter 25
有一个OSS项目使用WebDriver拍摄屏幕截图,然后比较图像以查看是否存在任何问题(http://code.google.com/p/fighting-layout-bugs/)).它通过将文件打开成流然后比较每一位来实现.
你可以用PIL做类似的事情.
编辑:
经过更多研究后我发现了
h1 = Image.open("image1").histogram()
h2 = Image.open("image2").histogram()
rms = math.sqrt(reduce(operator.add,
map(lambda a,b: (a-b)**2, h1, h2))/len(h1))
Run Code Online (Sandbox Code Playgroud)
在http://snipplr.com/view/757/compare-two-pil-images-in-python/和http://effbot.org/zone/pil-comparing-images.htm上
Xol*_*lve 20
从这里开始
确定两个图像是否具有完全相同内容的最快方法是获得两个图像之间的差异,然后计算该图像中非零区域的边界框.如果图像相同,则差异图像中的所有像素均为零,并且边界框函数返回"无".
import ImageChops
def equal(im1, im2):
return ImageChops.difference(im1, im2).getbbox() is None
Run Code Online (Sandbox Code Playgroud)
for*_*ran 11
我想你应该对图像进行解码并逐个像素地进行比较,看看它们是否相似.
有了PIL和Numpy,你可以很容易地做到:
import Image
import numpy
import sys
def main():
img1 = Image.open(sys.argv[1])
img2 = Image.open(sys.argv[2])
if img1.size != img2.size or img1.getbands() != img2.getbands():
return -1
s = 0
for band_index, band in enumerate(img1.getbands()):
m1 = numpy.array([p[band_index] for p in img1.getdata()]).reshape(*img1.size)
m2 = numpy.array([p[band_index] for p in img2.getdata()]).reshape(*img2.size)
s += numpy.sum(numpy.abs(m1-m2))
print s
if __name__ == "__main__":
sys.exit(main())
Run Code Online (Sandbox Code Playgroud)
如果图像完全相同,这将为您提供一个非常接近0的数值.
请注意,移位/旋转的图像将报告为非常不同,因为像素将不会逐个匹配.
sub*_*iet 10
使用ImageMagick,您只需在shell中使用[或通过程序内的OS库调用]
compare image1 image2 output
Run Code Online (Sandbox Code Playgroud)
这将创建一个带有差异标记的输出图像
compare -metric AE -fuzz 5% image1 image2 output
Run Code Online (Sandbox Code Playgroud)
会给你一个5%的模糊因子来忽略微小的像素差异.可以从这里获得更多信息