机器学习之SVD奇异值

本文深入探讨了奇异值分解(SVD)在图像压缩中的应用,通过分解图像矩阵为三个矩阵,选择适当的K值进行矩阵压缩,实现了图像的高效存储与传输。文中详细介绍了SVD的原理与步骤,并通过实例展示了如何利用SVD进行图像压缩。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1 import numpy as np
  2 from PIL import Image
  3 
  4 
  5 x1 = np.arange(9).reshape((3,3))
  6 x2 = np.arange(10,19,1).reshape((3,3))
  7 
  8 y2 = np.stack((x1,x2),axis=1)
  9 # -*- coding: utf-8 -*-
 10 """
 11 arr = 
 12     [[0, 0, 0, 2, 2], 
 13      [0, 0, 0, 3, 3], 
 14      [0, 0, 0, 1, 1],
 15      [1, 1, 1, 0, 0], 
 16      [2, 2, 2, 0, 0], 
 17      [5, 5, 5, 0, 0], 
 18      [1, 1, 1, 0, 0]]
 19     
 20 u = 7 * 7
 21 sigma = 7 * 5, 只返回了对角元素, 其余0元素被省略
 22 V = 5 * 5
 23 """
 24 from PIL import Image
 25 import numpy as np
 26  
 27 import matplotlib as mpl
 28 import matplotlib.pyplot as plt
 29 arr = np.array([[0, 0, 0, 2, 2], [0, 0, 0, 3, 3], [0, 0, 0, 1, 1],
 30                 [1, 1, 1, 0, 0], [2, 2, 2, 0, 0], [5, 5, 5, 0, 0], [1, 1, 1, 0, 0]])
 31  
 32 # 1. 分解
 33 u, sigma, v = np.linalg.svd(arr)
 34  
 35 # 2. 重构
 36 new_arr = np.mat(u[:, 0:2]) * np.mat(np.diag(sigma[0:2])) * np.mat(v[0:2, :])
 37 
 38     
 39 def xprinf(x):
 40     #f = open("out.txt", "w")# 打开文件以便写入
 41     print("\n**************************\n")
 42     #np.set_printoptions(threshold = 1e6)#设置打印数量的阈值
 43     np.savetxt("result.txt", x)
 44     #f.close()
 45     print(x)
 46     print("\n**************************\n")
 47 
 48 def restore_1(u, sigma, v, k):
 49     new_arr = np.mat(u[:, 0:k]) * np.mat(np.diag(sigma[0:k])) * np.mat(v[0:k, :])
 50     new_arr[new_arr < 0] = 0
 51     new_arr[new_arr > 255] = 255   
 52     return  np.rint(new_arr).astype('uint8')
 53 
 54 def restore_x(u, sigma, v, k):
 55     return  np.array(restore_1(u, sigma, v, k))
 56    
 57 def restore_2(u, sigma, v, k):
 58     m = len(u)
 59     n = len(v)
 60     a = np.zeros((m, n))
 61     # 重构图像
 62     #a = np.dot(u[:, :k], np.diag(sigma[:k])).dot(v[:k, :])
 63     # 上述语句等价于:
 64     for i in range(k):
 65         ui = u[:, i].reshape(m, 1)
 66         vi = v[i].reshape(1, n)
 67         test= np.dot(ui, vi)
 68         a += sigma[i] * np.dot(ui, vi)
 69 
 70     a[a < 0] = 0
 71     a[a > 255] = 255
 72     return np.rint(a).astype('uint8')    
 73     
 74 A = Image.open('lu.jpg')
 75 a = np.array(A)  # 转换成矩阵
 76 
 77 #print(a.shape)
 78 #xprinf(a)
 79 
 80 def percentage2n(eigVals,percentage):
 81     sortArray=np.sort(eigVals)   #升序
 82     sortArray=sortArray[-1::-1]  #逆转,即降序
 83     arraySum=sum(sortArray)
 84     tmpSum=0
 85     num=0
 86     for i in sortArray:
 87         tmpSum+=i
 88         num+=1
 89         if tmpSum>=arraySum*percentage:
 90             return num
 91 
 92 u_r, sigma_r, v_r = np.linalg.svd(a[:, :, 0])
 93 u_g, sigma_g, v_g = np.linalg.svd(a[:, :, 1])
 94 u_b, sigma_b, v_b = np.linalg.svd(a[:, :, 2])
 95 
 96 
 97 k=percentage2n(sigma_r,0.8)
 98 
 99 
100 
101 R_1=restore_x(u_r, sigma_r, v_r,k)
102 G_1=restore_x(u_g, sigma_g, v_g,k)
103 B_1=restore_x(u_b, sigma_b, v_b,k)
104 
105 
106 I_1 = np.stack((R_1, G_1, B_1), axis=2)
107 
108 
109 
110 #plt.imshow(I_1)
111 #plt.show()
112 
113 Image.fromarray(I_1.astype(np.uint8)).save('new.jpg')
114 
115 
116 
117 
118 
119 
120 
121 
122 
123 
124 
125 
126 
127 
128 
129 
130 # plt.imshow(R)
131 
132 # plt.show()
133 # plt.imshow(G)
134 
135 # plt.show()
136 # plt.imshow(B)
137 # plt.show()
138 #I = np.stack((R, G, B), axis=2)
139 # plt.imshow(R)
140 # plt.show()
141 # new_arr = np.mat(u[:, 0:2]) * np.mat(np.diag(sigma[0:2])) * np.mat(v[0:2, :])
142 
143 # print(np.diag(sigma[0:2]))
144 # print("\n\n\n")
145 # print(sigma[0:2])
146 # print(np.stack((x1,x2),axis=0))
147 # print("\n\n----------------------------------\n\n")
148 
149 # print(np.stack((x1,x2),axis=1))
150 # print("\n\n----------------------------------\n\n")
151 
152 # print(np.stack((x1,x2),axis=2))
153 #print(np.arange(10,28,2).reshape((3,3)))

 

对称矩阵可以分解成 特征向量+特征值,根据特征值的比重,构造主成分矩阵。

对于一般的矩阵(不对称),就要使用奇异值分解了,不失一般性。

u_r, sigma_r, v_r = np.linalg.svd(a[:, :, 0])    一个矩阵可以分解成u_r, sigma_r, v_r 这三个矩阵,m*m , m*n, n*n 的矩阵。

选取K值,可以压缩矩阵 m*k , k*k, k*n。 与主成分分析类似

转载于:https://www.cnblogs.com/shawnc24/p/9951030.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值