Python—SVD分解压缩图片

奇异值分解压缩图片

对任意的 A ∈ C r m × n 有 S V D 分解, A = U ( Σ O O O ) V H 其中 U , V 为酉矩阵, U = ( u 1 , . . , u m ) ∈ C m m × m V H = ( v 1 T . . v n T ) ∈ C n n × n Σ = d i a g ( σ 1 , . . , σ r ) , σ i 为 A 的奇异值 , i = 1 , . . , r 且 σ 1 ≥ σ 2 ≥ . . . ≥ σ r > 0 于是, A = σ 1 u 1 v 1 T + σ 2 u 2 v 2 T + . . . . + σ r u r v r T , 可以看到,奇异值 σ i 越小, σ i u i v i T 对 A 的贡献越小。 即只要保留较大 σ i 和对应的 u i , v i T ,就可以保留 A 的主要特征。 即保留前 k 个 σ i , ( k ≤ r ) , 用 B = σ 1 u 1 v 1 T + . . . + σ k u k v k T 来近似 A 压缩比 = m n ( m + n + 1 ) k , m n 为 A 的大小 , ( m + n + 1 ) k 为 B 的大小 ( n u m p y 带有 S V D 分解的函数,即求出 U , Σ , V H , 压缩图片就变得很简单了) 对任意的A\in C^{m \times n}_r\quad 有 SVD分解,\\ A=U \begin{pmatrix} \Sigma & O \\ O & O \end{pmatrix} V^H \\其中U,V为酉矩阵,U=(u_1,..,u_m) \in C^{m \times m}_m \quad V^H= \begin{pmatrix} v_1^T\\ .\\ .\\ v_nT \end{pmatrix}\in C^{n \times n}_n \\ \Sigma=diag(\sigma_1,..,\sigma_r),\sigma_i为A的奇异值,i=1,..,r \\且\sigma_1\ge\sigma_2\ge...\ge \sigma_r>0 \\ \\\quad \\ 于是,A=\sigma_1u_1v_1^T+\sigma_2u_2v_2^T+....+\sigma_ru_rv_r^T , \\可以看到,奇异值\sigma_i越小,\sigma_iu_iv_i^T对A的贡献越小。\\ 即只要保留较大\sigma_i和对应的u_i,v_i^T,就可以保留A的主要特征。 \\ 即保留前k个\sigma_i,(k\leq r),用B=\sigma_1u_1v_1^T+...+\sigma_k u_kv_k^T来近似A \\ 压缩比=\frac{mn}{(m+n+1)k},mn为A的大小,(m+n+1)k为B的大小 \\\quad \\(numpy带有SVD分解的函数,即求出U,\Sigma,V^H,压缩图片就变得很简单了) 对任意的ACrm×nSVD分解,A=U(ΣOOO)VH其中U,V为酉矩阵,U=(u1,..,um)Cmm×mVH= v1T..vnT Cnn×nΣ=diag(σ1,..,σr),σiA的奇异值,i=1,..,rσ1σ2...σr>0于是,A=σ1u1v1T+σ2u2v2T+....+σrurvrT可以看到,奇异值σi越小,σiuiviTA的贡献越小。即只要保留较大σi和对应的ui,viT,就可以保留A的主要特征。即保留前kσi,(kr),B=σ1u1v1T+...+σkukvkT来近似A压缩比=(m+n+1)kmn,mnA的大小,(m+n+1)kB的大小numpy带有SVD分解的函数,即求出U,Σ,VH,压缩图片就变得很简单了)

from PIL import Image
import numpy as np

image_dir = "D:/zmzm/test.png"
 
x = Image.open(image_dir)   #打开图片
data = np.asarray(x)        #转换为矩阵

image = Image.fromarray(data[:,:,0])  #显示原图
image.show()  

u, s, vh = np.linalg.svd(data[:,:,0])   #SVD分解,图片为四重矩阵,取第一重,即黑白图片 
u=np.asmatrix(u)
vh=np.asmatrix(vh)


A=np.asmatrix(np.zeros(data[:,:,0].shape))
m , n = A.shape
for  k in range(0,150):	#可以自己调节的值,调节压缩值
    if(k%30==0  and k!=0) :
        image = Image.fromarray(A)  
        image.show()    #输出图片
        print("压缩比:",m*n/(m+n+1)/k)
    A=A+s[k]*u[:,k]*vh[k]


Python—SVD分解压缩图片_第1张图片

压缩比: 20.516732026143792

压缩比: 10.258366013071896

压缩比: 6.838910675381263

压缩比: 5.129183006535948

原图

彩色原图

你可能感兴趣的:(笔记,python,numpy,开发语言)