K-means算法的理论网上一大堆,并且理论本身不难,所以直接跳过,注重实战。
首先导入包并且显示原图片:
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import MiniBatchKMeans
image=Image.open("./photo/PA261002.jpg")
m=np.asarray(image)
plt.figure(figsize=(18,24))
plt.imshow(m)
然后利用聚类算法K-means给这一堆像素设定一定数量的clusters,同属一个cluster聚类的像素就使用同一种颜色,从而实现色彩压缩的功能。
这里用到的是MiniBatchKmeans,相关参数详情可看MiniBatchKMeans
data=m/255.0 #把像素的范围变成0-1
data=data.reshape(-1,3)
kmeans=MiniBatchKMeans(16) #压缩成16种颜色
pred=kmeans.fit_predict(data)
new_colors=kmeans.cluster_centers_[pred]
pic_recolored=new_colors.reshape(m.shape)
plt.figure(figsize=(18,24))
plt.imshow(pic_recolored)
在fit_predict操作之后,所有的data都变成了压缩之后的颜色,即只有16种选择,pred表示的是对应的cluster编号(0-15号)
使用cluster_centers使得所有的色彩类别编号转换成对应的色彩像素(0-1)
然后reshape一下变成图片的格式(a,b,c)三维的
显示结果对比:
压缩前:
压缩后:
感觉像加了一层滤镜,如果把聚类的个数设的再少一点,图片颜色会越来越单调。比如4个clusters时就成这样了: