博主原文 https://blog.csdn.net/lanphaday/article/details/2325027

计算图像相似度——《Python也可以》之一

声明:本文最初发表于赖勇浩(恋花蝶)的博客http://blog.csdn.net/lanphaday,如蒙转载,敬请确保全文完整,未经同意,不得用于商业用途。

关于《Python也可以》系列:这是我打算把这几年里做的一些实验和代码写出来,涉及的面比较广,也比较杂,可能会有图像处理、检索等方面的内容,也会有中文分词、文本分类、拼音、纠错等内容。毫不掩饰地说:在博客发这系列文章的原因在于宣传 python ,所以这系列文章都会带有源码和相关的测试用例,这也是特色之一。但这系列文章都是“浅尝辄止”的,不会深入到专属领域,只是为了表明 python 功能很强大,不仅适合于web 或者 game 开发,也适合于科学研究。


要计算图像的相似度,肯定是要找出图像的特征。这样跟你描述一个人的面貌:国字脸,浓眉,双眼皮,直鼻梁,大而厚的嘴唇。Ok,这些特征决定了这个人跟你的同事、朋友、家人是不是有点像。图像也一样,要计算相似度,必须抽象出一些特征比如蓝天白云绿草。常用的图像特征有颜色特征、纹理特征、形状特征和空间关系特征等。颜色特征的算是最常用的,在其中又分为直方图、颜色集、颜色矩、聚合向量和相关图等。直方图能够描述一幅图像中颜色的全局分布,而且容易理解和实现,所以入门级的图像相似度计算都是使用它的;作为一篇示例性的“浅尝辄止”的文章,我们也不例外。

在进行我们试验之前,我们需要找到一批图片来作为测试用例。我上穷碧落下黄泉,最后终于在我的前同事西门的博客(http://blog.163.com/johnal1 )找到了一系列他在公司组织的年度旅游时去西藏林芝拍的一组风光图片(http://blog.163.com/johnal1/blog/static/9394912200812105654784 ),实在是难得之佳品,简直可以说得到了它们我们的实验已经完成了90%。哦耶!下面来看一下我们最重要的一组照片(两张):

找到一组很好的测试图片之后,我们需要再给 Python 环境安装一个图像库,我的选择是PIL(Python image library)。PIL 为 Python 提供了图像处理功能,并且支持数十种图像格式。(关于 PIL 的介绍,可以查看我之前的文章《用Python做图像处理》http://blog.csdn.net/lanphaday/archive/2007/10/28/1852726.aspx )

虽然这两张图片大小都是一样的,但为了通用性,我们有必要把所有的图片都统一到特别的规格,在这里我选择是的256x256的分辨率。

  

因为 PIL 为 RGB 模式的图像计算的 histogram 样点数为 768,计算量并不算太大,所以本文就直接使用,没有再作降维处理了。

6 def make_regalur_image(img, size = (256, 256)):

7     return img.resize(size).convert('RGB')

转化为规则图像之后,可以调用 img.histogram() 方法获得直方图数据,如上文两图的直方图如下:

得到规则图像之后,图像的相似度计算就转化为直方图的距离计算了,本文依照如下公式进行直方图相似度的定量度量:

Sim(G,S)=,其中G,S为直方图,N 为颜色空间样点数

转换为相应的 Python 代码如下:

19 def hist_similar(lh, rh):

20     assert len(lh) == len(rh)

21     return sum(1 - (0 if l == r else float(abs(l - r))/max(l, r)) for l, r in zip(lh, rh))/len(lh)

22

23 def calc_similar(li, ri):

24     return hist_similar(li.histogram(), ri.histogram())

短短十行代码不到就完成了图片相似度的计算,再加上从硬盘读取图像的函数和测试代码,也不过二十行上下:

28 def calc_similar_by_path(lf, rf):

29     li, ri = make_regalur_image(Image.open(lf)), make_regalur_image(Image.open(rf))

30     return calc_similar(li, ri)

31

32 if __name__ == '__main__':

33     path = r'test/TEST%d/%d.JPG'

34     for i in xrange(1, 7):

35        print 'test_case_%d: %.3f%%'%(i, calc_similar_by_path('test/TEST%d/%d.JPG'%(i, 1), 'test/TEST%d/%d.JPG'%(i, 2))*100)

那么这样做的效果到底怎么样呢?且来看看测试结果(测试用例和代码请猛击这里下载):

test_case_1: 63.322%

test_case_2: 66.950%

test_case_3: 51.990%

test_case_4: 70.401%

test_case_5: 32.755%

test_case_6: 42.203%

结合我们肉眼对测试用例的观察,这个程序工作得还算可以。不过 test_case_4 就暴露了直方图的缺点:它只是图像中颜色的全局分布的描述,无法描述颜色的局部分布和色彩所处的位置。test_case_4 的规则图如下:

  

可以看到它们的色彩局部分布有相当大的不同,但事实上它们的全局直方图相当相似:

虽然从直方图来看两图是极其相似的,但上述算法计算出相似度为70.4%的结果肯定是不可接受的。那么,怎么样才能克服直方图的缺点呢?答案是把规则图像分块,再对相应的小块进行相似度计算,最后根据各小块的平均相似度来反映整个图片的相似度。在实验中,我们把规则图像分为 4x4 块,每块的分辨率为 64x64:

分割图像的代码为:

9 def split_image(img, part_size = (64, 64)):

10     w, h = img.size

11     pw, ph = part_size

12

13     assert w % pw == h % ph == 0

14

15     return [img.crop((i, j, i+pw, j+ph)).copy() /

16                 for i in xrange(0, w, pw) /

17                 for j in xrange(0, h, ph)]

相应地,把计算相似图的函数calc_similar()修改为:

23 def calc_similar(li, ri):

24 #   return hist_similar(li.histogram(), ri.histogram())

25     return sum(hist_similar(l.histogram(), r.histogram()) for l, r in zip(split_image(li), split_image(ri))) / 16.0

进行这样的改进后,算法已经能够在一定的程序上反映色彩的局倍分布和颜色所处的位置,可以比较好的弥补全局直方图算法的不足。新的算法计算出来的结果如下:

test_case_1: 56.273%

test_case_2: 54.925%

test_case_3: 49.326%

test_case_4: 40.254%

test_case_5: 30.776%

test_case_6: 39.460%

可以看到,test_case_4的相似度由 70.4% 下降到 40.25%,基本上跟肉眼的判断是切合的;另外其它图像的相似度略有下降,这是因为加入了位置因子之的影响。从而可见基于分块的直方图相似算法是简单有效的。

图像的相似度计算是图像检索、识别的基础,本文只是浅尝辄止地介绍了其中最基本的计算方法,如果你要学习和研究更好的算法,也请记住 Python 也能帮助你哦~

本实验的所有代码和测试用例请猛击这里下载,再次感谢提供图片支持的西门同学。

直方图计算文章相似度相关推荐

  1. 【python 图片相似度】直方图计算图片相似度

    直方图能够描述一幅图像中颜色的全局分布,而且容易理解和实现,所以入门级的图像相似度计算都是使用它的. 直方图算法是对源图像与要筛选的图像进行直方图数据采集,对采集的各自图像直方图进行归一化再使用巴氏系 ...

  2. 标题相似度算法_一个简单的计算文章相似度功能!

    在做文章系统的时候,很多时候需要为这篇文章推荐最相近的文章. 解决思路是:给文章设定关键词然后模糊查询进行匹配.找到包含这个关键词的标题,然后给显示出来,作为最接近的文章. 但是有问题:这样的文章,排 ...

  3. 头条项目推荐的相关技术(四):离线文章画像的增量更新及离线文章相似度计算

    1. 写在前面 这里是有关于一个头条推荐项目的学习笔记,主要是整理工业上的推荐系统用到的一些常用技术, 这是第四篇, 上一篇文章整理了离线文章画像的计算过程,主要包括TFIDF和TextRank两种技 ...

  4. NLP——计算文本相似度的常用算法

    文章目录 一.绪论 二.余弦相似度 2.1 余弦相似度定义 2.2 计算相似度步骤 2.3 举例 2.4 改进方式 2.5 代码 三.TF-IDF计算 3.1 TF.IDE.TF-IDF的计算方法 3 ...

  5. Word2Vec与文章相似度--相似度计算

    2.7.4.2 相似度计算 目的:计算18号Python频道的文章之间相似度 步骤: 1.读取数据,进行类型处理(数组到Vector) 2.BRP进行FIT 读取数据,进行类型处理(数组到Vector ...

  6. 使用spark TF-IDF特征计算文章间相似度

    写在前面 计算字符串之前的相似度可以使用 Levenshtein distance(最小编辑距离)来实现,JAVA实现可以参考http://blog.csdn.net/ironrabbit/artic ...

  7. 【python 走进NLP】simhash 算法计算两篇文章相似度

    互联网网页存在大量的重复内容网页,无论对于搜索引擎的网页去重和过滤.新闻小说等内容网站的内容反盗版和追踪,还是社交媒体等文本去重和聚类,都需要对网页或者文本进行去重和过滤.最简单的文本相似性计算方法可 ...

  8. 【记录】文章相似度计算开发(附代码)

    写在前边:目前已经通过爬虫等手段获取了千万级的文章类数据,但是目前这些数据是只是简单的基于表层的应用,相对粗粒度的统计,文本之间的很多信息并没有被良好的利用起来.为了提高数据的使用率并获取更多有用信息 ...

  9. 计算图像相似度——《Python也可以》之一

    计算图像相似度--<Python也可以>之一 声明:本文最初发表于赖勇浩(恋花蝶)的博客http://blog.csdn.net/lanphaday,如蒙转载,敬请确保全文完整,未经同意, ...

最新文章

  1. ValueError: not enough values to unpack (expected 3, got 0)问题
  2. oracle 10g安装
  3. 关于Windows Unicode 编码的问题
  4. Making the Grade POJ - 3666(离散化+dp)
  5. vim文本编辑器的配置vimrc
  6. mysql 5.1版本无innodb trx_MySQL 5.7: Innodb 事务子系统优化-阿里云开发者社区
  7. 没有一款趁手的数据监控软件?试一下NetData不,用了你就绝对离不开他!
  8. 波兰表达式(前序表达式)的计算(栈)
  9. elementUI 学习入门之 Button 按钮
  10. 0-n-1中缺失的数字
  11. 双非本科:337家Java后台面试总结
  12. (转)遇到重复的Maven项目初始配置,就要创建自己的Maven Archetype
  13. 软件系统测试用例设计,软件系统测试用例设计步骤
  14. 软件开发人员需要记住的10个操作系统概念(译)
  15. Win10使用GPT格式为大硬盘分区(2.2T 以上)
  16. 【学习记录】SLAM线特征基础:LSD算法、LBD描述子、普朗克坐标、EDLines算法
  17. 【量亿数据-level2】唐奇安趋势跟踪系统
  18. 商品支付,支付逻辑漏洞安全(niushop)——实例讲解一毛钱购买手机
  19. goldengate中添加同步表的操作
  20. 【一天一个挨打小技巧】大黄蜂云课堂在听课时候做笔记,无法截图!安排

热门文章

  1. 转载:――放心油条自己做
  2. 学习模拟实现strlen strcmp strcpy strcat strstr等库函数
  3. 牛客网-[编程入门]有容乃大
  4. 从柴静的片子谈人力资源需求的趋势
  5. 955,远程办公,这家公司要落地杭州了!
  6. Qt 6.5 LTS发布!
  7. 光波导系统的性能研究
  8. 你的系统时间未与ntp服务器同步6,国家授时中心ntp(系统时间未与ntp服务器同步)...
  9. *************************** APPLICATION FAILED TO START *************************** Description: F
  10. DICGAN(CVPR2020,人脸SR)Deep Face Super-Resolution with Iterative Collaboration between Attentive Recov