Bag-of-Visual-Words SIFT 实现(matlab版本)

1.Bag-of-Visual-Words SIFT feature 相关知识

  1. https://blog.csdn.net/wsj998689aa/article/details/47089153 讲解BOW原理,C++实现
  2. http://yongyuan.name/blog/CBIR-BoW-for-image-retrieval-and-practice.html 讲解BOW原理,Python实现(推荐这篇!)
  3. http://www.vlfeat.org/install-matlab.html matlab工具箱下载(内含sift,kmeans函数)

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

你可能感兴趣的:(SIFT,BoW,图像特征提取,图像处理)