奇异值分解在图形压缩中的应用

奇异值分解在图形压缩中的应用


在研究奇异值分解的工程应用之前,我们得明白什么是奇异值?什么是奇异向量?

奇异值与奇异向量

概念:奇异值描述了矩阵在一组特定向量上的行为,奇异向量描述了其最大的作用方向。

奇异值分解(SVD)

矩阵A的分解涉及一个 m × n m \times n m×n的矩阵 Σ \Sigma Σ,其中 Σ \Sigma Σ= [ D 0 0 0 ] \begin{bmatrix} D &0\\0&0\end{bmatrix} [D000],D是一个 r × r r\times r r×r的方阵 ( r ≤ m , r ≤ n ) ( r \leq m , r\leq n) (r≤m,r≤n)

定理:设A是秩为 r r r的 m × n m\times n m×n的矩阵,那么存在一个类似于 Σ \Sigma Σ的矩阵,其中 D D D的对角线元素是 A A A的前 r r r个奇异值, σ 1 ≥ σ 2 ≥ σ 3 ≥ . . . ≥ σ r > 0 \sigma_1 \geq\sigma_2 \geq\sigma_3 \geq... \geq\sigma_r>0 σ1≥σ2≥σ3≥...≥σr>0并且存在一个 m × m m\times m m×m的正交矩阵 U U U 和一个 n × n n\times n n×n的正交矩阵 V T V^T VT使得 A = U Σ V T A=U\Sigma V^T A=UΣVT

奇异值分解计算过程

我们先假设一个矩阵 A = [ 2 3 0 2 ] A = \begin{bmatrix} 2 & 3 \\ \ 0 & 2\end{bmatrix} A=[2 032]

设 U = [ u 1 u 2 u 3 . . . ] U=[u_1 u_2 u_3 ...] U=[u1u2u3...] , ∑ = d i a g [ σ 1 σ 2 σ 3 . . . ] \sum = diag[\sigma_1 \sigma_2 \sigma_3 ...] ∑=diag[σ1σ2σ3...] , V = [ v 1 v 2 v 3 . . . ] T V=\begin{bmatrix} v_1 \\ v_2\\ v_3 \\ ...\end{bmatrix}^T V= v1v2v3... T

其中 U U U代表A的正交矩阵; ∑ \sum ∑代表A的由奇异值组成的左奇异向量矩阵; V V V代表A的右奇异向量矩阵。

求A的 U , ∑ , V U , \sum , V U,∑,V.

  1. 计算 A T A A^TA ATA
    A T A = [ 2 0 3 2 ] [ 2 3 0 2 ] = [ 13 6 6 4 ] A^TA =\begin{bmatrix} 2&0\\3&2 \end{bmatrix} \begin{bmatrix} 2&3\\0&2\end{bmatrix}= \begin{bmatrix} 13&6\\6&4 \end{bmatrix} ATA=[2302][2032]=[13664]
  2. 计算 A T A A^TA ATA的奇异值 σ \sigma σ
    σ 1 2 σ 2 2 = d e t A T A = 16 σ 1 2 + σ 2 2 = t r A T A = 17 ∴ σ 1 2 = 16 , σ 2 2 = 1 ∴ σ 1 = 4 , σ 2 = 1 ∴ Σ = [ 4 0 0 1 ] \sigma_1^2\sigma_2^2 = det A^TA = 16 \\ \sigma_1^2 + \sigma_2^2 = tr A^TA = 17 \\ \therefore \sigma_1^2 =16, \sigma_2^2= 1\\ \therefore \sigma_1 =4, \sigma_2= 1\\ \therefore \Sigma=\begin{bmatrix} 4&0\\0&1 \end{bmatrix} σ12σ22=detATA=16σ12+σ22=trATA=17∴σ12=16,σ22=1∴σ1=4,σ2=1∴Σ=[4001]
  3. 将 σ 1 , σ 2 \sigma_1,\sigma_2 σ1,σ2带入 A T A A^TA ATA中求其特征向量
    v 1 = [ 1 5 2 5 ] , v 2 = [ − 2 5 1 5 ] ∴ V = [ 1 5 − 2 5 2 5 1 5 ] \\ v_1= \begin{bmatrix} \frac{1}{\sqrt5} \\\\ \frac{2}{\sqrt5} \end{bmatrix} , v_2= \begin{bmatrix} -\frac{2}{\sqrt5}\\\\\frac{1}{\sqrt5} \end{bmatrix} \\\therefore V= \begin{bmatrix} \frac{1}{\sqrt5}&-\frac{2}{\sqrt5} \\\\ \frac{2}{\sqrt5}&\frac{1}{\sqrt5}\end{bmatrix} v1= 5 15 2 ,v2= −5 25 1 ∴V= 5 15 2−5 25 1
  4. 构造标准正交向量
    u i = 1 σ i A v i ∴ u 1 = 1 σ 1 A v 1 = 1 4 [ 2 3 0 2 ] [ 1 5 2 5 ] = [ 2 5 1 5 ] ∴ u 2 = 1 σ 2 A v 2 = 1 1 [ 2 3 0 2 ] [ − 2 5 1 5 ] = [ − 1 5 2 5 ] ∴ U = ( u 1 , u 2 ) = [ 2 5 − 1 5 1 5 2 5 ] u_i=\frac{1}{\sigma_i}Av_i \\ \therefore u_1=\frac{1}{\sigma_1}Av_1=\frac{1}{4}\begin{bmatrix} 2&3\\\\0&2\end {bmatrix} \begin{bmatrix} \frac{1}{\sqrt5} \\\\ \frac{2}{\sqrt5} \end{bmatrix} =\begin{bmatrix} \frac{2}{\sqrt5}\\ \\ \frac{1}{\sqrt5} \end {bmatrix} \\ \therefore u_2=\frac{1}{\sigma_2}Av_2=\frac{1}{1}\begin{bmatrix} 2&3\\\\0&2\end {bmatrix} \begin{bmatrix} - \frac{2}{\sqrt5} \\\\ \frac{1}{\sqrt5} \end{bmatrix} =\begin{bmatrix} -\frac{1}{\sqrt5}\\ \\ \frac{2}{\sqrt5} \end {bmatrix} \\ \therefore U=(u_1,u_2)=\begin{bmatrix} \frac{2}{\sqrt5} & -\frac{1}{\sqrt5} \\ \\ \frac{1}{\sqrt5} &\frac{2}{\sqrt5} \end{bmatrix} ui=σi1Avi∴u1=σ11Av1=41 2032 5 15 2 = 5 25 1 ∴u2=σ21Av2=11 2032 −5 25 1 = −5 15 2 ∴U=(u1,u2)= 5 25 1−5 15 2
  5. 写出表达式
    A = U Σ V T = [ 2 5 − 1 5 1 5 2 5 ] [ 4 0 0 1 ] [ 1 5 2 5 − 2 5 1 5 ] A=U\Sigma V^T=\begin{bmatrix} \frac{2}{\sqrt5} & -\frac{1}{\sqrt5} \\ \\ \frac{1}{\sqrt5} &\frac{2}{\sqrt5} \end{bmatrix} \begin{bmatrix} 4 & 0 \\\\ \ 0 & 1\end{bmatrix} \begin{bmatrix} \frac{1}{\sqrt5}& \frac{2}{\sqrt5}\\\\ -\frac{2}{\sqrt5}&\frac{1}{\sqrt5}\end{bmatrix} A=UΣVT= 5 25 1−5 15 2 4 001 5 1−5 25 25 1

利用奇异值分解(SVD)进行图片压缩

首先我们先找一张图片来进行实验。

通道分离

对于JPG格式的彩色图片,拥有3个颜色通道,R(红)、G(绿)、B(蓝),那么可以尝试将每个颜色通道进行分离,产生3个形状均为图像高 x 宽 的单通道剧展,即imageR,imageG,imageB。

进行通道分离,将imageArray数组中的每个通道分别单独取出来,得到3个高 × \times × 宽的二维数组。这3个二维数组中每个位置上的取值就是对应像素的某个颜色通道的取值,代码如下:

python 复制代码
import numpy as np
from PIL import Image
 
originalImage = Image.open(r'teriri.jpg', 'r')
imageArray = np.array(originalImage)
R = imageArray[:, :, 0]
G = imageArray[:, :, 1]
B = imageArray[:, :, 2]
print(R)
print(G)
print(B)

运行结果如下:

\[207 207 207 ... 141 141 141

207 207 207 ... 141 141 141

207 207 207 ... 141 141 141

...

246 247 248 ... 239 239 239

246 247 248 ... 239 239 239

246 247 248 ... 239 239 239\]

\[198 198 198 ... 126 126 126

198 198 198 ... 126 126 126

198 198 198 ... 126 126 126

...

233 234 235 ... 235 235 235

233 234 235 ... 235 235 235

233 234 235 ... 235 235 235\]

\[215 215 215 ... 149 147 147

215 215 215 ... 149 147 147

215 215 215 ... 149 147 147

...

230 231 233 ... 203 203 203

230 231 233 ... 203 203 203

230 231 233 ... 203 203 203\]

至此,我们成功得到了3个二维ndarray数组,将R、G、B三个通道成功进行了分离。

矩阵压缩

对每个单通道矩阵进行奇异值分解,按照压缩的实际需要取前k个奇异值,进行3个单通道的矩阵的压缩,最后分别形成3个压缩后的矩阵:imageRC,imageGC,imageBC,代码如下:

python 复制代码
def imgCompress(channel,percent):
    U,sigma,V_T = np.linalg.svd(channel)
    m = U.shape[0]
    n = V_T.shape[0]
    reChannel = np.zeros((m,n))
    for k in range (len(sigma)):
        reChannel = reChannel + sigma[k] * np.dot(U[:,k].reshape(m,1),V_T[k,:].reshape(1,n))
        if float(k) / len(sigma) > percent:
            reChannel[reChannel < 0] = 0
            reChannel[reChannel > 255] = 255
            break
        return np.rint(reChannel).astype("unit8")

图像重建

将经过奇异值分解处理的3个单通道矩阵合并,从而重构出压缩后的彩色图像。

python 复制代码
    for p in [0.001, 0.005, 0.01, 0.02, 0.03, 0.04, 0.05, 
              0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9]:
    #p表示取所有奇异值的前多少比例
        reR = imgCompress(R,p)
        reG = imgCompress(G,p)
        reB = imgCompress(B,p)
        reI = np.stack((reR,reG,reB),2)
        Image.fromarray(reI).save("{}".format(p)+"img.png")

整体运行结果如下:

比例为0.001至0.04
>0.05至0.5

0.6至原图

总结:

  1. 取前0.1%奇异值重建的图像是一个非常模糊的,基本只能看到大体轮廓。
  2. 取前1%奇异值重建的图像就可以看到一个比较清晰的图片了。
  3. 随着比例的提升,图片越来越清晰,到30%的时候就基本与原图一致了。
相关推荐
Alessio Micheli1 小时前
奇怪的公式
笔记·线性代数
Despacito0o21 小时前
RGB矩阵照明系统详解及WS2812配置指南
c语言·线性代数·矩阵·计算机外设·qmk
唐山柳林21 小时前
现代化水库运行管理矩阵平台如何建设?
线性代数·矩阵
SZ1701102312 天前
泰勒展开式
线性代数·概率论
Akiiiira4 天前
【日撸 Java 三百行】Day 7(Java的数组与矩阵元素相加)
线性代数·矩阵
18538162800余--5 天前
短视频矩阵系统批量剪辑模式开发详解,支持OEM
线性代数·ui·矩阵·音视频·概率论
HappyAcmen5 天前
线代第二章矩阵第五、六、七节矩阵的转置、方阵的行列式、方阵的伴随矩阵
笔记·学习·线性代数·矩阵
18538162800余--6 天前
矩阵系统源码搭建 UI 设计开发指南,支持OEM
线性代数·ui·矩阵
豆沙沙包?7 天前
2025年- H17-Lc125-73.矩阵置零(矩阵)---java版
java·线性代数·矩阵
Code_流苏7 天前
《Python星球日记》 第36天:线性代数基础
线性代数·numpy·数据科学·向量空间·矩阵运算