关闭

哈希算法实现图像相似度比较(Python&OpenCV)

标签: 哈希算法opencv图像相似度python
2789人阅读 评论(7) 收藏 举报
分类:

简述

相似图像搜索的哈希算法有三种:

  • 均值哈希算法
  • 差值哈希算法
  • 感知哈希算法

均值哈希算法

步骤

  1. 缩放:图片缩放为8*8,保留结构,出去细节。
  2. 灰度化:转换为256阶灰度图。
  3. 求平均值:计算灰度图所有像素的平均值。
  4. 比较:像素值大于平均值记作1,相反记作0,总共64位。
  5. 生成hash:将上述步骤生成的1和0按顺序组合起来既是图片的指纹(hash)。顺序不固定。但是比较时候必须是相同的顺序。
  6. 对比指纹:将两幅图的指纹对比,计算汉明距离,即两个64位的hash值有多少位是不一样的,不相同位数越少,图片越相似。

代码实现:

#均值哈希算法
def aHash(img):
    #缩放为8*8
    img=cv2.resize(img,(8,8),interpolation=cv2.INTER_CUBIC)
    #转换为灰度图
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    #s为像素和初值为0,hash_str为hash值初值为''
    s=0
    hash_str=''
    #遍历累加求像素和
    for i in range(8):
        for j in range(8):
            s=s+gray[i,j]
    #求平均灰度
    avg=s/64
    #灰度大于平均值为1相反为0生成图片的hash值
    for i in range(8):
        for j in range(8):
            if  gray[i,j]>avg:
                hash_str=hash_str+'1'
            else:
                hash_str=hash_str+'0'            
    return hash_str

差值哈希算法

差值哈希算法前期和后期基本相同,只有中间比较hash有变化。

步骤
1. 缩放:图片缩放为8*9,保留结构,出去细节。
2. 灰度化:转换为256阶灰度图。
3. 求平均值:计算灰度图所有像素的平均值。
4. 比较:像素值大于后一个像素值记作1,相反记作0。本行不与下一行对比,每行9个像素,八个差值,有8行,总共64位
5. 生成hash:将上述步骤生成的1和0按顺序组合起来既是图片的指纹(hash)。顺序不固定。但是比较时候必须是相同的顺序。
6. 对比指纹:将两幅图的指纹对比,计算汉明距离,即两个64位的hash值有多少位是不一样的,不相同位数越少,图片越相似。


#差值感知算法
def dHash(img):
    #缩放8*8
    img=cv2.resize(img,(9,8),interpolation=cv2.INTER_CUBIC)
    #转换灰度图
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    hash_str=''
    #每行前一个像素大于后一个像素为1,相反为0,生成哈希
    for i in range(8):
        for j in range(8):
            if   gray[i,j]>gray[i,j+1]:
                hash_str=hash_str+'1'
            else:
                hash_str=hash_str+'0'
    return hash_str

感知哈希算法

感知哈希算法可以参考
相似性︱python+opencv实现pHash算法+hamming距离(simhash)(三)
讲的很详细了。

Hash值对比

由于返回值为str字符串,所以直接遍历字符串进行比对。

#Hash值对比
def cmpHash(hash1,hash2):
    n=0
    #hash长度不同则返回-1代表传参出错
    if len(hash1)!=len(hash2):
        return -1
    #遍历判断
    for i in range(len(hash1)):
        #不相等则n计数+1,n最终为相似度
        if hash1[i]!=hash2[i]:
            n=n+1
    return n

总结

完整代码

import cv2
import  numpy as np

#均值哈希算法
def aHash(img):
    #缩放为8*8
    img=cv2.resize(img,(8,8),interpolation=cv2.INTER_CUBIC)
    #转换为灰度图
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    #s为像素和初值为0,hash_str为hash值初值为''
    s=0
    hash_str=''
    #遍历累加求像素和
    for i in range(8):
        for j in range(8):
            s=s+gray[i,j]
    #求平均灰度
    avg=s/64
    #灰度大于平均值为1相反为0生成图片的hash值
    for i in range(8):
        for j in range(8):
            if  gray[i,j]>avg:
                hash_str=hash_str+'1'
            else:
                hash_str=hash_str+'0'            
    return hash_str

#差值感知算法
def dHash(img):
    #缩放8*8
    img=cv2.resize(img,(9,8),interpolation=cv2.INTER_CUBIC)
    #转换灰度图
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    hash_str=''
    #每行前一个像素大于后一个像素为1,相反为0,生成哈希
    for i in range(8):
        for j in range(8):
            if   gray[i,j]>gray[i,j+1]:
                hash_str=hash_str+'1'
            else:
                hash_str=hash_str+'0'
    return hash_str

#Hash值对比
def cmpHash(hash1,hash2):
    n=0
    #hash长度不同则返回-1代表传参出错
    if len(hash1)!=len(hash2):
        return -1
    #遍历判断
    for i in range(len(hash1)):
        #不相等则n计数+1,n最终为相似度
        if hash1[i]!=hash2[i]:
            n=n+1
    return n

img1=cv2.imread('walk_m.jpg')
img2=cv2.imread('walks1.jpg')
hash1= aHash(img1)
hash2= aHash(img2)
print(hash1)
print(hash2)
n=cmpHash(hash1,hash2)
print('均值哈希算法相似度:',n)


hash1= dHash(img1)
hash2= dHash(img2)
print(hash1)
print(hash2)
n=cmpHash(hash1,hash2)
print('差值哈希算法相似度:',n)

测试图像两张如下

这里写图片描述这里写图片描述

测试结果如下:

这里写图片描述

根据不同的实际情况测试,选择自己合适的相似度算法才是最好的。

13
3
查看评论

Python 比较两张图片的相似百分比

1、比较图片和目录下的图片相似度; #!C:/Python27 #coding=utf-8 import pytesseract from pytesser import * from PIL import Image,ImageEnhance,ImageFilter import os imp...
  • qq_18808965
  • qq_18808965
  • 2017-06-30 14:40
  • 2630

python实现简单的图像对比

在UI自动化测试的结果验证过程中,不免会用到截图对比这个方式来判断是否测试通过。以下是一个简单的实现,使用第三方库:Pillow,精确度可能不会很高,但足够应付简单的验证
  • sinat_35059932
  • sinat_35059932
  • 2017-03-06 16:04
  • 3103

Python+Opencv进行识别相似图片

在网上看到python做图像识别的相关文章后,真心感觉python的功能实在太强大,因此将这些文章总结一下,建立一下自己的知识体系。 当然了,图像识别这个话题作为计算机科学的一个分支,不可能就在本文简单几句就说清,所以本文只作基本算法的科普向。 看到一篇博客是介绍这个,但他用的是PIL中的Ima...
  • feimengjuan
  • feimengjuan
  • 2016-04-29 10:22
  • 14866

比较两张图片的相似度-python

# Filename: histsimilar.py # -*- coding: utf-8 -*- import Image def make_regalur_image(img, size = (256, 256)): return img.resize(size).convert(...
  • sinat_17161487
  • sinat_17161487
  • 2015-02-03 23:59
  • 7959

python数字图像处理(8):对比度与亮度调整

声明:本文转自http://blog.csdn.NET/haoji007/article/category/6337049,但其也为转载,原作者不明,感谢原作者的付出和分享。 图像亮度与对比度的调整,是放在skimage包的exposure模块里面 1、gamma调整 原理:I...
  • fuwenyan
  • fuwenyan
  • 2016-12-17 13:57
  • 1282

python 中的hash

simhashimport re from simhash import Simhashdef get_features(s): withd=4 s=s.lower() s=re.sub(r'[^\w]+','',s) return ...
  • weiyudang11
  • weiyudang11
  • 2016-09-27 20:43
  • 3863

感知哈希算法--python实现

最近在看运动目标跟踪方面的资料,偶然间看到zouxy09大神的一篇《基于感知哈希算法的视觉跟踪》,觉得挺有意思的。于是去查了相关的感知哈希的资料,发现在图片搜索领域里面应用非常广泛,这种技术我觉得有点像模板匹配,其核心在于:通过指纹的相似度来搜索最相似的图片。 至于为什么可以实现跟踪,因为
  • insthink
  • insthink
  • 2016-05-10 21:04
  • 3720

一致性hash以及python代码实现

背景:自己之前的项目里面使用了redis作为KV存储,不仅是因为性能,主要是需要用redis的hash数据结构。后来随着业务发展,读写压力越来越大,一开始的做法是读写分离,接着一主多从,发现还是不能很好的解决写redis的压力,又因为自己使用的redis版本比较低还不支持分布式的功能,所以自己想去部...
  • tanghaiyu777
  • tanghaiyu777
  • 2017-02-16 19:04
  • 1179

python版本的各种hash算法

  • 2016-03-08 13:11
  • 3KB
  • 下载

Python OpenCV 简单图像比较

项目需要做两张图像比较的差,感觉Python用起来很方便,手头正好有OpenCV。红绿代表插值正负,为了更好的可视化,差值均放大10倍显示。 import cv2 def clmap(v, k, upBound): #mul and clamp val = v * k if ...
  • linian71
  • linian71
  • 2015-01-15 16:41
  • 1889
    个人资料
    • 访问:24819次
    • 积分:449
    • 等级:
    • 排名:千里之外
    • 原创:16篇
    • 转载:0篇
    • 译文:0篇
    • 评论:42条
    文章分类
    最新评论