0%

基于SVD的图片分解

简介

本篇python基于numpy包实现SVD,因为有现成的API,所以直接调用即可。本代码实现对图片的奇异值分解效果展示

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
'''
用户手册-by clever_bobo
本函数用于测试奇异矩阵对图片进行分解,暂未设置任何纠错设置,请按照对应参数进行输入
'''
#读取文件,方块图像与风景图像
im_square=mpimg.imread(r"C:\Users\97751\Desktop\SVD\test1.png")
im_nature=mpimg.imread(r"C:\Users\97751\Desktop\SVD\test2.png")
#读取图片大小
s1,s2,s3=im_square.shape
n1,n2,n3=im_nature.shape
#转换格式
im_square_temp = im_square.reshape(s1,s2 * s3)
im_nature_temp = im_nature.reshape(n1, n2 * n3)
#调用numpy库中的线性函数的库
U1,S1,VT1=np.linalg.svd(im_square_temp)
U2,S2,VT2=np.linalg.svd(im_nature_temp)
#设置标志位
flag=0
while flag!=1:
#设置精度
nums=int(input("请输入保留的多少位奇异值:"))
#对方块图形进行SVD分解
img_square = (U1[:,0:nums]).dot(np.diag(S1[0:nums])).dot(VT1[0:nums,:])
img_square= img_square.reshape(s1, s2 , s3)
#对风景图形进行SVD分解
img_nature = (U2[:,0:nums]).dot(np.diag(S2[0:nums])).dot(VT2[0:nums,:])
img_nature= img_nature.reshape(n1, n2 , n3)
#精度分析
error1,error2=sum(S1[0:nums])/sum(S1)*10000//1*0.01,sum(S2[0:nums])/sum(S2)*10000//1*0.01
#画图部分
fig,ax=plt.subplots(2,2)
#原始方块输出
ax[0][0].imshow(im_square)
ax[0][0].set(title = "original square")
#SVD方块输出
ax[0][1].imshow(img_square)
ax[0][1].set(title = " SVD's square precision="+str(error1)+'%')
#原始山脉输出
ax[1][0].imshow(im_nature)
ax[1][0].set(title = "original nature")
#SVD山脉输出
ax[1][1].imshow(img_nature)
ax[1][1].set(title = " SVD's nature precision="+str(error2)+'%')
plt.show()
flag=int(input("是否结束SVD分解?是请输入1: "))
print("感谢使用测试——by clever_bobo!!!")

效果展示

保留1位奇异值:

保留5位奇异值:

保留10位奇异值:

保留50位奇异值:

保留100位奇异值:

保留的奇异值位数越多,保留的信息就越多

如果对您有用的话,这里可以打赏哦~