Bag-of-Visual-Words SIFT 實現(matlab版本)
阿新 • • 發佈:2019-01-05
1.Bag-of-Visual-Words SIFT feature 相關知識
2.構建BoW碼本步驟
(copy上述連結2的步驟敘述)
假設訓練集有M幅影象,對訓練圖象集進行預處理。包括影象增強,分割,影象統一格式,統一規格等等。
1.提取SIFT特徵。對每一幅影象提取SIFT特徵(每一幅影象提取多少個SIFT特徵不定)。每一個SIFT特徵用一個128維的描述子矢量表示,假設M幅影象共提取出N個SIFT特徵。
2.用K-means對2中提取的N個SIFT特徵進行聚類,K-Means演算法是一種基於樣本間相似性度量的間接聚類方法,此演算法以K為引數,把N個物件分為K個簇,以使簇內具有較高的相似度,而簇間相似度較低。聚類中心有k個(在BOW模型中聚類中心我們稱它們為視覺詞),碼本的長度也就為k,計算每一幅影象的每一個SIFT特徵到這k個視覺詞的距離,並將其對映到距離最近的視覺詞中(即將該視覺詞的對應詞頻+1)。完成這一步後,每一幅影象就變成了一個與視覺詞序列相對應的詞頻向量。
3.構造碼本。碼本向量歸一化因為每一幅影象的SIFT特徵個數不定,所以需要歸一化。測試影象
3.matlab實現
需要安裝上述連結3的vlfeat工具箱。
clear all
[~,Image_names_train,~] = textread('trainset_txt_img_cat.txt','%s%s%[^\n]') ; %訓練集圖片名稱
[~,Image_names_test,~] = textread('testset_txt_img_cat.txt','%s%s%[^\n]'); %測試集圖片名稱
n_train = size (Image_names_train,1);
n_test = size(Image_names_test,1);
numClusters = 128;
D = [];
train_flag = [];
test_flag = [];
%%讀取圖片,SIFT特徵提取
for i=1:n_train
img = Image_names_train{i};
t = strcat(img,'.jpg');
Image = imread(t);
mysize = size(Image);
if numel(mysize)>2
Image = rgb2gray(Image);
end
Image = im2single(Image);
[~,Di] = vl_sift(Image);
D = [D Di];
train_flag(i) = size(Di,2);
end
for i=1:n_test
img = Image_names_test{i};
t = strcat(img,'.jpg');
Image = imread(t);
mysize = size(Image);
if numel(mysize)>2
Image = rgb2gray(Image);
end
Image = im2single(Image);
[~,Di] = vl_sift(Image);
D = [D Di];
test_flag(i) = size(Di,2);
end
%%構造詞頻碼
D = im2single(D);
[centers] = vl_kmeans(D, numClusters); %訓練集+測試集共同進行K均值聚類
flag_sum = 0;
for i = 1:n_train
H = zeros(1,numClusters);
Di = D(:,flag_sum+1: flag_sum + train_flag(i));
flag_sum = flag_sum + train_flag(i);
for j=1:train_flag(i)
[~, k] = min(vl_alldist(Di(:,j), centers)) ; %計算每一幅影象的每一個SIFT特徵到這k個視覺詞的距離
H(k) = H(k) + 1; %並將其對映到距離最近的視覺詞中(即將該視覺詞的對應詞頻+1)
end
my_I_tr(i,:) = 1/train_flag(i) * H; %碼本向量歸一化因為每一幅影象的SIFT特徵個數不定,所以需要歸一化。
end
for i = 1:n_test
H = zeros(1,numClusters);
Di = D(:,flag_sum+1: flag_sum + test_flag(i));
flag_sum = flag_sum + test_flag(i);
for j=1:test_flag(i)
[~, k] = min(vl_alldist(Di(:,j), centers)) ;
H(k) = H(k) + 1;
end
my_I_te(i,:) = 1/test_flag(i) * H;
end