利用K-means进行图像压缩

前面几篇文章 浅谈支持向量机 神经网络——手写数字识别 中涉及的算法都属于监督学习的范畴,今天小编给大家介绍一种属于无监督学习范畴的算法——K-means。

K-means是一种应用很广泛的聚类算法。聚类,通俗的讲就是“人以群分物以类聚”。

K-means是怎么实现聚类的呢?下面我们以一个简单的样例来阐述它的工作原理。

观察上面的图,我们一般会认为这些数据点集中分布在三个区域,即这些数据点可以聚成三个族。K-means的工作过程是:首先随机挑选三个点作为中心点,然后计算所有的数据点离哪个中心点最近,再根据离中心点近的点更新中心点,循环多次直到中心点不怎么变化即可。

利用K-means聚类上面的数据,中心点更新过程如下。

好了,现在大致了解了K-means的作用和工作原理,下面就进入我们这次的主题——图像压缩。

上图是128*128的png图像,存储格式是RGB,所以这副图像占用的位数是128×128×24=393216。我们怎样利用K-means算法实现这副图像的压缩呢?

我的想法是:这副图像存在许多很大一块区域的颜色相近,既然相近,我们就用一种颜色替代一大块区域中的各色。我们可以人为的用8、16、24、32种颜色表示整幅图像的颜色,也即说明聚类的个数为8、16、24、32。

具体的Python代码如下。

import matplotlib.pyplot as plt # plt 用于显示图片
import matplotlib.image as mpimg # mpimg 用于读取图片
from sklearn.cluster import KMeans
import numpy as np

pixel = mpimg.imread('bird_small.png')
pixel = pixel.reshape((128*128 , 3))

kmeans = KMeans(n_clusters=16, random_state=0).fit(pixel)

newPixel = []
for i in kmeans.labels_:
    newPixel.append(list(kmeans.cluster_centers_[i,:]))

newPixel = np.array(newPixel)
newPixel = newPixel.reshape((128,128,3))

plt.imshow(newPixel)
plt.show()

如果用了16个类,则压缩之后的图像占用的位数为128×128×4 = 65536,压缩比为16.7%。但这种压缩是有损压缩,图像质量会下降,使用8、16、24、32压缩后效果图如下。

可以看到,图像的质量较原图是有所下降的,有点类似在原图上进行平滑处理,并且分类数越多,图片质量越接近原图,这个应该不难理解。

好了,以上就是本次的全部内容。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章