MATLAB: рисовать центроиды

Мой главный вопрос - это центроид функции, как я могу нарисовать его в MATLAB?

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

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


person Myx    schedule 15.04.2010    source источник


Ответы (2)


Вот один из способов визуализации кластеров:

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

Далее мы можем визуализировать кластеры, назначенные каждому блоку. Обратите внимание, что я предполагаю, что блоки 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

person Amro    schedule 16.04.2010

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

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

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

%# 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)
person Jonas    schedule 16.04.2010