无监督の图像压缩(SVD与K-means)

Tatsumi这次带大家玩玩无监督,无监督方法更多的使用场景还是在数据分析挖掘的预处理或异常点检测中,但Tatsumi觉得通过图像处理来展示无监督的威力能更好地达到可视化的效果,因此这里选了图像压缩的小案例。

无监督在数据科学领域用的比较多的算法有聚类(如kmeans)、PCA还有SVD。由于图像的特点,通常可以将图像转化为一个行数和列数不相等的大矩阵,因此在会有聚类与SVD的应用(本文将用这两种方法实现图片的压缩的简单小案例),而PCA主要用于数据处理领域上字段或属性上的降维

首相讲的是SVD,SVD简单地来说就是矩阵分解,(专业点的名词就是求解奇异矩阵),如下图

一般来说一个矩阵A总是可以分解成三个小矩阵,其中左右两个的矩阵U和V是两个小方阵(里面的向量都是正交的),中间的E为一个对角阵(对角阵中只有对角线上的元素是非0的,并且对角线中的元素是从大到小排列的,通常把对角线上的元素成为奇异值)

在很多情况下,前10%甚至1%的奇异值的和就占了全部的奇异值之和的99%以上了,因此可以近似地分解成下图的形式

r是一个远小于m、n的数,这样矩阵的乘法看起来像是上面的样子:右边的三个矩阵相乘的结果将会是一个接近于A的矩阵,r越接近于n,则相乘的结果越接近于A。而这三个矩阵的面积之和(在存储观点来说,矩阵面积越小,存储量就越小)要远远小于原始的矩阵A,我们如果想要压缩空间来表示原矩阵A,我们存下这里的三个矩阵:U、E、V就好了。

Tatsumi这里使用SVD的方法对学友图像进行压缩,并且比较前r个奇异值,观察奇异值个数对压缩效果的影响

先上原图(帅帅的学友哥)

#由于图像是彩色,有rgb三原色的三个通道(可以看成有三层两维的矩阵堆叠而成)
#分别抽取图像中的三层矩阵并分别进行SVD分解
u_r, sigma_r, v_r = np.linalg.svd(a[:, :, 0])
u_g, sigma_g, v_g = np.linalg.svd(a[:, :, 1])
u_b, sigma_b, v_b = np.linalg.svd(a[:, :, 2])

#对三个已奇异分解的三原色矩阵重新进行堆积并恢复成图片形式(r为保存的奇异值数目)
R = restore1(sigma_r, u_r, v_r, r)
G = restore1(sigma_g, u_g, v_g, r)
B = restore1(sigma_b, u_b, v_b, r)
I = np.stack((R, G, B), 2)
Image.fromarray(I).save('%s\\svd_%d.png' % (output_path, r))

展示保存r个奇异值的图像效果

从图中可以看到当奇异值在30个以下时,图片还是有模糊的部分,当随着奇异值数目的增多,图片的清晰程度也越高,基本上有30个奇异值时,在人眼的视觉能力中已经能基本能达到原图的效果,这样子根据我们的需求就能一定程度地对图像进行压缩,对矩阵进行压缩能大大地减少图片的大小,并且在我们对图像进行分析时计算机内存运算负担也会减少,能更加高效地进行迭代训练。

Kmeans聚类应该是最常见也是最简单的一种聚类方法了

  •  
  •  
image2 = image.reshape(image.shape[0] * image.shape[1], 3)                  # 把图片拉直(每条记录相当图像上一个点,有个变量代表三原色)
kmeans = KMeans(n_clusters=k, n_init=10, max_iter=200)                  # 使用kmeans方法聚类(n_clusters为簇数目)
kmeans.fit(image2)

clusters = np.asarray(kmeans.cluster_centers_, dtype=np.uint8)           # 获取所得簇的中心点
labels = np.asarray(kmeans.labels_, dtype=np.uint8)                      # 获取每条记录即(图上每个点)的类标签
labels = labels.reshape(rows, cols)                                      # 把矩阵还原成原来大小

for i in range(labels.shape[0]):                                         # 用聚类后类标签所代表的数值替换原有的数值
        for j in range(labels.shape[1]):                                     # 画图展示
            image[i, j, :] = clusters[labels[i, j], :]

下图是使用kmeans方法选取不同的簇数目,颜色量化的效果图

从图中可以看到簇数目较少时颜色种类较少,随着簇数目的增多,颜色种类也更加丰富,表现得更接近原图。

项目心得:

通过实战无监督图像压缩的小例子,可以很好的感受到数据挖掘的算法不只能应用到传统的结构化数据中,像是图像文本处理等领域其实也还是能有很好的适用性。在无监督的算法中,比较核心的数学理论(距离,方差,熵)等等,都是要根据不同的情景进行选择和使用,加上无监督没有标准答案进行检验,因此实际需求中的业务解释会显得非常非常非常重要。

Github数据代码 链接 

转载于:https://my.oschina.net/wtatsumi/blog/1924702

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值