数学建模day17-SVD和图形处理

发布时间:2024年01月16日

注:本文源于数学建模学习交流相关公众号观看学习视频后所作

????????奇异值分解(Singular Value Decomposition)是线性代数中一种重要的矩阵分解,其在图形学、统计学、推荐系统、信号处理等领域有重要应用。本讲我们将介绍奇异值分解在图形压缩中的运用,并将简单介绍下Matlab对于图形和视频的处理。

目录

线性代数基础知识回顾

奇异值分解

三个引理

例子

U的计算

V的计算

Σ的计算

SVD的证明思路

利用SVD对数据进行"降维"?编辑

保留原矩阵的特征比例

Matlab进行奇异值分解:[U,S,V] = svd(A)

定义我们自己的mysvd函数

Matlab图形的处理

RGB模式

图片压缩的函数

SVD压缩后的效果

将视频分离为图片

分离效果

批量处理文件夹内的所有图片

SVD的评价和应用

最后


线性代数基础知识回顾


奇异值分解

三个引理

例子

U的计算

V的计算

Σ的计算

SVD的证明思路

利用SVD对数据进行"降维"

SVD 降维体现在什么地方?
感觉即使把分解的三个矩阵变小,可乘回去整个矩阵并没有小。

SVD 降维体现在什么地方? - 知乎 (zhihu.com)

保留原矩阵的特征比例


Matlab进行奇异值分解:[U,S,V] = svd(A)

?PPT_example.m

%%  注意
% matlab2021b版本后,神经网络拟合工具箱升级成了中文
% 如果直接使用课堂上的代码会报错,相应的解决方法请关注微信公众号
% 《数学建模学习交流》,后台发送:894145这六个数字,文章内有解决方法。

%% 下面是代码,matlab2017a至matlab2021a版本通用
load data_Octane.mat
% 在Matlab的菜单栏点击APP,再点击Neural Fitting app.

% 利用训练出来的神经网络模型对数据进行预测
% 例如我们要预测编号为51的样本,其对应的401个吸光度为:new_X(1,:)
% sim(net, new_X(1,:))
% 错误使用 network/sim (line 266)
% Input data sizes do not match net.inputs{1}.size.
% net.inputs{1}.size
 
% 这里要注意,我们要将指标变为列向量,然后再用sim函数预测
sim(net, new_X(1,:)')

%
% 写一个循环,预测接下来的十个样本的辛烷值
predict_y = zeros(10,1); % 初始化predict_y
for i = 1: 10
    result = sim(net, new_X(i,:)');
    predict_y(i) = result;
end
disp('预测值为:')
disp(predict_y)

定义我们自己的mysvd函数

mysvd.m

function [compress_A] = mysvd(A, ratio)
    % 函数作用:使用奇异值分解将矩阵A压缩到指定的特征比例
    % 输入变量
    %     A:要压缩的m*n维的矩阵
    %     ratio:要保留原矩阵的特征比例(100%表示不压缩)
    % 输出变量
    %     compress_A: 压缩后的矩阵
    [U,S,V] = svd(A);   % U:m*m         S:m*n      V : n*n
    eigs = diag(S);  % diag函数可以返回S的主对角线元素,即矩阵A的奇异值,并将其保存到列向量中
    SUM = sum(eigs);  % 计算所有奇异值的总和
    temp = 0;   % 新建临时变量,用于下面的循环
    for  i = 1: length(eigs)  % 循环
        temp =temp + eigs(i);  % 每循环一次,就更新temp的值为原来的temp值+接下来的一个奇异值
        if (temp/SUM) > ratio  % 如果现在的比例超过了ratio,就退出循环
            break
        end
    end
    disp(['压缩后保留原矩阵的比例特征为:',num2str(roundn(100*temp/SUM,-2)),'%'])  %roundn(x,-2)可将x四舍五入到小数点后两位
    compress_A= U(:,1:i)*S(1:i,1:i)*V(:,1:i)';
end

Matlab图形的处理

暂时跳过,后续更新~~~稍安勿躁啊亲`~~


RGB模式

????????RGB色彩就是常说的三原色,R代表Red(红色),G代表Green(绿色),B代表Blue(蓝色)。自然界中肉眼所能看到的任何色彩都可以由这三种色彩混合叠加而成。

图片压缩的函数

?photo_compress.m

function []= photo_compress(photo_address, save_address, ratio, greycompress)
    % 函数作用:利用SVD对图形进行压缩
    % 输入变量
    %     photo_address:要压缩的图片存放的位置(建议输入完整的路径)
    %     save_address:将压缩后的图片保存的位置(建议输入完整的路径)
    %     ratio:要保留原矩阵的特征比例(100%表示不压缩)
    %     greycompress: 如果该值等于1,则会彩色的原图片转换为灰色图片后再压缩;默认值为0,表示不进行转换
    % 输出变量
    %     无(不需要输出,因为函数运行过程中已经将图片保存了~)

    if nargin == 3  % 判断用户输入的参数,如果只输入了前三个参数,则默认最后的参数greycompress=0
        greycompress = 0;
    end

    img = double(imread(photo_address));
    % 图片保存的对象是 'uint8' 类型,需要将其转换为double类型才能进行奇异值分解的操作
    % 注意:  img是图形的像素矩阵,如果是彩色图片则是三维矩阵,如果是灰色图片则是二维矩阵
    % '赫本.jpg'是灰色的图片,得到的img类型是[914×1200]double
    % '千与千寻.jpg'是彩色的图片,得到的img类型是[768×1024×3]double
    % 因此我们可利用第三个维度的大小来判断图片是否为灰色的
    % 灰色图片的只有两个维度,所以size(img ,3) == 1
 
    if (greycompress == 1) && (size(img ,3) == 3)  % 如果图片为彩色,且greycompress的值等于1,则会彩色的原图片转换为灰色图片后再压缩
        img = double(rgb2gray(imread(photo_address)));    % rgb2gray函数可以将彩色图片转换为灰色图片, 注意:输入的变量要为默认的'uint8' 类型的图片对象
    end  % 注意: grey(英)和gray(美)都表示灰色

    if size(img ,3) == 3   % 判断图片是否为彩色的
        R=img(:,:,1);       % RGB色彩模式三要素:红色
        G=img(:,:,2);       % RGB色彩模式三要素:绿色
        B=img(:,:,3);       % RGB色彩模式三要素:蓝色
        disp(['正在压缩:  ',photo_address,'的红色要素'])
        r = mysvd(R, ratio);  % 调用自定义函数将R矩阵压缩成r
        disp(['正在压缩:  ',photo_address,'的绿色要素'])
        g = mysvd(G, ratio); % 调用自定义函数将G矩阵压缩成g
        disp(['正在压缩:  ',photo_address,'的蓝色要素'])
        b = mysvd(B, ratio); % 调用自定义函数将B矩阵压缩成b
        compress_img=cat(3,r,g,b);  % 根据三个RGB矩阵(压缩后的r、g、b)生成图片对象
    else  % 如果图片是灰色的要执行的步骤
        disp(['正在压缩灰色图片:  ',photo_address])
        compress_img = mysvd(img, ratio);  %如果是灰色图片的话,直接压缩img矩阵就好了
    end

    % 将压缩后的图片保存
    imwrite(uint8(compress_img), save_address);   % 如果你的矩阵是double格式的,导出时会自动将范围认为是[0 1],需要重新转换为uint8类型

end

SVD压缩后的效果


将视频分离为图片

注意:Matlab对视频的要求较高,如果出现下?的错误,则需要先将视频进行解码
我使用的是迅捷视频转换器
错误使用VideoReader/init (line 619)
无法确定所需的编解码器。
video中的对象讲解:[matlab]matlab读取视频VideoReader类_matlab 读取video文件-CSDN博客

分离效果


批量处理文件夹内的所有图片

folder_name = 'C:\Users\Desktop\奇异值分解\葫芦娃七兄弟';
dirOutput=dir(fullfile(folder_name, '*.jpg'));
files={dirOutput.name};
n = length(files);
ratio = 0.9;
for i = 1:n
    photoname = files(i);
    name = photoname{1};
    photo_address = fullfile(folder_name, name);
    disp(photo_address)
    save_address = fullfile(folder_name, strcat('compress_',name));
    photo_compress(photo_address, save_address, ratio)
end

SVD的评价和应用

SVD(奇异值分解):
???????(1)优点:简化数据,去除噪声点,对数据降维(减少秩);
? ? ? ? (2)缺点:数据的转换可能难以理解;
? ? ? ? (3)适用于数据类型:数值型。


????????通过SVD对数据的处理,我们可以对原始数据进行精简,这样做实际上是去除了噪声和冗余信息,以此达到了优化数据的目的。


SVD的另外两个重要应用:
????????潜在语义索引:最早的SVD应用之一就是信息检索,我们称利用SVD的方法为潜在语义检索(LSI)或隐形语义分析(LSA),有兴趣可以去阅读吴军老师的《数学之美》。
????????推荐系统:SVD的另一个应用就是推荐系统,较为先进的推荐系统先利用SVD从数据中构建一个主题空间,然后再在该空间下计算相似度,以此提高推荐的效果。

最后

对图形处理有需要的同学可阅读Matlab图形处理的资料:图形 - MATLAB & Simulink - MathWorks 中国

????????没有学过线性代数的同学可以提前学习下,bilibili上有很多优质的视频资源。比较推荐的线性代数的教材是 (美)莱(Lay D.C.)《线性代数及其应用》。但是其实都大差不差了

文章来源:https://blog.csdn.net/DDDDWJDDDD/article/details/135614443
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。