Matlab画像認識/検索シリーズ(10)—オープンソース紹介画像検索caltech-image-search
画像検索ツールボックスCaltech Large Scale Image Search Toolboxは、カリフォルニア州リボでMohamed Alaa El Dien Alyが作成したもので、サウジアラビアのKAUSTのVisual Computing Centerに加入しており、個人のホームページを見ることができます.このツールボックスの主な機能は,大規模な画像セットに対してBOWベースの画像検索を行うことである.高速化のため,画像検索にLSH(Locality Sensitive Hashing,位置敏感ハッシュ),Inverted File Index,Min-Hashなどの手法を用い,局所特徴生成辞書にAKM(Approximate K-Means)とHKM(Hierarchical K-Means)手法を用いた.このツールボックスで採用されるBOW,辞書生成は画像認識において現在主流ではないが,LSH,Inverted File Index,Min-Hash,AKM,HKMなどの手法は画像検索において依然として大きな参考と使用価値がある.特に高速検索方法LSHは,2005年にヨーロッパ式空間スキームEELSHが誕生してから10年以上になるが,高速画像検索において依然として大きな利点がある.テキスト処理において、BOWはドキュメントの量子化の重要な方法の一つである.この間、より効果的な検索方法は現れないはずです.今年上半期、国内の有名な研究機関が深さ学習とLSHを結合した検索方法を提案したが、方法が融合しただけだ.以下、ツールボックスのプログラム例Demoについて簡単に説明する.m、ここは一部のコードの展示です.完全版はツールボックスのソースコードを参照してください.
% Author: Mohamed Aly
% Date: October 6, 2010
root = pwd;
addpath(fullfile(root,'caltech-image-search-1.0')) ;
%
bag_of_words();
%
full_representation();
%--------------------------------------------------------------------------
% Bag of Words
%--------------------------------------------------------------------------
function bag_of_words()
%
old_seed = ccvRandSeed(123, 'set');
% ,
fprintf('Creating features
');
num_images = 100;
features_per_image = 1000;
dim = 128;
num_features = num_images * features_per_image;
features = uint8(ceil(rand(dim, num_features) * 255));
labels = reshape(repmat(uint32(1:num_images), features_per_image, 1), [], 1)';
%
dict_type = 'akmeans';
fprintf('Building the dictionary: %s
', dict_type);
%
switch dict_type
% AKM(Approximate k-means)
case 'akmeans'
num_words = 100;
num_iterations = 5;
num_trees = 2;
dict_params = {num_iterations, 'kdt', num_trees};
% HKM(Hierarchical k-means)
case 'hkmeans'
num_words = 100;
num_iterations = 5;
num_levels = 2;
num_branches = 10;
dict_params = {num_iterations, num_levels, num_branches};
end; % switch
%
dict_words = ccvBowGetDict(features, [], [], num_words, 'flat', dict_type, [], dict_params);
% ( cell , 。 , ID)
fprintf('Computing the words
');
dict = ccvBowGetWordsInit(dict_words, 'flat', dict_type, [], dict_params);
words = cell(1, num_images);
for i=1:num_images
words{i} = ccvBowGetWords(dict_words, features(:,labels==i), [], dict);
end;
ccvBowGetWordsClean(dict);
%
fprintf('Creating and searching an inverted file
');
if_weight = 'none';
if_norm = 'l1';
if_dist = 'l1';
inv_file = ccvInvFileInsert([], words, num_words);
ccvInvFileCompStats(inv_file, if_weight, if_norm);
%
[ids dists] = ccvInvFileSearch(inv_file, words(1:2), if_weight, if_norm, ...
if_dist, 5)
ccvInvFileClean(inv_file);
ccvRandSeed(old_seed, 'restore');
% LSH(Min-Hash LSH)
fprintf('Creating and searching a Min-Hash LSH index
');
ntables = 3;
nfuncs = 2;
dist = 'jac';
%
lsh = ccvLshCreate(ntables, nfuncs, 'min-hash', dist, 0, 0, 0, 100);
ccvLshInsert(lsh, words, 0);
% LSH
[ids dists] = ccvLshKnn(lsh, words, words(1:2), 5, dist)
ccvLshClean(lsh);
end % bag_of_words function
%--------------------------------------------------------------------------
% Full Representation
%--------------------------------------------------------------------------
function full_representation()
old_seed = ccvRandSeed(123, 'set');
fprintf('Creating features
');
num_images = 100;
features_per_image = 1000;
dim = 128;
num_features = num_images * features_per_image;
features = uint8(ceil(rand(dim, num_features) * 255));
labels = reshape(repmat(uint32(1:num_images), features_per_image, 1), [], 1)';
% ( Nearest Neighbor search )
nn_types = {'kdt', 'hkm', 'lsh-l2', 'lsh-simplex'};
for nni=1:length(nn_types);
%
type = nn_types{nni};
%
fprintf('
Creating index %d: %s
', nni, type);
switch type
% Kd-Tree
case 'kdt'
ntrees = 4;
index = ccvKdtCreate(features, ntrees);
% Hierarchical K-Means
case 'hkm'
nlevels = 4;
nbranches = 10;
niterations = 20;
index = ccvHkmCreate(features, niterations, nlevels, nbranches);
% LSH-L2
case 'lsh-l2'
ntables = 4;
nfuncs = 20;
index = ccvLshCreate(ntables, nfuncs, 'l2', 'l2', 1, dim, .1, 1000);
ccvLshInsert(index, features);
% LSH-Simplex
case 'lsh-simplex'
ntables = 4;
nfuncs = 2;
index = ccvLshCreate(ntables, nfuncs, 'sph-sim', 'l2', 1, dim, .1, 1000);
ccvLshInsert(index, features);
end;
%
fprintf('Searching for first image
');
switch type
case 'kdt'
[nnids nndists] = ccvKdtKnn(index, features, features(:,labels==1), 2);
case 'hkm'
[nnids nndists] = ccvHkmKnn(index, features, features(:,labels==1), 2);
case {'lsh-l2', 'lsh-simplex'}
[nnids nndists] = ccvLshKnn(index, features, features(:,labels==1), 2);
end;
%
nnlabels = labels(nnids(1,:));
counts = histc(nnlabels, 1:num_images);
[counts cids] = sort(counts, 'descend');
counts(1), cids(1)
%
switch type
case 'kdt'
ccvKdtClean(index);
case 'hkm'
ccvHkmClean(index);
case {'lsh-l2', 'lsh-simplex'}
ccvLshClean(index);
end;
end;
ccvRandSeed(old_seed, 'restore');
end
end