通过使用掩码提取CNN的某一层的特征,具体效果看下图
1、sift_mask
代码实现:
function mask = sift_mask(f,Hf,Wf,H,W)
% Hf和Wf是图像特征描述符的宽度和高度
% f是sift的特征描述符,这里使用sift进行提取
x_ratio = H/Hf;
y_ratio = W/Wf;
% 四舍五入
f(1,:) = round(f(1,:)/y_ratio);
f(2,:) = round(f(2,:)/x_ratio);
mask = zeros(Hf,Wf);
r = 1;
for j = 1:size(f,2)
mask(max(1,f(2,j)-r):min(Hf,f(2,j)+r),max(1,f(1,j)-r):min(Wf,f(1,j)+r)) = 1;
end
mask = mask > 0;
end
2、max_mask
代码实现:
function mask = max_mask(fea)
mask = zeros(size(fea,1),size(fea,2));
for j = 1:size(fea,3)
[v1,p1] = max(fea(:,:,j));
[~,p2] = max(v1);
% 这里有点迷,为啥要设置为1呢
mask(p1(p2),p2) = 1;
end
mask = mask(:);
end
3、sum_mask
代码实现:
function [ mask ] = sum_mask( fea )
mask = sum(fea,3);
% 计算数据集的百分位数
mask = (mask(:) >= prctile(mask(:),50));
end
4、完整的使用代码
function [masked_feat] = use_mask(filename,maskmethod)
% filename:输入的是单个.mat特征:.mat中就是fea
% maskmethod:mask方法:sift\sum\max
% return:处理后的局部特征
l = load(feature);
% 第三个维度
k = size(l.fea,3);
switch maskmethod
case 'max'
mask = max_mask(l.fea);
case 'sum'
mask = sum_mask(l.fea);
case 'sift'
% strrep 查找并替换子字符串 strrep(str,old,new);将 str 中出现的所有 old 都替换为 new
sift_loc = load(strrep(filename,'_fea.mat','_sift.mat'));
mask = sift_mask(sift_loc.f,size(l.fea,1),size(l.fea,2),sift_loc.H,sift_loc.W);
case 'none'
% 如果不使用mask就会默认使用特征的宽和高当作mask
mask = true(size(l.fea,1),size(l.fea,2));
end
% 将mask应用到所有的通道中
mask = repmat(mask,[1,1,k]);
masked_feat = l.fea(mask);
masked_feat = reshape(masked_feat,[length(masked_feat)/k,k])';
end