【矩阵分析】奇异值分解在图像压缩中的应用及编程实践

奇异值分解(Singular Value Decomposition, SVD)在图像处理与机器学习领域中应用较为广泛,如图像压缩、主成分分析、以及搜索引擎语义层次检索的LSI(Latent Semantic Indexing)。本文主要侧重于其在图像压缩和主成分分析中的应用,而关于SVD的计算公式和细节,这里不再表述,详细可见[1]。

—— SVD在图像压缩中的应用

以下代码是使用SVD将输入灰度图像进行分解,然后提取出前n个奇异值,以及对应的左右奇异值向量进行图像的重构。

% svd for image compression

clc; clear all; close all;

% read image
img = imread('tangwei.jpg');
[hei, wid, col] = size(img);
if col == 3
    img = rgb2gray(img);
end
fprintf('The size of image is: %d x %d.\n', [hei, wid] );

% svd decomposition
[u, s, v] = svd(double(img));

% reconstruction
recon_nums = [1, 5, 10, 50, 100];
img_recon = zeros(hei, wid, length(recon_nums));

for id = 1:length(recon_nums)
    for ii = 1: recon_nums(id)
        img_temp = s(ii, ii) * u(:, ii) * v(:, ii)';
        img_recon(:, :, id) = img_recon(:, :, id) + img_temp;
    end
end

% compute compression rate
compre_rate = (hei*wid) ./ ((hei+wid).*recon_nums + recon_nums); 

% show 
figure;
for id = 1:length(recon_nums)
    subplot(2, 3, id);
    imshow(uint8(img_recon(:, :, id)))
    title(['奇异值个数:', num2str(recon_nums(id)), ...
        ',压缩比:', num2str(compre_rate(id)) ]);
end

subplot(2, 3, 6);
imshow(uint8(img));
title('原始图像');

图示结果如下:
图1
——图1——

图像压缩比的计算公式为:

compre_rate=img_hei×img_widsv_num×(img_hei+img_wid+sv_num) c o m p r e _ r a t e = i m g _ h e i × i m g _ w i d s v _ n u m × ( i m g _ h e i + i m g _ w i d + s v _ n u m )

其中 sv_num s v _ n u m 代表选取的奇异值的个数。

由上图可知,当选取50个奇异值时,图像的重构效果视觉上基本可以接受了,但仍存在细小的马赛克,而选取100个奇异值时,重构结果与原图基本上便没有差别了。自然会想到一个问题,对于不同的图像,选取同样数目的奇异值其压缩效果会相同么?

下图(图2)是为一个草地,图像的灰度分布杂乱无章,此时即使选取了100个奇异值,恢复的图像上半部分仍存在明显的模糊。
图2
——图2——

下图(图3)则与图2相反,因为天空的灰度分布较为一致,当奇异值仅取5时,恢复出的图像已与原图差别不大,除了图像下方细小的草地有细微的区别。
图3
——图3——

从奇异值数值分布的角度来看待这个现象,我们计算一下对于不同的图像,前多少个奇异值的数值和占据所有奇异值总和的90%:

% put singular values into a vector
if hei <= wid
    s_vector = zeros(hei, 1);
else
    s_vector = zeros(wid, 1);
end

for ii = 1:length(s_vector)
    s_vector(ii) = s(ii, ii);
end

s_sum = sum(s_vector);
flag = 0;
s_temp = 0;
for ii = 1:length(s_vector)
    s_temp = s_temp + s_vector(ii);
    if s_temp/s_sum >= 0.9
        flag = ii;
        break;
    end
end
fprintf('奇异值数目总和: %d\n', length(s_vector));
fprintf('占比为90%%时的奇异值数目:%d\n', flag);

结果如下:

  • 图1:奇异值数目总和: 531,占比为90%时的奇异值数目:118
  • 图2:奇异值数目总和: 733,占比为90%时的奇异值数目:400
  • 图3:奇异值数目总和: 503,占比为90%时的奇异值数目:27

从上我们可以发现,灰度值在图像上分布越均匀的图像,越能用更少的奇异值及其对应的奇异值向量进行较好的重构,从而可压缩的程度则越大,这与行程编码是一致的。但与此不同的是,对于霍夫曼编码这种可变字长编码,即使灰度值在图像上分布不均匀,但只要图像整体的灰度阶比较少,压缩比仍然会比较大。


Reference

[1] 书籍:矩阵分析与应用,张贤达
[2] 博客:机器学习中的数学(5)-强大的矩阵奇异值分解(SVD)及其应用
[3] 知乎问答:奇异值的物理意义是什么?

奇异值分解(SVD)原理与在降维中的应用
机器学习中的数学(4)-线性判别分析(LDA), 主成分分析(PCA)

  • 4
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值