SVD奇异值图像压缩
本帖最后由 yinda_peng 于 2024-8-9 11:11 编辑import numpy as np
from numpy import linalg as LA
from PIL import Image
import pylab as plt
plt.rc('font',size=13)
plt.rc('font',family='SimHei')
a = Image.open("C:/Users/Lenovo/Pictures/Camera Roll/魁拔.jpg") #打开图像
if a.mode != 'L':
a = a.convert("L")#转化为灰度图像
b = np.array(a).astype(float)
= LA.svd(b)
m,n=b.shape #如果不转换为灰度,这里可能会因为too many values报错
R = LA.matrix_rank(b)
plt.figure(0)
plt.plot(np.arange(1,len(d)+1),d,'k.')
plt.title('图像矩阵的奇异值')
CR = []
for K in range(1,int(R/4),50): #如果较多,自行调整步长大小
plt.figure(K)
plt.subplot(121)
plt.title('原图')
plt.imshow(b,cmap='gray')
I = p[:,:K+1]@(np.diag(d[:K+1]))@(q[:K+1,:])
plt.subplot(122)
plt.title("图像矩阵的秩="+str(K))
plt.imshow(I,cmap='gray')
src=m*n
compress=K*(m+n+1)
radio=(1-compress/src)*100 #计算压缩比率
CR.append(radio)
print("Rank=%d;K=%d个;radio=%5.2f"%(R,K,radio))
plt.figure()
plt.plot(range(1,int(R/4),50),CR,'ob-') #如果上面的步长调整,这里记得跟着改变
plt.title("奇异值个数与压缩比率的关系")
plt.xlabel("奇异值的个数")
plt.ylabel("压缩比率")
plt.show()
虽然这个代码看起来很严肃,但我们可以把它想成是给图像做了一个“减肥”计划!让我们一起看看如何利用奇异值分解(SVD)来压缩图像,并且确保保持它的魅力,类似于把一张图片压缩到只剩下精华!
首先,代码的主要步骤如下:
1. **打开并转换图像**:你用`PIL`库打开了一张图像,并将其转换为灰度图像。如果不这样处理,颜色就像在喝酒之后的表演,可能会很混乱哦。
2. **进行SVD分解**:这里的`LA.svd(b)`就像给你的图像找到了一个完美的分身,能够以更少的信息表达出来。`p`和`q`分别是左奇异向量和右奇异向量,`d`是奇异值,就像每个演员在舞台上展示自己的一样。
3. **绘制奇异值**:接下来,你使用`plt.plot`画出了奇异值,这就像在托尔金的史诗中角色们为了争夺权力而收集能力值的过程。在这个图中,奇异值越大,信息越多,反之则压缩得越多。
4. **图像压缩**:然后通过保留不同数量的奇异值来重构图像。这就像一个魔术师,让观众逐渐失去注意力,最终用较少的奇异值仍然让图像保持相对的清晰度。
5. **计算压缩比率**:最后,你计算了压缩比率并用图表展示了奇异值的数量与压缩比率的关系,帮大家直观了解保留多少个奇异值是最佳选择。
现在,看看代码中的一些问题和需要改进的地方:
- CR =# 注意这里的变量应先初始化,比如 `CR = []`
- radio=(1-compress/src)*100#一般情况下,应该处理除数为零的情况,以避免意外
- I = p@(np.diag(d))@(q)# 保证在合并维数时,`K`的设置要合理
总之,这段代码不仅能帮你压缩图像,还能在过程中学到一些线性代数的小知识。希望你的图像像减肥成功的人一样,焕发光彩!别忘了多做实验,寻找最佳的压缩效果哦!
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 代码很精简 不二如是 发表于 2024-8-9 13:04
代码很精简
用机器学习可以处理彩色{:10_329:} {:10_256:}{:10_256:} 领个鱼币{:10_256:} 谢谢分享 支持{:10_254:} 膜拜 {:10_254:} {:7_114:} 很cool的阳 发表于 2024-8-17 16:52
{:7_131:} OK orz币 看看{:10_254:} 为啥呢
页:
[1]