奇异值(SVD)分解在图像处理中的意义及PCA的Python实现

  这学期矩阵分析期末考试整了个矩阵奇异值分解的题,没顶住,痛定思痛,查阅了相关的文献,结合自己图像处理的研究方向,对矩阵奇异值的意义有了更加清晰的认识,故留此记录。

什么是矩阵奇异值分解?

  根据教材的定义,对于任意m×n维复数矩阵A,存在m维酉矩阵P和n维酉矩阵Q,使得A满足分解式:
A = P ( D 0 0 0 ) Q H A=P \begin{pmatrix} D & 0 \\ 0&0 \\ \end{pmatrix} Q^H A=P(D000)QH

  其中 D = d i a g { d 1 , d 2 , ⋯ d r } , 且 d 1 ≥ d 2 ≥ ⋯ ≥ d r > 0 D = diag\{d_1 ,d_2 ,{\cdots} d_r\},且d_1\geq d_2\geq {\cdots} \geq d_r >0 D=diag{d1,d2,dr},d1d2dr>0  称di为矩阵A的奇异值。

矩阵奇异值有什么意义?

  我们将矩阵P和Q写成列向量形式,由于D矩阵为对角矩阵,则A可以表示成如下累加形式:
A = d 1 u 1 v 1 T + d 2 u 2 v 2 T + ⋯ + d r u r v r T A = d_1u_1v_1^T+d_2u_2v_2^T+{\cdots} +d_ru_rv_r^T A=d1u1v1T+d2u2v2T++drurvrT

  因为图像就是一个矩阵,所以这里用图像的方式进行直观解释。下面这张爱喝可乐的猫为原图(方便操作使用灰度图):
奇异值(SVD)分解在图像处理中的意义及PCA的Python实现_第1张图片
  图片大小为500*700,对该张图进行奇异值分解,至多有500个奇异值,保留前五个最大的奇异值即 A = d 1 u 1 v 1 T + d 2 u 2 v 2 T + ⋯ + d 5 u 5 v 5 T A = d_1u_1v_1^T+d_2u_2v_2^T+{\cdots} +d_5u_5v_5^T A=d1u1v1T+d2u2v2T++d5u5v5T  得到的图像效果如下:奇异值(SVD)分解在图像处理中的意义及PCA的Python实现_第2张图片
  可以看到图片的效果非常模糊。那么增加到前50个奇异值时得到的效果如下所示:奇异值(SVD)分解在图像处理中的意义及PCA的Python实现_第3张图片
  可以看到此时清晰度相比只取5个奇异值时,清晰度变化非常大,当取100个奇异值时效果如下所示:
奇异值(SVD)分解在图像处理中的意义及PCA的Python实现_第4张图片
  此时的图片相比原图已经变化不大,并且奇异值取5个和取50个之间的变化明显比取50个到取100个之间的变化大
  由此可见,如果把vi×ui看成小矩阵,那么其对应的奇异值di则表示该矩阵的权重,奇异值越大则权重越大,其在矩阵A中的重要程度越大(可以与泰勒级数对比理解),在图像处理时,通常可以把奇异值较小的部分看成噪声引起的,这时就可以达到对图像进行去噪的效果。在图像主成分分析(Principle Component Analysis,PCA)中就是选取图像奇异值前占比α%的分量,作为图像的主成分对图像进行降维去噪处理。
  下面附上PCA处理Python实现代码:

import cv2
import numpy as np

def Img_PCA(img,a):           #img为输入图像,a为保留主成分比例
    U,S,V=np.linalg.svd(img)  #将img进行奇异值分解,U为左酉矩阵大小M*M,S为奇异值,V为右酉矩阵N*N。
    SS=np.zeros(img.shape)
    for i in range(len(S)):
        SS[i][i]=S[i]       #将S转化为M*N对角矩阵

    sval=np.sum(S)
    for i in range(len(S)):
        if np.sum(S[:i]) >= a*sval:
        	k = i + 1
            break
    Uk=U[:,0:k]
    Sk=SS[0:k,0:k]
    Vk=V[0:k,:]
    img_pca = np.uint8(np.dot(np.dot(Uk,Sk),Vk))  #计算降维处理后的矩阵
    return img_pca

if  __name__ == "__main__":
	img = cv2.imread('mao.jpg',0)
	img_pca = Img_PCA(img,0.8)
	cv2.imshow("img_gray",img)
    cv2.imshow("img_pca",img_pca)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

参考文献:
【1】罗家洪、方卫东. 矩阵分析引论.第五版
【2】奇异值的物理意义是什么?

你可能感兴趣的:(奇异值(SVD)分解在图像处理中的意义及PCA的Python实现)