首页/文章/ 详情

基于SVD的图像压缩

1月前浏览972

奇异值分解(SVD)

  奇异值分解(Singular Value Decomposition,简称SVD)是线性代数中一种非常重要的矩阵分解技术,广泛应用于信号处理、图像处理、统计学、计算机科学等领域。它将一个复杂的矩阵分解为三个简单矩阵的乘积,这三个矩阵分别是:
  1、左奇异向量矩阵(U矩阵):一个正交矩阵,其列向量是原矩阵的左奇异向量。
  2、奇异值对角矩阵(      矩阵):一个对角矩阵,对角线上的元素是原矩阵的奇异值,这些奇异值是非负的,并且按降序排列。
  3、右奇异向量矩阵(      矩阵):一个正交矩阵,其列向量是原矩阵的右奇异向量。
  对于任意一个     的矩阵     ,其奇异值分解可以表示为:    
  其中,    是一个     的正交矩阵,    是一个对角矩阵,    是一个     的正交矩阵,    是     的转置。
  奇异值分解的步骤大致为
  1、计算奇异值:首先计算矩阵      的奇异值,即求解特征值问题     或     的非负平方根。
  2、构造奇异值矩阵:将奇异值按降序排列,构成对角矩阵     
  3.构造奇异向量矩阵:计算     与     的关系,得到左奇异向量和右奇异向量,分别构成矩阵     和     
  奇异值分解具有以下性质和应用
  1、降维:通过保留最大的几个奇异值和对应的奇异向量,可以对矩阵进行降维,这在数据压缩和特征提取中非常有用。
  2、噪声过滤:在信号处理中,奇异值分解可以用来过滤噪声,因为噪声通常对应较小的奇异值。
  3、数据近似:通过保留最大的几个奇异值,可以得到原矩阵的最佳近似,这在数据压缩和图像处理中非常有用。
  4、矩阵伪逆:奇异值分解可以用来计算矩阵的伪逆,这对于解决线性方程组的最小二乘问题非常有用。

图像压缩步骤

  奇异值分解(SVD)在图像压缩中的作用是通过减少矩阵的秩来实现压缩,同时尽量保留图像的关键视觉信息。具体来说,SVD在图像压缩中的应用可以分为以下几个步骤:

  1、图像矩阵转换:首先将图像表示为一个矩阵,其中每个像素值对应矩阵的一个元素。对于彩色图像,通常需要将其转换为灰度图像或分别对RGB三个通道进行处理。
  2、应用SVD:对图像矩阵进行奇异值分解,得到     三个矩阵。
  3、选择奇异值:由于奇异值按从大到小的顺序排列在     对角矩阵中,较大的奇异值代表了图像的主要特征,而较小的奇异值则代表了细节和噪声。在压缩时,可以选择保留最大的     个奇异值。
  4、重构图像:使用保留的     个奇异值和对应的      和      矩阵中的列向量,重构图像矩阵。具体来说,计算     ,其中     和     分别是     和     的前     列,Σ𝑘Σk 是由前     个奇异值构成的对角矩阵。
  5、压缩效果和质量权衡:通过选择不同的     值,可以控制压缩的程度和图像质量之间的平衡。较小的     值意味着更高的压缩率,但可能会丢失一些图像细节;较大的     值则保留了更多的图像信息,压缩率较低。

SVD压缩图像实例

  这里以一个图片为例,图片选自电影《荒岛余生》,截取主角快要精神崩溃时刻懵逼的场景,后面还有主角的精神支柱:Vilson,(剧透一下,后来主角决意离开小岛,扎了个皮筏,在海上漂浮的过程中,Vilson被大浪吹走了,主角万念俱灰,躺在皮筏上面等死,最后........。
  原图片为:

  帖子给出了详细的代码,下面逐行讲解代码。

clc; clear all;
%%
% 读取图像
img = imread('island.png');

% 将图像转换为灰度图像,如果它不是灰度图
if size(img, 3) == 3
    img = rgb2gray(img);
end

% 将图像转换为双精度浮点数格式
img_double = im2double(img);
 

  上面的代码将图片读进内存,但是matlab的imread函数读进的图片数据类型为unit8,因此需要将数据处理为浮点型数组,方便后续进行矩阵分解。

% 对图像进行奇异值分解
[U, S, V] = svd(img_double, 'econ');
 

  这里没有自己写算法进行分解,直接调用了matlab的svd函数,返回左右奇异值矩阵和对角矩阵。

% 选择奇异值的数量来压缩图像 
k = 50; % 选择一个较小的 k 值来压缩图像
 

  k就是我们选择的前     阶特征值,这里选择了50,后续我会修改     值,观察不同的k值对压缩后的图片质量影响。

% 选择奇异值的数量来压缩图像 
U_k = U(:, 1:k);
S_k = S(1:k,1:k);
V_k = V(:, 1:k);
 

  选取前     阶特征值对左右奇异值矩阵和对角矩阵重构。

% 重构压缩后的图像
img_compressed = U_k * S_k * V_k';
 

  生成重构后的矩阵,即生成保留前     阶特征值的图片。

% 显示原始图像和压缩后的图像
subplot(1, 2, 1);
imshow(img_double);
title('Original Image');

subplot(1, 2, 2);
imshow(img_compressed);
title(['Compressed Image with k = ', num2str(k)]);  
 

  上面的代码用与显示压缩前后的矩阵。  

         这张图片经过处理后的浮点矩阵大小为     ,因此,左奇异矩阵的大小为     ,右奇异矩阵的大小为     ,对角矩阵大小为     
  这张图片经过奇异值分解,共计849个特征值,我们依次保留不同的特征值,分别保留了25、50、75、100、125、15、175、200,比较压缩后的图片质量。
  下面给出了原图与压缩后的图片对比图,每张图片的左边均是原图,右面是压缩后的图片,图片下方标注了相应的压缩程度。  25/849  50/849
  75/849
  100/849
  可以发现,从这里开始,如果没有仔细分辨,已经看不出来原图和压缩后的图片的细微区别,这时截取的特征值占比为11.78%,压缩了将近百分之九十!  125/849  150/849  175/849
  200/849
  从上面图片的对比中发现,采用SVD对图像进行压缩,仅仅截取十分之一的特征值就达到了接近原图效果的压缩图。可见该方法在图像处理方面有极大的应用前景,并且已经有了极为广泛的应用。

详细的matlab代码

  下面给出了详细的matlab代码,使用的时候注意修改图片的名字。

clc; clear all;
%%
% 读取图像
img = imread('island.png');

% 将图像转换为灰度图像,如果它不是灰度图
if size(img, 3) == 3
    img = rgb2gray(img);
end

% 将图像转换为双精度浮点数格式
img_double = im2double(img);
imwrite(img_double, 'origin.png');

% 对图像进行奇异值分解
[U, S, V] = svd(img_double, 'econ');

% 选择奇异值的数量来压缩图像 
k = 200; % 选择一个较小的 k 值来压缩图像
U_k = U(:, 1:k);
S_k = S(1:k,1:k);
V_k = V(:, 1:k);

% 重构压缩后的图像
img_compressed = U_k * S_k * V_k';

% 显示原始图像和压缩后的图像
subplot(1, 2, 1);
imshow(img_double);
title('
Original Image');

subplot(1, 2, 2);
imshow(img_compressed);
title(['
Compressed Image with k = ', num2str(k)]);

% 如果需要,保存压缩后的图像
imwrite(img_compressed, string(k)+'
.png');
 

  上面的东西写的花里胡哨的,可是,这是有限元领域的公众 号啊!SVD跟有限元又有什么关系呢!?
  列位看官,敬请期待!

喜欢就点个关注呗


来源:有限元先生
MATLABUM控制Origin
著作权归作者所有,欢迎分享,未经许可,不得转载
首次发布时间:2024-10-26
最近编辑:1月前
外太空土豆儿
博士 我们穷极一生,究竟在追寻什么?
获赞 23粉丝 4文章 63课程 0
点赞
收藏
作者推荐

Jocabian 矩阵在等参元中的应用

壹概述初学有限元等参元理论,里面的单元映射变换给我带来了很大的困扰,我始终不明白这些东西如何通过Jocabian矩阵换来换去的。后来并没有继续一头扎进去思考里面的公式推导,想从思考新的方法论的角度来解决问题,开始反思之前学习过的内容有没有可能为现阶段的困难提供解决方案,最终决定把当下碰到的困难放到已经解决过的问题中去思考。然后想到了Jocabian行列式,Jocabian行列式广泛用于求解复杂的定积分问题,通过Jocabain行列式对定积分进行换元,就可以将复杂的被积函数或者积分区域进行化简,就解决了复杂积分问题。贰为什么要引入等参元总的来说,引入等参元是为了更高效和准确地表示复杂几何形状和提高计算精度。主要目的是为了解决复杂几何、非线性问题,提高有限元分析的精度和效率。等参元通过统一几何和物理场的表示,简化了计算和坐标变换过程,同时允许通过高阶形函数捕捉更复杂的物理现象。具体来讲有以下几个方面:1处理复杂几何形状在实际工程问题中,很多结构的几何形状是复杂的,例如弯曲的梁、曲面的壳结构等。传统的有限元单元,如矩形或三角形单元,难以准确描述这些复杂的几何形状。而等参元采用的是曲线边界,通过形函数的非线性映射能够精确描述复杂几何形状,使得有限元分析能够更好地适应各种实际结构。2统一表示几何和物理场等参元引入的一个核心思想是使用相同的形函数来表示几何坐标和物理场变量(如位移、温度等)。传统的非等参元方法通常需要分别处理几何和物理场,计算复杂度较高,且容易引入误差。等参元通过统一表示,避免了这些问题。3提高精度和效率等参元不仅能够更精确地描述几何形状,还可以通过增加形函数的阶数来提高有限元解的精度。例如,在弯曲结构或有较大几何变化的区域,等参元可以通过高阶形函数捕捉细节,获得更好的计算结果。同时,等参元允许将较少的单元用于复杂几何的建模,从而减少计算量。4方便坐标变换和数值积分在有限元分析中,很多问题涉及从参考坐标系到实际坐标系的坐标变换(如从局部单元坐标到全局坐标)。等参元通过引入参数坐标系(通常为自然坐标系,如ξ、η等),使得这些变换变得更加简单和系统。5处理非线性问题对于很多非线性问题,等参元提供了灵活的框架来处理复杂的边界条件和材料非线性。由于等参元能够精确表示非线性几何形状和应力-应变分布,它在解决非线性问题(如大变形、接触问题等)时表现尤为突出。6减少网格失配问题当模型中有复杂的几何特征或不同部分之间需要过渡时,等参元通过使用相同的形函数来表达几何和物理量,能够减少网格划分中的失配问题。它允许采用不规则的网格划分,而不会导致精度下降或计算不稳定性。叁定积分计算中的换元假如有如下定积分问题如果被积函数或者积分区域非常的复杂,如二重积分中出现弧形边界,这时候仅仅在直角坐标系中很难求解,可以尝试将定积分转化到极坐标系中求解,或者对积分变量进行换元,如下式引入Jocabian矩阵以后,原积分可以变换为其中,Jocabain矩阵对应的行列式为肆直角坐标与极坐标互换下面是一个直角坐标转换为极坐标的例子。假如有以下定积分假设积分区域为这个积分区域在直角坐标系中很复杂,直接用圆的直角坐标表达式求解分不太现实,就可以考虑进行坐标转换,把问题放到极坐标系中求解,引入原定积分转化为其中,Jocabian矩阵对应的行列式为则最初的定积分就化简为伍采用Jocabian矩阵完成等参变换这里以三维8节点单元的刚度矩阵为例讲解如何采用Jocabian完成等参变换。八节点单元的单元刚度矩阵为其中,B为应变-位移矩阵,为笛卡尔坐标x、y、z的函数,D这这里为线弹性材料矩阵,是常数。则整个被积函数可以可以表示为且笛卡尔坐标与母单元坐标存在函数关系因此,单元刚度矩阵可以表达为且Jocabian矩阵为通过Jocabian矩阵,就将刚度矩阵,即定积分转换到了母单元坐标系中,然后再利用数值积分手段,将连续的定积分转化为离散的数值求和上面的高斯积分假设每个方向有两个积分点,H为积分权重。陆反思我们不可能为所有遇到的新问题提供全新的解决方案,无论是从个人/团体资源来讲,还是时间精力角度来讲,都是不现实的。这时候就要求我们将眼光放到之前已经解过的问题上,对之前的工作进行反思和升华,与此同时将遇到的问题进行抽象或者具象,然后努力在二者之间寻找一个交汇点,到了这一步,我们遇到的问题往往可以处理成之前已经解决的问题的外延,或者是在过往问题的基础上附加了一些学科背景,总之,将一个无法解决的问题近似成已有解决方案的问题会让人感觉非常的踏实,也让我们解决现有的问题更加的有的放矢。这里面有很多值得思考的问题。点击卡片关注我们来源:有限元先生

未登录
还没有评论
课程
培训
服务
行家
VIP会员 学习计划 福利任务
下载APP
联系我们
帮助与反馈