奇异值分解 (SVD, Singular Value Decomposition) 是线性代数中一种重要的矩阵变换方法,对矩阵进行 SVD 分解,可以把复杂的矩阵简化,从而提取出重要的信息。数字图像的 SVD 分解是对数字图像建模的一种方法与工具,可以应用于图像压缩与图像处理等场景。本文主要介绍矩阵 SVD 分解的基本原理,以及使用 Matlab 对图像进行 SVD 分解与重建的过程。
目录
1. 矩阵的奇异值
2. 图像的 SVD 分解与重建
1. 矩阵的特征值与奇异值
对于 n 阶方阵 ,如果存在 和非零列向量 ,使
成立,则称 是矩阵 的一个特征值, 是 矩阵 对于特征值 的一个特征向量。
特征值的求解可以根据特征多项式 进行,进一步可以将矩阵 对角化,即把矩阵 改写成可逆矩阵 和对角矩阵 乘积的形式。
其中对角矩阵 对角线上的元素为 的特征值。
然而对于 m x n 阶矩阵 (m ≠ n),特征值计算的方法不再适用,这时可以计算矩阵的奇异值。对于 m x n 阶矩阵 ,总可以分解成
的形式,其中矩阵 和 是正交矩阵,对角矩阵 对角线上的元素为 的奇异值。
为了求出 和 ,先构建方阵 和 ,有
这表明 是 的对角化矩阵, 是 的对角化矩阵。矩阵 和 分别是 和 的对角变换矩阵。
2. 图像的 SVD 分解与重建
在数字图像处理中,一幅大小为 M x N 的灰色图像可以表示成如下矩阵的形式,
其中 是 xy 空间中的二维函数,其函数值表示图像在对应点的灰度。
对于彩色图像,可以将多个分量按照行或者列的方向进行拼接,例如 M x N x 3 的图像进行拼接得到一个 3M x N 的矩阵。了解了这一点,就可以对数字图像应用奇异值分解的方法。
Matlab 中关于 svd 奇异值分解函数的用法说明如下。
使用 Matlab 进行数字图像的 SVD 分解与重建的大致思路如下:
(1)读取想要处理的图像,转换数据类型为 double 类型;
(2)将图像的不同颜色分量按某个方向进行拼接,得到 img_merge;
(3)对 img_merge 进行 SVD 分解,求出 U,S 和 V 三个矩阵;
(4)选取想要保留的奇异值的个数 k,构建新的矩阵 U1,S1 和 V1;
(5)使用 U1,S1 和 V1 生成生成新的图像,并进行显示。
Matlab 代码和运行结果如下。
clear, clc
% 基于SVD的图像压缩
img = imread('./cat.png');
img = im2double(img);
% 图像颜色分量的拼接
[m,n,d] = size(img);
img_merge = [img(:,:,1); img(:,:,2); img(:,:,3)];
% 图像的svd分解
[U,S,V] = svd(img_merge, 'econ');
% 保留前k个奇异值,生成新的图像
s = diag(S);
i = 0;
figure(1)
for k = [10,30,70,100] % k分别取10,30,70和100
U1 = U(:,1:k);
S1 = diag(s(1:k));
V1 = V(:,1:k);
tmp = U1*S1*V1';
img_new(:,:,1) = tmp(0*m+1:1*m,:);
img_new(:,:,2) = tmp(1*m+1:2*m,:);
img_new(:,:,3) = tmp(2*m+1:3*m,:);
subplot(221+i)
imshow(im2uint8(img_new)) % 显示图像
title(['k=',num2str(k)]) % 添加标题
hold on
i = i + 1;
end
可以看到,当 k 取 70 的时候,重建的图像已经可以很好地还原图像。
如果有写得不正确的地方,欢迎指正 ~