跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

Python 机器学习案例:利用 SVD 压缩梵高《星空》图片

介绍如何使用奇异值分解(SVD)技术对图像进行压缩。通过 Python 的 NumPy 和 Pillow 库,将彩色图像转换为矩阵并进行 SVD 分解。通过保留前 k 个奇异值重构图像,实现数据量的减少。实验展示了不同 k 值下图像质量与压缩率的平衡,适用于理解降维与近似在图像处理中的应用。文章详细解析了代码逻辑、数学原理及结果分析,帮助读者掌握 SVD 在机器学习中的基础应用。

月亮邮递员发布于 2025/2/6更新于 2026/10/2493 浏览
Python 机器学习案例:利用 SVD 压缩梵高《星空》图片

Python 机器学习案例:利用 SVD 压缩梵高《星空》图片

1. 案例背景

在数字图像处理领域,图像压缩是一项基础且关键的技术。随着多媒体数据的爆发式增长,如何在保证视觉质量的前提下减少存储空间和传输带宽,成为了计算机视觉与机器学习的重要应用场景之一。

本案例将奇异值分解(Singular Value Decomposition, SVD)应用于处理图像压缩任务。我们要处理的图片是文森特·梵高的著名作品《星空》。通过数学手段对图像矩阵进行降维近似,我们可以直观地观察到数据压缩的效果。

原图

2. 理论基础

2.1 图像的数字表示

在计算机中,彩色图像通常被表示为三维矩阵。对于一张分辨率为 $H \times W$ 的 RGB 图像,其数据结构可以看作是一个 $H \times W \times 3$ 的数组。其中,前两个维度代表像素的行和列,第三个维度代表红(R)、绿(G)、蓝(B)三个颜色通道。每个通道的像素值通常在 0 到 255 之间。

2.2 奇异值分解 (SVD)

任何实数矩阵 $A$ 都可以分解为三个矩阵的乘积: $$ A = U \Sigma V^T $$ 其中:

  • $U$ 是左奇异向量矩阵,列向量为正交单位向量。
  • $\Sigma$ 是对角矩阵,对角线上的元素称为奇异值,按从大到小排列。
  • $V^T$ 是右奇异向量矩阵的转置。

2.3 SVD 在图像压缩中的应用

根据 Eckart-Young-Mirsky 定理,使用秩为 $k$ 的矩阵来近似原矩阵 $A$ 时,SVD 截断提供了最小二乘意义下的最优解。

如果我们只保留前 $k$ 个最大的奇异值及其对应的左右奇异向量,就可以重构出一个低秩矩阵 $A_k$: $$ A_k = U_k \Sigma_k V_k^T $$ 这里 $U_k$ 包含前 $k$ 列,$\Sigma_k$ 包含前 $k$ 个对角元素,$V_k$ 包含前 $k$ 行。

当 $k$ 远小于矩阵的秩(即图像的实际信息量)时,存储 $A_k$ 所需的数据量将远小于原始图像。虽然会丢失部分细节(产生模糊或噪点),但在人眼可接受的范围内,这实现了有效的压缩。

3. 环境准备

本案例基于 Python 语言实现,需要安装以下第三方库:

  • Pillow: 用于图像读取和处理。
  • NumPy: 用于矩阵运算和 SVD 分解。
  • Matplotlib: 用于可视化展示结果。

安装命令如下:

pip install pillow numpy matplotlib

4. 代码实现

以下是完整的 Python 实现代码。代码逻辑分为图像加载、通道分离、SVD 分解、图像重构及可视化展示五个步骤。

from PIL import Image
import os
import numpy as np
import matplotlib.pyplot as plt

if __name__ == '__main__':
    # 设置绘图字体支持中文显示
    plt.rcParams[] = []
    plt.rcParams[] = 

    
    
      os.path.exists():
         FileNotFoundError()
    
    img = Image.()
    a = np.array(img)  

    
    
    u_r, sigma_r, v_r = np.linalg.svd(a[:, :, ])
    u_g, sigma_g, v_g = np.linalg.svd(a[:, :, ])
    u_b, sigma_b, v_b = np.linalg.svd(a[:, :, ])

     ():
        
        m = (u)
        n = (v)
        
        reconstructed = np.zeros((m, n))
        
        
        
         i  (k):
            ui = u[:, i].reshape(m, )
            vi = v[i, :].reshape(, n)
            reconstructed += sigma[i] * np.dot(ui, vi)
        
        
        reconstructed[reconstructed < ] = 
        reconstructed[reconstructed > ] = 
         np.rint(reconstructed).astype()

    
    plt.figure(facecolor=, figsize=(, ))
    
    
    K = 
     k  (, K + ):
        ()
        
        
        R = restore(u_r, sigma_r, v_r, k)
        G = restore(u_g, sigma_g, v_g, k)
        B = restore(u_b, sigma_b, v_b, k)
        
        
        I = np.stack((R, G, B), axis=)
        
        
        plt.subplot(, , k)
        plt.imshow(I)
        plt.axis()
        plt.title( % k)
    
    plt.suptitle(, fontsize=)
    plt.tight_layout(, rect=(, , , ))
    plt.show()
'font.sans-serif'
'SimHei'
'axes.unicode_minus'
False
# 1. 读取图像并转换为 NumPy 数组
# 假设当前目录下存在 'starry_night.jpg' 文件
if
not
'starry_night.jpg'
raise
"未找到图片文件 'starry_night.jpg',请确保文件在当前目录"
open
'starry_night.jpg'
# 转换成矩阵
# 由于是彩色图像,所以有 3 个通道。a 的最内层数组为三个数,分别表示 RGB,用来表示一个像素
# 对 R, G, B 三个通道分别进行 SVD 分解
0
1
2
def
restore
u, sigma, v, k
""" 使用保留的前 k 个奇异值重构图像 :param u: 左奇异向量矩阵 :param sigma: 奇异值向量 :param v: 右奇异向量矩阵 :param k: 保留的奇异值个数 :return: 重构后的图像矩阵 """
len
len
# 初始化全零矩阵
# 重构图像公式:A_k = U_k * Sigma_k * V_k^T
# 等价于累加前 k 个秩 1 矩阵的和
for
in
range
1
1
# 限制像素值范围在 [0, 255]
0
0
255
255
return
'uint8'
# 2. 可视化不同 k 值下的重构效果
'w'
10
10
# 保留的奇异值个数依次为:1, 2, ..., K
12
for
in
range
1
1
print
f'Processing k={k}'
# 分别重构三个通道
# 合并通道
2
# 显示重构后的图片
3
4
'off'
u'奇异值个数:%d'
u'SVD 与图像分解'
20
0.1
0
0
1
0.92

5. 运行结果分析

运行上述代码后,程序会生成一系列子图,展示随着保留奇异值数量 $k$ 的增加,图像清晰度的变化过程。

压缩效果对比

5.1 现象观察

  • 当 k 较小时(如 k=1, 2):图像非常模糊,仅能看出大致的轮廓和主要色块。此时压缩率极高,但信息损失严重。
  • 当 k 适中时(如 k=5~8):图像开始呈现出明显的细节,色彩过渡变得自然,大部分结构特征得以保留。
  • 当 k 较大时(如 k=12+):图像质量接近原图,几乎看不出失真。此时压缩带来的空间节省相对于图像质量的提升来说边际效应递减。

5.2 压缩率计算

假设原图尺寸为 $M \times N$,则原始数据量为 $M \times N \times 3$(RGB)。 使用 SVD 压缩后,我们需要存储的数据量为: $$ M \times k + k + N \times k = k(M + N + 1) $$ 压缩比约为: $$ \text{Ratio} = \frac{k(M + N + 1)}{3MN} $$ 由此可见,当 $k$ 远小于 $\min(M, N)$ 时,压缩效果显著。

6. 总结

本案例通过 Python 实现了基于奇异值分解的图像压缩算法。我们不仅掌握了 SVD 的数学原理,还学会了如何利用 NumPy 进行矩阵操作以及 Matplotlib 进行可视化。

该技术的核心思想是利用矩阵的低秩近似来去除冗余信息。在实际应用中,SVD 不仅可以用于图像压缩,还可以广泛应用于推荐系统(矩阵补全)、噪声过滤、主成分分析(PCA)降维等领域。理解这一机制,有助于深入掌握线性代数在机器学习中的实际价值。

通过调整参数 $k$,开发者可以在存储空间和图像质量之间找到最佳平衡点,满足不同的业务需求。

目录

  1. Python 机器学习案例:利用 SVD 压缩梵高《星空》图片
  2. 1. 案例背景
  3. 2. 理论基础
  4. 2.1 图像的数字表示
  5. 2.2 奇异值分解 (SVD)
  6. 2.3 SVD 在图像压缩中的应用
  7. 3. 环境准备
  8. 4. 代码实现
  9. 5. 运行结果分析
  10. 5.1 现象观察
  11. 5.2 压缩率计算
  12. 6. 总结

更多推荐文章

查看全部
  • Docker 安装部署全流程使用指南(Linux 通用版)
  • 自然语言处理在金融领域的实战应用
  • Meta 发布 Llama 3 系列模型:性能、训练与部署详解
  • YOLOv8 构建的无人机红外图像下极小目标检测系统
  • AI 时代产品经理的能力边界:AI 能做什么与不能做什么
  • 前缀和算法实战:和为 K 的子数组与和可被 K 整除的子数组
  • 基于昇腾 Atlas 部署 llama.cpp 实战
  • Spring Web MVC 核心原理与实战应用
  • MiroFish:基于群体智能的万物预测引擎
  • Whisper 驱动的多语种交互异常检测框架实战
  • Mac 开发者指南:从零搭建 VSCode + Git + 阿里云效环境
  • Unity-MCP 完全指南:从零开始构建 AI 游戏开发助手
  • C++ 入门:历史、首个程序与命名空间详解
  • GitHub 上值得关注的计算机视觉开源项目
  • 前端开发中集成与应用 AI 技术详解
  • Lychee-Rerank 部署教程:国产化信创环境(统信 UOS+ 申威 CPU)适配方案
  • HunyuanVideo-Foley 技术解析及 AIGC 音频赛道融资趋势
  • 递归算法核心:二叉树遍历与结构判断实现
  • 31 岁转行软件测试:一位 34 岁从业者的经历与感悟
  • 黑客入门教程:安全工程师能力要求与学习路线

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online