matlab 图像压缩问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了matlab 图像压缩问题相关的知识,希望对你有一定的参考价值。
clear
InitialImage=imread('lena.bmp');
%
rat=4;
InitialImage=double(InitialImage)/255;
%
figure(1);
imshow(InitialImage);
%
T=dctmtx(8);
DCTCoe=blkproc(InitialImage,[8 8],'P1*x*P2',T ,T');
%
CoeVar=im2col(DCTCoe,[8 8],'distinct');
Coe=CoeVar;
%
[Y,Ind]=sort(CoeVar);
%
[m,n]=size(CoeVar);
Snum=64-64*rat;
for i=1:n
Coe(Ind(1:Snum),i)=0;
end
%
B2=col2im(Coe,[8 8],[256 256],'distinct');
%
I2=blkproc(B2,[8 8],'P1*x*P2',T', T);
%
figure(4);
imshow(I2);
% 计算归一化图像的均方误差
error=InitialImage.^2-I2.^2;
MSE=sum(error(:))/prod(size(I2))
%---------------------------------------------------------以下是错误
Error in ==> blkproc at 89
aa(border(1)+(1:ma),border(2)+(1:na)) = a;
Error in ==> DCTencode at 12
DCTCoe=blkproc(InitialImage,[8 8],'P1*x*P2',T,T');仅出现一张图片
据我所知xcomp应该不是重构后的图像,只是去噪后的图像,还得进行重构才能得到真正重构的图像。
那可能是我孤陋寡闻了,不过要评价是否被压缩了不是看图像的大小变了没有,而是看压缩后的图像占多少空间,即所占字节数,与原图所占空间相比,这样可以算出被压缩了多少了
那这样的话我看你要修改一下你的参数了,比如thr等应该是阈值吧。如果他里边的数据都成片的相同,应该说已经阈值分割了呀。那我就不太了解了。
参考技术A 一、小波入门简介
(1)小波分析的起源、发展与应用
(2)感受小波
二、小波变换与信号分解重构专题
(1)小波变换与信号分解重构
(2)自己动手编写小波信号分解与重构的Matlab程序
(3)用自编的程序实现小波图像分解与重构
三、小波图像融合专题
(1)小波图像融合综述
(2)小波图像融合的Matlab实现示例
四、小波图像压缩专题
(1)基于小波变换的图像压缩技术初探
(2)零树小波图像压缩专题
(3)嵌入式小波零树(EZW)算法的过程详解和Matlab代码
(4)多级树集合分裂(SPIHT)算法的过程详解与Matlab实现
(5)讨论:一种基于状态位图的SPIHT改进算法
另外,附件 Wavelet.rar 给出了几个Matlab程序,分别是:
1、基于低频融合策略的小波图像融合程序(Imfus.rar);
2、嵌入式零树小波(EZW)算法的图像压缩编解码程序(EZW.rar);
3、多级树集合分裂(SPIHT)算法的图像压缩编解码程序(SPIHT.rar);
4、一种SPIHT改进算法(Mod-SPIHT.rar)。
其中都包含了基本的小波图像分解与重构程序,使用的是基本的Haar小波,根据Mallat算法编写。
matlab的小波变换源代码可以用来做图像分析:
在 MATLAB 中使用 SVD 压缩图像
【中文标题】在 MATLAB 中使用 SVD 压缩图像【英文标题】:Using SVD to compress an image in MATLAB 【发布时间】:2012-11-16 21:12:06 【问题描述】:我是 MATLAB 的新手,但我正在尝试为灰度图像做一些图像压缩代码。
问题
如何使用 SVD 修剪低值特征值以重建压缩图像?
目前的工作/尝试
到目前为止我的代码是:
B=imread('images1.jpeg');
B=rgb2gray(B);
doubleB=double(B);
%read the image and store it as matrix B, convert the image to a grayscale
photo and convert the matrix to a class 'double' for values 0-255
[U,S,V]=svd(doubleB);
这使我能够成功地分解图像矩阵,其特征值存储在变量 S 中。
如何截断 S(即 167x301,双精度类)?假设我只想取前 100 个(或任何 n 个)的 167 个特征值,我该怎么做并重建压缩图像?
更新的代码/想法
我没有在 cmets 部分放一堆代码,这是我目前的草稿。我已经能够通过手动更改 N 成功创建压缩图像,但我还想做两件事:
1- 为各种压缩显示一组图像(即,为 N = 5、10、25 等运行循环)
2- 以某种方式计算每个图像与原始图像之间的差异(误差)并绘制图表。
我对循环和输出的理解很糟糕,但这是我尝试过的:
B=imread('images1.jpeg');
B=rgb2gray(B);
doubleB=im2double(B);%
%read the image and store it as matrix B, convert the image to a grayscale
%photo and convert the image to a class 'double'
[U,S,V]=svd(doubleB);
C=S;
for N=[5,10,25,50,100]
C(N+1:end,:)=0;
C(:,N+1:end)=0;
D=U*C*V';
%Use singular value decomposition on the image doubleB, create a new matrix
%C (for Compression diagonal) and zero out all entries above N, (which in
%this case is 100). Then construct a new image, D, by using the new
%diagonal matrix C.
imshow(D);
error=C-D;
end
显然有一些错误,因为我没有得到多张图片或知道如何“绘制”错误矩阵
【问题讨论】:
【参考方案1】:取前 n 个最大特征值及其对应的特征向量可能会解决您的问题。对于 PCA,原始数据乘以第一个升序特征向量将构建您的图像,其中 d 表示特征向量的数量。
【讨论】:
【参考方案2】:首先,我假设您知道 SVD 确实不是对单个图像中的像素进行去相关的最佳工具。但这是一种很好的做法。
好的,所以我们知道B = U*S*V'
。我们知道 S 是对角线,并按大小排序。因此,仅使用 S 的前几个值,您将获得图像的近似值。假设C=U*S2*V'
,其中 S2 是修改后的 S。U 和 V 的大小没有改变,所以现在最简单的做法是将 S 中不想使用的元素归零,然后运行重建。 (最简单的方法是:S2=S; S2(N+1:end, :) = 0; S2(:, N+1:end) = 0;
)。
现在是压缩部分。 U
已满,V
也已满,所以无论 S2
发生什么情况,您的数据量都不会改变。但是看看U*S2
会发生什么。 (绘制图像)。如果您在 S2
中保留 N 个奇异值,则只有 S2
的前 N 行是非零的。压缩!除了你仍然需要处理V
。在你已经完成(U*S2)
之后,你不能使用相同的技巧,因为更多的U*S2
是非零的而不是S2
本身。我们如何在两边都使用 S2?嗯,它是对角线,所以使用D=sqrt(S2)
,现在使用C=U*D*D*V'
。所以现在U*D
只有 N 个非零行,D*V'
只有 N 个非零列。只传输这些量,你就可以重构出 C,它与 B 差不多。
【讨论】:
感谢您的详尽解释。如果我有问题/问题,我会看看这个并回来。 目前这是我正在使用的代码:B=imread('images1.jpeg'); B=rgb2gray(B); doubleB=double(B); [U,S,V]=svd(doubleB); C=S; N=100; C(N+1:end,:)=0; C(:,N+1:end)=0; D=U*C*V'; imshow(D);
,无论我做什么 N,似乎新图像都是相同的(而且看起来非常粗略)。作为参考,S 为 167x301。我做错了什么?
嗯,实际上,当我运行 imshow(doubleB) 时,图像看起来很糟糕......看起来不像原来的
尝试使用 im2double(B) 代替 double(B)
我刚刚在原始帖子中添加了一些额外的代码和想法。无法理解如何从循环输出图像(更改 N)以及绘制压缩和原始图像之间的差异/错误。【参考方案3】:
虽然这个问题很老,但它对我理解 SVD 有很大帮助。我已经修改了您在问题中编写的代码以使其正常工作。
我相信您可能已经解决了这个问题,但只是为了供任何访问此页面的人将来参考,我在此处包含完整的代码以及输出图像和图表。
下面是代码:
close all
clear all
clc
%reading and converting the image
inImage=imread('fruits.jpg');
inImage=rgb2gray(inImage);
inImageD=double(inImage);
% decomposing the image using singular value decomposition
[U,S,V]=svd(inImageD);
% Using different number of singular values (diagonal of S) to compress and
% reconstruct the image
dispEr = [];
numSVals = [];
for N=5:25:300
% store the singular values in a temporary var
C = S;
% discard the diagonal values not required for compression
C(N+1:end,:)=0;
C(:,N+1:end)=0;
% Construct an Image using the selected singular values
D=U*C*V';
% display and compute error
figure;
buffer = sprintf('Image output using %d singular values', N)
imshow(uint8(D));
title(buffer);
error=sum(sum((inImageD-D).^2));
% store vals for display
dispEr = [dispEr; error];
numSVals = [numSVals; N];
end
% dislay the error graph
figure;
title('Error in compression');
plot(numSVals, dispEr);
grid on
xlabel('Number of Singular Values used');
ylabel('Error between compress and original image');
将此应用于以下图像:
仅使用前 5 个奇异值给出以下结果,
前 30 个奇异值,
以及前 55 个奇异值,
如下图所示,随着奇异值数量的增加,误差的变化。
您可以注意到,该图显示使用大约 200 个第一奇异值会产生大约零误差。
【讨论】:
【参考方案4】:例如,这是Lena 的 512 x 512 黑白图像:
我们计算 Lena 的 SVD。选择大于最大奇异值 1% 的奇异值,我们只剩下 53 个奇异值。用这些奇异值和对应的(左右)奇异向量重构Lena,我们得到Lena的low-rank approximation:
我们可以存储 2 x (512 x 53) + 53 = 54325 个值,而不是存储 512 * 512 = 262144 个值(每个值占用 8 位),这大约是原始大小的 20%。这是如何使用 SVD 进行有损图像压缩的一个示例。
这是 MATLAB 代码:
% open Lena image and convert from uint8 to double
Lena = double(imread('LenaBW.bmp'));
% perform SVD on Lena
[U,S,V] = svd(Lena);
% extract singular values
singvals = diag(S);
% find out where to truncate the U, S, V matrices
indices = find(singvals >= 0.01 * singvals(1));
% reduce SVD matrices
U_red = U(:,indices);
S_red = S(indices,indices);
V_red = V(:,indices);
% construct low-rank approximation of Lena
Lena_red = U_red * S_red * V_red';
% print results to command window
r = num2str(length(indices));
m = num2str(length(singvals));
disp(['Low-rank approximation used ',r,' of ',m,' singular values']);
% save reduced Lena
imwrite(uint8(Lena_red),'Reduced Lena.bmp');
【讨论】:
以上是关于matlab 图像压缩问题的主要内容,如果未能解决你的问题,请参考以下文章