Prima le basi:
La segmentazione Mean Shift è una tecnica di omogeneizzazione locale che è molto utile per smorzare ombreggiature o differenze di tonalità negli oggetti localizzati. Un esempio è meglio di tante parole:
Azione: sostituisce ogni pixel con la media dei pixel in un quartiere range-r e il cui valore è entro una distanza d.
Il Mean Shift richiede solitamente 3 input:
- Una funzione di distanza per misurare le distanze tra i pixel. Di solito la distanza euclidea, ma può essere utilizzata qualsiasi altra funzione di distanza ben definita. La distanza di Manhattan a volte è un'altra scelta utile.
- Un raggio. Tutti i pixel all'interno di questo raggio (misurati in base alla distanza di cui sopra) verranno presi in considerazione per il calcolo.
- Una differenza di valore. Da tutti i pixel all'interno del raggio r, prenderemo solo quelli i cui valori rientrano in questa differenza per calcolare la media
Tieni presente che l'algoritmo non è ben definito ai bordi, quindi implementazioni diverse ti daranno risultati diversi lì.
NON discuterò qui i dettagli matematici cruenti, poiché sono impossibili da mostrare senza un'adeguata notazione matematica, non disponibile in StackOverflow, e anche perché possono essere trovati da buone fonti altrove .
Diamo un'occhiata al centro della tua matrice:
153 153 153 153
147 96 98 153
153 97 96 147
153 153 147 156
Con scelte ragionevoli per raggio e distanza, i quattro pixel centrali avranno il valore di 97 (la loro media) e saranno diversi dai pixel adiacenti.
Calcoliamolo in Mathematica . Invece di mostrare i numeri effettivi, visualizzeremo una codifica a colori, quindi è più facile capire cosa sta succedendo:
Il codice colore per la tua matrice è:
Quindi prendiamo un ragionevole spostamento medio:
MeanShiftFilter[a, 3, 3]
E otteniamo:
Dove tutti gli elementi centrali sono uguali (a 97, BTW).
Puoi iterare più volte con Mean Shift, cercando di ottenere una colorazione più omogenea. Dopo alcune iterazioni, si arriva a una configurazione stabile non isotropa:
A questo punto, dovrebbe essere chiaro che non è possibile selezionare quanti "colori" si ottengono dopo aver applicato Mean Shift. Quindi, mostriamo come farlo, perché questa è la seconda parte della tua domanda.
Ciò di cui hai bisogno per essere in grado di impostare in anticipo il numero di cluster di output è qualcosa come il clustering di Kmeans .
Funziona in questo modo per la tua matrice:
b = ClusteringComponents[a, 3]
{{1, 1, 1, 1, 1, 1, 1, 1},
{1, 2, 2, 3, 2, 3, 3, 1},
{1, 3, 3, 3, 3, 3, 3, 1},
{1, 3, 2, 1, 1, 3, 3, 1},
{1, 3, 3, 1, 1, 2, 3, 1},
{1, 3, 3, 2, 3, 3, 3, 1},
{1, 3, 3, 2, 2, 3, 3, 1},
{1, 1, 1, 1, 1, 1, 1, 1}}
O:
Il che è molto simile al nostro risultato precedente, ma come puoi vedere, ora abbiamo solo tre livelli di output.
HTH!