计算给定图像的差分散列(感知散列),用于检测重复项

dhash的Python项目详细描述


dhash是一个python库,它为给定的图像生成“差分散列” –基于neal krawetz在this “Hacker Factor” blog entry中的dhash算法的perceptual hash

这个库是on the Python Package Index (PyPI),可以在两个python上工作 3和Python2.7。要安装它,请启动命令提示符,激活 虚拟环境如果您正在使用虚拟环境,请键入:

pip install dhash

创建差异哈希的算法非常简单:

  • 将图像转换为灰度
  • 将其缩小为9x9缩略图(大小=8表示8+1×8+1图像)
  • 产生64位“行散列”:1位表示像素强度正在增加 在x方向,0表示它在减小
  • 执行同样的操作,在Y方向生成64位“列哈希值”
  • 将这两个值组合起来生成最终的128位哈希值

库默认生成大小为8的dhash,但您可以覆盖它 通过将size=N作为关键字参数传递给大多数函数很容易。为了 例如,您可以生成一个更精确的 通过指定size=16获得512位。

我发现dhash非常适合检测近重复的(在 {A4}我们使用大小为8的DHASH找到DUPES,最大Delta为2。 比特)。但由于算法简单,它在 找到相似的图像或复制但剪切的图像-您需要更多 复杂的图像指纹如果你想要的话。然而,达什是好的 用于查找精确的重复项和接近的重复项,例如,相同的图像 有轻微改变的光照,几个像素的裁剪,或者非常轻 拍照。

要使用dhash库,您需要wandimagemagick绑定或 已安装Pillow (PIL)库。挑一个坚持下去-他们会的 由于灰度的不同,产生稍微不同的dhash值 转换和调整大小算法。

如果同时安装了这两个库,默认情况下dhash将使用wand。到 覆盖此项并强制使用枕头/pil,在调用dhash.force_pil()之前 使用库。

使用魔杖产生达什值:

importdhashfromwand.imageimportImagewithImage(filename='dhash-test.jpg')asimage:row,col=dhash.dhash_row_col(image)print(dhash.format_hex(row,col))

使用枕头产生DHASH值:

importdhashfromPILimportImageimage=Image.open('dhash-test.jpg')row,col=dhash.dhash_row_col(image)print(dhash.format_hex(row,col))

如果您有自己的库来将图像转换为灰度并缩小其大小 对于9x9(或17x17,如果size=16),可以向dhash_row_col()传递 整数像素强度(例如,从0到255)。例如:

>>>importdhash>>>row,col=dhash.dhash_row_col([0,0,1,1,1,0,1,1,3,4,0,1,6,6,7,7,7,7,7,9,8,7,7,8,9],size=4)>>>format(row,'016b')'0100101111010001'>>>format(col,'016b')'0101001111111001'

要将哈希值直接生成为128位整数,请使用 dhash_int(image, size=N)。要以各种方式格式化散列值,请使用 format_*函数:

>>>row,col=(13962536140006260880,9510476289765573406)>>>dhash.format_bytes(row,col)b'\xc1\xc4\xe4\xa4\x84\xa0\x80\x90\x83\xfb\xff\xcc\x00@\x83\x1e'>>>dhash.format_hex(row,col)'c1c4e4a484a0809083fbffcc0040831e'

计算两个之间不同的位数(汉明距离) 散列,您可以使用get_num_bits_different(hash1, hash2)helper 功能:

>>>importdhash>>>dhash.get_num_bits_different(0x4bd1,0x5bd2)3

还可以使用dhash为特定图像生成差异散列 从命令行:

$ python -m dhash dhash-test.jpg
c1c4e4a484a0809083fbffcc0040831e

$ python -m dhash --format=decimal dhash-test.jpg
13962536140006260880 9510476289765573406

# show the 8x8 row and column grids
$ python -m dhash --format=matrix dhash-test.jpg
* * . . . . . *
* * . . . * . .
* * * . . * . .
* . * . . * . .
* . . . . * . .
* . * . . . . .
* . . . . . . .
* . . * . . . .

* . . . . . * *
* * * * * . * *
* * * * * * * *
* * . . * * . .
. . . . . . . .
. * . . . . . .
* . . . . . * *
. . . * * * * .

# compute the bit delta between two images
$ python -m dhash dhash-test.jpg similar.jpg
1 bit differs out of 128 (0.8%)

阅读dhash.py中的代码了解更多详细信息–它非常小!

dhash是由Ben HoytJetsetter编写的,并获得了 许可MIT许可证(见LICENSE.txt)。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java组织。openqa。硒。遥远的UnreachableBrowserException如何定义EXE路径?   java Camel AdviceWith不使用指定文件替换端点   基于字符串的java图像加载   Java中的启发式算法,计算8个谜题状态的线性冲突   java为什么不支持文件。probeContentType返回null   JPA@EntityListeners、@PrePersist和Spring@RepositoryEventHandler、@HandleBeforeSave之间的java差异   可能前缀的Java字符串到字符串[]   安装rJava | Makefile时发生java错误。全部:38:target’libjri的配方。所以他失败了   Java公共静态void main()   java如何覆盖txt文件中的某些单词   java如何获得循环中生成的字符值之和?   java Log4j创建另一个具有相同属性的appender   java如何在从Axis2 Web服务客户端通过代理服务器调用Web服务时设置代理设置?   在Windows上安装Elasticsearch时发生java错误   java如何向EditText组件添加TextChangedListener?