图像相似度对比方法

1.哈希方法,其中包括均值哈希、插值哈希、感知哈希方法。计算出图片的哈希值,一般使用汉明

距离计算两个图片间的差距。

2.直方图算法,其中包括灰度直方图算法,RGB直方图算法,

3.灰度图算法:MSE、SSIM、图像相似度算法

4.余弦相似性、欧氏距离

5.MD5

一、直方图算法

方法描述:按照某种距离度量的标准对两幅图像的直方图进行相似度的测量。

  • 优点:计算量比较小。
  • 缺点: 直方图反应的是图像灰度值得概率分布,并没有图像的空间位置信息在里面,因此,会出现误判;比如纹理结构相同,但明暗不同的图像,应该相似度很高,但实际结果是相似度很低,而纹理结构不同,但明暗相近的图像,相似度却很高。

分析:两幅图像之间的距离度量,采用的是巴氏距离或者归一化相关系数,这种用分析数学向量的方法去分析图像本身就是一个很不好的办法。

(1)单通道直方图

def histogram(image1, image2):# 灰度直方图算法# 计算单通道的直方图的相似值hist1 = cv2.calcHist([image1], [0], None, [256], [0.0, 255.0])hist2 = cv2.calcHist([image2], [0], None, [256], [0.0, 255.0])# 计算直方图的重合度degree = 0for i in range(len(hist1)):if hist1[i] != hist2[i]:degree = degree + \(1 - abs(hist1[i] - hist2[i]) / max(hist1[i], hist2[i]))else:degree = degree + 1degree = degree / len(hist1)return degree

(2)RGB三通道直方图

def Multiparty_histogram(self, image1, image2, size=(256, 256)):# RGB每个通道的直方图相似度# 将图像resize后,分离为RGB三个通道,再计算每个通道的相似值image1 = cv2.resize(image1, size)image2 = cv2.resize(image2, size)sub_image1 = cv2.split(image1)sub_image2 = cv2.split(image2)sub_data = 0for im1, im2 in zip(sub_image1, sub_image2):sub_data += self.calculate(im1, im2)sub_data = sub_data / 3return sub_data

二、灰度图算法:利用灰度图的值、均值、方差计算图像的差异性

(1)MSE(Mean Squared Error)均方误差:针对单通道灰度图

对于两个m×n的单通道图像I和K,它们的均方误差可定义为:

yH5BAAAAAAALAAAAAAOAA4AAAIMhI+py+0Po5y02qsKADs=

缺点:当差值大于1时,会放大误差;而当差值小于1时,则会缩小误差,这是平方运算决定的。MSE对于较大的误差(>1)给予较大的惩罚,较小的误差(<1)给予较小的惩罚。也就是说,对离群点比较敏感,受其影响较大。

(2)SSIM(structural similarity)结构相似性:针对单通道灰度图

SSIM(structural similarity),结构相似性,是一种衡量两幅图像相似度的指标。

SSIM公式基于样本x和y之间的三个比较衡量:亮度 (luminance)、对比度 (contrast) 和结构 (structure)。

𝝁𝒙为均值, 𝝈𝒙 为方差, 𝝈𝒙𝒚 表示协方差。

常数𝑪𝟏, 𝑪𝟐, 𝑪𝟑是为了避免当分母为 0 时造成的不稳定问题。

在实际应用中,可以利用滑动窗将图像分块,令分块总数为N,考虑到窗口形状对分块的影响,采用高斯加权计算每一窗口的均值、方差以及协方差,然后计算对应块的结构相似度SSIM,最后将平均值作为两图像的结构相似性度量,即平均结构相似性SSIM。

def contrast_image(imageA, imageB):"""对比两张图片的相似度,相似度等于1 完美匹配:param imageA::param imageB::return:"""imageA = cv2.imread(imageA)imageB = cv2.imread(imageB)grayA = cv2.cvtColor(imageA, cv2.COLOR_BGR2GRAY)grayB = cv2.cvtColor(imageB, cv2.COLOR_BGR2GRAY)# 计算两个灰度图像之间的结构相似度指数,相似度等于1完美匹配(score, diff) = structural_similarity(grayA, grayB, full=True)diff = (diff * 255).astype("uint8")print("SSIM:{}".format(score))return score, diff

skimage.metrics包下的SSIM算法

def structural_similarity(*, im1, im2,
                         win_size=None, gradient=False, data_range=None,
                         multichannel=False, gaussian_weights=False,
                         full=False, **kwargs)

 返回值:
mssim—平均结构相似度
grad—结构相似性梯度 (gradient=True)
S—结构相似性图像(full=True

(3)图片相似度算法(对像素求方差并比对)的学习

步骤:

1)缩放图片

       将需要处理的图片所放到指定尺寸,缩放后图片大小由图片的信息量和复杂度决定。譬如,一些简单的图标之类图像包含的信息量少,复杂度低,可以缩放小一点。风景等复杂场景信息量大,复杂度高就不能缩放太小,容易丢失重要信息。根据自己需求,弹性的缩放。在效率和准确度之间维持平衡。

2)灰度处理

  通常对比图像相似度和颜色关系不是很大,所以处理为灰度图,减少后期计算的复杂度。如果有特殊需求则保留图像色彩。

3)计算平均值

  此处开始,与传统的哈希算法不同:分别依次计算图像每行像素点的平均值,记录每行像素点的平均值。每一个平均值对应着一行的特征。

4)计算方差

  对得到的所有平均值进行计算方差,得到的方差就是图像的特征值。方差可以很好的反应每行像素特征的波动,既记录了图片的主要信息。

5)比较方差

        经过上面的计算之后,每张图都会生成一个特征值(方差)。到此,比较图像相似度就是比较图像生成方差的接近成程度。
  一组数据方差的大小可以判断稳定性,多组数据方差的接近程度可以反应数据波动的接近程度。我们不关注方差的大小,只关注两个方差的差值的大小。方差差值越小图像越相似!

(4)PSNR

def PSNR(img1, img2):mse = np.mean((img1/255. - img2/255.) ** 2)if mse == 0:return 100PIXEL_MAX = 1return 20 * math.log10(PIXEL_MAX / math.sqrt(mse))

三、哈希算法

计算图片的哈希表示后,利用汉明距离计算两张图片的差异

哈希相似度

实现图片相似度比较的hash算法有三种:均值哈希算法(AHash),差值哈希算法(DHash),感知哈希算法 (PHash)。(图片转成哈希表示后,用汉明距离计算两个图片的差距)

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

(1)均值哈希算法(AHash)

具体步骤

  1. 缩小尺寸:将图片缩小到8x8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。
  2. 简化色彩:将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。
  3. 计算平均值:计算所有64个像素的灰度平均值
  4. 比较像素的灰度:将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。
  5. 计算哈希值:将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。组合的次序并不重要,只要保证所有图片都采用同样次序就行了。

分析: 均值哈希算法计算速度快,不受图片尺寸大小的影响,但是缺点就是对均值敏感,例如对图像进行伽马校正或直方图均衡就会影响均值,从而影响最终的hash值。

def aHash(img):# 平均值哈希算法# 缩放为8*8img = cv2.resize(img, (8, 8))# 转换为灰度图gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# s为像素和初值为0,hash为hash值初值为''s = 0hash= ''# 遍历累加求像素和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 + '1'else:hash_str = hash + '0'return hash_str

(2)感知哈希算法 (PHash)

感知哈希算法是一个比均值哈希算法更为健壮的一种算法,与均值哈希算法的区别在于感知哈希算法是通过DCT(离散余弦变换)来获取图片的低频信息。

具体步骤

  1. 缩小尺寸:pHash以小图片开始,但图片大于8x8,32x32是最好的。这样做的目的是简化了DCT的计算,而不是减小频率。
  2. 简化色彩:将图片转化成灰度图像,进一步简化计算量。
  3. 计算DCT:计算图片的DCT变换,得到32x32的DCT系数矩阵。
  4. 缩小DCT:虽然DCT的结果是32x32大小的矩阵,但我们只要保留左上角的8x8的矩阵,这部分呈现了图片中的最低频率。
  5. 计算平均值:如同均值哈希一样,计算DCT的均值。
  6. 计算hash值:这是最主要的一步,根据8x8的DCT矩阵,设置0或1的64位的hash值,大于等于DCT均值的设为”1”,小于DCT均值的设为“0”。组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。

分析: 结果并不能告诉我们真实性的低频率,只能粗略地告诉我们相对于平均值频率的相对比例。只要图片的整体结构保持不变,hash结果值就不变。能够避免伽马校正或颜色直方图被调整带来的影响。对于变形程度在25%以内的图片也能精准识别。

def pHash(img):# 感知哈希算法# 缩放32*32img = cv2.resize(img, (32, 32))  # , interpolation=cv2.INTER_CUBIC# 转换为灰度图gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 将灰度图转为浮点型,再进行dct变换,cv2.dct()是离弦余弦变换dct = cv2.dct(np.float32(gray))# opencv实现的掩码操作dct_roi = dct[0:8, 0:8]hash = []avreage = np.mean(dct_roi)for i in range(dct_roi.shape[0]):for j in range(dct_roi.shape[1]):if dct_roi[i, j] > avreage:hash.append(1)else:hash.append(0)return hash

(3)差值哈希算法(DHash)

比pHash,dHash的速度要快的多,相比aHash,dHash在效率几乎相同的情况下的效果要更好,它是基于渐变实现的。

主要步骤:

  1. 缩小尺寸:收缩到8x9(高x宽)的大小,一遍它有72的像素点
  2. 转化为灰度图:把缩放后的图片转化为256阶的灰度图。
  3. 计算差异值:dHash算法工作在相邻像素之间,这样每行9个像素之间产生了8个不同的差异,一共8行,则产生了64个差异值
  4. 获得指纹:如果左边的像素比右边的更亮,则记录为1,否则为0
def dHash(img):# 差值哈希算法# 缩放8*8img = cv2.resize(img, (9, 8))# 转换灰度图gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)hash = ''# 每行前一个像素大于后一个像素为1,相反为0,生成哈希for i in range(8):for j in range(8):if gray[i, j] > gray[i, j + 1]:hash_str = hash + '1'else:hash_str = hash + '0'return hash_str

汉明距离计算两个图像的哈希差值

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+1return n

MD5

粗暴的md5比较 返回是否完全相同

def md5_similarity(img1_path, img2_path):file1 = open(img1_path, "rb")file2 = open(img2_path, "rb")md = hashlib.md5()md.update(file1.read())res1 = md.hexdigest()md = hashlib.md5()md.update(file2.read())res2 = md.hexdigest()return res1 == res2

余弦相似度

把图片表示成一个向量,两个向量夹角的余弦值作为衡量两个个体间差异的大小。

欧氏距离

衡量的是多维空间中各个点之间的绝对距离。

借助三维坐标系来看下欧氏距离和余弦距离的区别:

clip_image009

从上图可以看出,

欧氏距离衡量的是空间各点的绝对距离,跟各个点所在的位置坐标直接相关;

余弦距离衡量的是空间向量的夹角,更加体现在方向上的差异,而不是位置。

如果保持A点位置不变,B点朝原方向远离坐标轴原点,那么这个时候余弦距离 cos是保持不变的(因为夹角没有发生变化),而A、B两点的距离显然在发生改变,这就是欧氏距离和余弦距离之间的不同之处。

欧氏距离和余弦距离各自有不同的计算方式和衡量特征,因此它们适用于不同的数据分析模型:

欧氏距离能够体现个体数值特征的绝对差异,所以更多的用于需要从维度的数值大小中体现差异的分析,如使用用户行为指标分析用户价值的相似度或差异。

余弦距离更多的是从方向上区分差异,而对绝对的数值不敏感,更多的用于使用用户对内容评分来区分兴趣的相似度和差异,同时修正了用户间可能存在的度量标准不统一的问题(因为余弦距离对绝对数值不敏感)。

【精选】图像相似度匹配——距离大全_pairwise_distances图像距离-CSDN博客
​​​​​​​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/139935.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ELK之Logstash解析时间相差8h的问题

一、问题描述 服务器当前时间为&#xff1a;2022年 06月 28日 星期二 11:24:22 CST 而logstash解析的时间为2022-06-28T03:15:25.545Z与实际时间相差8h 一、解决办法&#xff1a; 需改logstash的配置文件&#xff1a; 原理就是&#xff1a;定义一个中间变量timestamp&…

第十三章《搞懂算法:神经网络是怎么回事》笔记

目前神经网络技术受到追捧&#xff0c;一方面是由于数据传感设备、数据通信技术和数据存储技术 的成熟与完善&#xff0c;使得低成本采集和存储海量数据得以成为现实;另一方面则是由于计算能力的大幅提升&#xff0c;如图形处理器(Graphics Processing Unit&#xff0c;GPU)在神…

【数据结构】拓扑序列求法

概念不多说了&#xff0c;有疑问的搜一下&#xff0c;这里直接放求法&#xff1a; 找到入度为0的节点输出并删除该节点&#xff0c;并删除与该点链接的边重复第一步 例子 输出a&#xff0c;删除a输出b&#xff0c;删除b输出c&#xff0c;删除c 最终结果为abcdef 注意 拓扑排…

实战Leetcode(四)

Practice makes perfect&#xff01; 实战一&#xff1a; 这个题由于我们不知道两个链表的长度我们也不知道它是否有相交的节点&#xff0c;所以我们的方法是先求出两个链表的长度&#xff0c;长度长的先走相差的步数&#xff0c;使得两个链表处于同一起点&#xff0c;两个链…

杂记 | 使用FRP搭建内网穿透服务(新版toml配置文件,搭配反向代理食用)

文章目录 01 需求与回顾02 下载程序包03 编辑.toml文件3.1 编辑frps.toml3.2 编辑frpc.toml 04 启动服务4.1 启动服务端4.2 启动客户端 05 配置反向代理&#xff08;可选&#xff09;06 windows设置为默认启动&#xff08;可选&#xff09;6.1 创建启动脚本6.2 设置为开机自启 …

Liunx命令汇总

一.用户相关命令 1.1账号管理 创建用户&#xff1a; useradd &#xff08;选项&#xff09; 用户名用户口令&#xff1a; passwd &#xff08;选项&#xff09; 用户名修改用户&#xff1a; usermod 选项 用户名删除用户&#xff1a; userdel &#xff08;选项&#xff09; 用…

加班把数据库重构完毕

加班把数据库重构完毕 本文的数据库重构是基于 clickhouse 时序非关系型的数据库。该数据库适合存储股票数据&#xff0c;速度快&#xff0c;一般查询都是 ms 级别&#xff0c;不需要异步查询更新界面 ui。 达到目标效果&#xff1a;数据表随便删除&#xff0c;重新拉数据以及指…

elastic-job 完结篇

一 elastic-job 1.1 案例场景分析 1.设置4个分片&#xff0c;10秒执行一次。 分片弹性扩容缩容机制测试&#xff1a; 测试1&#xff1a;测试窗口1不关闭&#xff0c;再次运行main方法查看控制台日志&#xff0c;注意修改application.properties中的 server.port&#xf…

Vant 移动端UI 组件自动引入

Vue项目中安装Vant # Vue 3 项目&#xff0c;安装最新版 Vant npm i vant 组件按需引入配置 Vant按需引入- - -安装&#xff1a;unplugin-vue-components 插件 unplugin-vue-components 插件可以在Vue文件中自动引入组件&#xff08;包括项目自身的组件和各种组件库中的组件&…

7.运算符

目录 一.算数运算符 1、算术运算符 2、比较运算符 1、等号()用来判断数字、字符串和表达式是否相等。 2、安全等于运算符(<>) 3、不等于运算符(<>或者!) 4、小于或等于运算符(<) 5、小于运算符(<) 6、IS NULL(IS NULL)&#xff0c;IS NOT NULL 运算…

2352 智能社区医院管理系统JSP【程序源码+文档+调试运行】

摘要 本文介绍了一个智能社区医院管理系统的设计和实现。该系统包括管理员、护工和医生三种用户&#xff0c;具有社区资料管理、药品管理、挂号管理和系统管理等功能。通过数据库设计和界面设计&#xff0c;实现了用户友好的操作体验和数据管理。经过测试和优化&#xff0c;系…

WorkPlus Meet:局域网内部使用的高效视频会议系统

随着全球化和远程办公的趋势&#xff0c;视频会议已成为现代企业和机构不可或缺的沟通工具。而现在&#xff0c;大多数政企单位或者涉密强的企业&#xff0c;都会使用局域网部署的音视频会议系统&#xff0c;提供更高的安全性和隐私保护。因为音视频会议中可能涉及到公司机密和…

程序员的护城河:职业发展的关键元素

目录 1. 技术深度与广度 2. 项目经验与实际操作 3. 沟通与团队协作 4. 持续学习与自我更新 5. 社区参与与开源贡献 6. 创新思维与解决问题的能力 7. 职业规划与自我管理 结语 在科技日新月异的今天&#xff0c;程序员的竞争已经不再仅仅依赖于技术水平&#xff0c;而是…

C++: 内存管理 (new / delete)

文章目录 一. C/C 内存分布二. C 语言中动态内存管理方式: malloc/calloc/realloc/free三. C内存管理方式1. new / delete 操作内置类型2. new / delete 操作自定义类型 四. operator new 与 operator delete 函数五. new 和 delete 的实现原理1. 内置类型2. 自定义类型 六. 定…

【中间件篇-Redis缓存数据库02】Redis高级特性和应用(慢查询、Pipeline、事务、Lua)

Redis高级特性和应用(慢查询、Pipeline、事务、Lua) Redis的慢查询 许多存储系统&#xff08;例如 MySQL)提供慢查询日志帮助开发和运维人员定位系统存在的慢操作。所谓慢查询日志就是系统在命令执行前后计算每条命令的执行时间&#xff0c;当超过预设阀值,就将这条命令的相关…

互联网大厂招兵买马开发鸿蒙应用,移动开发的春天又来了?

日前&#xff0c;美团拟开发鸿蒙系统APP的多个相关岗位正招聘开发人员引发业内关注。事实上&#xff0c;鸿蒙开发者已经成为京东、WPS、凤凰新闻、微博等互联网大厂争相招聘的人才&#xff0c;且招聘岗位众多。也就是说&#xff0c;这些公司正在加快鸿蒙化开发&#xff0c;为鸿…

基于C#+WPF编写的调用讯飞星火大模型工具

工具源码&#xff1a;https://github.com/lishuangquan1987/XFYun.SparkChat 工具效果截图&#xff1a; 支持流式输出: 其中ApiKey/ApiSecret/AppId需要自己到讯飞星火大模型官网去注册账号申请&#xff0c;免费的。 申请地址&#xff1a;https://xinghuo.xfyun.cn/ 注册之…

【OpenCV实现图像:用OpenCV图像处理技巧之白平衡算法2】

文章目录 概要Gray-world AlgotithmGround Truth Algorithm结论&#xff1a; 概要 随着数字图像处理技术的不断发展&#xff0c;白平衡算法成为了图像处理中一个关键的环节。白平衡的目标是校正图像中的颜色偏差&#xff0c;使得白色在图像中呈现真实的白色&#xff0c;从而提…

利用MSF设置代理

1、介绍&#xff1a; 通过MSF拿到一个机器的权限后&#xff0c;通过MSF搭建socks代理&#xff0c;然后通内网。 拿到目标权限&#xff0c;有很多方法&#xff0c;比如&#xff1a;①ms17-010 ②补丁漏洞 ③MSF生成后门 在此直接使用MSF生成后门 MSF中有三个代理模块&#x…

【ATTCK】MITRE Caldera - 测试数据泄露技巧

CALDERA是一个由python语言编写的红蓝对抗工具&#xff08;攻击模拟工具&#xff09;。它是MITRE公司发起的一个研究项目&#xff0c;该工具的攻击流程是建立在ATT&CK攻击行为模型和知识库之上的&#xff0c;能够较真实地APT攻击行为模式。 通过CALDERA工具&#xff0c;安全…