图片哈希概论及python中如何实现对比两张相似的图片

Google 以图搜图的原理,其中的获取图片 hash 值的方法就是 AHash。

每张图片都可以通过某种算法得到一个 hash 值,称为图片指纹,两张指纹相近的图片可以认为是相似图片。

以图搜图的原理就是获取你上传的图片的指纹,和图库的图片指纹对比,查找出最相似的若干张图片展示。

除了以图搜图,图片哈希还可以做什么呢?例如图片检索,重复图片剔除,图片相似度比较等等。

这种哈希算法大概有 4 种:

1,差值哈希:DHash(Difference Hash)
2,均值哈希:AHash(Average Hash)
3,感知哈希:PHash(Perceptual Hash)
4,小波哈希:WHash(Wavelet Hash)

注:常用的是前面三种,DHash、AHash、PHash。其中 PHash 是增强版的 AHash。

图片基本概念

图片是由像素点矩阵组成的,信息可保存在数组中,如下图 4*4 的图片,可保存在二维数组中:

左上角为起始点

row 表示行,对应图片的高 height,y 方向

col 表示列,对应图片的宽 width,x 方向

下面我只讲下感知哈希算法的实现:

感知哈希(核心就是:离散余弦变换(DCT))

1,缩小尺寸,建议 32*32
2,灰度化
3,进行离散余弦变换(DCT)
4,取左上角的 8*8 的大小
5,计算平均值
6,比较像素的灰度
7,计算哈希值
PhotoHash 它是python中一个感知哈希算法,用来发现两个图像是否相似。

1,安装包

pip install PhotoHash

2, average_hash

使用平均哈希算法返回图像的哈希值。该算法将图像中的每个像素与所有像素的平均值进行比较:

import photohash
hash_one = photohash.average_hash(‘123/dy.jpg‘)
print(hash_one)

hash_two = photohash.average_hash(‘123/6000.jpg‘)
print(hash_two)

结果:

1fffffd48000f0e1
0effff1b10001f02

3,distance

返回给定图像的average_hash之间的汉明距离

import photohash
distance = photohash.distance(‘123/dy.jpg‘, ‘123/6000.jpg‘)
print(distance)

结果:9

4,is_look_alike

返回一个布尔值,判断照片是否相似

import photohash
similar = photohash.is_look_alike(‘123/dy.jpg‘, ‘123/6000.jpg‘)
print(similar)

结果:True
import photohashsimilar = photohash.is_look_alike(‘123/dy.jpg‘, ‘123/6000.jpg‘, tolerance=3)//is_look_alike还接受一个可选的宽容参数,该参数定义了比较的严格程度。print(similar)

5,hash_distance

返回相同长度的两个哈希之间的汉明距离

import photohash
hash_one = photohash.average_hash(‘123/dy.jpg‘)
hash_two = photohash.average_hash(‘123/6000.jpg‘)
distance = photohash.hash_distance(hash_one, hash_two)
print(distance)

结果:5

6,hashes_are_similar

返回一个布尔值,表示两个哈希值是否在给定的公差范围内。与is_look_alike相同,但使用散列而不是图像路径

import photohash
hash_one = photohash.average_hash(‘123/dy.jpg‘)
hash_two = photohash.average_hash(‘123/6000.jpg‘)
similar = photohash.hashes_are_similar(hash_one, hash_two)
print(similar)

注:通常汉明距离 小于等于5时我们认为这两张图非常相似,大于10 则认为这两张图完全不一样

原文地址:https://www.cnblogs.com/lvye001/p/12084437.html

时间: 2024-10-08 12:23:32

图片哈希概论及python中如何实现对比两张相似的图片的相关文章

解决linux系统下python中的matplotlib模块内的pyplot输出图片不能显示中文的问题

问题: 我在ubuntu14.04下用python中的matplotlib模块内的pyplot输出图片不能显示中文,怎么解决呢? 解决: 1.指定默认编码为UTF-8: 在python代码开头加入如下代码 import sys reload(sys) sys.setdefaultencoding('utf-8') 2.确认你ubuntu系统环境下拥有的中文字体文件: 在终端运行命令"fc-list :lang=zh",得到自己系统的中文字体 命令输出如下: /usr/share/fon

python中判断语句用两个or连接的奇葩

学python的时候犯的一个错误,放在这吧.就是在循环某个列表的时候不要去操作它,这是容易忽略的一个地方.所以如果要操作某个列表本身,那么先把该列表copy一份,然后再读取的时候读copy的那份.操作原来的列表. 正确的如下: import re a="hen/zg /zg qd/a /a ,/x /x hen/zg /zg xh/v /v " b=re.split('[ ]', a) b_copy=b[:] print b cixing=["/x","/

Android向系统相册中插入图片,相册中会出现两张 一样的图片(只是图片大小不一致)

向系统相册中插入图片调用此方法时,相册中会出现两张一样的图片 MediaStore.Images.Media.insertImage 一张图片是原图一张图片是缩略图.表现形式为:android4.4.4系统中插入的缩略图和原图在sdcard根目录下的DCIM文件夹这种,Android5.0以上的机型插入的缩略图在sdcard根目录下的Pictures文件夹下,原图存放在DCIM文件夹下. 导致这个问题的原因查看代码后知道在插入原图的同时系统自动生成了一个缩略图并保存再相应的文件目录下,代码如下.

python中执行shell的两种方法总结

这篇文章主要介绍了python中执行shell的两种方法,有两种方法可以在Python中执行SHELL程序,方法一是使用Python的commands包,方法二则是使用subprocess包,这两个包均是Python现有的内置模块.需要的朋友可以参考借鉴,下面来一起看看吧. 一.使用python内置commands模块执行shell commands对Python的os.popen()进行了封装,使用SHELL命令字符串作为其参数,返回命令的结果数据以及命令执行的状态: 该命令目前已经废弃,被s

【转载】Python中如何高效实现两个字典合并,三种方法比较。

本文转载自:http://www.pythoner.com/13.html Python中将两个字典进行合并操作,是一个比较常见的问题.本文将介绍几种实现两个字典合并的方案,并对其进行比较. 对于这个问题,比较直观的想法是将两个字典做相加操作,赋值给结果字典,其代码为: 方法一: dictMerged1 = dict( dict1.items() + dict2.items() ) 然而,该方法合并时所用时间较长,效率更高的代码为: 方法二: dictMerged2 = dict( dict1,

Python中os与sys两模块的区别

转载文章 os与sys模块的官方解释如下: os: This module provides a portable way of using operating system dependent functionality. 这个模块提供了一种方便的使用操作系统函数的方法. sys: This module provides access to some variables used or maintained by the interpreter and to functions that i

Python中使用正则表达式获取两个字符中间部分

问题背景:当我们爬取网页信息时,对于一些标签的提取是没有意义的,所以需要提取标签中间的信息. 解决办法:用到了re包下的函数 方法1:用到了research()方法和group()方法 方法2:用到了findall()方法 具体实现: import re # 匹配两个字符中间的所有字符 a = '<p>life is short, i use python<a/>i love it<p>' r = re.search('<p>(.*)<a/>(.

SQLSERVER中如何快速比较两张表的不一样

一般来说,如何检测两张表的内容是否一致,体现在复制的时候发布端和订阅端的两端的数据上面 我这里罗列了一些如何从数据库层面来解决此类问题的方法 第一步当然就是检查记录数是否一致,否则不用想其他方法了~这里我们用两张表t1_old,t1_new来演示 方法介绍 方法一:老老实实看表结构和表记录数,弊端是根本看不到两张表的数据是否一致,只是看到表结构和记录数是否一致 --表结构: CREATE TABLE t1_old ( id int NOT NULL, log_time DATETIME DEFA

python中数据类型操作对比总结

1.创建操作    列表 a = ['data1','data2']   元组 a = ('data1','data2') 字典 a = {'key':'value'} a = dict(name='',age='')    集合 set():可变的. frozenset():不可变. 2.添加操作 列表 a + b:生成一个新列表. extend:接受参数并将每个参数都添加到原有列表.    a.extend([1,2,3]) append:添加任意对象到列表末端.a.append(data)