Кластеризация 2D-графика в Mathematica - PullRequest
3 голосов
/ 04 сентября 2011
laListe={{{{10, 17}, 1}, {{33, 12}, 1}, {{32, 17}, 1}, {{9, 10},1}, 
         {{22, 24}, 1},{{27, 6}, 2}, {{25, 13}, 2}, {{30, 9}, 2}}, 
         {{{14, 12}, 1},{{19, 17}, 1}, {{7, 21}, 1}, {{7, 24},1}, 
         {{27, 19}, 1}, {{12, 16}, 2}, {{13, 20}, 2}, {{20, 22}, 2}}}

FrameXYs = {{4.32, 3.23}, {35.68, 26.75}}


Row[Function[compNo, 
             Graphics[{White, EdgeForm[Thick], 
             Rectangle @@ FrameXYs, 
             Black, 
             Disk[Sequence @@ laListe[[compNo, #]]] & /@ 
             Range[Length@laListe[[compNo]]]}, ImageSize -> 300]] /@ 
             {1, 2}]

enter image description here

Я хотел бы найти способ кластеризации этих дисков, учитывая их близость друг к другу. Есть ли в Mathematica встроенные функции для таких вещей?

РЕДАКТИРОВАТЬ

Пока я пытался найти FindClusters, я столкнулся с несколькими неудобствами:

С:

list1={{{24.413, 6.5978}, {7.68887, 7.2147}, {29.357, 13.2822}, 
       {6.22436, 9.7145}, {22.7162, 17.7198}, {13.6851, 5.7635}, 
       {18.8062, 12.9946}, {8.04889, 16.7414}}}

Действительно ли FindClusters отображает десятичные дроби:

FindClusters[Flatten[list1,1]]

Out:

  {{{{24.413, 6.5978}, {7.68887, 7.2147}, {29.357, 13.2822}, 
     {6.22436,9.7145}, {22.7162, 17.7198}, {13.6851, 5.7635}, 
     {18.8062,12.9946}, {8.04889, 16.7414}}}}

Принимая во внимание:

  FindClusters[Flatten[Round[list1], 1]]

Out:

   {{{24, 7}, {29, 13}, {23, 18}, {14, 6}, {19, 13}}, 
    {{8, 7}, {6, 10}, {8, 17}}}

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

Я пытаюсь "заострить" диски следующим образом:

pointize[{{x_,y_},r_},size_:12] :=
                                  Table[{x+r Cos[i ((2\[Pi])/size)],
                                  y+r Sin[i ((2\[Pi])/size)]},{i,0,size}]

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

Кроме того, я надеюсь, что это была проблема только с десятичными знаками, но я не мог использовать FindClusters [список] как таковой, но должен был указать количество кластеров, которое я хочу FindClusters [список, 3], тогда как я хочу иметь тот же алгоритм, который может найти разные номера кластеров на другой состав.

Не могли бы вы подумать о конкретных настройках и / или функции расстояния, чтобы сделать это с FindClusters?

EDIT

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

comp1 = Graphics[{White, Rectangle @@ FrameXYs, Black, 
     Disk[Sequence @@ laListe[[1, #]]] & /@ Range[Length@laListe[[1]]]},
     ImageSize -> 300]

enter image description here

     Binarize[ImageCorrelate[comp1, GaussianMatrix[40]], .95]

enter image description here

Ответы [ 2 ]

7 голосов
/ 04 сентября 2011

Да, FindClusters должен делать то, что вы хотите. Существует учебник . Возможно, вам придется сгладить данные, чтобы получить матрицу n х 3.

4 голосов
/ 06 сентября 2011

Кроме того, вы можете использовать что-то вроде:

Table[Colorize[
  MorphologicalComponents[Blur[ColorNegate@comp1, i], .05]], {i, 1, 60, 10}]

enter image description here

Вы также можете использовать Dilation, в зависимости от того, какие регионы вы хотите получить в результате

Table[Colorize@
  MorphologicalComponents@Dilation[ColorNegate@comp1, DiskMatrix@i], {i,1,60,10}]

enter image description here

Кстати, у вас есть способ использовать FindClusters, не очень эффективный и, вероятно, с неинтуитивными результатами:

ImageRotate[Rasterize[
  Show[
    ListPlot@
    FindClusters[Position[ImageData@Binarize@ColorNegate@comp1, 1, {2}], 3],
  Axes -> False, AspectRatio -> Automatic]], 3 Pi/2]

enter image description here

Редактировать

Возможно, вы сможете управлять параметрами FindClusters, чтобы получить лучшие результаты. Например:

ImageRotate[Rasterize[Show[
   ListPlot@
    FindClusters[
     Position[ImageData@Binarize@Rasterize[ColorNegate@comp1, RasterSize -> 200], 
     1, {2}], 
    3, Method -> {"Agglomerate", "Linkage" -> "Complete"}], 
   Axes -> False, AspectRatio -> Automatic]], 3 Pi/2]

enter image description here

И отсюда вы также можете перейти к выпуклой оболочке:

<< ComputationalGeometry`
fc = FindClusters[
       Position[
         ImageData@Binarize@
            Rasterize[ColorNegate@comp1, RasterSize -> 200], 
       1, {2}], 
     3, Method -> {"Agglomerate", "Linkage" -> "Complete"}];
ImageRotate[Graphics[Polygon@(#[[ConvexHull[#]]]) & /@ fc, Frame->True], 3 Pi/2]

enter image description here

...