2015-08-19 4 views
2

У меня вопрос простой, но очень интересный. Как вы знаете, Kmeans может давать разные результаты после каждого запуска из-за случайно начального центра кластера. Однако предположим, что я знаю, что кластер 1 имеет меньшее среднее значение, чем кластер 2, кластер 2 имеет меньшее среднее значение, чем кластер 3 и т. Д. Я хочу сделать алгоритм для реализации этого кластера с небольшим средним значением, тогда он будет назначен для небольшого индекса кластера.Сортировка меток сегментированного изображения в километрах на основе среднего кластера

Это мой код Matlab. Если у вас есть более или более четкий способ. Пожалуйста, предложите мне

%% K-mean 
num_cluster=2; 
nrows = size(Img_original,1); 
ncols = size(Img_original,2); 
I_1D = reshape(Img_original,nrows*ncols,1); 
[cluster_idx mu]=kmeans(double(I_1D),num_cluster,'distance','sqEuclidean','Replicates',3); 
cluster_label = reshape(cluster_idx,nrows,ncols); 
%% Sort based on mu 
[mu_sort id_sort]=sort(mu); 
idx=cell(1,num_cluster) 
%% Save index of order if mu 
for i=1:num_cluster 
    idx{i}=find(cluster_label==id_sort(i)); 
end 
%% Sort cluster label based on mu 
for i=1:num_cluster 
    cluster_label(idx{i})=i; 
end 
+0

Я не понимаю. Во-первых, что такое «среднее значение» кластера? Поскольку k-средство, как правило, работает в многомерных пространствах, оно кажется мне непонятным. Тогда, каков ваш вопрос? – Ratbert

+0

Среднее значение означает среднее значение этого кластера. В математике оно обозначается mu. Мой вопрос заключается в том, как сделать вывод kmeans, подверженного малой кластерной метке, для кластера с малым средним значением – user3051460

+0

ОК, вы говорите о центроиде кластера, а не о (неопределенном) «среднем значении». Поскольку ваши начальные векторы находятся в 2D, их невозможно сравнивать, как «x больше y», и поэтому вы не можете сравнивать их с «sort». Я думаю, что нет надежды на то, что вы пытаетесь сделать. – Ratbert

ответ

1

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

Тем не менее, первоначальная идея, что вам пришлось сортировать центроиды, является хорошей. Последняя часть вашего кода кажется довольно неэффективной, потому что вы перебираете каждую метку и выполняете переназначение. Одна вещь, которую я мог бы предложить, - это иметь таблицу поиска, в которой ввод является исходной меткой, а вывод - переупорядоченные метки на основе отсортированных центроидов.

Если вы хотите продолжить этот маршрут, вы можете использовать containers.Map, где ключи являются метками, указанными в порядке сортировки, которые выводятся из sort, а значения являются переупорядоченными метками ... а именно, вектор, который идет от 1 до нескольких классов, которые у вас есть. Вам нужно сделать это, потому что второй вывод sort сообщает вам, где каждое значение в исходном массиве будет отображаться в отсортированном результате, поэтому вы должны использовать этот порядок, чтобы правильно выполнять перемаркировку. Кроме того, я бы использовал функцию sortrows в MATLAB, а не raw sort. Как вы это делаете, вы сортируете каждый столбец самостоятельно и это даст неправильные центроиды. Это будет работать для изображений в оттенках серого, где у вас будет только одна особенность, а именно оттенки серого, но если вы выходите за рамки серого и, возможно, заходите в RGB или в любое другое цветовое пространство, которое вам нужно, использование raw sort даст неверные результаты. Вы должны рассматривать каждую строку как одну точку, а затем сортировать строки совместно.

Учитывая код, вы могли бы сделать что-то вроде этого:

%% K-mean 
num_cluster=2; 
nrows = size(Img_original,1); 
ncols = size(Img_original,2); 
I_1D = reshape(Img_original,nrows*ncols,1); 
[cluster_idx mu]=kmeans(double(I_1D),num_cluster,'distance','sqEuclidean','Replicates',3); 

%% Sort based on mu 
[mu_sort id_sort]=sortrows(mu); 

%// New - Create lookup 
lookup = containers.Map(id_sort, 1:size(mu_sort,1)); 

%// Relabel the vector 
cluster_idx_sort = lookup.values(num2cell(cluster_idx)); 
cluster_idx_sort = [cluster_idx_sort{:}]; 

%// Reshape back to original image dimensions 
cluster_label = reshape(cluster_idx_sort,nrows,ncols); 

Это следует надеяться дать вам некоторое ускорение в вашем коде.


Для двойной проверки, я попробовал это на cameraman.tif изображения, что часть обработки изображения инструментов. Выполнение кода дает мне эти кластерные центры:

>> mu 

mu = 

    153.3484 
    23.7291 

После того, как сортировать кластеры в порядке возрастания, это то, что я получаю за упорядочением и центроиды:

>> mu_sort 

mu_sort = 

    23.7291 
    153.3484 

>> id_sort 

id_sort = 

    2 
    1 

Так что работает, как мы ожидается ... теперь, если мы покажем исходную карту меток кластера перед сортировкой по центроидам с:

...мы получаем это изображение:

enter image description here

Теперь, если мы запустим через сортировочную логику и отображать центроиды:

imshow(cluster_label, []); 

... мы получаем это изображение:

enter image description here

Это работает так, как я ожидал. Потому что центроиды перевернуты, так же как и окраска.

+0

@rayeyeng: Спасибо. Но я запускаю ваш код выше, и он дает разные результаты для каждого запуска теста. Не могли бы вы это увидеть в моем обновленном вопросе. Я удалю его позже – user3051460

+0

@ user3051460 - Я посмотрю. – rayryeng

+0

@ user3051460 - Ах, я что-то перевернул. Позвольте мне исправить это. – rayryeng

Смежные вопросы