相似图片搜索的原理
谷歌几年前就在首页开放“相似图片搜索”,对图片搜索的原理不甚了解,查阅了资料,现在记录下备忘。
要判断某两张图片是否相似,本质来说就是看他们的特征是否一致。就像我们使用指纹来区分不同的人一样,如果我们能提取到图片的指纹,那么区分图像是否相似将变得很简单。如果我们能将图片的特征量化成一个字符串(姑且称为特征码吧),这个特征码就可以作为图片的指纹,通过分析两个特征码之间的差异,就能得出是否相似的结论。最重要的就是要得到图片的特征码。
方案一:
一、缩小尺寸
将图片缩小到8×8的尺寸,总共64个像素。这一步的作用是去除图片的细节,只保留结构、明暗等基本信息,摒弃不同尺寸、比例带来的图片差异。
二、简化色彩
将缩小后的图片,转为64级灰度。也就是说,所有像素点总共只有64种颜色。
三、计算平均值
计算所有64个像素的灰度平均值。
四、比较像素的灰度
将每个像素的灰度,与平均值进行比较。大于或等于平均值,记为1;小于平均值,记为0。
五、计算特征码
将上一步的比较结果,组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。
得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。在理论上,这等同于计算Hamming distance。如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。
方案二:
每张图片都可以生成颜色分布的直方图。如果两张图片的直方图很接近,就可以认为它们很相似。
任何一种颜色都是由红绿蓝三原色(RGB)构成的,如果每种原色都可以取256个值,那么整个颜色空间共有1600万种颜色。针对这1600万种颜色比较直方图,计算量实在太大了,因此需要采用简化方法。可以将0~255分成四个区:0~63为第0区,64~127为第1区,128~191为第2区,192~255为第3区。这意味着红绿蓝分别有4个区,总共可以构成64种组合。
任何一种颜色必然属于这64种组合中的一种,这样就可以统计每一种组合包含的像素数量。
上图是某张图片的颜色分布表,将表中最后一栏提取出来,组成一个64维向量,这个向量就是这张图片的特征码。
方案三:
除了颜色构成,还可以从比较图片内容的相似性入手。
首先,将原图转成一张较小的灰度图片,假定为50×50像素。然后,确定一个阈值,将灰度图片转成黑白图片。如果两张图片很相似,它们的黑白轮廓应该是相近的。于是,问题就变成了,第一步如何确定一个合理的阈值,正确呈现照片中的轮廓?
显然,前景色与背景色反差越大,轮廓就越明显。这意味着,如果我们找到一个值,可以使得前景色和背景色各自的”类内差异最小”,或者”类间差异最大”,那么这个值就是理想的阈值。