python+opencv 计算图片的感知hash值,来计算汉明距离,简单的找相似图片

感知哈希算法是一类算法的总称,包括aHash、pHash、dHash。顾名思义,感知哈希不是以严格的方式计算Hash值,而是以更加相对的方式计算哈希值,因为“相似”与否,就是一种相对的判定。

  • aHash:平均值哈希。速度比较快,但是常常不太精确。
  • pHash:感知哈希。精确度比较高,但是速度方面较差一些。
  • dHash:差异值哈希。精确度较高,且速度也非常快

注意: 但是在下面我用了ahash和dhash得到的哈希值都是一样的,我就有点懵逼了!!!

计算图片的hanming距离步骤(代码里面有介绍):

  • 先将图片压缩成8*8的小图
  • 将图片转化为灰度图
  • 计算图片的Hash值,这里的hash值是64位,或者是32位01字符串
  • 将上面的hash值转换为16位的
  • 通过hash值来计算汉明距离

给出图片:

img1:                                                    img2:

python+opencv 计算图片的感知hash值,来计算汉明距离,简单的找相似图片_第1张图片 python+opencv 计算图片的感知hash值,来计算汉明距离,简单的找相似图片_第2张图片

# -*- coding: utf-8 -*-
# !/usr/bin/env python
# @Time    : 2018/11/16 15:40
# @Author  : xhh
# @Desc    : 图片的hash算法
# @File    : image_3hash.py
# @Software: PyCharm
import cv2

# 均值哈希算法
def ahash(image):
    # 将图片缩放为8*8的
    image =  cv2.resize(image, (8,8), interpolation=cv2.INTER_CUBIC)
    # 将图片转化为灰度图
    gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    # s为像素和初始灰度值,hash_str为哈希值初始值
    s = 0
    ahash_str = ''
    # 遍历像素累加和
    for i in range(8):
        for j in range(8):
            s = s+gray[i, j]
    # 计算像素平均值
    avg = s/64
    # 灰度大于平均值为1相反为0,得到图片的平均哈希值,此时得到的hash值为64位的01字符串
    ahash_str  = ''
    for i in range(8):
        for j in range(8):
            if gray[i,j]>avg:
                ahash_str = ahash_str + '1'
            else:
                ahash_str = ahash_str + '0'
    result = ''
    for i in range(0, 64, 4):
        result += ''.join('%x' % int(ahash_str[i: i + 4], 2))
    # print("ahash值:",result)
    return result

# 差异值哈希算法
def dhash(image):
    # 将图片转化为8*8
    image = cv2.resize(image,(9,8),interpolation=cv2.INTER_CUBIC )
    # 将图片转化为灰度图
    gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    dhash_str = ''
    for i in range(8):
        for j in range(8):
            if gray[i,j]>gray[i, j+1]:
                dhash_str = dhash_str + '1'
            else:
                dhash_str = dhash_str + '0'
    result = ''
    for i in range(0, 64, 4):
        result += ''.join('%x'%int(dhash_str[i: i+4],2))
    # print("dhash值",result)
    return result

# 计算两个哈希值之间的差异
def campHash(hash1, hash2):
    n = 0
    # hash长度不同返回-1,此时不能比较
    if len(hash1) != len(hash2):
        return -1
    # 如果hash长度相同遍历长度
    for i in range(len(hash1)):
        if hash1[i] != hash2[i]:
            n = n+1
    return n
img1 = "../doraemon/image-003.png"
img2 = "../doraemon/image-019.jpg"
img1 = cv2.imread(img1)
img2 = cv2.imread(img2)

hash1 = ahash(img1)
print('img1的ahash值',hash1)
hash2= dhash(img1)
print('img1的dhash值',hash2)
hash3= ahash(img2)
print('img2的ahash值',hash3)
hash4= dhash(img2)
print('img2的dhash值',hash4)
camphash1 = campHash(hash1, hash3)
camphash2= campHash(hash2, hash4)
print("ahash均值哈希相似度:",camphash1)
print("dhash差异哈希相似度:",camphash2)

运行结果:

python+opencv 计算图片的感知hash值,来计算汉明距离,简单的找相似图片_第3张图片

还有一种计算汉明距离的方法,对两者方法都试了一次,一样的:

# -*- coding: utf-8 -*-
# !/usr/bin/env python
# @Time    : 2018/11/17 9:57
# @Author  : xhh
# @Desc    : 图片hash值,与汉明距离的计算
# @File    : image_phash1.py
# @Software: PyCharm
import numpy as py
import cv2

# 计算hash值
def p_pash(path):
    # 读取图片
    src = cv2.imread(path, 0)
    # 将图片压缩为8*8的,并转化为灰度图
    img = cv2.resize(src, (8,8), cv2.COLOR_RGB2GRAY)

    # 计算图片的平均灰度值
    avg = sum([sum(img[i]) for i in range(8)])/64

    # 计算哈希值,与平均值比较生成01字符串
    str = ''
    for i in range(8):
        str += ''.join(map(lambda i: '0' if i< avg else '1', img[i]))

    # 计算hash值, 将64位的hash值,每4位合成以为,转化为16 位的hash值
    result = ''
    for i in range(0, 64, 4):
        result += ''.join('%x'%int(str[i: i+4], 2))
    print(result)
    return result

# 计算汉明距离
def hamming_distance(str1, str2):
    if len(str1) != len(str2):
        return
    count = 0
    for i in range(len(str1)):
        if str1[i] != str2[i]:
            count += 1
    return count

h1 = p_pash('../cat1/cat.1.jpg')
h2 = p_pash('../doraemon/image-003.png')
h3 = p_pash('../doraemon/image-019.jpg')
print(hamming_distance(h1, h2))
print(hamming_distance(h1, h3))
print(hamming_distance(h2, h3))

运行结果:

python+opencv 计算图片的感知hash值,来计算汉明距离,简单的找相似图片_第4张图片

大家可以关注我和我小伙伴的公众号~~~这里有我和我的小伙伴不定时的更新一些python技术资料哦!!大家也可以留言,讨论一下技术问题,希望大家多多支持,关注一下啦,谢谢大家啦~~

你可能感兴趣的:(Python)