使用 k-means 算法对图像数据集的 SURF 特征进行聚类

Clustering SURF features of an image dataset using k-means algorithm

我想在 MATLAB 中实现 Bag of Visual Words。首先,我从数据集目录中读取图像,然后检测 SURF 特征并使用这两个函数 detectSURFFeaturesextractFeatures 提取它们。

我将每个特征存储到一个元胞数组中,最后我想使用 k-means 算法对它们进行聚类,但我无法将这些数据放入 k-means 函数输入中。如何将 SURF 特征插入 MATLAB 中的 k 均值聚类算法?

这是我的示例代码,它从文件中读取图像并提取它们的 SURF 特征。

clc;
clear;
close all;
folder = 'CarData/TrainImages/cars';
filePattern = fullfile(folder, '*.pgm');
f=dir(filePattern);
files={f.name}; 
for k=1:numel(files)
    fullFileName = fullfile(folder, files{k});
    image=imread(fullFileName);
    temp =  detectSURFFeatures(image);
    [im_features, temp] = extractFeatures(image, temp);
    features{k}= im_features;

end

[centers, assignments] = kmeans(double(features), 100);

kmeans 需要输入数据的 N x P 矩阵,其中 N 是示例总数,P 是特征总数。您做错的是将每个特征矩阵放入一个元胞数组中。您要做的是将所有图像的所有特征连接到一个矩阵中。

最简单的方法是在 kmeans 调用之前添加以下代码:

features = vertcat(features{:});

函数vertcat will vertically stack matrices together given a list of matrices that all share the same number of columns. Doing features{:} extracts out a comma-separated list这样相当于做:

features = vertcat(features{1}, features{2}, ...);

最终效果是,这会将每个图像的所有 SURF 特征垂直堆叠到一个 2D 矩阵中。您使用的是 SURF 的默认版本,因此每个特征的长度应为 64,因此您应该有 64 列。行数应该是所有图像中检测到的特征总数。

因此,要绝对清楚:

clc;
clear;
close all;
folder = 'CarData/TrainImages/cars';
filePattern = fullfile(folder, '*.pgm');
f=dir(filePattern);
files={f.name}; 
for k=1:numel(files)
    fullFileName = fullfile(folder, files{k});
    image=imread(fullFileName);
    temp =  detectSURFFeatures(image);
    [im_features, temp] = extractFeatures(image, temp);
    features{k}= im_features;

end

% New code
features = vertcat(features{:});

% Resume old code
[centers, assignments] = kmeans(double(features), 100);