奇异值分解SVD真的能压缩图片吗?

一堆博客(下方推荐栏中)说奇异值分解(SVD)能用于图片压缩,判断方法无一例外都是肉眼观测,例如

2c2a75c80b2b4021bfa1ce4a7ae5551d.png

通过肉眼观察,奇异值个数越少,图片越模糊,因此SVD能够压缩图片。

emm……

判断能不能压缩图片,不看压缩后的图片文件大小,而是看图片的模糊程度??

问题:SVD能否压缩图片(文件大小)?

方法:

参考SVD Image Compression, Explained | dmicz devblog这篇博客,该博客的代码在GitHub - dmicz/devblognotebooks: Repository of notebooks featured on dmicz.github.io

将图片转化为灰度图并保存,作为原始图片,之后分别取前1个至350个奇异值重构图片,并将重构后的图片储存起来,读取储存后的图片文件大小,并画图。示例代码如下

# 保存原图
cv2.imwrite("origin_cat.png", image)
# SVD
U, S, Vt = np.linalg.svd(image, full_matrices=False)

pic_size = []
for n in range(1,351):
    # 重构图片
    reconstructed = np.matrix(U[:, :n]) * np.diag(S[:n]) * np.matrix(Vt[:n, :])
    #保存重构后的图片
    cv2.imwrite("reconstructed_cat.png", reconstructed)
    # 获取图片文件大小
    pic_size.append(os.stat("reconstructed_cat.png").st_size)

plt.plot(pic_size)
plt.xlabel("奇异值个数")
plt.ylabel("文件大小/B")
plt.axhline(os.stat("origin_cat.png").st_size,color='red', linestyle='dashed')

结果如下图所示,X轴为奇异值个数,Y轴为重构后的图片文件大小,红色虚线为原图文件大小,约57000B,即56KB。

b70fccbf8cb541d6b4a499e84f8b7316.png

可以看出,当奇异值个数小于40时,重构后的图片文件大小比原图更小,然而当奇异值个数在40至250之间时,重构后图片文件居然比原文件更大。之后随着奇异值个数的继续增加,重构后的图片才与原文件大小相同。

结论:

虽然直觉判断SVD能够压缩图片,并且奇异值个数越少,重构后图片越小;奇异值个数越多,重构后图片越大。

试验结果表明,SVD不一定能压缩图片

不一定奇异值个数越少,重构后图片越小,甚至重构后的图片可能比原图还大

( 之前看到过这样一种解释,和这篇博客差不多,对于一张400×400的图片,取K个奇异值,则U、S、V矩阵中分别有400×K、K、K×400个元素,总共801×K个。原图有400×400=160000个元素,只要

801×K ≤ 160000,即K ≤ 199,

就能实现压缩,当K > 199时,SVD的总元素个数多于原图,就无法实现压缩的目的。

但就算这样,801×K 是单调递增的线性函数,文件大小也应该越来越大,而不是先变大后变小。。

非常希望有人能说明该现象产生的原因,能给出证据就更好了;)

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值