对于像谷歌、百度识图这种图像搜索的算法,主要有三个步骤:
将目标图片进行特征提取,描述图像的算法很多,用的比较多的是:SIFT描述子,指纹算法函数,bundling features算法,hash function(散列函数)等。也可以根据不同的图像,设计不同的算法,比如图像局部N阶矩的方法提取图像特征。
将图像特征信息进行编码,并将海量图像编码做查找表。对于目标图像,可以对分辨率较大的图像进行降采样,减少运算量后在进行图像特征提取和编码处理。
相似度匹配运算:利用目标图像的编码值,在图像搜索引擎中的图像数据库进行全局或是局部的相似度计算;根据所需要的鲁棒性,设定阈值,然后将相似度高的图片预保留下来;最后应该还有一步筛选最佳匹配图片,这个应该还是用到特征检测算法。
对于谷歌的相似图片的搜索,Neal Krawetz博士的解释是利用感知哈希算法(Perceptual hash algorithm),该技术通过对每张图片产生一个“指纹”(fingerprint)字符串,然后比较不同的指纹。差异越小,则图片月接近。均值哈希算法主要利用的是图像的低频信息。
具体实现为:
3)计算平均值:计算这64个像素的灰度平均值。
4)比较像素灰度:大于或等于平均值的像素记为1,小于平均值的记为0.
5)计算hash值:将步骤4中得到的结果组合构成一个64位的整数,这就是该图片的指纹。组合的次序不重要,只要保证所有图片都采样相同的次序就行了。
得到指纹以后,就可以对比不同的图片,看看64位中有多少位是不一样的。在理论上,这等同于计算”汉明距离”(Hamming distance)。如果不相同的数据位不超过5,就说明两张图片很相似;如果大于10,就说明这是两张不同的图片。
均值哈希算法受均值影响比较大,因此有人提出更加鲁棒的算法,叫pHash算法。该算法使用离散余弦变换(DCT)来获取图片的低频成分。
离散余弦变换(DCT)是种图像压缩算法,它将图像从像素域变换到频率域。然后一般图像都存在很多冗余和相关性的,所以转换到频率域之后,只有很少的一部分频率分量的系数才不为0,大部分系数都为0(或者说接近于0)。
pHash的算法步骤如下:
(1)缩小尺寸:pHash以小图片开始,但图片大于8*8,32*32是最好的。这样做的目的是简化了DCT的计算,而不是减小频率。
(2)简化色彩:将图片转化成灰度图像,进一步简化计算量。
(3)计算DCT:计算图片的DCT变换,得到32*32的DCT系数矩阵。
(4)缩小DCT:虽然DCT的结果是32*32大小的矩阵,但我们只要保留左上角的8*8的矩阵,这部分呈现了图片中的最低频率。
(5)计算平均值:如同均值哈希一样,计算DCT的均值。
(6)计算hash值:这是最主要的一步,根据8*8的DCT矩阵,设置0或1的64位的hash值,大于等于DCT均值的设为”1”,小于DCT均值的设为“0”。组合在一起,就构成了一个64位的整数,这就是这张图片的指纹。
结果并不能告诉我们真实性的低频率,只能粗略地告诉我们相对于平均值频率的相对比例。只要图片的整体结构保持不变,hash结果值就不变。能够避免伽马校正或颜色直方图被调整带来的影响。