奇异值分解SVD数学原理及代码(Python)

奇异值分解SVD数学原理及代码(Python)

  • 首先简单介绍一下什么是正交矩阵(酉矩阵)
    如果
    在这里插入图片描述在这里插入图片描述
    其中,E为单位矩阵,或,则n阶实矩阵A称为正交矩阵。正交矩阵是实数特殊化的酉矩阵,因此总是属于正规矩阵。

  • 下面进入正题:
    奇异值分解SVD数学原理及代码(Python)_第1张图片
    由上式可知U,V为正交方阵,故可进行特征值和特征向量的求解

    奇异值分解SVD数学原理及代码(Python)_第2张图片奇异值分解SVD数学原理及代码(Python)_第3张图片
    在这里插入图片描述
    从下面的例子中可以更容易增强对奇异值分解的理解
    奇异值分解SVD数学原理及代码(Python)_第4张图片
    奇异值分解SVD数学原理及代码(Python)_第5张图片
    上式中正交矩阵的特征值和特征向量求解过程通过下面简单的例子进行展示:

奇异值分解SVD数学原理及代码(Python)_第6张图片
奇异值分解SVD数学原理及代码(Python)_第7张图片

import numpy as np
import os
from PIL import Image
import cv2


def restore(sigma, u, v, K):  # 奇异值、左特征向量、右特征向量
    m = len(u)
    n = len(v[0])
    a = np.zeros((m, n))
    for k in range(K):
        uk = u[:, k].reshape(m, 1)
        vk = v[k].reshape(1, n)
        a += sigma[k] * np.dot(uk, vk)  # 前 k 个奇异值的加和
    a = a.clip(0, 255)
    return np.rint(a).astype('uint8')


if __name__ == "__main__":
    A = cv2.imread('D:\Pycharm/untitled/13.jpg')
    a = np.array(A)
    print('type(a) = ', type(a))
    print('原始图片大小:', a.shape)

       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])
    root_path = "D:\Pycharm/untitled/"
    dir = root_path + "images" + "/"
    # 使用前100个奇异值分解
    K = 100
    for k in range(1, K + 1):
        R = restore(sigma_r, u_r, v_r, k)
        G = restore(sigma_g, u_g, v_g, k)
        B = restore(sigma_b, u_b, v_b, k)
        I = np.stack((R, G, B), axis=2)  #合并
        cv2.imwrite(dir+str(k)+'.jpg',I)

  • 这里我一共进行了前100次奇异值运算,原图大小为1024*880,可以看出,在第33张的时候图片基本就可以达到原图的效果。

你可能感兴趣的:(数字图像处理)