Matlab找到几个像素的聚类中心并计算聚类

时间:2014-11-12 01:24:03

标签: arrays matlab function image-processing matrix

所以我有这个矩阵A,它由1和0组成,我有大约10到14个许多像素的白点,但是我想要每个白色簇只有1个白色像素/中心坐标,我该如何计算有多少集群及其中心。

尝试将矩阵A想象为黑色天空中的白色天空,以及如何计算星星和星星的中心,加上星星由白色像素簇组成。

群集的大小也不完全相同。

1 个答案:

答案 0 :(得分:1)

以下是使用bwlabel和/或regioprops的一些代码,它们分别用于识别矩阵中的连通分量和其他属性。我觉得它很适合你的问题;但是你可能想稍微调整我的代码,因为它更像是一个起点。

clear
clc

%// Create dummy matrix.
BW = logical ([ 1     1     1     0     1     1     1     0
                1     1     1     0     1     1     1     0
                1     1     1     0     1     1     1     0
                0     0     0     0     0     0     0     0
                0     0     0     0     0     1     1     0
                1     1     1     1     0     1     1     0
                1     1     1     1     0     1     1     0
                1     1     1     1     0     0     0     0]);

%// Identify clusters.
L = bwlabel(BW,4)

Matrix L看起来像这样:

L =

     1     1     1     0     3     3     3     0
     1     1     1     0     3     3     3     0
     1     1     1     0     3     3     3     0
     0     0     0     0     0     0     0     0
     0     0     0     0     0     4     4     0
     2     2     2     2     0     4     4     0
     2     2     2     2     0     4     4     0
     2     2     2     2     0     0     0     0

在这里,您可以通过多种方式找到群集的中心。第一个使用bwlabel的输出来查找每个簇并计算循环中的坐标。它的工作原理和教学方法虽然有点长,但效率却不高。 @nkjt提到的第二种方法使用了regionprops,它使用' Centroid'属性。所以这里有两种方法:

方法1 :有点复杂 所以bwlabel确定了4个集群,这是有道理的。现在我们需要确定每个集群的中心。我的方法可能会简化;但是我有点过时了,所以你可以随意修改它。

%// Get number of clusters
NumClusters = numel(unique(L)) -1;

Centers = zeros(NumClusters,2);
CenterLinIdices = zeros(NumClusters,1);

for k = 1:NumClusters

%// Find indices for elements forming each cluster.
    [r, c] = find(L==k);

%// Sort the elements to know hot many rows and columns the cluster is spanning.
    [~,y] = sort(r);
    c = c(y);
    r = r(y);

    NumRow = numel(unique(r));
    NumCol = numel(unique(c));

%// Calculate the approximate center of the cluster.
    CenterCoord = [r(1)+floor(NumRow/2) c(1)+floor(NumCol/2)];

%// Actually this array is not used here but you might want to keep it for future reference.
    Centers(k,:) = [CenterCoord(1) CenterCoord(2)];

%// Convert the subscripts indices to linear indices for easy reference.
    CenterLinIdices(k) = sub2ind(size(BW),CenterCoord(1),CenterCoord(2));
end

%// Create output matrix full of 0s, except at the center of the clusters.
BW2 = false(size(BW));
BW2(CenterLinIdices) = 1

BW2 =

     0     0     0     0     0     0     0     0
     0     1     0     0     0     1     0     0
     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     1     0
     0     0     1     0     0     0     0     0
     0     0     0     0     0     0     0     0

方法2 使用regionprops和' Centroid'属性。

一旦得到矩阵L,应用regionprops并连接输出以获得直接包含坐标的数组。更简单!

%// Create dummy matrix.
BW = logical ([ 1     1     1     0     1     1     1     0
                1     1     1     0     1     1     1     0
                1     1     1     0     1     1     1     0
                0     0     0     0     0     0     0     0
                0     0     0     0     0     1     1     0
                1     1     1     1     0     1     1     0
                1     1     1     1     0     1     1     0
                1     1     1     1     0     0     0     0]);

%// Identify clusters.
L = bwlabel(BW,4)

s = regionprops(L,'Centroid');

CentroidCoord = vertcat(s.Centroid)

给出了这个:

CentroidCoord =

    2.0000    2.0000
    2.5000    7.0000
    6.0000    2.0000
    6.5000    6.0000

一旦你使用地板,这会更简单并提供相同的输出。

希望有所帮助!