Java 对图片像素进行K-means聚类
聚类是机器学习中很重要的一部分,是一种无监督学习,本次选择K-means算法对图片的像素进行聚类
K-means,顾名思义,K-均值,首先随机地选择k个对象,每个对象初始地代表了一个簇的平均值或中心。对剩余的每个对象根据其与各个簇中心的距离,将它赋给最近的簇,然后重新计算每个簇的平均值。这个过程不断重复,直到每个簇的中心确定不变。
首先关注一下空间中每个点如何计算,普遍采用欧式距离,对于空间中两个点来说便是计算两个向量的欧式距离:
通过每次计算每个点与中心点的距离,来确定每次K个类的中心,然后不断迭代直到K个中心不再变化为止。
算法的优缺点还是比较多的,主要算法太经典太了,想知道更具体的请看Wiki上的解释把。
接下来是实验部分了,实验主要对图片的像素聚类:
对一张图片的像素点进行聚类,每个像素点是一个五维样本(x,y,r,g,b)进行聚类,其中x,y代表像素的位置,r,g,b分别代表个每个像素的图像特征RGB值。
算法步骤:
1随机初始K个初始点作为聚类中心
2对图像中每一个点计算与每个聚类中心的距离,选择距离最小的聚类中心作为相同的类
3对所有点一次聚类结束后,求其中心点作为新的聚类中心
4重复2-3过程直到聚类中心不再发生变化为止。
实验用Java语言实现,K从1-10,20,50,100,200,500,分别做了实验,
先来原图:(女神)
之后来聚类的图
先来1-9的:其中1-3效果比较差,从5-10效果就好多了:
从上面看到效果逐渐变化的过程,明显发现K从4开始效果就已经很明显了,而且迭代时间也很短,图片大小也比之前小了很多,为了好玩·~~,又聚了20,50,100,200
怎么样,女神已经很美丽了把~~~时间上呢,聚到50还是非常快的,100就比较慢了,200就不知道聚了多久了(期间去吃饭了)~效果上呢:也没太大差距了。
对于存储呢:文件大小比之前小了好多:
针对此次实验,还是有很多可以拓展的地方,比如图片压缩,例如20-means的效果已经很逼真的情况下,一个图片可以只存下20个图片像素和其他位置所属的类,即可大大减小存储空间,比如在web响应中,对于大图的显示速度,可以以小图代替,这样变在响应时间内给浏览者一个好的印象把~~~~