1. 程式人生 > >Bag-of-Visual-Words SIFT 實現(matlab版本)

Bag-of-Visual-Words SIFT 實現(matlab版本)

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特徵個數不定,所以需要歸一化。測試影象

也需經過預處理,提取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