图像相似性搜索的原理
%http://blog.sina.com.cn/s/blog_b27f71160101gp9c.html clear; close all; clc; srcDir=uigetdir('Choose source directory.'); cd(srcDir); allnames=struct2cell(dir('*.jpg')); [k,len]=size(allnames); FinalResult = {}; for i=1:len name=allnames{1,i}; picture1 = imread(name); picture2 = imread('006.jpg'); v=tineyesearch_ahash(picture1,picture2); FinalResult{i,1} = char('006.jgp'); FinalResult{i,2} = name; FinalResult{i,3} = v; end figure('NumberTitle','off','Name','统计表'); columnname = {'ReferenceImage','TestImage','SimilarScore'}; %各列的名称 % columnformat = {'numeric','bank','numeric'}; %各列的数据类型 columneditable = [false true true]; %各列是否是可编辑的,true是可以编辑,false是不可编辑 t = uitable('Units','normalized','Position',... [0.1 0.1 0.9 0.9],'Data',FinalResult,... 'ColumnName',columnname,... 'ColumnEditable',columneditable); 具体的代码实现,可以参见Wote用python语言写的imgHash.py。代码很短,只有53行。使用的时候,第一个参数是基准图片,第二个参数是用来比较的其他图片所在的目录,返回结果是两张图片之间不相同的数据位数量(汉明距离)。 这种算法的优点是简单快速,不受图片大小缩放的影响,缺点是图片的内容不能变更。如果在图片上加几个文字,它就认不出来了。所以,它的最佳用途是根据缩略图,找出原图。 实际应用中,往往采用更强大的pHash算法和SIFT算法,它们能够识别图片的变形。只要变形程度不超过25%,它们就能匹配原图。这些算法虽然更复杂,但是原理与上面的简便算法是一样的,就是先将图片转化成Hash字符串,然后再进行比较。
如果图片放大或缩小,或改变纵横比,结果值也不会改变。增加或减少亮度或对比度,或改变颜色,对hash值都不会太大的影响。最大的优点:计算速度快! 如果你想比较两张图片,为每张图片构造hash值并且计算不同位的个数。(汉明距离)如果这个值为0,则表示这两张图片非常相似,如果汉明距离小于5,则表示有些不同,但比较相近,如果汉明距离大于10则表明完全不同的图片。 二、效果更佳的感知哈希算法pHash虽然均值哈希更简单且更快速,但是在比较上更死板、僵硬。它可能产生错误的漏洞,如果有一个伽马校正或颜色直方图被用于到图像。这是因为颜色沿着一个非线性标尺?-?改变其中“平均值”的位置,并因此改变哪些高于/低于平均值的比特数。 一个更健壮的算法叫pHash,?pHash的做法是将均值的方法发挥到极致。使用离散余弦变换(DCT)降低频率。 平均哈希算法过于严格,不够精确,更适合搜索缩略图,为了获得更精确的结果可以选择感知哈希算法,它采用的是DCT(离散余弦变换)来降低频率的方法 1.缩小尺寸pHash以小图片开始,但图片大于8*8,32*32是最好的。这样做的目的是简化了DCT的计算,而不是减小频率。 2.简化色彩将图片转化成灰度图像,进一步简化计算量。 3.计算DCTDCT是把图片分解频率聚集和梯状形,虽然JPEG使用8*8的DCT变换,在这里使用32*32的DCT变换。 4.缩小DCT虽然DCT的结果是32*32大小的矩阵,但我们只要保留左上角的8*8的矩阵,这部分呈现了图片中的最低频率。 5.计算平均值如同均值哈希一样,计算DCT的均值, 6.进一步减小DCT这是最主要的一步,根据8*8的DCT矩阵,设置0或1的64位的hash值,大于等于DCT均值的设为”1”,小于DCT均值的设为“0”。结果并不能告诉我们真实性的低频率,只能粗略地告诉我们相对于平均值频率的相对比例。只要图片的整体结构保持不变,hash结果值就不变。能够避免伽马校正或颜色直方图被调整带来的影响。 7.构造hash值将64bit设置成64位的长整型,组合的次序并不重要,只要保证所有图片都采用同样次序就行了。将32*32的DCT转换成32*32的图像。
与均值哈希一样,pHash同样可以用汉明距离来进行比较。(只需要比较每一位对应的位置并算计不同的位的个数) 步骤说明:
步骤: 1.缩小图片:32 * 32是一个较好的大小,这样方便DCT计算 2.转化为灰度图:把缩放后的图片转化为256阶的灰度图。(具体算法见平均哈希算法步骤) 3.计算DCT:DCT把图片分离成分率的集合 4.缩小DCT:DCT是32*32,保留左上角的8*8,这些代表的图片的最低频率 5.计算平均值:计算缩小DCT后的所有像素点的平均值。 6.进一步减小DCT:大于平均值记录为1,反之记录为0. 7.得到信息指纹:组合64个信息位,顺序随意保持一致性即可。 8.对比指纹:计算两幅图片的指纹,计算汉明距离(从一个指纹到另一个指纹需要变几次),汉明距离越大则说明图片越不一致,反之,汉明距离越小则说明图片越相似,当距离为0时,说明完全相同。(通常认为距离>10 就是两张完全不同的图片) 使用matlab实现 PHash 算法
clear; close all; clc; % read image I = imread('cameraman.tif'); % cosine transform and reduction d = dct2(I); d = d(1:8,1:8); % compute average a = mean(mean(d)); % set bits,here unclear whether > or >= shall be used b = d > a; % maybe convert to string: string = num2str(b(:)'); (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |