特征值和奇异值分解(数据分析算法--奇异值分解)
特征值和奇异值分解(数据分析算法--奇异值分解)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 (tem
奇异值分解(Singular Value Decomposition)是线性代数中一种重要的矩阵分解,其在图形学、统计学、推荐系统、信号处理等领域有重要应用。此处介绍奇异值分解在图形压缩中的运用,并将介绍Matlab对于图形和视频的处理。
Matlab代码:
A = [4 0 1 6;0 0 5 1;2 1 3 2] % A : 3*4% 注意:U*S*(V的转置) == A U:3*3 S:3*4 V:4*4[U S V] = svd(A) U(: 1:2)*S(1:2 1:2)*V(: 1:2)' U(: 1:3)*S(1:3 1:3)*V(: 1:3)' % 就是A
<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
<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是图形的像素矩阵,如果是彩色图片则是三维矩阵,如果是灰色图片(R=G=B)则是二维矩阵 % '赫本.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