【问题标题】:how run kmean algorithm on sift keypoint in matlab如何在matlab中的筛选关键点上运行kmean算法
【发布时间】:2021-01-02 23:54:38
【问题描述】:

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

【问题讨论】:

  • 您好,欢迎来到 Stackoverflow!你的问题不够精确。请创建一个minimal and reproducible example。还向我们展示您已经尝试过的内容,并向我们解释为什么它不能按预期工作。如果您根本不知道如何使用函数kmeans,请查看documentation。出于这些原因,我投票结束你的问题。随意编辑您的问题,以添加必要的附加信息。

标签: matlab image-processing


【解决方案1】:

首先,将关键点放入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

【讨论】:

  • 你好,我是图像处理编程的初学者,非常感谢你的帮助,我会测试这个方法
  • 嗨@puiholam 感谢您的帮助我知道我的问题可能看起来很初级,但我使用VLFeat's sift algorithm 的代码并且我不知道如何将关键点放在x 中。
  • "矩阵 f 的每一帧都有一列,A 帧是一个中心为 f(1:2) 的圆盘"。因此,所有圆盘的中心位置可以通过f(1:2,:)提取出来
猜你喜欢
  • 1970-01-01
  • 2017-11-20
  • 2012-06-05
  • 1970-01-01
  • 2021-02-17
  • 1970-01-01
  • 2022-11-15
  • 1970-01-01
  • 2013-10-03
相关资源
最近更新 更多