繁体   English   中英

使用 Matlab 从 VLFeat 中的 SIFT 描述符中提取 VLAD

[英]Extracting VLAD from SIFT Descriptors in VLFeat with Matlab

我有一个图像文件夹。 我想从每个图像计算 VLAD 特征。

我循环遍历每个图像,加载它,并按如下方式获取 SIFT 描述符:

repo = '/media/data/images/';
filelist = dir([repo '*.jpg']);
sift_descr = {}

for i = 1:size(filelist, 1)
    I = imread([repo filelist(i).name]) ;
    I = single(rgb2gray(I)) ;
    [f,d] = vl_sift(I) ;
    sift_descr{i} = d
end

然而,VLAD 要求描述符矩阵是二维的。 这里 在 VLAD 编码之前处理我的 SIFT 描述符的正确方法是什么? 谢谢你。

首先,您需要获得一个视觉词词典,或者更具体地说:使用k均值聚类对所有图像的 SIFT 特征进行聚类。 在 [1] 中,推荐使用例如 64 或 256 个集群的粗聚类。

为此,我们必须将所有描述符连接成一个矩阵,然后我们可以将其传递给vl_kmeans函数。 此外,我们将描述符从uint8转换为single ,因为vl_kmeans函数要求输入为singledouble

all_descr = single([sift_descr{:}]);
centroids = vl_kmeans(all_descr, 64);

其次,您必须创建一个分配矩阵,该矩阵具有NumberOfClusters-by-NumberOfDescriptors维度,它将每个描述符分配给一个集群。 您在创建此分配矩阵时具有很大的灵活性:您可以进行软分配或硬分配,您可以自行决定使用简单的最近邻搜索或 kd 树或其他近似或分层最近邻方案。

在教程中,他们使用 kd-trees,所以让我们坚持这一点:首先,必须构建一个 kd-tree。 在找到centroids之后,这个操作就属于:

kdtree = vl_kdtreebuild(centroids);

然后,我们准备为每个图像构建 VLAD 向量。 因此,我们必须再次遍历所有图像,并独立计算它们的 VLAD 向量。 首先,我们完全按照教程中的描述创建分配矩阵。 然后,我们可以使用vl_vlad函数对 SIFT 描述符进行编码。 生成的 VLAD 向量的大小为NumberOfClusters * SiftDescriptorSize ,即在我们的示例中为 64*128。

enc = zeros(64*128, numel(sift_descr));

for k=1:numel(sift_descr)

    % Create assignment matrix
    nn = vl_kdtreequery(kdtree, centroids, single(sift_descr{k}));
    assignments = zeros(64, numel(nn), 'single');
    assignments(sub2ind(size(assignments)), nn, 1:numel(nn))) = 1;

    % Encode using VLAD
    enc(:, k) = vl_vlad(single(sift_descr{k}), centroids, assignments);
end

最后,我们有数据库中所有图像的高维 VLAD 向量。 通常,您会希望降低 VLAD 描述符的维数,例如使用 PCA。

现在,赋予了新的形象这是不是在数据库中,你可以提取SIFT特征使用vl_sift ,创建具有分配矩阵vl_kdtreequery ,并创建使用该图像的VLAD矢量vl_vlad 因此,您不必找到新的质心或创建新的 kd 树:

% Load image and extract SIFT features
new_image = imread('filename.jpg');
new_image = single(rgb2gray(new_image));
[~, new_sift] = vl_sift(new_image);

% Create assignment matrix
nn = vl_kdtreequery(kdtree, centroids, single(new_sift));
assignments = zeros(64, numel(nn), 'single');
assignments(sub2ind(size(assignments)), nn, 1:numel(nn))) = 1;

% Encode using VLAD
new_vlad = vl_vlad(single(new_sift), centroids, assignments);

[1] Arandjelovic, R., & Zisserman, A. (2013)。 关于 VLAD。 IEEE 计算机视觉和模式识别会议 (CVPR),1578-1585。 https://doi.org/10.1109/CVPR.2013.207

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM