Pergunta

Minha pergunta principal recebe um recurso Centroid, como posso desenhá -lo no Matlab?

Em mais detalhes, eu tenho um NxNx3 imagem (uma imagem RGB) da qual tomo 4x4 bloqueia e calcule um 6Vector de recurso dimensional para cada bloco. Eu guardo esses vetores de recursos em um Mx6 matriz em que eu corro kmeans funcionar e obter os centróides em um kx6 Matrix, onde k é o número de grupos e 6 é o número de recursos para cada bloco.

Como posso desenhar esses clusters centrais na minha imagem para visualizar se o algoritmo está executando a maneira como eu gostaria de realizar? Ou, se alguém tiver outra maneira/sugestão sobre como eu posso visualizar os centróides na minha imagem, eu agradeço muito.

Foi útil?

Solução

Aqui está uma maneira de visualizar os clusters:

Como você descreveu, primeiro extrai os blocos, calculo o vetor de recurso para cada um e cluster essa matriz.

Em seguida, podemos visualizar os clusters atribuídos a cada bloco. Observe que estou assumindo que os blocos 4x4 são distintos, isso é importante para que possamos mapear os blocos para o local deles de volta na imagem original.

Por fim, para exibir os centróides do cluster na imagem, simplesmente encontro o bloco mais próximo de cada cluster e exibi -lo como um representante desse cluster.

Aqui está um exemplo completo para mostrar a idéia acima (no seu caso, você deseja substituir a função que calcula os recursos de cada bloco por sua própria implementação; estou simplesmente tomando o min/max/média/mediana/q1/Q3 como Meu vetor de recurso para cada bloco 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

Outras dicas

Os centróides não correspondem às coordenadas na imagem, mas para coordenadas no espaço de recursos. Há duas maneiras pelas quais você pode testar o desempenho do Kmeans. Para os dois lados, você deseja associar os pontos ao seu cluster mais próximo. Você obtém essas informações da primeira saída de Kmeans.

(1) Você pode visualizar o resultado do cluster, reduzindo o espaço 6-dimensional para o espaço 2 ou tridimensional e, em seguida, plotando as coordenadas classificadas de maneira diferente em cores diferentes.

Supondo que os vetores de recurso sejam coletados em uma matriz chamada featureArray, e que você pediu nClusters Clusters, você faria o enredo o seguinte usando MDSCALE Para transformar os dados em, digamos, 3D Space:

%# 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) Você pode, alternativamente, criar uma imagem pseudo-cor que mostra qual parte da imagem pertence a qual cluster

Supondo que você tenha nRows por nCols Blocks, você escreve

%# 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)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top