Singular Value Decomposition。
SVD是一種基於矩陣分解的,提取資訊的強大工具,能夠發現資料中的潛在模式。應用領域比如:
以2×2的線性變換矩陣為例,現在有一個對角矩陣
M
=
[
3
0
0
1
]
M=\left[\begin{array}{ll}3 & 0 \\ 0 & 1\end{array}\right]
M=[3001]
對角矩陣M是將二維平面上的點(x,y)經過線性變換到另一個點的變換矩陣(變換效果:平面沿著x水平方向進行3倍拉伸,垂直方向沒變化): [ 3 0 0 1 ] [ x y ] = [ 3 x y ] \left[\begin{array}{ll} 3 & 0 \\ 0 & 1 \end{array}\right]\left[\begin{array}{l} x \\ y \end{array}\right]=\left[\begin{array}{c} 3 x \\ y \end{array}\right] [3001][xy]=[3xy]
從幾何角度理解二維SVD:藉助SVD可將一個相互垂直的網路(orthogonal grid)變換到另一個互相垂直的網路。
實際應用中,我們僅需保留著三個比較小的矩陣,就能表示A,不僅節省儲存量,在計算的時候更是減少了計算量。SVD在資訊檢索(隱性語意索引)、影象壓縮、推薦系統、金融等領域都有應用。
其中正交矩陣的特徵值和特徵向量的求解可以複習線性代數。
(1)下載cv2
:pip install opencv-python
。
(2)其中np.linalg.svd(a, full_matrices=1, compute_uv=1)
函數:
input引數:
a
是一個形如(M,N)矩陣full_matrices
的取值是為0或者1,預設值為1,這時u的大小為(M,M),v的大小為(N,N) 。否則u的大小為(M,K),v的大小為(K,N) ,K=min(M,N)。compute_uv
的取值是為0或者1,預設值為1,表示計算u,s,v。為0的時候只計算s。output引數(三個):
(3)numpy.stack
函數:將多個陣列進行堆疊,按照指定的維度,可參考部落格。
# -*- coding: utf-8 -*-
"""
Created on Sat Dec 11 23:14:35 2021
@author: 86493
"""
import cv2
import matplotlib as mpl
import numpy as np
import matplotlib.pyplot as plt
#轉為u8型別
def restore1(u, sigma, v, k):
m = len(u)
n = len(v)
a = np.zeros((m, n))
a = np.dot(u[:, :k], np.diag(sigma[:k])).dot(v[:k, :])
# s1 = np.size(u[:, :k])
# s1+= np.size(np.diag(sigma[:k]))
# s1+= np.size(np.diag(v[:k, :]))
# s2 = np.size(a)
# print("壓縮率:",s1/s2)
a[a < 0] = 0
a[a > 255] = 255
return np.rint(a).astype('uint8')
def SVD(frame,K=10):
a = np.array(frame)
#由於是彩色影象,所以3通道。a的最內層陣列為三個數,分別表示RGB,用來表示一個畫素
u_r, sigma_r, v_r = np.linalg.svd(a[:, :, 0])
u_g, sigma_g, v_g = np.linalg.svd(a[:, :, 1])
u_b, sigma_b, v_b = np.linalg.svd(a[:, :, 2])
R = restore1(u_r, sigma_r, v_r, K)
G = restore1(u_g, sigma_g, v_g, K)
B = restore1(u_b, sigma_b, v_b, K)
I = np.stack((R, G, B), axis = 2)
return I
if __name__ == "__main__":
mpl.rcParams['font.sans-serif'] = [u'simHei']
mpl.rcParams['axes.unicode_minus'] = False
# frame = cv2.imread("./liuyifei.bmp",-1)
frame = cv2.imread("pig.jpg",-1)
I = SVD(frame,40)
plt.imshow(I)
cv2.imwrite("out.bmp",I)
原圖為:
影象壓縮後的圖為:
(1)SVD-矩陣奇異值分解 —— 原理與幾何意義
(2)SVD應用於影象壓縮 Python程式碼測試
(3)https://www.zhihu.com/question/277311874
(4)矩陣的SVD分解(應用之一:手寫數位識別)
(5)淺談SVD原理以及python實現小demo
(6)SVD(奇異值分解)Python實現(原理清晰)