转自:https://blog.youkuaiyun.com/smartdazhi/article/details/79796893
1.Bag-of-Visual-Words SIFT feature 相关知识
https://blog.youkuaiyun.com/wsj998689aa/article/details/47089153 讲解BOW原理,C++实现
http://yongyuan.name/blog/CBIR-BoW-for-image-retrieval-and-practice.html 讲解BOW原理,Python实现(推荐这篇!)
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
---------------------
作者:SmartDazhi
来源:优快云
原文:https://blog.youkuaiyun.com/smartdazhi/article/details/79796893
版权声明:本文为博主原创文章,转载请附上博文链接!