MatLab: рисунок центроидами
-
27-09-2019 - |
Вопрос
Мой главный вопрос дан объект центроид, как я могу нарисовать его в MatLab?
Более подробно, у меня есть NxNx3
изображение (изображение RGB) из которых я беру 4x4
блокирует и вычислять 6
-Меновальный вектор функции для каждого блока. Хранив эти векторы функции в Mx6
Матрица, на которой я бегу kmeans
функция и получить центроиды в kx6
Матрица, где k
это количество кластеров и 6
Количество функций для каждого блока.
Как я могу нарисовать эти центральные кластеры в моем изображении, чтобы визуализировать, если алгоритм выполняет то, как я хочу, чтобы это выполнить? Или если у кого-то есть какие-либо другие способы / предложения о том, как я могу визуализировать центроиды на моем изображении, я бы очень ценю.
Решение
Вот так, как вы можете визуализировать кластеры:
Как вы описали, сначала я извлекаю блоки, вычисляйте вектор функции для каждого, а кластер это функции матрицы.
Далее мы можем визуализировать кластеры, назначенные каждому блок. Обратите внимание, что я предполагаю, что 4x4 блоки отличаются, это важно, чтобы мы могли сопоставить блоки к их расположению обратно в исходное изображение.
Наконец, для того, чтобы отобразить центроиды кластера на изображении, я просто нахожу ближайший блок к каждому кластеру и отобразить его как представителя этого кластера.
Вот полный пример, чтобы показать вышеуказанную идею (в вашем случае, вы захотите заменить функцию, которая вычисляет функции каждого блока по своей собственной реализации; я просто принимаю Min / Max / 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')
Другие советы
Центроиды не соответствуют координатам на изображении, а координаты в пространстве объектов. Есть два способа, которые вы можете проверить, насколько хорошо проведены KMANS. Для обоих способов вы хотите, чтобы кулак связывал очки со своим ближайшим кластером. Вы получаете эту информацию с первого выхода KMAIANS.
(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)