计算图像相似度——《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%。哦耶!下面来看一下我们最重要的一组照片(两张):
<shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="width: 415.5pt; height: 310.5pt;" type="#_x0000_t75"><imagedata o:title="1" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.jpg"></imagedata></shape><shape id="_x0000_i1026" style="width: 415.5pt; height: 310.5pt;" type="#_x0000_t75"><imagedata o:title="2" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image003.jpg"></imagedata></shape>
找到一组很好的测试图片之后,我们需要再给 Python 环境安装一个图像库,我的选择是PIL(Python image library)。PIL 为 Python 提供了图像处理功能,并且支持数十种图像格式。(关于 PIL 的介绍,可以查看我之前的文章《用Python做图像处理》http://blog.csdn.net/lanphaday/archive/2007/10/28/1852726.aspx )
虽然这两张图片大小都是一样的,但为了通用性,我们有必要把所有的图片都统一到特别的规格,在这里我选择是的256x256的分辨率。
<shape id="_x0000_i1027" style="width: 192pt; height: 192pt;" type="#_x0000_t75"><imagedata o:title="1" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image005.png"></imagedata></shape> <shape id="_x0000_i1028" style="width: 192pt; height: 192pt;" type="#_x0000_t75"><imagedata o:title="2" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image007.png"></imagedata></shape>
因为 PIL 为 RGB 模式的图像计算的 histogram 样点数为 768,计算量并不算太大,所以本文就直接使用,没有再作降维处理了。
6 def make_regalur_image(img, size = (256, 256)):
7 return img.resize(size).convert('RGB')
转化为规则图像之后,可以调用 img.histogram() 方法获得直方图数据,如上文两图的直方图如下:
<shape id="_x0000_i1029" style="width: 414.75pt; height: 210.75pt;" type="#_x0000_t75"><imagedata o:title="test1_hist" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image009.png"></imagedata></shape>
得到规则图像之后,图像的相似度计算就转化为直方图的距离计算了,本文依照如下公式进行直方图相似度的定量度量:
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: %<chmetcnv w:st="on" unitname="F" sourcevalue=".3" hasspace="False" negative="False" numbertype="1" tcsc="0">.3f</chmetcnv>%%'%(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 的规则图如下:
<shape id="_x0000_i1031" style="width: 192pt; height: 192pt;" type="#_x0000_t75"><imagedata o:title="4_1" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image013.png"></imagedata></shape> <shape id="_x0000_i1032" style="width: 192pt; height: 192pt;" type="#_x0000_t75"><imagedata o:title="4_2" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image015.png"></imagedata></shape>
可以看到它们的色彩局部分布有相当大的不同,但事实上它们的全局直方图相当相似:
<shape id="_x0000_i1033" style="width: 414.75pt; height: 210.75pt;" type="#_x0000_t75"><imagedata o:title="test4_hist" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image017.png"></imagedata></shape>虽然从直方图来看两图是极其相似的,但上述算法计算出相似度为70.4%的结果肯定是不可接受的。那么,怎么样才能克服直方图的缺点呢?答案是把规则图像分块,再对相应的小块进行相似度计算,最后根据各小块的平均相似度来反映整个图片的相似度。在实验中,我们把规则图像分为 4x4 块,每块的分辨率为 64x64:
<shape id="_x0000_i1034" style="width: 192pt; height: 192pt;" type="#_x0000_t75"><imagedata o:title="4_1" src="file:///C:%5CDOCUME~1%5CADMINI~1%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image019.png"></imagedata></shape>
分割图像的代码为:
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 也能帮助你哦~
本实验的所有代码和测试用例请猛击这里下载,再次感谢提供图片支持的西门同学。
<!-- SiteSearch Google -->
有问题不明白?请教Google大神吧!
|
输入您的搜索字词 提交搜索表单
|
|
|
<!-- SiteSearch Google -->
分享到:
相关推荐
Python 计算机视觉学习————图像内容分类 计算机视觉.pdf 本资源摘要信息是关于 Python 计算机视觉学习的,特别是图像内容分类的计算机视觉。内容涵盖了 K最近邻(KNN)分类法的原理、算法步骤、距离衡量方法、...
本文将详细介绍一个Python脚本案例——人脸相似度对比,旨在通过编程实现对两张图像中人脸相似程度的计算。该案例不仅能够帮助我们了解人脸识别的基本原理,还能让我们掌握如何利用Python来处理图像数据。 #### 一...
在这个项目中,开发者可能提供了用Python编写的代码来实现这一功能,同时也可能包含与MATLAB相关的代码,尽管MATLAB本身是另一种编程环境,但有时会用于科学计算和图像处理。 描述中的“python实现图像修复”确认了...
在图像分析和模式识别中,对称性是关键特征之一,它可以帮助我们理解图像的内容,甚至用于物体识别、场景理解以及图像分类。 在"SymmetryAxes-master (1).zip"这个压缩包中,包含了一个名为"SymmetryAxes-master"的...
SSIM是衡量两幅图像相似度的一种指标,范围从-1到1,越接近1表示两张图片越相似。通过调用compare_ssim函数计算SSIM值,并将计算得到的差异图像diff进行二值化处理,转换为可以识别的轮廓。 一旦有了不同点的轮廓,...
《Python中的图像搜索库——python_imagesearch 1.1.1版详解》 在Python的开发世界中,有一个名为`python_imagesearch`的库,它为开发者提供了强大的图像搜索功能。这个库主要用于后端开发,特别是在自动化测试、...
在本项目中,我们将专注于一种特殊类型的神经网络——卷积神经网络(CNN),用于解决基于Python的图片验证码识别问题。 卷积神经网络是一种深度学习模型,特别适用于图像处理任务。CNN的特点在于其卷积层,该层通过...
在人脸识别中,VSM可以用来表示人脸图像的关键特征,通过计算两个向量之间的相似度(如余弦相似度)来判断两张人脸是否相似。 **Python3实现**: Python3因其丰富的库资源和简洁的语法,成为了数据处理和机器学习...
#### PIL——Python Imaging Library PIL是Python中用于图像处理的一个基础库,它提供了丰富的图像处理功能,如图像打开、保存、显示以及各种变换操作(旋转、缩放、裁剪等)。PIL支持多种图像格式,并且能够进行...
空间滤波器是图像处理中非常重要的工具之一,它们可以用来改善图像质量、去除噪声或突出某些特定特征。本教程重点讲解了线性和非线性滤波器,并探讨了它们在不同场景下的应用。此外,还详细介绍了几种常用的边缘检测...
理解并掌握NCUT,不仅可以深化对图像处理的理解,也是提升计算机视觉项目性能的关键。对于初学者而言,Ncut_9提供的实例代码是一份宝贵的教育资源,可以借此深入学习和实践这一强大的分割技术。
Python中的KNN(K-...总的来说,通过Python的KNN算法进行验证码识别,我们可以学习到图像预处理、特征提取、模型训练和评估等多个环节,这不仅有助于理解机器学习的基本流程,也为解决实际问题提供了有价值的工具。
在这个“这是图像恢复的基线_Python_下载.zip”压缩包中,我们很可能找到了一个Python实现的图像恢复基础框架——BaselineIR-master。这个项目可能是为研究人员和开发者提供了一个起点,帮助他们理解和实践图像恢复...
通过运行这些代码,我们可以计算出不同图像的模糊度值,并进行比较。在处理低分辨率或像素较少的图像时,由于信息量有限,可能会导致图像看起来更模糊,因此模糊度值可能较高。 总之,图像模糊度判别是图像处理中的...
在二维或高维空间中,"距离"通常用欧氏距离、曼哈顿距离或余弦相似度等度量来计算。 对于验证码识别,以下是一些关键步骤: 1. **数据预处理**:验证码图像通常需要进行灰度化、二值化处理,以减少颜色信息并突出...
这里的“近”通常用欧氏距离、曼哈顿距离或余弦相似度等度量方式计算。 **2. 工作流程** 1. **数据预处理**:对数据进行清洗,处理缺失值,可能还需要进行特征缩放,确保不同特征在同一尺度上。 2. **选择距离...
通过在Python环境中结合PyTorch等工具,我们可以实现这一创新技术,为破损图像提供高质量的恢复效果。虽然DIP在某些场景下表现出色,但它并非万能解决方案,需要根据具体应用场景进行选择和优化。
在图像处理领域,图像清晰度是衡量图像质量的重要指标之一,它关系到图像的可读性和分析准确性。本文将深入探讨“图像清晰度算法”中的一个特定方法——reblur算法,以及如何使用MATLAB实现这一算法。 reblur算法是...
本文档旨在介绍一个基于Python开发的本科论文项目——人脸识别系统的设计与实现。该系统利用了Python的强大功能,结合百度AI提供的先进人脸识别技术,实现了高效稳定的人脸识别服务。本论文详细介绍了系统的背景意义...