W innym miejscu tego wątku użytkownik1149913 zapewnia świetne porady (definiuje model probabilistyczny) i koduje potężne podejście (szacowanie EM). Do rozwiązania pozostają dwie kwestie:
Jak radzić sobie z odstępstwami od modelu probabilistycznego (które są bardzo widoczne w danych z lat 2011–2012 i nieco widoczne w falowaniu punktów o mniejszym nachyleniu).
Jak zidentyfikować dobre wartości początkowe dla algorytmu EM (lub dowolnego innego algorytmu).
Aby rozwiązać problem nr 2, rozważ użycie transformacji Hougha . Jest to algorytm wykrywania cech, który w celu znalezienia liniowych ciągów cech może być skutecznie obliczony jako transformacja Radona .
xyx,yw transformacji Hougha. Kiedy elementy na oryginalnym wykresie spadają wzdłuż wspólnej linii lub blisko niej, wówczas zbiory krzywych, które tworzą w transformacie Hougha, zwykle mają wspólne przecięcie odpowiadające tej wspólnej linii. Znajdując te punkty o największej intensywności w transformacji Hougha, możemy odczytać dobre rozwiązania pierwotnego problemu.
Aby zacząć od tych danych, najpierw wyciąłem elementy pomocnicze (osie, znaczniki i etykiety) i dla pewności wyciąłem oczywiście odległe punkty w prawym dolnym rogu i posypałem wzdłuż dolnej osi. (Gdy te elementy nie są wykadrowane, procedura nadal działa dobrze, ale wykrywa również osie, ramki, liniowe sekwencje kleszczy, liniowe sekwencje etykiet, a nawet punkty leżące sporadycznie na dolnej osi!)
img = Import["http://i.stack.imgur.com/SkEm3.png"]
i = ColorNegate[Binarize[img]]
crop2 = ImageCrop[ImageCrop[i, {694, 531}, {Left, Bottom}], {565, 467}, {Right, Top}]
(To i reszta kodu są w Mathematica .)
Każdej kropce na tym zdjęciu odpowiada wąski zakres krzywych w transformacji Hougha, widoczny tutaj. Są to fale sinusoidalne:
hough2 = Radon[crop2, Method -> "Hough"] // ImageAdjust
To sprawia, że wizualnie uwidacznia się sens, w którym pytanie jest problemem klastrowania linii : transformacja Hougha redukuje go do problemu klastrowania punktowego , do którego możemy zastosować dowolną metodę grupowania.
W tym przypadku grupowanie jest tak jasne, że wystarczy proste przetwarzanie końcowe transformacji Hougha. Aby zidentyfikować lokalizacje o największej intensywności w transformacji, zwiększyłem kontrast i rozmazałem transformację w promieniu około 1%: jest to porównywalne ze średnicą punktów wykresu na oryginalnym obrazie.
blur = ImageAdjust[Blur[ImageAdjust[hough2, {1, 0}], 8]]
Próg wyniku zawęził go do dwóch drobnych plamek, których centroidy racjonalnie identyfikują punkty o największej intensywności: szacują dopasowane linie.
comp = MorphologicalComponents[blur, 0.777]) // Colorize
0.777
Lewa strona obrazu odpowiada kierunkowi 0 stopni (poziomo) i, gdy patrzymy od lewej do prawej, kąt ten wzrasta liniowo do 180 stopni. Interpolując, obliczam, że dwie plamy są wyśrodkowane odpowiednio w 19 i 57,1 stopniach. Możemy również odczytać przecięcia z pozycji pionowych obiektów blob. Ta informacja daje początkowe pasowania:
width = ImageDimensions[blur][[1]];
slopes = Module[{x, y, z}, ComponentMeasurements[comp, "Centroid"] /.
Rule[x_, {y_, z_}] :> Round[((y - 1/2)/(width - 1)) 180., 0.1]
]
{19., 57.1}
W podobny sposób można obliczyć przecięcia odpowiadające tym zboczom, dając następujące pasowania:
(Czerwona linia odpowiada małej różowej kropce na poprzednim zdjęciu, a niebieska linia odpowiada większej kropli wody).
W dużym stopniu podejście to automatycznie rozwiązało pierwszy problem: odchylenia od liniowości rozmazują punkty o największej intensywności, ale zazwyczaj nie zmieniają ich znacznie. Szczerze mówiąc, odległe punkty przyczynią się do niskiego poziomu hałasu podczas transformacji Hougha, który zniknie podczas procedur przetwarzania końcowego.
W tym momencie można podać te szacunki jako wartości początkowe dla algorytmu EM lub minimalizatora prawdopodobieństwa (który przy dobrych oszacowaniach szybko się zbiegnie). Lepiej byłoby jednak użyć solidnego estymatora regresji, takiego jak iteracyjnie przeważone najmniejsze kwadraty . Jest w stanie zapewnić wagę regresji do każdego punktu. Niskie ciężary wskazują, że punkt nie „należy” do linii. W razie potrzeby wykorzystaj te ciężary, aby przypisać każdy punkt do właściwej linii. Następnie, po sklasyfikowaniu punktów, możesz użyć zwykłych najmniejszych kwadratów (lub dowolnej innej procedury regresji) osobno na dwóch grupach punktów.