python图像识别之图片相似度计算


python图像识别之图片相似度计算

文章插图
 
作者 | a1131825850疯子
来源 | Python爬虫scrapy
1.背景
要识别两张图片是否相似,首先我们可能会区分这两张图是人物照,还是风景照等......对应的风景照是蓝天还是大海......做一系列的分类 。
从机器学习的的角度来说,首先要提取图片的特征,将这些特征进行分类处理,训练并建立模型,然后在进行识别 。
但是让计算机去区分这些图片分别是哪一类是很不容易的,不过计算机可以知道图像的像素值的,因此,在图像识别过程中,通过颜色特征来识别是相似图片是我们常用的(当然还有其特征还有纹理特征、形状特征和空间关系特征等,这些有分为直方图,颜色集,颜色局,聚合向量,相关图等来计算颜色特征),
为了得到两张相似的图片,在这里通过以下几种简单的计算方式来计算图片的相似度:
直方图计算图片的相似度
通过哈希值,汉明距离计算
通过图片的余弦距离计算
通过图片结构度量计算
一、直方图计算图片的相似度
上三张图片,分别是img1.png, img2.jpg,img.png:
python图像识别之图片相似度计算

文章插图
 

python图像识别之图片相似度计算

文章插图
 

python图像识别之图片相似度计算

文章插图
 
可以看出上面这三张图是挺相似的,在颜色上是差不多的,最相似的是哪两张大家可以猜猜看,看和我们计算的是否一样 。
在python中利用opencv中的calcHist()方法获取其直方图数据,返回的结果是一个列表:
# 计算图img1的直方图H1 = cv2.calcHist([img1], [1], None, [256], [0, 256])H1 = cv2.normalize(H1, H1, 0, 1, cv2.NORM_MINMAX, -1) # 对图片进行归一化处理先计算img1的直方图,在对其归一化,最后在分别对img2,img3计算,做归一化,然后在利用python自带的compareHist()进行相似度的比较:
利用compareHist()进行比较相似度similarity1 = cv2.compareHist(H1, H2, 0)最后得到三张图片的直方图如下:
python图像识别之图片相似度计算

文章插图
 
图像的x轴是指的图片的0~255之间的像素变化,y轴指的是在这0~255像素所占的比列 。
我们可以明显的看出img2与img3的直方图的变化趋势是相符的有重合态的,运行结果如下:
python图像识别之图片相似度计算

文章插图
 
通过运行结果知道img2和img3是值是最为相似的(代码calcImage.py)
上面的是直接调用opencv中的方法来实现的,下面还有自己写的方法:
首先是将图片转化为RGB格式,在这里是用的pillow中的Image来对图片做处理的:
# 将图片转化为RGBdef make_regalur_image(img, size=(64, 64)): gray_image = img.resize(size).convert('RGB') return gray_image在计算两图片的直方图:
# 计算直方图def hist_similar(lh, rh): assert len(lh) == len(rh) hist = sum(1 - (0 if l == r else float(abs(l - r)) / max(l, r)) for l, r in zip(lh, rh)) / len(lh) return hist在计算其相似度:
# 计算相似度def calc_similar(li, ri): calc_sim = hist_similar(li.histogram(), ri.histogram())returncalc_sim得到最终的运行结果:
python图像识别之图片相似度计算

文章插图
 
两种方法的的结果还是有点差距的,可以看到img1和img3的结果相似度高些 。
不过两者的相似度计算方法如下:
python图像识别之图片相似度计算

文章插图
 
gi和si分别指的是两条曲线的第i个点 。
总结:
利用直方图计算图片的相似度时,是按照颜色的全局分布情况来看待的,无法对局部的色彩进行分析,同一张图片如果转化成为灰度图时,在计算其直方图时差距就更大了 。
为了解决这个问题,可以将图片进行等分,然后在计算图片的相似度 。不过在这里我就不叙述了,大家自行探讨!!!
二、哈希算法计算图片的相似度
在计算之前我们先了解一下图像指纹和汉明距离:
图像指纹:
图像指纹和人的指纹一样,是身份的象征,而图像指纹简单点来讲,就是将图像按照一定的哈希算法,经过运算后得出的一组二进制数字 。
汉明距离:
假如一组二进制数据为101,另外一组为111,那么显然把第一组的第二位数据0改成1就可以变成第二组数据111,所以两组数据的汉明距离就为1 。简单点说,汉明距离就是一组二进制数据变成另一组数据所需的步骤数,显然,这个数值可以衡量两张图片的差异,汉明距离越小,则代表相似度越高 。汉明距离为0,即代表两张图片完全一样 。


推荐阅读