一:数学原理
K-Means算法的作者是MacQueen, 基本的数学原理很容易理解,假设有一个像素
数据集P。我们要根据值不同将它分为两个基本的数据集合Cluster1, Cluster2,使
用K-Means算法大致如下:
假设两个Cluster的RGB值分别为112,225,244和23,34,99则像素集合中的像素点
a(222,212,234), b(198,205,229), c(25,77,52),d(34,55,101)计算每个像素点与这
两个cluster中心点的欧几里德距离,则像素点a, b属于前面一个cluster, c,d属于
后面一个cluster。然后在根据(222+198)/2, (212+205)/2, (234+52)/2更新cluster
的RGB值,对后一个cluster做同样处理。然后再计算每个像素点到cluster中心点
的欧几里德距离。最终值没有变化则得到分类Cluster点集合。
二:算法基本流程
三:算法关键代码解析
初始化cluster中心点代码如下:
[java] view plaincopy
- Random random = new Random();
- for (int i = 0; i < numOfCluster; i++)
- {
- int randomNumber1 = random.nextInt(width);
- int randomNumber2 = random.nextInt(height);
- index = randomNumber2 * width + randomNumber1;
- ClusterCenter cc = new ClusterCenter(randomNumber1, randomNumber2, inPixels[index]);
- cc.setcIndex(i);
- clusterCenterList.add(cc);
- }
初始化所有像素点代码如下:
[java] view plaincopy
- // create all cluster point
- for (int row = 0; row < height; ++row)
- {
- for (int col = 0; col < width; ++col)
- {
- index = row * width + col;
- int color = inPixels[index];
- pointList.add(new ClusterPoint(row, col, color));
- }
- }
计算两个像素点之间欧几里德距离的代码如下:
[java] view plaincopy
- // int pa = (p.getPixelColor() >> 24) & 0xff;
- int pr = (p.getPixelColor() >> 16) & 0xff;
- int pg = (p.getPixelColor() >> 8) & 0xff;
- int pb = p.getPixelColor() & 0xff;
- // int ca = (c.getPixelColor() >> 24) & 0xff;
- int cr = (c.getPixelColor() >> 16) & 0xff;
- int cg = (c.getPixelColor() >> 8) & 0xff;
- int cb = c.getPixelColor() & 0xff;
- return Math.sqrt(Math.pow((pr - cr), 2.0) + Math.pow((pg - cg), 2.0) + Math.pow((pb - cb), 2.0));
; i<clusterCenterList.size(); i++)