"K-Means" 主要目的係將一組資料,將之分為k類。其數學式如下 :


其演算流程 :

  1. 隨機給予K(K=2)個初始點(下圖標記為紅點):



     
  2. 與其他資料計算其距離(相關程度)




     
  3. 將資料與其相近的類別歸類,並求出該群資料的中心點



     
  4. 重複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);

}

 

若須詳細實作完整原始碼可以參考(連結)。

arrow
arrow
    文章標籤
    cluster ML
    全站熱搜

    Lung-Yu,Tsai 發表在 痞客邦 留言(0) 人氣()