我想将PIL图像的信息存储在键值存储中。为此,我对图像进行散列并使用散列作为键。
我一直在使用以下代码来计算哈希值:
def hash(img):
return hashlib.md5(img.tobytes()).hexdigest()
但似乎这不稳定。我还没弄清楚为什么,但是对于不同机器上的相同图像,我会得到不同的哈希值。
是否有一种简单的哈希图像只依赖于图像本身的方式(不是时间戳,系统架构等)?
请注意,我不需要类似的图像来获得类似/相同的哈希值,如image hashing中所示。实际上,我希望不同的图像具有不同的散列,例如改变图像的亮度应改变它的散列。
答案 0 :(得分:2)
我猜你的目标是在Python中执行图像散列(这与经典散列有很大不同,因为图像的字节表示取决于格式,分辨率等)。
其中一种图像散列技术是平均散列。确保这不是100%准确,但在大多数情况下都可以正常工作。
首先,我们通过减小图像的尺寸和颜色来简化图像,降低图像的复杂性,大大有助于提高其他图像之间的比较精度:
缩小尺寸:
img = img.resize((10, 10), Image.ANTIALIAS)
缩小颜色
img = img.convert("L")
然后,我们找到图像的平均像素值(这显然是平均散列的主要组成部分之一):
pixel_data = list(img.getdata())
avg_pixel = sum(pixel_data)/len(pixel_data)
最后计算哈希值,我们将图像中的每个像素与平均像素值进行比较。如果像素大于或等于平均像素,那么我们得到1,否则它是0.然后我们将这些位转换为基数16表示:
bits = "".join(['1' if (px >= avg_pixel) else '0' for px in pixel_data])
hex_representation = str(hex(int(bits, 2)))[2:][::-1].upper()
如果要将此图像与其他图像进行比较,请执行上述操作,并找出平均哈希图像的十六进制表示之间的相似性。您可以使用简单的hamming distance或更复杂的算法,例如Levenshtein distance,Ratcliff/Obershelp pattern recognition(SequenceMatcher),Cosine Similarity等。
答案 1 :(得分:1)
认识到您所说的时间戳, ImageMagick 具有这样的功能。首先,一个例子。
在这里我创建了两个像素相同但时间戳至少相差1秒的图像:
convert -size 600x100 gradient:magenta-cyan 1.png
sleep 2
convert -size 600x100 gradient:magenta-cyan 2.png
如果我在macOS上对它们进行校验和,则表明它们由于嵌入的时间戳而有所不同:
md5 -r [12].png
c7454aa225e3e368abeb5290b1d7a080 1.png
66cb4de0b315505de528fb338779d983 2.png
但是,如果我使用 ImageMagick (其中%#
是逐个像素的校验和)对只是像素进行校验,它会知道像素相同,因此得到:
identify -format '%# - %f\n' 1.png 2.png
70680e2827ad671f3732c0e1c2e1d33acb957bc0d9e3a43094783b4049225ea5 - 1.png
70680e2827ad671f3732c0e1c2e1d33acb957bc0d9e3a43094783b4049225ea5 - 2.png
事实上,如果我用相同的图像内容制作了一个TIFF
文件,无论是使用Motorola还是Intel字节顺序,还是使用NetPBM PPM
文件:
convert -size 600x100 gradient:magenta-cyan -define tiff:endian=msb 3motorola.tif
convert -size 600x100 gradient:magenta-cyan -define tiff:endian=lsb 3intel.tif
convert -size 600x100 gradient:magenta-cyan 3.ppm
ImageMagick 知道它们是相同的,尽管文件格式,CPU体系结构和时间戳不同,
identify -format '%# - %f\n' 1.png 3.ppm 3{motorola,intel}.tif
70680e2827ad671f3732c0e1c2e1d33acb957bc0d9e3a43094783b4049225ea5 - 1.png
70680e2827ad671f3732c0e1c2e1d33acb957bc0d9e3a43094783b4049225ea5 - 3.ppm
70680e2827ad671f3732c0e1c2e1d33acb957bc0d9e3a43094783b4049225ea5 - 3motorola.tif
70680e2827ad671f3732c0e1c2e1d33acb957bc0d9e3a43094783b4049225ea5 - 3intel.tif
因此,为回答您的问题,我建议您使用Python子进程模块使用 ImageMagick ,并使用 ImageMagick 。