function similarity_result = pyramid_match_kernel(descriptor,tem)
% 此函数通过描述符计算图像之间的相似性
% 用EMD算法的最小功表示相似性,功越小,图片越相似
% 计算出存储相似性结果的矩阵形式:1*n 的 matrix
% n是图片或者说特征的个数
similarity_result = tem * descriptor;
% 我们每一张图片的256*1的特征矩阵
% 所以向量空间X的直径为D
D = size(descriptor,1);
% d = 特征向量的维度
d = size(tem,1);
% L = 共有几个不同分辨率的直方图进行交叉核
L = fix(log2(D));
% R:L个直方图的分辨率都不一样,每一个的r_L都存在R中。
for i = 1:L+1
% 每一个Hi(x)直方图的bin的高度(从0开始)
ri_number = (D/(2^(i-1) * sqrt(d)))^d ;
% 存储所有直方图的bin高度
R_number(1,i) = ri_number;
% 边长(从0开始)
side = 2^(i-1);
% 存储
R_number(2,i) = side;
end
for i = 1:size(descriptor,2)
% 对每一张图片的特征进行抽取
% deccriptor
one_img = descriptor(:,i);
% 进行交叉核之前,所需要的变量
for k = 1:L+1
% 提取每一个直方图中bin的分辨率
L_side = R_number(2,k);
% Hi(x)中的bin的高度
L_n_historgram = R_number(1,k);
% 分成多少份
each_batch = D / L_n_historgram;
if each_batch ==1
% 无需计算
tmp_img = one_img;
else
for p = 1:L_n_historgram
% 算每一份的值
each_val = sum(one_img(((each_batch-1) * p):(each_batch * p),1));
% 赋值
tmp_img(p,1) = each_val;
end
end
% 算出第Hi(x)个直方图的特征,数据库中的图片
img_feature = (tmp_img / L_side)';
% 查询的图片特征
tem_feature = tem / L_side;
% 进行直方图交叉核操作,取最小值
logic_feature1 = double(logical(img_feature <= tem_feature));
logic_feature2 = double(logical(tem_feature < img_feature));
% 算出直方图交叉之后的Hi(X)的特征
sum_feature_L = (logic_feature1 .* img_feature) + (logic_feature2 .* tem_feature);
tmp_Ni(1,k) = sum(sum_feature_L ~= 0);
% Ni是代表每两层之间新匹配的数目
if k == 1
Ni = tmp_Ni(1,k);
else
res = tmp_Ni(1,k);
Ni = res - tmp_Ni(1,k-1);
end
Ni_L(1,k) = Ni;
end
tm_simi = 0;
% 进行权重加和
for m = 1:L+1
weight = 1/(2^(m-1));
tm = Ni_L(1,m) * weight;
tm_simi = tm+ tm_simi;
end
% 存储每一张图片的相似度
similarity_result(i) = tm_simi;
end
% 归一化
similarity_result = similarity_result / max(similarity_result);
end
Pyramid_Match_Kernel算法是用于人脸识别中的一种比较好的算法,也是一种衡量两幅图片之间相似性的算法,但是我认为最好图片特征信息是用historgram表示的image_feature再用这种方法评测。
代码如上图所示。