SVD 奇异值分解

SVD 是一种矩阵分解和降维的算法,通过分解矩阵找到奇异值,奇异值越大代表特征越重要。公式如下

A = U Σ V T A = U \Sigma V^T A=UΣVT

  • U : 左矩阵 ( m × \times × m )
  • Σ \Sigma Σ: 对角奇异值矩阵
  • V:右矩阵( n × \times × n )

Sklearn 实现 SVD

import numpy as np
A = np.array([[0,1],[1,1],[1,0]])
u, s, vt = np.linalg.svd(A, full_matrices=True)
print(u.shape, s.shape, vt.shape)

SVD 可以用于图片的压缩,只保留最重要信息,从 k=1 到 k=50:

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

# 定义恢复函数,由分解后的矩阵恢复到原矩阵
def restore(u, s, v, K): 
    '''
    u:左奇异矩阵
    v:右奇异矩阵
    s:奇异值矩阵
    K:奇异值个数
    '''
    m, n = len(u), 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)
        # 前k个奇异值的加总
        a += s[k] * np.dot(uk, vk)   
    a = a.clip(0, 255)
    return np.rint(a).astype('uint8')

A = np.array(Image.open("./mountain.png", 'r'))
# 对RGB图像进行奇异值分解
u_r, s_r, v_r = np.linalg.svd(A[:, :, 0])    
u_g, s_g, v_g = np.linalg.svd(A[:, :, 1])
u_b, s_b, v_b = np.linalg.svd(A[:, :, 2])

# 使用前50个奇异值
K = 50 
output_path = './svd_pic'
# 
for k in tqdm(range(1, K+1)):
    R = restore(u_r, s_r, v_r, k)
    G = restore(u_g, s_g, v_g, k)
    B = restore(u_b, s_b, v_b, k)
    I = np.stack((R, G, B), axis=2)   
    Image.fromarray(I).save('%s/svd_%d.jpg' % (output_path, k))

显示图片

from PIL import Image
from IPython.display import display, HTML
import os
import re
import time

# Path to the folder containing images
image_folder = "./svd_pic"

# List all image files
image_files = [f for f in os.listdir(image_folder) if f.endswith(('.png', '.jpg', '.jpeg'))]

# Sort image files by the numeric part of the filename
def extract_number(filename):
    match = re.search(r'_(\d+)\.', filename)
    return int(match.group(1)) if match else float('inf')

image_files = sorted(image_files, key=extract_number)

# Generate HTML for horizontal display with cache busting
html = "<div style='display: flex; flex-direction: row; flex-wrap: wrap;'>"
timestamp = int(time.time())  # Use current timestamp for cache busting

for idx, image_file in enumerate(image_files):
    img_path = os.path.join(image_folder, image_file)
    # Add a unique query parameter to disable caching
    img_url = f"{img_path}?v={timestamp}"
    img = Image.open(img_path)
    img_resized = img.resize((150, 150))  # Resize to 300x300
    img_resized.save("temp_resized.jpg")  # Save resized image temporarily
    # Add image with index number overlay
    html += f"""
    <div style="margin: 10px; position: relative; display: inline-block; text-align: center;">
        <img src="{img_url}" style="width: 150px; height: 150px; display: block;">
        <div style="position: absolute; top: 10px; left: 10px; 
                    background-color: rgba(0, 0, 0, 0.6); color: white; 
                    padding: 5px 10px; font-size: 16px; border-radius: 5px;">
            {idx + 1}
        </div>
    </div>
    """

html += "</div>"

# Display the images horizontally with no cache
display(HTML(html))

随着K 值增大,图片会越来越清晰。

总结

SVD 算法通过求解奇异值对矩阵进行分解,较大奇异值能表达更重要的信息。

相关推荐
胡牧之.3 个月前
词嵌入(一):基于矩阵分解的静态词嵌入(VSM、TF-IDF、SVD)
矩阵·tf-idf·svd·词嵌入·vsm
旋转的油纸伞4 个月前
视频生成【文章汇总】SVD, Sora, Latte, VideoCrafter12, DiT...
音视频·svd·视频生成·sora·dit
曾小蛙10 个月前
【SVD生成视频+可本地部署】ComfyUI使用(二)——使用Stable Video Diffusion生成视频 (2023.11开源)
aigc·ai绘画·svd·diffusion·comfyui·视频生成·stable video
maowenbei1 年前
ubuntu 系统部署 Stable Video Diffusion
ubuntu·stable diffusion·svd·comfyui·image2video
Gene_20221 年前
ORB-SLAM之SVD奇异值分解——理论 (一)
线性代数·svd
Shier833_Ww1 年前
【数模】奇异值分解SVD和图形处理
图像处理·算法·数学建模·matlab·奇异值分解·svd