qinguan
2010-01-09, 12:19
DCT图像压缩一般分几部分:分块、DCT变换、量化、编码、解码、DCT逆变换、合成。
我自己编了个图像压缩程序,但其中的解码部分出现了数组越界问题,很纳闷。。
我开始测试encode和dcede函数的时候是正确的,也就是编码解码后是可以还原到原来的矩阵的。
但当我输入一幅RGB图像时,才出现问题。
报错语句:x(s,r)=data(t);
主要是x的范围大于了data的范围,导致越界。但本来应该是x和data的大小是一样的。
结果data变小了,不知什么原因。。。
编码部分采用了游程编码算法。。。
就是把一个二维矩阵先转换成一维序列,再对一维序列进行编码。
解码部分是根据图像大小,申请一个空间,然后再根据编码提供的(值,数目)序列,先还原成一维序列,再还原成二维矩阵。
求高人解答。谢谢。
%编码
%x为一维序列
%若y为二维矩阵,则x=y(:)
function [value,num]=encode(x)
j=1;
num(1)=1;
for z=1:1:(length(x)-1)
if x(z)==x(z+1)
num(j)=num(j)+1;
else
value(j)=x(z);
j=j+1;
num(j)=1;
end
end
value(j)=x(length(x));
%=========================================================
%解码
%m\n为原矩阵大小
%value\num为编码后的两个值
function x=dcode(m,n,value,num)
x=zeros(m,n);
k=1;
[value1,value2]=size(value);
%还原成一维序列
for i=1:1:value2
for j=1:1:num(i)
data(k)=value(1,i);
k=k+1;
end
end
disp('data:');
disp(size(data));
%还原矩阵
t=1;
for r=1:1:n
for s=1:1:m
x(s,r)=data(t);
t=t+1;
end
end
%=====================================================
%主函数
%下面是对彩色图像的DCT变换处理
clear;
close all;
%读取图像
RGB =imread('D:\Program Files\MATLAB\pics\8.jpg');
%将RGB转换为灰度图像
GRAY = rgb2gray(RGB);
%掩模
mask = [1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];
%RGB图分层处理,得到三个分量图
R1 = RGB(:,:,1);
G1 = RGB(:,:,2);
B1 = RGB(:,:,3);
%转化为双精度
IR = im2double(R1);
IG = im2double(G1);
IB = im2double(B1);
%三个分量图像处理
%分别对图像进行分块,DCT变换,
RR = blkproc(IR,[8 8],'dct2');
GG = blkproc(IG,[8 8],'dct2');
BB = blkproc(IB,[8 8],'dct2');
%保留部分DCT系数
RR2 = blkproc(RR,[8 8],'P1.*x',mask);
GG2 = blkproc(GG,[8 8],'P1.*x',mask);
BB2 = blkproc(BB,[8 8],'P1.*x',mask);
%编码
[value_R,num_R]=encode(RR2(:));
[value_G,num_G]=encode(GG2(:));
[value_B,num_B]=encode(BB2(:));
%取得大小参数
[p_R,q_R]=size(RR2);
[p_G,q_G]=size(GG2);
[p_B,q_B]=size(BB2);
%解码
RR2=dcode(p_R,q_R,value_R,num_G);
GG2=dcode(p_G,q_G,value_G,num_G);
BB2=dcode(p_B,q_B,value_B,num_B);
%DCT逆变换操作
R2 = blkproc(RR2,[8 8],'idct2');
G2 = blkproc(GG2,[8 8],'idct2');
B2 = blkproc(BB2,[8 8],'idct2');
%将三个分量图像整合,RGB2即为重构后的真彩图
RGB2(:,:,1)=R2;
RGB2(:,:,2)=G2;
RGB2(:,:,3)=B2;
figure('Name','原始真彩图'),imshow(RGB);
figure('Name','分层处理进行DCT变换整合后的效果'),imshow(RGB2);
我自己编了个图像压缩程序,但其中的解码部分出现了数组越界问题,很纳闷。。
我开始测试encode和dcede函数的时候是正确的,也就是编码解码后是可以还原到原来的矩阵的。
但当我输入一幅RGB图像时,才出现问题。
报错语句:x(s,r)=data(t);
主要是x的范围大于了data的范围,导致越界。但本来应该是x和data的大小是一样的。
结果data变小了,不知什么原因。。。
编码部分采用了游程编码算法。。。
就是把一个二维矩阵先转换成一维序列,再对一维序列进行编码。
解码部分是根据图像大小,申请一个空间,然后再根据编码提供的(值,数目)序列,先还原成一维序列,再还原成二维矩阵。
求高人解答。谢谢。
%编码
%x为一维序列
%若y为二维矩阵,则x=y(:)
function [value,num]=encode(x)
j=1;
num(1)=1;
for z=1:1:(length(x)-1)
if x(z)==x(z+1)
num(j)=num(j)+1;
else
value(j)=x(z);
j=j+1;
num(j)=1;
end
end
value(j)=x(length(x));
%=========================================================
%解码
%m\n为原矩阵大小
%value\num为编码后的两个值
function x=dcode(m,n,value,num)
x=zeros(m,n);
k=1;
[value1,value2]=size(value);
%还原成一维序列
for i=1:1:value2
for j=1:1:num(i)
data(k)=value(1,i);
k=k+1;
end
end
disp('data:');
disp(size(data));
%还原矩阵
t=1;
for r=1:1:n
for s=1:1:m
x(s,r)=data(t);
t=t+1;
end
end
%=====================================================
%主函数
%下面是对彩色图像的DCT变换处理
clear;
close all;
%读取图像
RGB =imread('D:\Program Files\MATLAB\pics\8.jpg');
%将RGB转换为灰度图像
GRAY = rgb2gray(RGB);
%掩模
mask = [1 1 1 1 0 0 0 0
1 1 1 0 0 0 0 0
1 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0];
%RGB图分层处理,得到三个分量图
R1 = RGB(:,:,1);
G1 = RGB(:,:,2);
B1 = RGB(:,:,3);
%转化为双精度
IR = im2double(R1);
IG = im2double(G1);
IB = im2double(B1);
%三个分量图像处理
%分别对图像进行分块,DCT变换,
RR = blkproc(IR,[8 8],'dct2');
GG = blkproc(IG,[8 8],'dct2');
BB = blkproc(IB,[8 8],'dct2');
%保留部分DCT系数
RR2 = blkproc(RR,[8 8],'P1.*x',mask);
GG2 = blkproc(GG,[8 8],'P1.*x',mask);
BB2 = blkproc(BB,[8 8],'P1.*x',mask);
%编码
[value_R,num_R]=encode(RR2(:));
[value_G,num_G]=encode(GG2(:));
[value_B,num_B]=encode(BB2(:));
%取得大小参数
[p_R,q_R]=size(RR2);
[p_G,q_G]=size(GG2);
[p_B,q_B]=size(BB2);
%解码
RR2=dcode(p_R,q_R,value_R,num_G);
GG2=dcode(p_G,q_G,value_G,num_G);
BB2=dcode(p_B,q_B,value_B,num_B);
%DCT逆变换操作
R2 = blkproc(RR2,[8 8],'idct2');
G2 = blkproc(GG2,[8 8],'idct2');
B2 = blkproc(BB2,[8 8],'idct2');
%将三个分量图像整合,RGB2即为重构后的真彩图
RGB2(:,:,1)=R2;
RGB2(:,:,2)=G2;
RGB2(:,:,3)=B2;
figure('Name','原始真彩图'),imshow(RGB);
figure('Name','分层处理进行DCT变换整合后的效果'),imshow(RGB2);