机器学习与深度学习——通过奇异值分解算法压缩图片

news/2024/11/9 4:41:17/

机器学习与深度学习——通过奇异值分解算法压缩图片

什么是奇异值分解?

奇异值分解(Singular Value Decomposition,SVD)是一种重要的线性代数方法,用于将一个矩阵分解成三个部分的乘积形式。它的应用非常广泛,包括数据降维、图像压缩、信号处理等领域。

对于一个 m × n m\times n m×n的实数矩阵 A A A,它的SVD分解可以表示为:

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

其中, U U U V V V是正交矩阵, Σ \Sigma Σ是一个 m × n m\times n m×n的对角矩阵,且对角线上的元素 σ i \sigma_i σi称为 A A A的奇异值(Singular Value)。具体来说,我们有以下步骤:

  1. 对矩阵 A A T AA^T AAT求特征值和特征向量,得到 A A T = U Σ 2 U T AA^T = U\Sigma^2U^T AAT=UΣ2UT,其中 U U U是由AAT的特征向量组成的正交矩阵,$\Sigma^2$是由AAT的特征值组成的对角矩阵。

  2. 对矩阵 A T A A^TA ATA求特征值和特征向量,得到 A T A = V Σ 2 V T A^TA = V\Sigma^2V^T ATA=VΣ2VT,其中 V V V是由A^T A的特征向量组成的正交矩阵, Σ 2 \Sigma^2 Σ2与上面一步相同。

  3. U U U V V V中的列向量单位化。

  4. Σ \Sigma Σ Σ 2 \sqrt{\Sigma^2} Σ2 的矩阵,即对角线上的元素为 σ i \sigma_i σi,其余为0。

最后得到的 U U U V V V满足 U U T = I UU^T=I UUT=I V V T = I VV^T=I VVT=I,即 U U U V V V是正交矩阵。这样,我们就将一个矩阵分解成了三个部分的乘积形式。更具体地说,我们可以将矩阵 A A A表示为:

A = U Σ V T = ∑ i = 1 r σ i u i v i T A = U \Sigma V^T = \sum_{i=1}^{r}\sigma_iu_iv_i^T A=UΣVT=i=1rσiuiviT

其中 r r r是矩阵 A A A的秩, σ i \sigma_i σi是奇异值, u i u_i ui v i v_i vi分别是左奇异向量和右奇异向量,它们是对应于 σ i \sigma_i σi的特征向量。奇异向量具有非常重要的性质,可以用于数据降维、图像压缩、信号处理等领域。

我们来做一个案列,感受一下奇异值分解算法。

目的

通过奇异值分解进行图片压缩,绘制出压缩后的图片和计算出压缩率

步骤

1、导入所需的库;
2、定义压缩函数 zip_img_by_svd
3、初始化压缩后的图片 zip_img 为全零数组
4、对每个通道进行 SVD 分解并进行归一化处理
5、将压缩后的近似矩阵乘以 255 并转换为 uint8 类型,并将原图像压缩成低维矩阵。
6、展示压缩前后的图像

代码:

#导入所需的库
import numpy as np
import matplotlib.pyplot as plt
#定义压缩函数 zip_img_by_svd ,函数的输入参数为待压缩的图片 img,绘图所需的参数 plotId,以及压缩比率 rate(默认值为 0.8)
def zip_img_by_svd(img, plotId, rate=0.8):
#初始化压缩后的图片 zip_img 为全零数组,并初始化三个变量 u_shape、sigma_shape、vT_shape 为零。u_shape、sigma_shape、vT_shape 分别表示 u、sigma、vT 三个矩阵的形状zip_img = np.zeros(img.shape)u_shape = 0sigma_shape = 0vT_shape = 0
#对图片的三个通道进行遍历,并对每个通道进行 SVD 分解。然后通过奇异值数量,创建对应的 SigmaMat 对角矩阵,并将其填充为选取的奇异值。最后将三个矩阵相乘,得到压缩后的近似矩阵。for chanel in range(3):  # 3个图层u, sigma, v = np.linalg.svd(img[:, :, chanel])  # numpy svd函数sigma_i = 0temp = 0while (temp / np.sum(sigma)) < rate:  # 选取的奇异值和需要达到设定的权重temp += sigma[sigma_i]sigma_i += 1SigmaMat = np.zeros((sigma_i, sigma_i))  # 选取了sigma_i 最大的奇异值for i in range(sigma_i):SigmaMa
#对压缩后的每个通道进行归一化处理。for i in range(3):  # 对三个通道的矩阵数值进行归一化处理MAX = np.max(zip_img[:, :, i])MIN = np.min(zip_img[:, :, i])zip_img[:, :, i] = (zip_img[:, :, i] - MIN) / (MAX - MIN)
#将压缩后的近似矩阵乘以 255 并转换为 uint8 类型,并原图像压缩成低维矩阵。
## 保存压缩后的图片并输出相关压缩信息
plt.imsave("压缩.jpg", zip_img)  # 保存压缩后的图片zip_rate = (img.size - 3 * (u_shape[0] * u_shape[1] + sigma_shape[0] * sigma_shape[1] + vT_shape[0] * vT_shape[1])) / (zip_img.size)f = plt.subplot(3, 3, plotId)f.imshow(zip_img)f.set_title("SVD压缩率 %.4f,奇异值数量:%d" % (zip_rate, sigma_i))print("设置的压缩率:", rate)print("使用的奇异值数量:", sigma_i)print("原始图片大小:
#展示压缩前后的图像
if __name__ == '__main__':imgfile = "1.jpg"plt.figure(figsize=(12, 12))plt.rcParams['font.sans-serif'] = 'SimHei'  # 消除中文乱码img = plt.imread(imgfile)f1 = plt.subplot(331)  # 绘制子图,3行3列,3*3个子图,现在画第1幅f1.imshow(img)f1.set_title("原始图片")for i in range(8):  # 再画8个子图rate = (i + 1) / 10.0  # 压缩率 10% - 80%zip_img_by_svd(img, i + 2, rate)

效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
该代码主要分为两个部分:

zip_img_by_svd函数
这个函数接收待压缩的图片img,绘图所需的参数plotId以及压缩比率rate,然后对图片的三个通道进行遍历,并对每个通道进行奇异值分解(SVD)。然后通过设定的奇异值数量创建对应的SigmaMat对角矩阵,并将其填充为选取的奇异值。最后将三个矩阵相乘,得到压缩后的近似矩阵。

主函数
这个主函数首先读取指定路径下的原始图片,然后使用zip_img_by_svd函数对图片进行压缩,并展示压缩前后的图像。压缩率从10%变化到80%。

Σ是一个m×n的奇异值矩阵,对角线上的元素称为奇异值。SVD的一个重要应用是数据降维,即将高维数据压缩成低维数据,同时保留尽可能多的信息。在这个过程中,可以选择只保留最大的k个奇异值,从而得到一个k维的低维表示。

奇异值算法(Singular Value Algorithm,简称SVA)是一种用于求解矩阵特征值和特征向量的迭代算法。它的主要优点和缺点如下:

优点:

  1. 简单易实现:奇异值算法的实现相对简单,计算量较小,适用于小规模矩阵的求解。
  2. 收敛速度快:奇异值算法具有较快的收敛速度,特别是对于较大的矩阵,收敛性能较好。
  3. 在线性代数理论支持:奇异值算法是基于线性代数理论的,因此在理论上具有较好的保证。

缺点:

  1. 不保证唯一解:虽然奇异值算法具有收敛性,但并不保证一定能找到唯一的解。如果存在多个特征值相等的情况,需要通过其他方法进行处理。
  2. 数值稳定性问题:奇异值算法在处理某些特殊矩阵时可能存在数值稳定性问题,如退化现象、奇异值爆炸等。
  3. 对于稀疏矩阵的处理能力有限:奇异值算法主要适用于稠密矩阵的求解,对于稀疏矩阵的处理能力有限。

总之,奇异值算法是一种简单有效的求解矩阵特征值和特征向量的算法,但在实际应用中需要注意其局限性。


http://www.ppmy.cn/news/87480.html

相关文章

Linux之创建进程、查看进程、进程的状态以及进程的优先级

文章目录 前言一、初识fork1.演示2.介绍3.将子进程与父进程执行的任务分离4.多进程并行 二、进程的状态1.进程的状态都有哪些&#xff1f;2.查看进程的状态2.运行&#xff08;R&#xff09;3.阻塞4.僵尸进程&#xff08;Z&#xff09;1.僵尸状态概念2.为什么要有僵尸状态&#…

C#开发的OpenRA游戏之基地工程车移动3

C#开发的OpenRA游戏之基地工程车移动3 从前面可以知道,基地工程车移动的过程是鼠标点击,然后查找对象的命令,接着把命令发送给服务器,服务器再收到命令,最后把命令放到当前活动执行队列。 在上一文里,已经分析到放到当前活动执行队列: self.QueueActivity(order.Queu…

【iOS锁_@synchronized源码浅析】

文章目录 前言synchronized介绍加锁实例synchronized实现objc_sync_enter 和 objc_sync_exit objc_sync_enterobj存在SyncList的结构SyncList和SyncData的关系id2data函数的实现1. 使用快速缓存2. 获取该线程下的SyncCache3. 全局哈希表查找4. 生成新数据并写入缓存 总结 前言 …

JDK8-17的特性发生了哪些变化

JDK8-17的特性发生了哪些变化 垃圾回收器Java交互式编程接口定义扩展String底层结构变更of 创建不可变序列HTTP 2 协议接口引入 var 关键字字符串增强lambda 表达式类型推导switch 增强支持文本块定义instanceof 模式匹配引入record 关键字新增密封类的定义switch二度加强模块…

LabVIEWCompactRIO 开发指南37 在第三方模拟器中执行

LabVIEWCompactRIO 开发指南37 在第三方模拟器中执行 如果需要验证时序和功能&#xff0c;在将LabVIEW FPGA VI编译到硬件之前&#xff0c;可以与三款第三方仿真器进行交互&#xff1a;MentorGraphicsModelSim&#xff08;LabVIEW2013及更早版本&#xff09;、MentorGraphics…

MATLAB算法实战应用案例精讲-【数模应用】主效应分析

前言 在有一个或几个因子(自变量)的多水平的实验中,描述一个因子在各水平上对反应量(因变量)影响大小的度量。对有S个水平的单因子A的试验,若随机变量 yij是在第 j次试验中于第 i个水平上的观测值,则模型为E(yij)=μ+ai,(i=1,2,...,s,j=1,2,...,ni),这里E是期望, μ是总…

三、尚医通医院管理实现

文章目录 三、医院管理实现1、医院列表1.1 医院列表api接口1.1.1 添加service分页接口与实现1.1.2 添加controller方法 1.2 service-cmn模块提供接口1.2.1添加service接口与实现1.2.2添加controller方法 1.3封装Feign服务调用1.3.1搭建service-client父模块1.3.2 搭建service-c…

性能测试——服务端监控工具nmon

这里写自定义目录标题 一、性能监控工具nmon介绍二、nmon可监控的数据类型三、nmon特点四、Linux下安装1、检查安装环境2、下载nmon3、解压 五、运行nmon1、启动nmon2、常用nmon快捷命令3、nmon命令行参数4、命令行例子5、重点 六、查看 nmon 监控结果1、nmon_analyser 介绍2、…