通过k-means进行图像量化压缩--python实现
逻辑梳理
- 对于电脑来说,每种颜色都会有一个对应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~
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
19. 删除链表的倒数第N个节点
题目 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。示例:给定一个链表: 1->2->3->4->5, 和 n = 2.当删除了倒数第二个节点后,链表变为 1->2->3->5.说明:给定的 n 保证是有效的。进阶:你能尝试使用一趟扫描实现吗? 分析 链表的题目基本上都是优先考虑双指针。一个指针先走N步,然后两个指针同步移动到链表末尾,移除前一个指针所指着的节点即可。但是越简单的题目越要考虑边界条件,不要掉坑里面,具体看代码吧,争取一次Bugfree. Code /** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { ListNode right = head; ListN...
- 下一篇
linux一句话反弹shell
参考文献:https://www.anquanke.com/post/id/87017 实验环境: 阿里云服务器:120.xxx.xxx.xx(开启了8989端口) 内网ubuntu:192.xxx.xx.xxx(无外网ip不可直接访问) 安装netcat 默认的各个linux发行版本已经自带了netcat工具包,但是可能由于处于安全考虑原生版本的netcat带有可以直接发布与反弹本地shell的功能参数 -e这里都被阉割了,所以需要手动下载二进制安装包。 下载安装包: #wget https://nchc.dl.sourceforge.net/project/netcat/netcat/0.7.1/netcat-0.7.1.tar.gz --no-check-certifica 解压: #tar -xvzf netcat-0.7.1.tar.gz 编译安装: /netcat-0.7.1# ./configure /netcat-0.7.1# make /netcat-0.7.1# make install /netcat-0.7.1# make clean 1.使用bash命令反弹 ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS6,CentOS7官方镜像安装Oracle11G
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS8编译安装MySQL8.0.19
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- CentOS关闭SELinux安全模块