图像识别进入深度学习时代后,特征提取这个词的使用频率明显下降了。因为深度网络已经完成了从图像输入到分类结果输出的全过程,似乎不需要再关心特征的好坏和特征提取对于识别结果的影响。不过,不管从算法研究还是工程实现角度看,将特征提取独立出来应该更有利。这样我们可以对各种特征提取方法和各种识别算法进行组合,找出效果最好的方案。
我们先考虑非神经网络提取的特征,在深度神经网络大热以前,局部特征、空间金字塔、稀疏编码的结合合应该是达到最高识别准确率的方案。它在一些应用场合能够以更低的代价带来不次于深度网络的识别效果,可应用于实现方案。这里的代码是在工具箱reco_toolbox基础上修改的:
%exam1.m extract features from every image
clc,close all, clear all,drawnow
database_name = {‘JDTest‘};
database_ext = {‘jpg‘ , ‘jpg‘ , ‘png‘};
descriptors_name = {‘mlhoee_spyr‘ , ‘mlhmslsd_spyr‘ , ‘mlhmslbp_spyr‘ , ‘mlhmsldp_spyr‘};
choice_database = [1];
choice_descriptors = [3]; %mlhoee_spyr=1/mlhmslsd_spyr=2/mlhmslbp_spyr=3/mlhmsldp_spyr=4
do_extract_feature = 1; %no=0/yes=1
data_name = database_name{choice_database(1)};
im_ext = database_ext{choice_database(1)};
rootbase_dir = pwd;
images_dir = fullfile(pwd , ‘images‘ , data_name);
core_dir = fullfile(pwd , ‘core‘);
feat_dir = fullfile(pwd , ‘features‘);
des_dir = fullfile(pwd , ‘descriptors‘);
addpath(core_dir);
%执行描述符配置脚本文件
eval([data_name , ‘_config_descriptors‘]);
descriptors_param = cell(1 , length(descriptors_name));
descriptors_param{1} = mlhoee;
descriptors_param{2} = mlhmslsd;
descriptors_param{3} = mlhmslbp;
descriptors_param{4} = mlhmsldp;
descriptors_size = cell(1 , length(descriptors_name));
descriptors_size{1} = descriptors_param{1}{1}.size;
descriptors_size{2} = descriptors_param{2}{1}.size;
descriptors_size{3} = descriptors_param{3}{1}.size;
descriptors_size{4} = descriptors_param{4}{1}.size;
nb_descriptors = length(choice_descriptors);
if(do_extract_feature)
for j = 1 : nb_descriptors
current_path = fullfile(pwd , ‘images‘ , data_name );
current_dir = dir(fullfile(current_path , [‘*.‘ , im_ext]));
m = length(current_dir);
current_descriptor = choice_descriptors(j);
current_size = descriptors_size{current_descriptor};
base_descriptor = descriptors_name{current_descriptor};
eval([‘descriptors = @‘ base_descriptor ‘;‘]);
%初始化特征存储变量
X = zeros(descriptors_size{current_descriptor} , m);
for i = 1 : m
I = imread(fullfile(current_path , current_dir(i).name));
[h,w] = size(I);
%将图像缩小一半
J = imresize(I,[h/2,w/2]);
X(:,i) = descriptors(J , descriptors_param{current_descriptor}{:});
fprintf(‘descriptor = %s, image = %s (%d/%d)\n‘ , base_descriptor , current_dir(i).name , i , m)
drawnow
end
%将图像特征存储为文件
save(fullfile(feat_dir , [data_name , ‘_‘ , base_descriptor]) , ‘X‘ )
clear X ;
end
fprintf(‘Feature extraction finished!‘);
end
运行该程序就可以对image文件夹下JDTest文件夹内各子文件夹内的图像提取特征并存为文件。
%exam2.m extract bag-of-features for every image
clc,close all, clear ,drawnow
database_name = {‘JDPig‘ };
database_ext = {‘jpg‘ , ‘jpg‘ , ‘png‘};
descriptors_name = {‘denseSIFT‘ , ‘denseCOLOR‘ , ‘densePATCH‘ , ‘denseMBLBP‘ , ‘denseMBLDP‘};
encoding_name = {‘yael_kmeans‘ , ‘mexTrainDL‘};
features_name = {‘mlhbow_spyr‘ , ‘dl_spyr‘ , ‘mlhlcc_spyr‘};
choice_database = [1];
choice_descriptors = [1];
choice_encoding = [2]; %Kmeans=1/Sparse Learning =2
choice_feature = [2]; %SP-Histogram = 1/Sparse Pooling = 2/LCC = 3
do_extract_patches = 1; %no=0/yes=1
do_encoding = 1; %no=0/yes=1
do_compute_features = 1; %no=0/yes=1
dicoshared = 0; %no=0/yes=1
data_name = database_name{choice_database(1)};
im_ext = database_ext{choice_database(1)};
rootbase_dir = pwd;
images_dir = fullfile(pwd , ‘images‘ , data_name);
core_dir = fullfile(pwd , ‘core‘);
feat_dir = fullfile(pwd , ‘features‘);
dico_dir = fullfile(pwd , ‘dico‘);
des_dir = fullfile(pwd , ‘descriptors‘);
addpath(core_dir)
dirim = dir(images_dir);
nb_topic = length(dirim) - 2;
classe_name = cellstr(char(dirim(3:nb_topic+2).name))‘;
%执行相关配置文件
eval([data_name , ‘_config_descriptors‘]);
eval([data_name , ‘_config_encoding‘]);
eval([data_name , ‘_config_features‘]);
nbimagespertopic = zeros(1 , nb_topic);
for i = 1:nb_topic
dir_name = dir(fullfile(pwd , ‘images‘ , data_name , dirim(i+2).name , [‘*.‘ , im_ext]));
nbimagespertopic(i) = length(dir_name);
end
N = sum(nbimagespertopic);
descriptors_param = cell(1 , length(descriptors_name));
descriptors_param{1} = sift;
descriptors_param{2} = color;
descriptors_param{3} = patch;
descriptors_param{4} = mblbp;
descriptors_param{5} = mbldp;
descriptors_size = cell(1 , length(descriptors_name));
descriptors_size{1} = descriptors_param{1}{1}.size;
descriptors_size{2} = descriptors_param{2}{1}.size;
descriptors_size{3} = descriptors_param{3}{1}.size;
descriptors_size{4} = descriptors_param{4}{1}.size;
descriptors_size{5} = descriptors_param{5}{1}.size;
encoding_param = cell(1 , length(encoding_name));
encoding_param{1} = yael;
encoding_param{2} = spams;
features_param = cell(1 , length(features_name));
features_param{1} = mlhbow_feat;
features_param{2} = dl_feat;
features_param{3} = mlhlcc_feat;
nb_descriptors = length(choice_descriptors);
nb_encoding = length(choice_encoding);
nb_features = length(choice_encoding);
current_descriptor = choice_descriptors;
base_descriptor = descriptors_name{current_descriptor};
featfile = fullfile(feat_dir , [data_name , ‘_‘ , base_descriptor]);
featfile = [featfile,‘.mat‘];
if (~exist(featfile))
do_extract_patches = 1;
else
do_extract_patches = 0;
end
if(do_extract_patches)
for j = 1 : nb_descriptors
current_descriptor = choice_descriptors(j);
current_size = descriptors_size{current_descriptor};
base_descriptor = descriptors_name{current_descriptor};
nbpatches = descriptors_param{current_descriptor}{1}.nbpatches;
nbpatchetotal = nbpatches*N;
standardize = descriptors_param{current_descriptor}{1}.standardize;
whithning = descriptors_param{current_descriptor}{1}.whithning;
patchdim = descriptors_param{current_descriptor}{1}.patchdim;
eval([‘descriptors = @‘ base_descriptor ‘;‘]);
fprintf(‘descriptor = %s \n\n‘ , base_descriptor)
drawnow
X = zeros(descriptors_size{current_descriptor} , N , ‘single‘);
Z = zeros(nbpatches*6 , N , ‘single‘);
S = zeros(2 , N , ‘uint16‘);
Y = zeros(nbpatches , N , ‘single‘);
y = zeros(1 , N );
co = 1;
%对每类图像进行处理
for t = 1 : nb_topic
current_path = fullfile(pwd , ‘images‘ , data_name , dirim(t+2).name);
current_dir = dir(fullfile(current_path , [‘*.‘ , im_ext]));
current_topic = char(classe_name(t));
for i = 1 : length(current_dir)
I = imread(fullfile(current_path , current_dir(i).name));
fprintf(‘descriptor = %s, topic = %s (%d/%d), image = %s (%d/%d)\n‘ , base_descriptor , current_topic, t , nb_topic , current_dir(i).name , i , nbimagespertopic(t))
drawnow
[des , fea] = descriptors(I , descriptors_param{current_descriptor}{:});
X(: , co) = reshape(single(des) , current_size , 1);
Z(: , co) = reshape(single(fea(1:6,:)) , nbpatches*6 , 1);
Y(: , co) = t*ones(nbpatches , 1);
y(co) = t;
co = co + 1;
end
end
if(dicoshared)
Z(3:4 , :) = 1;
descriptors_param{current_descriptor}{1}.scale = 1;
descriptors_param{current_descriptor}{1}.nbscale = 1;
descriptors_param{current_descriptor}{1}.dimcolor = 1;
features_param{current_features}.scale = 1;
end
X = reshape(X , patchdim , nbpatchetotal);
Z = reshape(Z , [6 , nbpatchetotal]);
Y = reshape(Y , 1 , nbpatchetotal);
if(standardize)
fprintf(‘Standardize patches\n‘ )
drawnow
mX = mean(X , 2);
stdX = std(X , 0 , 2);
stdX(stdX==0) = 1;
X = (X - mX(: , ones(1 , size(X , 2))))./stdX(: , ones(1 , size(X , 2)));
fprintf(‘End Standardize\n‘ )
drawnow
end
if(whithning)
fprintf(‘Whithning patches\n‘ )
drawnow
covX = (1/(size(X,2)-1))*(X*X‘);
[V,D] = eig(covX);
T = (V*diag(sqrt(1 ./(diag(D) + 0.1))))*V‘;
X = T * X;
fprintf(‘End whithning\n‘ )
drawnow
end
fprintf(‘Saving patches descriptor %s ...\n‘ , [data_name , ‘_‘ , base_descriptor]);
drawnow
save(fullfile(des_dir , [data_name , ‘_‘ , base_descriptor]) , ‘X‘ , ‘Z‘ , ‘Y‘ , ‘y‘ , ‘classe_name‘ , ‘patchdim‘ , ‘nbpatches‘ , ‘N‘ , ‘-v7.3‘)
clear X Z Y y;
end
end
current_descriptor = choice_descriptors;
base_descriptor = descriptors_name{current_descriptor};
current_encoding = choice_encoding
base_encoding = encoding_name{current_encoding};
dictfile = fullfile(dico_dir , [data_name , ‘_‘ , base_encoding , ‘_‘ , base_descriptor]);
dictfile = [dictfile,‘.mat‘];
if (~exist(featfile))
do_encoding = 1;
else
do_encoding = 0;
end
if(do_encoding)
for j = 1 : nb_encoding
current_encoding = choice_encoding(j);
base_encoding = encoding_name{current_encoding};
eval([‘encoding = @‘ base_encoding ‘;‘]);
for i = 1 : nb_descriptors
current_descriptor = choice_descriptors(i);
base_descriptor = descriptors_name{current_descriptor};
nbpatches = descriptors_param{current_descriptor}{1}.nbpatches;
nbpatchetotal = nbpatches*N;
patchdim = descriptors_param{current_descriptor}{1}.patchdim;
nbscale = descriptors_param{current_descriptor}{1}.nbscale;
dimcolor = descriptors_param{current_descriptor}{1}.dimcolor;
K = encoding_param{current_encoding}{current_descriptor}.K;
nbpatchesperclass = encoding_param{current_encoding}{current_descriptor}.nbpatchesperclass;
D = zeros(patchdim , K , nbscale , dimcolor , ‘single‘);
fprintf(‘Loading patches descriptor %s ...\n‘ , [data_name , ‘_‘ , base_descriptor]);
drawnow
load(fullfile(des_dir , [data_name , ‘_‘ , base_descriptor]) , ‘X‘ , ‘Z‘ , ‘Y‘ , ‘y‘ , ‘classe_name‘)
for c = 1 : dimcolor
for s = 1 : nbscale
currentscale = descriptors_param{current_descriptor}{1}.scale(s);
index = find( (Z(3 , :) == currentscale ) & (Z(4 , :) == c) );
Yindex = Y(index);
lindex = length(index);
indexdico = [];
for t = 1 : nb_topic
indt = find(Yindex == t);
lindt = length(indt);
idx = randperm(lindt);
idxtemp = idx(1:min(nbpatchesperclass ,lindt));
indexdico = [indexdico , index(indt(idxtemp))];
end
fprintf(‘Learning dictionary of K = %d words with encoder = %s, scale = %5.3f, dimcolor = %d from %d/%d patches of %s \n‘ , K , base_encoding , currentscale , c , length(indexdico) , lindex , base_descriptor)
drawnow
D(: , : , s , c) = encoding(X(: , indexdico) , encoding_param{current_encoding}{current_descriptor});
end
end
fprintf(‘Saving dictionary %s ...\n‘ , [data_name , ‘_‘ , base_encoding , ‘_‘ , base_descriptor]);
drawnow
save(fullfile(dico_dir , [data_name , ‘_‘ , base_encoding , ‘_‘ , base_descriptor]) , ‘D‘);
clear X Z Y y classe_name;
end
end
end
current_descriptor = choice_descriptors;
base_descriptor = descriptors_name{current_descriptor};
current_features = choice_feature;
base_features = features_name{current_features};
dlfeatfile = fullfile(feat_dir , [data_name , ‘_‘ , base_descriptor , ‘_‘ , base_features]);
dlfeatfile = [dlfeatfile,‘.mat‘];
if (~exist(dlfeatfile))
do_compute_features = 1;
else
do_compute_features = 0;
end
if(do_compute_features)
for j = 1 : nb_encoding
current_features = choice_feature(j);
base_features = features_name{current_features};
current_encoding = choice_encoding(j);
base_encoding = encoding_name{current_encoding};
eval([‘features = @‘ base_features ‘;‘]);
for i = 1 : nb_descriptors
current_descriptor = choice_descriptors(i);
base_descriptor = descriptors_name{current_descriptor};
nbpatches = descriptors_param{current_descriptor}{1}.nbpatches;
nbpatchetotal = nbpatches*N;
patchdim = descriptors_param{current_descriptor}{1}.patchdim;
nbscale = descriptors_param{current_descriptor}{1}.nbscale;
dimcolor = descriptors_param{current_descriptor}{1}.dimcolor;
features_param{current_features}{current_descriptor}.scale = descriptors_param{current_descriptor}{1}.scale;
features_param{current_features}{current_descriptor}.L = patchdim;
current_feature_param = features_param{current_features}{current_descriptor};
fprintf(‘Loading dictionnary %s ...\n‘ , [data_name , ‘_‘ , base_encoding , ‘_‘ , base_descriptor]);
drawnow
load(fullfile(dico_dir , [data_name , ‘_‘ , base_encoding , ‘_‘ , base_descriptor]) , ‘D‘);
fprintf(‘Loading patches descriptor %s ...\n‘ , [data_name , ‘_‘ , base_descriptor]);
drawnow
load(fullfile(des_dir , [data_name , ‘_‘ , base_descriptor]) , ‘X‘ , ‘Z‘ , ‘y‘ , ‘classe_name‘);
K = size(D , 2);
nH = current_feature_param.nH;
X = reshape(X , descriptors_size{current_descriptor} , N);
Z = reshape(Z , 6*nbpatches , N);
F = zeros(K*nH*nbscale*dimcolor , N);
co = 1;
for t = 1 : nb_topic
current_path = fullfile(pwd , ‘images‘ , data_name , dirim(t+2).name);
current_dir = dir(fullfile(current_path , [‘*.‘ , im_ext]));
current_topic = char(classe_name(t));
for i = 1 : length(current_dir)
fprintf(‘encoder = %s, topic = %s (%d/%d), patches = %s , image = %s (%d/%d)\n‘ , base_features , current_topic, t , nb_topic , base_descriptor , current_dir(i).name , i , nbimagespertopic(t))
drawnow
XX = reshape(X(: , co) , patchdim , nbpatches);
ZZ = reshape(Z(: , co) , 6 , nbpatches);
F(: , co) = features(D , XX , ZZ , current_feature_param);
co = co + 1;
end
end
X = F;
clear F Z S;
fprintf(‘Saving features %s ...\n‘ , [data_name , ‘_‘ , base_descriptor , ‘_‘ , base_features]);
drawnow
dlfeatfile = fullfile(feat_dir , [data_name , ‘_‘ , base_descriptor , ‘_‘ , base_features]);
save( dlfeatfile, ‘X‘ , ‘y‘ , ‘classe_name‘ , ‘-v7.3‘);
end
end
end
fprintf(‘Feature extraction finished!!‘);
该程序提取提取后对特征聚类生成词袋,并依据词袋对图像特征进行编码,为每幅图像生成特征。详细内容可参看Matlab图像识别/检索系列(9)—开源工具介绍之图像识别reco_toolbox。
原文地址:http://blog.51cto.com/8764888/2085964
时间: 2024-10-14 09:28:50