OpenCV书签 #互信息的原理与相似图片搜索实验

1. 介绍

互信息(Mutual Information) 是信息论中的一个概念,用于衡量两个随机变量之间的关联程度。在图像处理和计算机视觉中,互信息常被用来度量两幅图像之间的相似性。

互信息可以看成是一个随机变量中包含的关于另一个随机变量的信息量,或者说是一个随机变量由于已知另一个随机变量而减少的不肯定性对任意随机变量。比如,不会由于你知道了一个事件,反而使另一个事件的不确定度增加。

1.1 助记

这里引用知乎神贴 - 什么是互信息 中的比喻:

比如说有一天你的女神突然问你:“你猜猜我的爱豆是TFboys里的谁?”
唉,这要是猜不到,女神的心岂不是很完蛋,追求女神的路从此就凉了。
正当你非常不确定的时候,女神又说:“给你个提示吧,名字是四个字。”
此时你特别开心,因为对于答案的不确定性一下子就减少了(当然这个例子比较极端,不确定性直接降为0)

所以,互信息的意思就是,通过了知道一个变量减少了对另一个变量的不确定性。

这个不确定性减少的量也就是互信息的大小。

 

2. 魔法

使用互信息来度量两幅图像之间的相似性,只需要三步核心操作:

  1. 图像配准: Image Registration,在使用互信息进行相似性度量之前,通常需要对图像进行配准,确保它们对齐。这可以通过一些配准算法来实现,确保图像的空间位置相匹配。
  2. 计算互信息: 使用配准后的图像,计算它们之间的互信息。可以使用一些图像处理库,如 Scikit-ImageOpenCV,来实现互信息的计算。
  3. 相似性度量: 可以根据具体的需求和任务,设定一个阈值,选择互信息值高于该阈值的图像作为相似图像。

 

3. 实验

3.1 魔法拆解

第一步:图像配准

图像配准(Image Registration),在使用互信息进行相似性度量之前,通常需要对图像进行配准,确保它们对齐。这可以通过一些配准算法来实现,确保图像的空间位置相匹配。

# 读取图像
img1 = cv2.imread(img1_path)
img2 = cv2.imread(img2_path)# 检查图像形状,保证两个图像必须具有相同的尺寸,即相同的高度和宽度
if img1.shape != img2.shape:# 调整图像大小,使它们具有相同的形状img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0]))

第二步:计算互信息

使用配准后的图像,计算它们之间的互信息。可以使用一些图像处理库,如 Scikit-ImageOpenCV,来实现互信息的计算。

这里我们先使用灰度直方图来计算互信息:

# 将直方图归一化
# 即将直方图中的每个元素除以直方图的总和,以确保它们的和为1
# 这样做的目的是为了消除不同图像的像素数量差异,使得直方图的形状更具可比性
hist1 /= hist1.sum()
hist2 /= hist2.sum()# 计算两个归一化直方图的互信息
mutual_score = np.sum(np.minimum(hist1, hist2))
print(f"图像2:{os.path.basename(img2_path)} 与 图像1:{img1_path} 的相似性指数:{mutual_score}")

这里首先使用 np.minimum 函数计算 hist1 和 hist2 中每个对应位置的元素的较小值,然后使用 np.sum 计算这些较小值的总和。这个总和即为互信息的计算结果,即互信息的大小。

第三步:相似性度量

根据具体的需求和任务,设定一个阈值,选择互信息值高于该阈值的图像作为相似图像。

# 在实际应用中,可以根据互信息的阈值来判断两幅图像是否相似
if mutual_score > 0.7:print("两图相似")
else:print("两图不相似")

 

3.2 小实验

实验场景

计算两幅灰度图像的直方图,然后通过归一化的直方图计算它们的互信息。最后,根据设定的阈值判断两幅图像是否相似。

实验代码

"""
以图搜图:互信息(Mutual Information)查找相似图像的原理与实现
实验环境:Win10 | python 3.12.1 | OpenCV 4.9.0 | numpy 1.26.3 | Matplotlib 3.8.2
实验时间:2024-01-24
实验目的:计算两幅灰度图像的直方图,然后通过归一化的直方图计算它们的互信息。最后,根据设定的阈值判断两幅图像是否相似
实例名称:mutualInformation_v1.0.py
"""import os
import cv2
import time
import numpy as nptime_start = time.time()# 目标图像素材库文件夹路径
database_dir = '../../P0_Doc/img_data/'# 读取查询图像和数据库中的图像
img1_path = database_dir + 'car-101.jpg'
img2_path = database_dir + 'car-102.jpg'
img2_path = database_dir + 'car-103.jpg'# 读取两幅图像
img1 = cv2.imread(img1_path, cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread(img2_path, cv2.IMREAD_GRAYSCALE)# 检查图像形状,保证两个图像必须具有相同的尺寸,即相同的高度和宽度
if img1.shape != img2.shape:# 调整图像大小,使它们具有相同的形状img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0]))# 使用 OpenCV 中的 calcHist 函数计算直方图
hist1 = cv2.calcHist([img1], [0], None, [256], [0, 256])
hist2 = cv2.calcHist([img2], [0], None, [256], [0, 256])# 将直方图归一化
# 即将直方图中的每个元素除以直方图的总和,以确保它们的和为1
# 这样做的目的是为了消除不同图像的像素数量差异,使得直方图的形状更具可比性
hist1 /= hist1.sum()
hist2 /= hist2.sum()# 计算两个归一化直方图的互信息
# 首先,使用 np.minimum 函数计算了 hist1 和 hist2 中每个对应位置的元素的较小值,然后使用 np.sum 计算了这些较小值的总和。这个总和即为互信息的计算结果
mutual_score = np.sum(np.minimum(hist1, hist2))
print(f"图像2:{os.path.basename(img2_path)} 与 图像1:{img1_path} 的相似性指数:{mutual_score}")# 在实际应用中,可以根据互信息的阈值来判断两幅图像是否相似
if mutual_score > 0.7:print("两图相似")
else:print("两图不相似")time_end = time.time()
print(f"耗时:{time_end - time_start}")

输出打印:

图像2:car-103.jpg 与 图像1../../P0_Doc/img_data/car-101.jpg 的相似性指数:0.6439836025238037
两图不相似
耗时:0.0687875747680664

示例中的互信息计算,利用了灰度直方图比较方法,通过比较两幅图像的灰度直方图,评估它们的相似性。
注意: 如果这里不进行图像配准,不保证等高等宽,互信息的相似度也会产生差异。

插播: 直方图是一种统计图像中像素值分布的方法,它可以描述图像中不同灰度级别的像素数量。关于直方图的原理与实验,可详见:OpenCV书签 #直方图算法的原理与相似图片搜索实验

 

为什么要用灰度直方图呢?有什么关联和区别?

互信息和灰度直方图算法是两个不同的概念,虽然在图像处理中它们有时候会交叉使用,但是还是需要注意:

互信息(Mutual Information):

  • 互信息是一种信息论中的概念,用于衡量两个随机变量之间的关联程度。
  • 在图像处理中,互信息通常用于度量两幅图像之间的相似性。它考虑的是两个变量的联合概率分布与各自边缘概率分布之间的关系。
  • 互信息越高,表示两个随机变量之间的关联越强。

灰度直方图算法(Image Histogram):

  • 灰度直方图是一种统计图像中像素值分布的方法,它描述了图像中不同灰度级别的像素数量。
  • 在灰度直方图算法中,图像的直方图表示了图像中每个灰度级别的像素数量。
  • 直方图比较是通过比较两幅图像的灰度直方图来评估它们的相似性。常见的比较方法包括交叉相关性、巴氏距离等。

虽然互信息的计算可以涉及到灰度直方图,但两者并不等同。互信息是一种更广泛的概念,而灰度直方图算法是一种具体的图像表示和相似性度量方法。

 

4. 测试

4.1 实验素材

MutualInformation-001

4.2 实验过程

纵向比较

通过 sklearn.metrics 提供的各类互信息比较算法,纵向比较两图的相似性。

实验代码
"""
以图搜图:互信息(Mutual Information)查找相似图像的原理与实现
实验环境:Win10 | python 3.12.1 | OpenCV 4.9.0 | numpy 1.26.3 | Matplotlib 3.8.2
实验时间:2024-01-24
实验目的:通过 sklearn.metrics 提供的各类互信息比较算法,纵向比较两图的相似性
实例名称:mutualInformation_v2.1.py
"""import time
import cv2
from sklearn import metrics as mr
# from sklearn.metrics.cluster import normalized_mutual_info_score
# from sklearn.metrics.cluster import adjusted_mutual_info_scoredef mutual_information_score(img1_reshape, img2_reshape):# mutual_info_score:标准互信息分数。度量两个随机变量之间的互信息,可用于衡量它们之间的关联性m_time_start = time.time()score_info = mr.mutual_info_score(img1_reshape, img2_reshape)m_time_end = time.time()print(f"互信息 mutual_info_score:标准互信息分数:{score_info},耗时:{m_time_end - m_time_start}")# normalized_mutual_info_score:归一化互信息分数。用于衡量两个聚类结果之间的相似性,考虑到了数据集的随机性。通常被用作聚类性能的评估指标m_time_start = time.time()score_normal = mr.normalized_mutual_info_score(img1_reshape, img2_reshape)m_time_end = time.time()print(f"互信息 normalized_mutual_info_score:归一化互信息分数:{score_normal},耗时:{m_time_end - m_time_start}")# adjusted_mutual_info_score:调整的归一化互信息分数。该分数考虑到了数据集的随机性,对标准互信息进行了调整,以提供更准确的聚类性能度量m_time_start = time.time()score_adjusted = mr.adjusted_mutual_info_score(img1_reshape, img2_reshape)m_time_end = time.time()print(f"互信息 adjusted_mutual_info_score:调整的归一化互信息分数:{score_adjusted},耗时:{m_time_end - m_time_start}")# v_measure_score: V-Measure(V值)分数。结合了聚类的均匀性和完整性,提供了一个综合的聚类性能度量m_time_start = time.time()score_measure = mr.v_measure_score(img1_reshape, img2_reshape)m_time_end = time.time()print(f"互信息 v_measure_score:V-Measure(V值)分数:{score_measure},耗时:{m_time_end - m_time_start}")# homogeneity_score: 均匀性分数。用于度量每个聚类的成员是否都属于同一类别,高均匀性表示每个聚类都很“纯净”m_time_start = time.time()score_homogeneity = mr.homogeneity_score(img1_reshape, img2_reshape)m_time_end = time.time()print(f"互信息 homogeneity_score:均匀性分数:{score_homogeneity},耗时:{m_time_end - m_time_start}")# completeness_score: 完整性分数。度量每个真实类别的成员是否都被分配到同一聚类中,高完整性表示每个类别都被很好地捕捉m_time_start = time.time()score_completeness = mr.completeness_score(img1_reshape, img2_reshape)m_time_end = time.time()print(f"互信息 completeness_score:完整性分数:{score_completeness},耗时:{m_time_end - m_time_start}")# adjusted_rand_score: 调整的兰德指数。度量两个聚类结果之间的相似性,考虑了数据集的随机性m_time_start = time.time()score_adjusted_rand = mr.adjusted_rand_score(img1_reshape, img2_reshape)m_time_end = time.time()print(f"互信息 adjusted_rand_score:调整的兰德指数:{score_adjusted_rand},耗时:{m_time_end - m_time_start}")# fowlkes_mallows: Fowlkes-Mallows指数。度量两个聚类结果之间的精度,考虑了聚类的精确度m_time_start = time.time()score_fowlkes_mallows = mr.fowlkes_mallows_score(img1_reshape, img2_reshape)m_time_end = time.time()print(f"互信息 fowlkes_mallows_score:Fowlkes-Mallows指数:{score_fowlkes_mallows},耗时:{m_time_end - m_time_start}")# silhouette_score: 轮廓系数。度量每个样本在其自己的聚类中的相似性与最近的相邻聚类之间的不相似性# 输入是两张图片,而不是聚类数据,计算轮廓系数就不太适用了,因为轮廓系数通常用于衡量聚类的质量# score_silhouette = mr.silhouette_score(img1.reshape(-1, 1), img2.reshape(-1, 1))if __name__ == "__main__":time_start = time.time()# 目标图像素材库文件夹路径database_dir = '../../P0_Doc/img_data/'# 读取查询图像和数据库中的图像img1_path = database_dir + 'car-101.jpg'img2_path = database_dir + 'car-102.jpg'img1_path = database_dir + 'apple-101.jpg'img2_path = database_dir + 'apple-102.jpg'print(f"互信息相似度比较,图像1:{img1_path},图像2:{img2_path}")# 读取图像img1 = cv2.imread(img1_path)img2 = cv2.imread(img2_path)# 检查图像形状,保证两个图像必须具有相同的尺寸,即相同的高度和宽度if img1.shape != img2.shape:# 调整图像大小,使它们具有相同的形状img2 = cv2.resize(img2, (img1.shape[1], img1.shape[0]))print("------------------------- 原图像 互信息相似度           -------------------------")# 原图应用于常见的互信息相关方法和算法及相似度mutual_information_score(img1.reshape(-1), img2.reshape(-1))# 将图像转换为灰度图像img1_gray = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)img2_gray = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)print("------------------------- 图像转换为灰度图像 互信息相似度 -------------------------")# 原图灰度图像应用于常见的互信息相关方法和算法及相似度mutual_information_score(img1_gray.reshape(-1), img2_gray.reshape(-1))time_end = time.time()print(f"耗时:{time_end - time_start}")

sklearn.metrics.cluster 提供了很多互信息相关的方法和算法,主要用于不同的评估场景,涉及到聚类的性能和相似性的测量:

互信息算法/方法说明
adjusted_mutual_info_score调整的归一化互信息分数。该分数考虑到了数据集的随机性,对标准互信息进行了调整,以提供更准确的聚类性能度量
normalized_mutual_info_score归一化互信息分数。用于衡量两个聚类结果之间的相似性,考虑到了数据集的随机性。通常被用作聚类性能的评估指标
mutual_info_score标准互信息分数。度量两个随机变量之间的互信息,可用于衡量它们之间的关联性
v_measure_scoreV-Measure(V值)分数。结合了聚类的均匀性和完整性,提供了一个综合的聚类性能度量
homogeneity_score均匀性分数。用于度量每个聚类的成员是否都属于同一类别,高均匀性表示每个聚类都很“纯净”
completeness_score完整性分数。度量每个真实类别的成员是否都被分配到同一聚类中,高完整性表示每个类别都被很好地捕捉
adjusted_rand_score调整的兰德指数。度量两个聚类结果之间的相似性,考虑了数据集的随机性
fowlkes_mallows_scoreFowlkes-Mallows指数。度量两个聚类结果之间的精度,考虑了聚类的精确度
silhouette_score轮廓系数。度量每个样本在其自己的聚类中的相似性与最近的相邻聚类之间的不相似性

img1_reshape.reshape(-1)img1_reshape.reshape(-1, 1)NumPy 中用于改变数组形状的方法。
reshape(-1) 用于展平数组,而 reshape(-1, 1) 用于将数组转换为包含单个列的二维数组。区别在于得到的形状不同。

  • img1_reshape.reshape(-1): 这将多维数组 img1_reshape 转换为一个展平的一维数组。NumPy 会根据数组的大小自动计算另一维度的大小,以确保总的元素数量不变。这通常用于将多维数组展平为一维数组,方便某些操作。
  • img1_reshape.reshape(-1, 1): 这将多维数组 img1_reshape 转换为一个包含单个列的二维数组。其中,-1 表示自动计算行数,而 1 表示只有一列。这通常用于确保某些函数接受的输入是二维数组,并且每个样本在单独的列中。

关于这些算法/方法,源码提供了使用 Demo,可以通过源码了解更多,比如:

    Examples--------Perfect labelings are both homogeneous and complete, hence havescore 1.0::>>> from sklearn.metrics.cluster import normalized_mutual_info_score>>> normalized_mutual_info_score([0, 0, 1, 1], [0, 0, 1, 1])... # doctest: +SKIP1.0>>> normalized_mutual_info_score([0, 0, 1, 1], [1, 1, 0, 0])... # doctest: +SKIP1.0If classes members are completely split across different clusters,the assignment is totally in-complete, hence the NMI is null::>>> normalized_mutual_info_score([0, 0, 0, 0], [0, 1, 2, 3])... # doctest: +SKIP0.0

实验代码输出打印:

互信息相似度比较,图像1../../P0_Doc/img_data/apple-101.jpg,图像2../../P0_Doc/img_data/apple-102.jpg
------------------------- 原图像 互信息相似度           -------------------------
互信息 mutual_info_score:标准互信息分数:0.3334500090190323,耗时:0.4178807735443115
互信息 normalized_mutual_info_score:归一化互信息分数:0.1442800195961649,耗时:0.704125165939331
互信息 adjusted_mutual_info_score:调整的归一化互信息分数:0.13897879139743463,耗时:27.81876230239868
互信息 v_measure_score:V-Measure(V值)分数:0.14428001959616493,耗时:0.6462442874908447
互信息 homogeneity_score:均匀性分数:0.1393427892877539,耗时:0.6453077793121338
互信息 completeness_score:完整性分数:0.14957997661474184,耗时:0.6043868064880371
互信息 adjusted_rand_score:调整的兰德指数:0.5983897700024668,耗时:0.39893531799316406
互信息 fowlkes_mallows_score:Fowlkes-Mallows指数:0.7874850623258953,耗时:0.3939492702484131
------------------------- 图像转换为灰度图像 互信息相似度 -------------------------
互信息 mutual_info_score:标准互信息分数:0.3114601065499291,耗时:0.12766075134277344
互信息 normalized_mutual_info_score:归一化互信息分数:0.14164731215313434,耗时:0.2203817367553711
互信息 adjusted_mutual_info_score:调整的归一化互信息分数:0.13105360189408213,耗时:6.436821222305298
互信息 v_measure_score:V-Measure(V值)分数:0.14164731215313434,耗时:0.20248985290527344
互信息 homogeneity_score:均匀性分数:0.1361761519096563,耗时:0.25429248809814453
互信息 completeness_score:完整性分数:0.14757650531529792,耗时:0.19750332832336426
互信息 adjusted_rand_score:调整的兰德指数:0.6065766924224203,耗时:0.1396336555480957
互信息 fowlkes_mallows_score:Fowlkes-Mallows指数:0.7932503296629234,耗时:0.13862109184265137
耗时:39.388914585113525

通过简单的测试,从纵向比较两图的相似性结果来看:

原图像

  • 互信息使用 adjusted_mutual_info_score 算法,相似度得分最低,耗时最长。
  • 互信息使用 fowlkes_mallows_score 算法,相似度得分最高,耗时最短。

图像灰度之后,去除了彩色像素处理,速度明显变快很多:

  • 互信息使用 adjusted_mutual_info_score 算法,相似度得分最低,耗时最长。
  • 互信息使用 fowlkes_mallows_score 算法,相似度得分最高。
  • 互信息使用 mutual_info_score 算法,耗时最短。

横向比较

通过使用某一互信息计算方法,配合相似阈值,在测试图片素材库中搜索查找与目标图像相似的图片。

实验代码
"""
以图搜图:互信息(Mutual Information)查找相似图像的原理与实现
实验环境:Win10 | python 3.12.1 | OpenCV 4.9.0 | numpy 1.26.3 | Matplotlib 3.8.2
实验时间:2024-01-24
实验目的:通过使用某一互信息计算方法,配合相似阈值,在测试图片素材库中搜索查找与目标图像相似的图片
实例名称:mutualInformation_v2.2.py
"""import os
import time
import cv2
import matplotlib.pyplot as plt
from sklearn import metrics as mrdef search_mutual_info(img_org_path, database_paths):# 将原图像转换为灰度图像img_original_gray = cv2.cvtColor(cv2.imread(img_org_path), cv2.COLOR_BGR2GRAY)# 遍历数据库图像并比较相似度similaritys = []for img_path in database_paths:# 获取相似图像文件路径img_target_path = os.path.join(script_dir, database_dir_path, img_path)# 将图像转换为灰度图像img_target_gray = cv2.cvtColor(cv2.imread(img_target_path), cv2.COLOR_BGR2GRAY)# 检查图像形状,保证两个图像必须具有相同的尺寸,即相同的高度和宽度if img_original_gray.shape != img_target_gray.shape:# 调整图像大小,使它们具有相同的形状img_target_gray = cv2.resize(img_target_gray, (img_original_gray.shape[1], img_original_gray.shape[0]))# 灰度图像应用于常见的互信息相关方法和算法及相似度score = mr.fowlkes_mallows_score(img_original_gray.reshape(-1), img_target_gray.reshape(-1))# print(f"互信息 fowlkes_mallows_score:{score}")# 将结果保存到列表中(仅保留相似值大于等于 0.7 的图像)if (score >= 0.7):similaritys.append((os.path.relpath(img_target_path), score))# print(f"图像名称:{img_target_path},与目标图像 {os.path.basename(img_resouce)} 的近似值:{ssim[0]}")return similaritysdef show_similar_images(similar_images, images_per_column=4):# 计算总共的图片数量num_images = len(similar_images)# 计算所需的行数num_rows = (num_images + images_per_column - 1) // images_per_column# 创建一个子图,每行显示 images_per_column 张图片fig, axes = plt.subplots(num_rows, images_per_column, figsize=(12, 15), squeeze=False)# 遍历每一行for row in range(num_rows):# 遍历每一列for col in range(images_per_column):# 计算当前图片在列表中的索引index = row * images_per_column + col# 检查索引是否越界if index < num_images:# 获取当前相似图片的路径和相似度image_path = similar_images[index][0]similarity = similar_images[index][1]# 读取图片并转换颜色通道image = cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_BGR2RGB)# 在子图中显示图片axes[row, col].imshow(image)# 设置子图标题,包括图片路径和相似度axes[row, col].set_title(f"Similar Image: {os.path.basename(image_path)} \n Similar Score: {similarity}")# 关闭坐标轴axes[row, col].axis('off')# 显示整个图plt.show()if __name__ == "__main__":time_start = time.time()# 获取当前执行脚本所在目录script_dir = os.path.dirname(__file__)# 目标图像素材库文件夹路径database_dir_path = '../../P0_Doc/img_data/'# 指定测试图像文件扩展名img_suffix = ['.jpg', '.jpeg', '.png', '.bmp', '.gif']# 获取测试图像库中所有文件all_files = os.listdir(os.path.join(script_dir, database_dir_path))# 筛选测试图像库中指定后缀的图像文件img_files = [img_file for img_file in all_files if any(img_file.endswith(suffix) for suffix in img_suffix)]# 获取测试图像库中所有图像的路径img_files_path = [os.path.join(database_dir_path, filename) for filename in img_files]# 获取目标测试图像的全路径img_org_path = os.path.join(script_dir, database_dir_path, 'apple-101.jpg')img_org_path = os.path.join(script_dir, database_dir_path, 'iphone15-001.jpg')img_org_path = os.path.join(script_dir, database_dir_path, 'car-101.jpg')# 原图应用于常见的互信息相关方法和算法及相似度img_search_results = search_mutual_info(img_org_path, img_files_path)# 按相似度降序排序img_search_results.sort(key=lambda item: item[1], reverse=True)for similarity in img_search_results:print(f"图像:{similarity[0]},与目标图像 {os.path.basename(img_org_path)} 的相似值:{similarity[1]}")time_end = time.time()print(f"测试素材库图像数量:{len(img_files)},耗时:{time_end - time_start}")# 显示目标相似图像show_similar_images(img_search_results)
第一组测试

测试结果输出打印:

图像:..\..\P0_Doc\img_data\apple-101.jpg,与目标图像 apple-101.jpg 的相似值:1.0
图像:..\..\P0_Doc\img_data\apple-103.jpg,与目标图像 apple-101.jpg 的相似值:0.8185132476782856
图像:..\..\P0_Doc\img_data\apple-105.jpg,与目标图像 apple-101.jpg 的相似值:0.8069378648696433
图像:..\..\P0_Doc\img_data\apple-102.jpg,与目标图像 apple-101.jpg 的相似值:0.7932928654393832
图像:..\..\P0_Doc\img_data\iphone15-001.jpg,与目标图像 apple-101.jpg 的相似值:0.771736183796336
图像:..\..\P0_Doc\img_data\iphone15-002.jpg,与目标图像 apple-101.jpg 的相似值:0.7715952189959523
图像:..\..\P0_Doc\img_data\iphone15-003.jpg,与目标图像 apple-101.jpg 的相似值:0.7707667748546456
图像:..\..\P0_Doc\img_data\apple-109.jpg,与目标图像 apple-101.jpg 的相似值:0.7528870440060801
图像:..\..\P0_Doc\img_data\pear-201.jpg,与目标图像 apple-101.jpg 的相似值:0.7208068021727383
图像:..\..\P0_Doc\img_data\apple-104.jpg,与目标图像 apple-101.jpg 的相似值:0.7066478416742119
测试素材库图像数量:48,耗时:7.807173013687134

互信息相似图片查找效果可视化:
MutualInformation-002

第二组测试

测试结果输出打印:

图像:..\..\P0_Doc\img_data\iphone15-001.jpg,与目标图像 iphone15-001.jpg 的相似值:1.0
图像:..\..\P0_Doc\img_data\iphone15-002.jpg,与目标图像 iphone15-001.jpg 的相似值:0.9985563921236876
图像:..\..\P0_Doc\img_data\iphone15-003.jpg,与目标图像 iphone15-001.jpg 的相似值:0.996718480433257
图像:..\..\P0_Doc\img_data\apple-102.jpg,与目标图像 iphone15-001.jpg 的相似值:0.8165921658980023
图像:..\..\P0_Doc\img_data\apple-104.jpg,与目标图像 iphone15-001.jpg 的相似值:0.7733543220682563
图像:..\..\P0_Doc\img_data\apple-101.jpg,与目标图像 iphone15-001.jpg 的相似值:0.7717483756822613
图像:..\..\P0_Doc\img_data\apple-103.jpg,与目标图像 iphone15-001.jpg 的相似值:0.7579136253684923
图像:..\..\P0_Doc\img_data\apple-105.jpg,与目标图像 iphone15-001.jpg 的相似值:0.7540519846067019
测试素材库图像数量:48,耗时:30.248269081115723

互信息相似图片查找效果可视化:
MutualInformation-003

 

5. 总结

在图像处理中,互信息可以用来衡量两幅图像的相似性,尤其在配准(registration)和图像匹配(image matching)的任务中经常被使用。通过最大化互信息,可以找到两个图像之间的最佳匹配,以便更好地对齐它们。

优点

  1. 对比度不敏感: 互信息对比度不敏感,适用于对比度较大的图像。
  2. 非线性关系: 互信息适用于具有非线性关系的图像数据,因此对于复杂的图像相似性度量具有一定优势。
  3. 不依赖特定颜色空间: 互信息在计算过程中不依赖于特定的颜色空间,因此对于不同颜色表示的图像也能够有效计算相似性。

缺点

  1. 图像配准: 如果两张图片尺寸相同,还是能在一定程度上表征两张图片的相似性的。但是,大部分情况下图片的尺寸不相同,如果把两张图片尺寸调成相同的话,又会让原来很多的信息丢失,所以很难把握。
  2. 计算复杂度: 互信息的计算涉及到直方图的操作,因此在图像尺寸较大、直方图维度较高时计算复杂度较高。
  3. 对噪声敏感: 互信息对噪声敏感,噪声可能对互信息的计算产生一定影响。
  4. 不考虑空间结构: 互信息不考虑像素在图像中的空间结构,可能对图像中物体的空间排列不敏感。

 

6. 问题

异常现象1

    from skimage.feature import mutual_info_score
ImportError: cannot import name 'mutual_info_score' from 'skimage.feature' (D:\Tp_Mylocal\20_Install\python-3.9.13\lib\site-packages\skimage\feature\__init__.py)

可以尝试安装或更新 scikit-image 依赖项:

pip install --upgrade scikit-image
Installing collected packages: pillow, packaging, numpy, networkx, lazy_loader, tifffile, scipy, imageio, scikit-imageWARNING: Failed to write executable - trying to use .deleteme logic
ERROR: Could not install packages due to an OSError: [WinError 2] 系统找不到指定的文件。: 'C:\\Python312\\Scripts\\f2py.exe' -> 'C:\\Python312\\Scripts\\f2py.exe.deleteme'

f2py.exeFortran 到 Python 接口生成器的可执行文件。它用于将 Fortran 代码集成到 Python 中,使得可以在 Python 中调用 Fortran 编写的函数或子程序。

在正常情况下,f2py.exe 应该包含在 NumPy 库中。由于我本地环境没有,可能是之前安装出现的问题。这里重新安装 NumPy,以获取缺失的文件:

pip install --upgrade --force-reinstall numpy

还是不行的话,尝试一下在应用程序中先卸载 Python,再重装最新版的 Python。

以我的案例看,我本地的 Python 版本是 python 3.9.13,卸载后重装了最新版的 Python 3.12.1。
如果重装 python 时,选择了新的路径,这里同样需要确认或调整一下系统环境变量中关于 python 的路径指向。
然后重新安装本地运行 python 脚本缺失的依赖项,包括 scikit-learn。
然后就可以了。也没有类似需要 f2py.exe 的错误提示。
需要注意的是,目前互信息提供的相似算法都在 from sklearn.metrics.cluster 下。

安装 scikit-learn 依赖项:

pip install scikit-learn

 

异常现象2

Traceback (most recent call last):File "D:\Ct_ iSpace\Wei\Python\iPython\T30_Algorithm\P2_Algo\03_MutualInformation\mutualInformation_v2.1.py", line 119, in <module>mutual_information_score(img1.reshape(-1), img2.reshape(-1))File "D:\Ct_ iSpace\Wei\Python\iPython\T30_Algorithm\P2_Algo\03_MutualInformation\mutualInformation_v2.1.py", line 89, in mutual_information_scorescore_silhouette = mr.silhouette_score(img1_reshape, img2_reshape)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "D:\Ct_ iSpace\Wei\Python\iPython\T00_Env\Lib\site-packages\sklearn\utils\_param_validation.py", line 213, in wrapperreturn func(*args, **kwargs)^^^^^^^^^^^^^^^^^^^^^File "D:\Ct_ iSpace\Wei\Python\iPython\T00_Env\Lib\site-packages\sklearn\metrics\cluster\_unsupervised.py", line 140, in silhouette_scorereturn np.mean(silhouette_samples(X, labels, metric=metric, **kwds))^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "D:\Ct_ iSpace\Wei\Python\iPython\T00_Env\Lib\site-packages\sklearn\utils\_param_validation.py", line 186, in wrapperreturn func(*args, **kwargs)^^^^^^^^^^^^^^^^^^^^^File "D:\Ct_ iSpace\Wei\Python\iPython\T00_Env\Lib\site-packages\sklearn\metrics\cluster\_unsupervised.py", line 267, in silhouette_samplesX, labels = check_X_y(X, labels, accept_sparse=["csr"])^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "D:\Ct_ iSpace\Wei\Python\iPython\T00_Env\Lib\site-packages\sklearn\utils\validation.py", line 1192, in check_X_yX = check_array(^^^^^^^^^^^^File "D:\Ct_ iSpace\Wei\Python\iPython\T00_Env\Lib\site-packages\sklearn\utils\validation.py", line 989, in check_arrayraise ValueError(msg)
ValueError: Expected 2D array, got 1D array instead:
array=[253 253 253 ... 253 253 253].
Reshape your data either using array.reshape(-1, 1) if your data has a single feature or array.reshape(1, -1) if it contains a single sample.

异常原因: silhouette_score 函数期望接收的数据是一个2D数组,而 Demo 提供的是一个1维数组。因为输入是两张图片,而不是聚类数据,计算轮廓系数就不太适用了,因为轮廓系数通常用于衡量聚类的质量。

解决方案: 使用 array.reshape(-1, 1) 来将数据转换成2D数组。

 

7. 参考资料

互信息 - 百度百科
什么是「互信息」?
互信息是什么?

 

8. 系列书签

均值哈希算法: OpenCV书签 #均值哈希算法的原理与相似图片搜索实验
感知哈希算法: OpenCV书签 #感知哈希算法的原理与相似图片搜索实验
差值哈希算法: OpenCV书签 #差值哈希算法的原理与相似图片搜索实验
直方图算法: OpenCV书签 #直方图算法的原理与相似图片搜索实验
余弦相似度: OpenCV书签 #余弦相似度的原理与相似图片/相似文件搜索实验
SSIM结构相似性: OpenCV书签 #结构相似性SSIM算法的原理与图片相似性实验

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

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

相关文章

FastDeploy项目简介,使用其进行(图像分类、目标检测、语义分割、文本检测|orc部署)

FastDeploy是一款全场景、易用灵活、极致高效的AI推理部署工具&#xff0c; 支持云边端部署。提供超过 &#x1f525;160 Text&#xff0c;Vision&#xff0c; Speech和跨模态模型&#x1f4e6;开箱即用的部署体验&#xff0c;并实现&#x1f51a;端到端的推理性能优化。包括 物…

win10+elasticsearch8.12 安装教程

Elasticsearch是一种搜索引擎&#xff0c;本地安装完成之后&#xff0c;可使用其他编程语言&#xff08;例如python&#xff09;与elasticsearch建立连接&#xff0c;然后使用python脚本搜索elasticsearch中的数据 1下载 elasticsearch elasticsearch最新版官网下载链接 点击…

如何降低微服务复杂度丨云栖大会微服务主题分享实录

作者&#xff1a;谢吉宝 本文整理自阿里云资深技术专家、中间件负责人谢吉宝在2023云栖大会《极简微服务模式&#xff0c;降低微服务复杂度的最佳实践》的分享 2023 云栖大会现场 当面临复杂的挑战时&#xff0c;"分而治之"的方法往往能取得显著的效果。微服务架构…

HCIA——25FTP 的工作原理、功能、TFTP、控制连接、数据连接的选择、解答

学习目标&#xff1a; 计算机网络 1.掌握计算机网络的基本概念、基本原理和基本方法。 2.掌握计算机网络的体系结构和典型网络协议&#xff0c;了解典型网络设备的组成和特点&#xff0c;理解典型网络设备的工作原理。 3.能够运用计算机网络的基本概念、基本原理和基本方法进行…

使用 Redis 的 List 数据结构实现分页查询的思路

假设有一个存储数据的 List&#xff0c;每个元素代表一个记录&#xff0c;例如 recordsList。 按页存储数据&#xff1a; 每页存储一定数量的记录。例如&#xff0c;第一页存储索引 0 到 N-1 的记录&#xff0c;第二页存储索引 N 到 2N-1 的记录&#xff0c;以此类推。 分页查…

Java入门——基本语法(注释、字面量、变量、使用变量的注意事项、关键字、标识符)

目录 注释 字面量 变量 使用变量的注意事项 关键字 标识符 注释 什么是注释 注释是写在程序中对代码进行解释说明的文字&#xff0c;方便自己和其他人查看&#xff0c;以便理解程序的。 注释有哪些 单行注释 // 注释内容&#xff0c;只能写一行 多行注释 /* 注释内…

Java中的HTTPS通信

在Java中实现HTTPS通信&#xff0c;主要涉及到SSL/TLS协议的使用&#xff0c;用于提供数据传输的安全性。下面我们将深入探讨如何使用Java进行HTTPS通信。 一、基本概念 HTTPS&#xff0c;全称为Hypertext Transfer Protocol Secure&#xff0c;是HTTP的安全版本。它使用SSL/…

Matlab|含风电-光伏-光热电站电力系统N-k安全优化调度模型

目录 1 主要内容 程序算例 程序模型 程序亮点 2 部分程序 3 部分结果 4 下载链接 1 主要内容 该程序参考《光热电站促进风电消纳的电力系统优化调度》光热电站模型&#xff0c;主要做的是考虑N-k安全约束的含义风电-光伏-光热电站的电力系统优化调度模型&#xff0c;从而…

uniapp page宽度设置为750rpx,子元素宽度100%,大小不一致

uniapp page宽度设置为750rpx&#xff0c;子元素宽度100%&#xff0c;大小不一致。 原因是我在page加了margin: 0 auto;去掉就正常了&#xff08;但是如果在超大屏幕还是会出现&#xff0c;我猜是使用rpx导致的&#xff0c;rpx渲染成页面时会转成精确到一个小数点几位数的rem&a…

【创建vue项目的两种方式】

Vue环境搭建 NodeJs安装包安装淘宝镜像 环境搭建webpack安装全局安装vue/cli查看模板创建项目1.webpack2. vue-cli NodeJs安装包 下载链接&#xff1a;官网链接 下载下来后&#xff0c;直接傻瓜式的安装即可。 通过在cmd控制台输入以下命令查看是否安装成功 node -v因为适配某…

【oracle】oracle客户端及oracle连接工具

一、关于oracle客户端 1.1 Oracle Client 完整客户端 包含完整的客户端连接工具。 包很大&#xff0c;需要安装 1.2 instantclient 即时客户端 是 Oracle(R) 发布的轻量级数据库客户端&#xff0c;减少甚至只包含几个文件&#xff0c;您无需安装标准的客户端&#xff0c;就可以…

第四篇【传奇开心果短博文系列】Python的OpenCV库技术点案例示例:机器学习

传奇开心短博文系列 系列短博文目录Python的OpenCV库技术点案例示例系列短博文 短博文目录一、项目目标二、OpenCV机器学习介绍三、OpenCV支持向量机示例代码四、OpenCV支持向量机示例代码扩展五、OpenCVK均值聚类示例代码六、OpenCVK均值聚类示例代码扩展七、OpenCV决策树示例…

jetson-inference----docker内运行分类任务

系列文章目录 jetson-inference入门 jetson-inference----docker内运行分类任务 文章目录 系列文章目录前言一、进入jetson-inference的docker二、分类任务总结 前言 继jetson-inference入门 一、进入jetson-inference的docker 官方运行命令 进入jetson-inference的docker d…

opencv012 滤波器04 中值滤波,双边滤波

中值滤波 取中位数&#xff0c;可以处理椒盐噪音 CV自带medianBlur函数dst cv2.medianBlur(src, ksize) 参数说明&#xff1a;1.src: 需要滤波的图片&#xff1b;2.ksize&#xff1a;核大小&#xff0c;必须是比1大的奇数【举个例子&#xff1a;3&#xff0c;5&#xff0c;7……

CSS复合选择器和CSS层叠性、继承性有哪些内容?

知识引入 1.CSS复合选择器 书写CSS样式表时&#xff0c;可以使用CSS基础选择器选中目标元素。但是在实际网站开发中&#xff0c;一个网页中可能包含成千上万的元素&#xff0c;如果仅使用CSS基础选择器&#xff0c;是远远不够的。为此&#xff0c;CSS提供了几种复合选择器&am…

node.js安装配置详细教程(附图-贼详细)

一&#xff1a;下载 Node.js官网下载地址&#xff1a;Node.js — Download 选择自己需要的版本我用的Windows ps:如果想下载指定版本&#xff0c;点下面这个就可以选择想要的版本 二&#xff1a;安装 1.下载完成后&#xff0c;双击安装包开始安装 2.安装过程&#xff1a;一步…

基于禁忌搜索算法的TSP路径规划matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 TSP问题描述 4.2 禁忌搜索算法原理 4.3 算法步骤 5.完整程序 1.程序功能描述 基于禁忌搜索算法的TSP路径规划,输出优化收敛曲线以及路线规划图。 2.测试软件版本以及运行结果展示 …

redis-发布缓存

一.redis的发布订阅 什么 是发布和订阅 Redis 发布订阅 (pub/sub) 是一种消息通信模式&#xff1a;发送者 (pub) 发送消息&#xff0c;订阅者 (sub) 接收消息。 Redis 客户端可以订阅任意数量的频道。 Redis的发布和订阅 客户端订阅频道发布的消息 频道发布消息 订阅者就可…

C语言练习题110例(十)

91.杨辉三角 题目描述: KK知道什么叫杨辉三角之后对杨辉三角产生了浓厚的兴趣&#xff0c;他想知道杨辉三角的前n行&#xff0c;请编程帮他 解答。杨辉三角&#xff0c;本质上是二项式(ab)的n次方展开后各项的系数排成的三角形。其性质包括&#xff1a;每行的端点数为1&…

【量化交易】股市舞者:小明的撮合交易之旅

马西森AES撮合交易系统 在繁华的都市中&#xff0c;小明&#xff0c;一个普通的青年&#xff0c;刚刚赚到了人生的第一桶金——20万。这笔意外的财富&#xff0c;点燃了他对股市的强烈兴趣。他开始如饥似渴地学习金融知识&#xff0c;钻研各种交易策略。 一天&#xff0c;小…