加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

App基于手机壳颜色换肤?完全做不到吗?这不就“做”出来了!

发布时间:2020-12-17 01:03:04 所属栏目:Python 来源:网络整理
导读:程序员桌面必备杯垫.JPG KMeans 算法 k -平均算法 (英文: k -means clustering)源于信号处理中的一种向量量化方法,现在则更多地作为一种聚类分析方法流行于数据挖掘领域。 k -平均聚类的目的是:把 n 个点(可以是样本的一次观察或一个实例)划分到 k 个

程序员桌面必备杯垫.JPG

KMeans 算法

k -平均算法 (英文: k -means clustering)源于信号处理中的一种向量量化方法,现在则更多地作为一种聚类分析方法流行于数据挖掘领域。 k -平均聚类的目的是:把 n 个点(可以是样本的一次观察或一个实例)划分到 k 个聚类中,使得每个点都属于离他最近的均值(此即聚类中心)对应的聚类,以之作为聚类的标准。这个问题将归结为一个把数据空间划分为Voronoi cells的问题。

进群:548377875 ??即可获取数十套PDF哦!

算法实现

public?List?extract(ColorProcessor processor) {

// 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 colors =?new?ArrayList();

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读