2

На мой главный вопрос дается функция центроида, как я могу нарисовать ее в MATLAB?MATLAB: draw centroids

Более подробно, у меня есть NxNx3 изображения (цветовые оттенки изображения) из которых я принимать 4x4 блоков и вычислить 6-мерный вектор признаки для каждого блока. Я сохраняю эти векторы признаков в матрице Mx6, на которой я запускаю функцию kmeans, и получаю центроиды в матрице kx6, где k - это число кластеров, а 6 - количество функций для каждого блока.

Как я могу нарисовать эти центральные кластеры на своем изображении, чтобы визуализировать, работает ли алгоритм так, как я его желаю? Или если у кого-то есть другие способы/предложения о том, как я могу визуализировать центроиды на моем изображении, я бы очень признателен.

ответ

3

Вот один из способов вы можете визуализировать кластеры:

Как описано выше, первый извлечь блоки, вычислить вектор признаков для каждого, и кластер этой функции матрицы.

Далее мы можем визуализировать кластеры, назначенные каждому блоку. Обратите внимание, что я предполагаю, что блоки 4x4 отличаются друг от друга, это важно для того, чтобы мы могли сопоставить блоки с их местоположением в исходном изображении.

Наконец, для отображения центроидов кластера на изображении я просто нахожу ближайший блок для каждого кластера и отображаю его как представителя этого кластера.

Вот полный пример, чтобы показать вышеприведенную идею (в вашем случае вы хотели бы заменить функцию, которая вычисляет функции каждого блока по вашей собственной реализации, я просто беру min/max/mean/median/Q1/Q3 как мой вектор признаков для каждого 4x4 блока):

%# params 
NUM_CLUSTERS = 3; 
BLOCK_SIZE = 4; 
featureFunc = @(X) [min(X); max(X); mean(X); prctile(X, [25 50 75])]; 

%# read image 
I = imread('peppers.png'); 
I = double(rgb2gray(I)); 

%# extract blocks as column 
J = im2col(I, [BLOCK_SIZE BLOCK_SIZE], 'distinct'); %# 16-by-NumBlocks 

%# compute features for each block 
JJ = featureFunc(J)';        %'# NumBlocks-by-6 

%# cluster blocks according to the features extracted 
[clustIDX, ~, ~, Dist] = kmeans(JJ, NUM_CLUSTERS); 

%# display the cluster index assigned for each block as an image 
cc = reshape(clustIDX, ceil(size(I)/BLOCK_SIZE)); 
RGB = label2rgb(cc); 
imshow(RGB), hold on 

%# find and display the closest block to each cluster 
[~,idx] = min(Dist); 
[r c] = ind2sub(ceil(size(I)/BLOCK_SIZE), idx); 
for i=1:NUM_CLUSTERS 
    text(c(i)+2, r(i), num2str(i), 'fontsize',20) 
end 
plot(c, r, 'k.', 'markersize',30) 
legend('Centroids') 

clusters image

0

Центроиды не соответствуют координатам на изображении, а координаты в пространстве объектов. Существует два способа проверить, насколько хорошо выполняются kmeans. В обоих направлениях вы хотите, чтобы кулак связывал точки с их ближайшим кластером. Вы получаете эту информацию из первого выхода kmeans.

(1) Вы можете визуализировать результат кластеризации, уменьшив 6-мерное пространство до 2 или 3-мерного пространства, а затем построив по-разному классифицированные координаты в разных цветах.

Предполагая, что векторы функции собраны в массиве с именем featureArray, и что вы просили nClusters кластеров, вы могли бы сделать сюжет следующим использованием mdscale для преобразования данных, скажем, в 3D-пространстве:

%# kmeans clustering 
[idx,centroids6D] = kmeans(featureArray,nClusters); 
%# find the dissimilarity between features in the array for mdscale. 
%# Add the cluster centroids to the points, so that they get transformed by mdscale as well. 
%# I assume that you use Euclidean distance. 
dissimilarities = pdist([featureArray;centroids6D]); 
%# transform onto 3D space 
transformedCoords = mdscale(dissimilarities,3); 
%# create colormap with nClusters colors 
cmap = hsv(nClusters); 
%# loop to plot 
figure 
hold on, 
for c = 1:nClusters 
    %# plot the coordinates 
    currentIdx = find(idx==c); 
    plot3(transformedCoords(currentIdx,1),transformedCoords(currentIdx,2),... 
     transformedCoords(currentIdx,3),'.','Color',cmap(c,:)); 
    %# plot the cluster centroid with a black-edged square 
    plot3(transformedCoords(1:end-nClusters+c,1),transformedCoords(1:end-nClusters+c,2),... 
     transformedCoords(1:end-nClusters+c,3),'s','MarkerFaceColor',cmap(c,:),... 
     MarkerEdgeColor','k'); 
end 

(2) вы можете, в качестве альтернативы, создать псевдо-цветное изображение, которое показывает, какую часть изображения принадлежит к какому кластеру

Если предположить, что у вас есть nRows от nCols блоков, вы пишете

%# kmeans clustering 
[idx,centroids6D] = kmeans(featureArray,nClusters); 
%# create image 
img = reshape(idx,nRows,nCols); 
%# create colormap 
cmap = hsv(nClusters); 

%# show the image and color according to clusters 
figure 
imshow(img,[]) 
colormap(cmap)