有些数字图像的数据量是非常大的,这无疑对图像的存储、处理和传送带来很大的困难,所以要用到图像压缩。在这里用K-Means算法实现了一个简单的图像压缩。
K-Means原理
1 随机选取k个中心点(把数据分成n类)
2 遍历所有数据,将每个数据划分到最近的中心点(质心)
3 计算每个聚类的平均值,并作为新的质心
4 重复多次,直到这k个中线点不再变化(收敛了),或执行了足够多的迭代。
代码
我选取了一张猴子的图进行压缩
from skimage import io
from sklearn.cluster import KMeans
import numpy as np
image=io.imread('C:/Users/18256/Desktop/monkey.jpg')#读入图片
io.imshow(image)
io.show() #展示图片
rows=image.shape[0] #行数
cols=image.shape[1] #列数,两者相乘就是像素点个数
image=image.reshape(image.shape[0]*image.shape[1],3)#将像素点中R G B值拿出来,组成像素点数量image.shape[0]*image.shape[1]和颜色深度二维数组
kmeans=KMeans(n_clusters=128,n_init=10,max_iter=200)#像素点取值范围为0-255,这里压缩成0-128
kmeans.fit(image) #如果图片像素点比较多的话,跑的时间会有点长
clusters=np.asarray(kmeans.cluster_centers_,dtype=np.uint8)#kmeans.cluster_centers_为聚类后的结果,即在R G B上的值等于多少
labels=np.asarray(kmeans.labels_,dtype=np.uint8)
labels=labels.reshape(rows,cols) #利用压缩后的像素点组成一张灰度图
np.save('存储路径/test.txt',clusters)#保存像素点数据
io.imsave('存储路径/test.jpg',labels)#保存压缩后的图像
image=io.imread(路径/test.jpg')
io.imshow(image)
io.show()
效果如下:
变化还是挺大的,有点面目全非了,但是还是隐隐约约可以看出来这是个猴子……但是这样一来,图片的大小就变小了。