首页 > 解决方案 > 如何在matlab中的筛选关键点上运行kmean算法

问题描述

我需要在 MATLAB 中对 Sift 算法的关键点运行 K-Means 算法。我想对图像中的关键点进行聚类,但我不知道该怎么做。

标签: matlabimage-processing

解决方案


首先,将关键点放入 X 中,x 坐标在第一列,y 坐标在第二列,如下所示

X=[reshape(keypxcoord,numel(keypxcoord),1),reshape(keypycoord,numel(keypycoord),1))]

然后,如果你有统计工具箱,你可以像这样使用内置的“kmeans”函数

output = kmeans(X,num_clusters)

否则,编写您自己的 kmeans 函数:

function [ min_group, mu ] = mykmeans( X,K )
%MYKMEANS
% X = N obervations of D element vectors
% K = number of centroids
assert(K > 0);
D = size(X,1); %No. of r.v.
N = size(X,2); %No. of observations
group_size = zeros(1,K);
min_group = zeros(1,N);
step = 0;
%% init centroids
mu = kpp(X,K);
%% 2-phase iterative approach (local then global)
while step < 400
    %% phase 1, batch update
    old_group = min_group;
    % computing distances
    d2 = distances2(X,mu);
    % reassignment all points to closest centroids
    [~, min_group] = min(d2,[],1);
    % recomputing centroids (K number of means)
    for k = 1 : K
        group_size(k) = sum(min_group==k);
        % check empty group
        %if group_size(k) == 0
            assert(group_size(k)>0);
        %else
            mu(:,k) = sum(X(:,min_group==k),2)/group_size(k);
        %end
    end
    changed = sum(min_group ~= old_group);
    p1_converged = changed <= N*0.001;
    %% phase 2, individual update
    changed = 0;
    for n = 1 : N
        d2 = distances2(X(:,n),mu);
        [~, new_group] = min(d2,[],1);
        % recomputing centroids of affected groups
        k = min_group(n);
        if (new_group ~= k)
            mu(:,k)=(mu(:,k)*group_size(k)-X(:,n));
            group_size(k) = group_size(k) - 1;
            mu(:,k)=mu(:,k)/group_size(k);
            mu(:,new_group) = mu(:,new_group)*group_size(new_group)+ X(:,n);
            group_size(new_group) = group_size(new_group) + 1;
            mu(:,new_group)=mu(:,new_group)/group_size(new_group);
            min_group(n) = new_group;
            changed = changed + 1;
        end
    end
    %% check convergence
    if p1_converged && changed <= N*0.001
        break;
    else
        step = step + 1;
    end
end
end

function d2 = distances2(X, mu)
    K = size(mu,2);
    N = size(X,2);
    d2 = zeros(K,N);
    for j = 1 : K
        d2(j,:) = sum((X - repmat(mu(:,j),1,N)).^2,1);
    end
end

function mu = kpp( X,K )
% kmeans++ init
D = size(X,1); %No. of r.v.
N = size(X,2); %No. of observations
mu = zeros(D, K);
mu(:,1) = X(:,round(rand(1) * (size(X, 2)-1)+1));
for k = 2 : K
    % computing distances between centroids and observations
    d2 = distances2(X, mu(1:k-1));
    % assignment
    [min_dist, ~] = min(d2,[],1);
    % select new centroids by selecting point with the cumulative dist
    % value (distance) larger than random value (falls in range between
    % dist(n-1) : dist(n), dist(0)= 0)
    rv = sum(min_dist) * rand(1);
    for n = 1 : N
        if min_dist(n) >= rv
            mu(:,k) = X(:,n);
            break;
        else
            rv = rv - min_dist(n);
        end
    end
end
end

推荐阅读