程序员桌面必备杯垫.JPG
KMeans 算法
k -平均算法 (英文: k -means clustering)源于信号处理中的一种向量量化方法,现在则更多地作为一种聚类分析方法流行于数据挖掘领域。 k -平均聚类的目的是:把 n 个点(可以是样本的一次观察或一个实例)划分到 k 个聚类中,使得每个点都属于离他最近的均值(此即聚类中心)对应的聚类,以之作为聚类的标准。这个问题将归结为一个把数据空间划分为Voronoi cells的问题。
进群:548377875 即可获取数十套pdf哦!
算法实现
public List
// initialization the pixel data
int wIDth = processor.getWIDth();
int height = processor.getHeight();
byte[] R = processor.getRed();
byte[] G = processor.getGreen();
byte[] B = processor.getBlue();
//Create random points to use a the cluster center
Random random = new Random();
int index = 0;
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,R[index]&0xff,G[index]&0xff,B[index]&0xff);
cc.cIndex = i;
clusterCenterList.add(cc);
}
// create all cluster point
for (int row = 0; row < height; ++row)
{
for (int col = 0; col < wIDth; ++col)
{
index = row * wIDth + col;
pointList.add(new ClusterPoint(row,col,B[index]&0xff));
}
}
// initialize the clusters for each point
double[] clusterdisValues = new double[clusterCenterList.size()];
for(int i=0; i { for(int j=0; j { clusterdisValues[j] = calculateEuclIDeandistance(pointList.get(i),clusterCenterList.get(j)); } pointList.get(i).clusterIndex = (getCloserCluster(clusterdisValues)); } // calculate the old summary // assign the points to cluster center // calculate the new cluster center // computation the delta value // stop condition-- double[][] oldClusterCentercolors = reCalculateClusterCenters(); int times = 10; while(true) { stepClusters(); double[][] newClusterCentercolors = reCalculateClusterCenters(); if(isstop(oldClusterCentercolors,newClusterCentercolors)) { break; } else { oldClusterCentercolors = newClusterCentercolors; } if(times > 10) { break; } times++; } //update the result image List for(ClusterCenter cc : clusterCenterList) { colors.add(cc.color); } return colors; } private boolean isstop(double[][] oldClusterCentercolors, double[][] newClusterCentercolors) { boolean stop = false; for (int i = 0; i < oldClusterCentercolors.length; i++) { if (oldClusterCentercolors[i][0] == newClusterCentercolors[i][0] && oldClusterCentercolors[i][1] == newClusterCentercolors[i][1] && oldClusterCentercolors[i][2] == newClusterCentercolors[i][2]) { stop = true; break; } } return stop; } /** * update the cluster index by distance value */ private voID stepClusters() { // initialize the clusters for each point double[] clusterdisValues = new double[clusterCenterList.size()]; for(int i=0; i { for(int j=0; j { clusterdisValues[j] = calculateEuclIDeandistance(pointList.get(i),clusterCenterList.get(j)); } pointList.get(i).clusterIndex = (getCloserCluster(clusterdisValues)); } } /** * using cluster color of each point to update cluster center color * * @return */ private double[][] reCalculateClusterCenters() { // clear the points Now for(int i=0; i { clusterCenterList.get(i).numOfPoints = 0; } // recalculate the sum and total of points for each cluster double[] redSums = new double[numOfCluster]; double[] greenSum = new double[numOfCluster]; double[] blueSum = new double[numOfCluster]; for(int i=0; i { int cIndex = (int)pointList.get(i).clusterIndex; clusterCenterList.get(cIndex).numOfPoints++; int tr = pointList.get(i).pixelcolor.red; int tg = pointList.get(i).pixelcolor.green; int tb = pointList.get(i).pixelcolor.blue; redSums[cIndex] += tr; greenSum[cIndex] += tg; blueSum[cIndex] += tb; } double[][] oldClusterCenterscolors = new double[clusterCenterList.size()][3]; for(int i=0; i { double sum = clusterCenterList.get(i).numOfPoints; int cIndex = clusterCenterList.get(i).cIndex; int red = (int)(greenSum[cIndex]/sum); int green = (int)(greenSum[cIndex]/sum); int blue = (int)(blueSum[cIndex]/sum); clusterCenterList.get(i).color = new Scalar(red,green,blue); oldClusterCenterscolors[i][0] = red; oldClusterCenterscolors[i][0] = green; oldClusterCenterscolors[i][0] = blue; } return oldClusterCenterscolors; } /** * * @param clusterdisValues * @return */ private double getCloserCluster(double[] clusterdisValues) { double min = clusterdisValues[0]; int clusterIndex = 0; for(int i=0; i { if(min > clusterdisValues[i]) { min = clusterdisValues[i]; clusterIndex = i; } } return clusterIndex; } /** * * @param p * @param c * @return distance value */ private double calculateEuclIDeandistance(ClusterPoint p,ClusterCenter c) { int pr = p.pixelcolor.red; int pg = p.pixelcolor.green; int pb = p.pixelcolor.blue; int cr = c.color.red; int cg = c.color.green; int cb = c.color.blue; return Math.sqrt(Math.pow((pr - cr),2.0) + Math.pow((pg - cg),2.0) + Math.pow((pb - cb),2.0)); } 在 AndroID 中使用该算法来提取主色: demo1.png 以上是内存溢出为你收集整理的App基于手机壳颜色换肤?完全做不到吗?这不就“做”出来了!全部内容,希望文章能够帮你解决App基于手机壳颜色换肤?完全做不到吗?这不就“做”出来了!所遇到的程序开发问题。 如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。 欢迎分享,转载请注明来源:内存溢出
评论列表(0条)