基于matlab2020b,不同版本可能会出错
步骤:
读取图片数据(相当于一个矩阵)
转换成灰度图片(256级)
缩放到32×32尺寸(剔除图片细节)
计算二维离散余弦变换(变换后还是32×32矩阵)
截取矩阵左上角8×8部分(因为高频部分大部分都在左上角)
计算该8×8矩阵的均值
遍历矩阵,大于等于均值的元素赋值为1,否则赋值为0,生成一个8×8的hash指纹图
hash指纹图就代表一串64位二进制的hash值,比较两张图的hash值,计算汉明距离,得到相似度(汉明距离=0代表完全相似,距离越大越不相似)
代码实现:
clc;clear;
img1=imread('abc.jpg');
img2=imread('def.jpg');
figure('NumberTitle','off','Name','原始图像');
subplot(1,2,1);imshow(img1);
subplot(1,2,2);imshow(img2);
figure('NumberTitle','off','Name','256级灰度图像');
img11=rgb2gray(img1);
img21=rgb2gray(img2);
subplot(1,2,1);imshow(img11);
subplot(1,2,2);imshow(img21);
figure('NumberTitle','off','Name','缩放32*32图像');
img12=imresize(img11,[32,32]);
img22=imresize(img21,[32,32]);
subplot(1,2,1);imshow(img12);
subplot(1,2,2);imshow(img22);
imgdct1=dct2(img12); %计算二维dct
imgdct2=dct2(img22);
imgdct11=imgdct1(1:8,1:8); %截取左上角8*8
imgdct21=imgdct2(1:8,1:8);
mean1=sum(imgdct11(:))/64; %计算均值
mean2=sum(imgdct21(:))/64;
imghash1=zeros(8,8);
imghash2=zeros(8,8);
for i=1:8 %遍历生成hash指纹
for j=1:8
if(imgdct11(i,j)>=mean1)
imghash1(i,j)=1;end
if(imgdct21(i,j)>=mean2)
imghash2(i,j)=1;end
end
end
cyjz=xor(imghash1,imghash2); %求异或
hanming=sum(cyjz(:)); %求汉明距离
similarity=(64-hanming)/64;
figure('NumberTitle','off','Name','phash指纹图');
subplot(1,2,1);imshow(imghash1);
subplot(1,2,2);imshow(imghash2);
title(['与前者相似度为',num2str(100*similarity),'%']);
计算结果:
原始图像(前一阵在千岛湖玩拍的)灰度图像(256级)
转化成32×32尺寸
两张hash指纹图,并计算得到相似度为87.5%