"K-Means" 主要目的係將一組資料,將之分為k類。其數學式如下 :
其演算流程 :
- 隨機給予K(K=2)個初始點(下圖標記為紅點):
- 與其他資料計算其距離(相關程度)
- 將資料與其相近的類別歸類,並求出該群資料的中心點
- 重複2~3步驟,直到中止條件達成
- 中心點無修正
- 迭代次數已滿 (itrs>終止條件)
本實驗針對影像進行"K-Means" (K=3,Iterat=30)成果如下圖所示。
由此可發現影像被分為三個類別,其中景物與背景被有效的分割開來。
由於k-mean的收斂結果會受初始點的影響,因此本案透過以下算法將初始點平均分配於各個像數值之間。
private static byte[,] initializeK(int k)
{
byte[,] ks = new byte[k, 3];
for (int i = 0; i < k; i++)
{
ks[i, 0] = (byte)((255 / k) * i);
ks[i, 1] = (byte)((255 / k) * i);
ks[i, 2] = (byte)((255 / k) * i);
}
return ks;
}
將初始化的k以及影像矩正進行k-mean演算法的跌代,最終結果即為切割好之影像。
private static void k_means(int level, int width, int height, int k, ref byte[, ,] martix, ref byte[,] kv)
{
bool IsQuit = false;
int size = kv.Length;
int[] nkv = new int[size];
int levelCount = 0;
do
{
//把圖點進行分類
pixelClassify(k, height, width, ref kv, ref martix);
//各類統計
List<ColorRGBModel>[] cols;
KAddUp(k, width, height, martix, out cols);
//產生新平均值
newMean(k, kv, cols, ref IsQuit);
levelCount++;
} while (!IsQuit && levelCount < level);
}
若須詳細實作完整原始碼可以參考(連結)。
文章標籤
全站熱搜
留言列表