开发者社区> AwesomeTang> 正文

通过k-means进行图像量化压缩--python实现

简介: image.png 逻辑梳理 对于电脑来说,每种颜色都会有一个对应RGB值,比如黑色是[0,0,0],白色是[255,255,255],所以RGB模式下,最多可以区分16581375(255的三次方)种颜色。
+关注继续查看
img_74ca77185efb85af4d9c405d7bd22689.png
image.png

逻辑梳理

  • 对于电脑来说,每种颜色都会有一个对应RGB值,比如黑色是[0,0,0],白色是[255,255,255],所以RGB模式下,最多可以区分16581375(255的三次方)种颜色。
  • 另外我们知道,一张图片的大小与分辨率正相关,但其实也与图片颜色的复杂度是正相关的,相同分辨率的情况下,一张纯色图片是比一张五彩斑斓的图片要小的。
  • 一张分辨率为100*100的图片,其实就是由10000个RGB值组成。所以我们要做的就是对于这10000个RGB值聚类成K个簇,然后使用每个簇内的质心点来替换簇内所有的RGB值,这样在不改变分辨率的情况下使用的颜色减少了,图片大小也就会减小了。

内容

导入包

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.cluster import KMeans  #导入kmeans
from sklearn.utils import shuffle
import numpy as np
from skimage import io
import warnings

warnings.filterwarnings('ignore')

图片读取

original = mpl.image.imread('Yosemite 5.jpg') 
width,height,depth = original.shape
temp = original.reshape(width*height,depth)
temp = np.array(temp, dtype=np.float64) / 255

图像读取完我们获取到的其实是一个width*height的三维矩阵(width,height是图片的分辨率)

训练模型

original_sample = shuffle(temp, random_state=0)[:1000] #随机取1000个RGB值作为训练集
def cluster(k):
    estimator = KMeans(n_clusters=k,n_jobs=8,random_state=0)#构造聚类器
    kmeans = estimator.fit(original_sample)#聚类   
    return kmeans

我们只随机取了1000组RGB值作为训练,k表示聚类成 k个簇,对于本文就是K种颜色。

RGB值转化为图像

def recreate_image(codebook, labels, w, h):
    d = codebook.shape[1]
    image = np.zeros((w, h, d))
    label_idx = 0
    for i in range(w):
        for j in range(h):
            image[i][j] = codebook[labels[label_idx]]
            label_idx += 1
    return image

聚类

我们选取了32,64,128三个K值来做比较:

kmeans = cluster(32)
labels = kmeans.predict(temp)
kmeans_32 = recreate_image(kmeans.cluster_centers_, labels,width,height)
kmeans = cluster(64)
labels = kmeans.predict(temp)
kmeans_64 = recreate_image(kmeans.cluster_centers_, labels,width,height)
kmeans = cluster(128)
labels = kmeans.predict(temp)
kmeans_128 = recreate_image(kmeans.cluster_centers_, labels,width,height)

画图并保存

plt.figure(figsize = (15,10))
plt.subplot(2,2,1)
plt.axis('off')
plt.title('Original image')
plt.imshow(original.reshape(width,height,depth))
plt.subplot(2,2,2)
plt.axis('off')
plt.title('Quantized image (128 colors, K-Means)')
plt.imshow(kmeans_128)
io.imsave('kmeans_128.png',kmeans_128)
plt.subplot(2,2,3)
plt.axis('off')
plt.title('Quantized image (64 colors, K-Means)')
plt.imshow(kmeans_64)
io.imsave('kmeans_64.png',kmeans_64)
plt.subplot(2,2,4)
plt.axis('off')
plt.title('Quantized image (32 colors, K-Means)')
plt.imshow(kmeans_32)
io.imsave('kmeans_32.png',kmeans_32)
plt.show()

结果如下:


img_f76344cb0d562dd4dcf83acff3520698.png

差别还是比较明显的,随着颜色变少,图片也越来越马赛克了。


其实对于图片压缩这块,各大互联网公司投入人力优化,在保证图片清晰的情况下,减小文件大小,这样一能为公司节省一大笔带宽费用,二也能让用户更快的加载出图片,提升用户体验。
这篇文章也只是我在学k-means时候看到的一个案例,对于图片压缩只是很小的一部分,写这片文章的时候我也查了下相关的知识,真要下功夫研究,可是一门大学问。
最后:
peace~

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
手撸一款简单高效的线程池(一)
线程池大家应该都用过,不过如何从 0 到 1 的设计一款简单好用且性能较好的线程池?我们在接下来的几篇文章中,为您一一介绍。
4 0
python自动化办公之使用xlrd读取excel文件
python自动化办公之使用xlrd读取excel文件
5 0
神策杯 2018高校算法大师赛(个人、top2、top6)方案总结(上)
神策杯 2018高校算法大师赛(个人、top2、top6)方案总结(上)
5 0
神策杯 2018高校算法大师赛(个人、top2、top6)方案总结(下)
神策杯 2018高校算法大师赛(个人、top2、top6)方案总结(下)
5 0
文本点击率预估挑战赛-冠亚季军方案总结(上)
文本点击率预估挑战赛-冠亚季军方案总结(上)
4 0
变量、常量
变量、常量
4 0
微信小游戏推广运营专业术语汇总
本文内容包括与微信小游戏运营推广相关的专业术语的汇总和解释。作为一个游戏开发者,不光要知道如何做游戏,也要知道如何让别人玩自己做的游戏。
4 0
心中有“树”!图文并茂介绍数据结构中常见的树(三)
在前面两篇文章中,我们简要介绍了数据结构中的各种【树】在搜索、数据库等领域的使用场景,希望对大家有所帮助。
10 0
Travis CI简介
什么是持续集成? Travis CI 提供的是持续集成服务(Continuous Integration,简称 CI)。它绑定 Github 上面的项目,只要有新的代码,就会自动抓取。然后,提供一个运行环境,执行测试,完成构建,还能部署到服务器。
8 0
+关注
AwesomeTang
Done is better than perfect.
19
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
OceanBase 入门到实战教程
立即下载
阿里云图数据库GDB,加速开启“图智”未来.ppt
立即下载
实时数仓Hologres技术实战一本通2.0版(下)
立即下载