通过k-means进行图像量化压缩--python实现
时间:2022-06-10
本文章向大家介绍通过k-means进行图像量化压缩--python实现,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
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()
结果如下:
差别还是比较明显的,随着颜色变少,图片也越来越马赛克了。
其实对于图片压缩这块,各大互联网公司投入人力优化,在保证图片清晰的情况下,减小文件大小,这样一能为公司节省一大笔带宽费用,二也能让用户更快的加载出图片,提升用户体验。 这篇文章也只是我在学k-means时候看到的一个案例,对于图片压缩只是很小的一部分,写这片文章的时候我也查了下相关的知识,真要下功夫研究,可是一门大学问。 最后: peace~
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 让终端支持https,移植OpenSSL和libcurl到嵌入式linux,遇到的问题总结
- ComplexHeatmap|根据excel表绘制突变景观图(oncoplot)
- R-plotly|甘特图(Gantt chart)- 一不小心年中了,立个flag
- XXE漏洞那些事儿(JAVA)
- Hexo 建站过程
- Tidyverse|tidyr数据重塑之gather,spread(长数据宽数据转化)
- fastjson中的jndi注入
- R|生存分析-结果整理
- 实验吧-因缺思汀的绕过
- MySQL 用户与授权管理详解
- 基本知识|R语言简单饼图的绘制
- 分享一个有趣且牛逼的漏洞
- ggplot2-annotation|画图点“精”,让图自己“解释”
- 使用curl工具调试https接口
- 让android支持https访问银联后台,测试成功