matlab - 如何在matlab中的筛选关键点上运行kmean算法
问题描述
我需要在 MATLAB 中对 Sift 算法的关键点运行 K-Means 算法。我想对图像中的关键点进行聚类,但我不知道该怎么做。
解决方案
首先,将关键点放入 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
推荐阅读
- c# - HoloLens 无法通过 BT 和 TCP 发送或接收数据
- python - Pytorch 保存模型用户警告:无法检索网络类型容器的源代码
- android - 如何将相机图像传递给另一个活动?
- java - 构建 Play 2.6 java 项目时的 Scala java.lang.StackOverflowError
- pyspark - pyspark blaze-AttributeError:“有向图”对象没有属性“边缘”
- css - sass 文件夹中的 CSS 文件 - laravel
- c++ - Unresolved external symbol error related class with template
- r - pass string from document properties drop down list in Spotfire to R script
- snapcraft - 在 snapcraft.io 上选择 18.04 工具链以在 github commit 上自动更新 qt5 snap
- c# - How to use the same input twice or more