k-means算法另类应用:压缩图片

不看广告,直接看“疗效”:

网络上下载的图片,图片中有大面积色块的还是有压缩空间:


保留原图片中64种颜色。压缩率:66%,也就是节省了1/3的存储空间

对于网络上色彩斑斓的图片。压缩率有可能不降反增。



其实很多网站的图片已经优化压缩了,能再压缩的空间很小。

自己拍摄的图片,即使保留更多的颜色也能获得较大压缩比:


压缩率:33%

原理:

  • 保留少数量的颜色,取代原图片中的N多颜色
  • 采用聚类方式得到新的颜色种类,用种类中心的颜色代表这个颜色种类
  • 用选出来的颜色重新对图片着色

代码在此:

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
import imageio

iname = "original.jpg"
cname = "compress_" + iname

#保留的颜色数量
n_colors = 64
img = imageio.imread(iname)


ax = plt.axes(xticks=[], yticks=[])
ax.imshow(img);


img.shape


data = img / 255.0 # 颜色从0-255转换为0-1之间的小数
data = data.reshape(-1, 3)
data.shape

#批量KMeans
from sklearn.cluster import MiniBatchKMeans
kmeans = MiniBatchKMeans(n_colors)
kmeans.fit(data)
new_colors = kmeans.cluster_centers_[kmeans.predict(data)]


#重新着色
new_img = new_colors.reshape(img.shape)
new_img = (255 * new_img).astype(np.uint8)

fig, ax = plt.subplots(1, 2, figsize=(16, 6),
                       subplot_kw=dict(xticks=[], yticks=[]))
fig.subplots_adjust(wspace=0.05)
ax[0].imshow(img)
ax[0].set_title('Original Image', size=16)
ax[1].imshow(new_img)
ax[1].set_title(str(n_colors)+'-color Image', size=16);
#保存压缩后的图片
imageio.imsave(cname,new_img)


# 计算压缩率

import os
from os.path import join, getsize

compress_ratio = getsize(cname) / getsize(iname)
compress_ratio

代码参考:
https://mybinder.org/v2/gh/jakevdp/PythonDataScienceHandbook/master?filepath=notebooks%2FIndex.ipynb

里面的In Depth: k-Means Clustering:

KevinZhang
Sep 20, 2018

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 摘要:对android 上图片压缩,其实总结起来基本可以分为两类压缩:尺寸压缩和质量压缩, 尺寸压缩其实也可以理解...
    男爵是只猫丶阅读 9,040评论 2赞 14
  • 三月,是温润的。 只是步履有些匆忙,稍有不留意,树梢上的叶子又不知什么时候哗啦哗啦长大...
    阿芬阿小郑阅读 274评论 0赞 0
  • 积极觉察表。 早起,低标准。阅读,低标准。锻炼:高标准。 今天跟朋友一起玩,从一开始就想着放松,所以并没有严格要求...
    再见你好_8260阅读 180评论 0赞 0
  • 关键词:基于数据元素值的查找、基于结点的查找 0. 查找的方式 基于数据元素值的查找GTreeNode<T>* f...
    编程半岛阅读 564评论 0赞 0

友情链接更多精彩内容