function JPEG_main()
% ********************** JPEG压缩编码算法函数 **************************
% 函数名称:
% JPEG_main()
% 说明:
% 编程实现 子块DCT变换的图像频谱显示;8×8子块DCT变换系数按“Z”(Zig-Zag)扫描的图像重建;
% JPEG压缩编码(进行8×8子块的DCT图像变换,JPEG量化矩阵的量化与反量化,8×8子块DCT的图像重建);
% 计算图像的均方根误差 、显示误差图像和误差直方图。
%
% 调用函数:
% Block=DctBlock(oldbuf,Block) DCT n*n 块频谱函数
% DCTch=DctCode(oldbuf,DCTch) DCT 8*8 块系数“Z”字扫描图像压缩函数
% Scale=JpegCode(oldbuf,Scale) JPEG近似基准编码函数
% eimag(oldbuf,newbuf) 计算均方根误差、显示误差图像和误差直方图函数
% *************************************************************************
clear;close;clc;
Block=3; %块大小
DCTch=1; %
Scale=1;
set(gcf,'name','数字图像实验十五__JPEG压缩编码','numbertitle','off',...
'unit','normalized','position',[0.05,0.1,0.9,0.75],...
'menubar','none');
K=0;
while (K<6) % 菜单选择
K=menu('JPEG菜单','读入图像','n*n DCT频谱+','8*8 DCT压缩+','JPEG压缩编码+','CLOSE');
switch K
case 1
oldbuf=ReadImage; %调用读图像函数
case 2
Block=DctBlock(oldbuf,Block); %调用DCT n*n 块频谱函数
case 3
DCTch=DctCode(oldbuf,DCTch); %调用DCT 8*8 块系数“Z”字扫描图像压缩函数
case 4
Scale=JpegCode(oldbuf,Scale); %调用JPEG近似基准编码函数
case 5
close;clear;
end
end;
%-------------------------------------------------------------------------
function oldbuf=ReadImage;
% *************************************************************************
% 函数名称:
% ReadImage()
% 说明:
% 读入原图像。
% *************************************************************************
oldbuf=imread('lena.bmp');
subplot(2,2,1);
imshow(oldbuf);
title('原图像');
%-------------------------------------------------------------------------
function Block=DctBlock(oldbuf,Block);
% *************************************************************************
% 函数名称:
% DctBlock() DCT n*n 块频谱函数
%
% 参数:
% oldbuf 原图像数组
% Block DCT n*n 当前块选择值
% newbuf 存放处理后的图像二维数组
%
% 说明:
% 根据Block块的当前选择值,计算原图像的n*n块DCT变换,并转换为可视频谱图,
% 有利于频谱的观察。
% *************************************************************************
n=pow2(Block); %分块大小
x=double(oldbuf);
t=dctmtx(n); %取变换矩阵
dctfre=blkproc(x,[n n],'P1 * x * P2',t,t'); %对x进行n*n分块、DCT变换
newbuf=log(abs(dctfre)*5+1); %对数坐标
subplot(2,2,2),imshow(newbuf,[]);
ch = num2str(n);
strch = strcat(ch ,'*' ,ch ,'频谱显示');
title(strch);
subplot(2,2,3),imshow([]);
subplot(2,2,4),imshow([]);
Block=Block+1;
if Block==9 Block=3; end
%-------------------------------------------------------------------------
function DCTch=DctCode(oldbuf,DCTch)
% *************************************************************************
% 函数名称:
% DctCode() DCT 8*8 块系数“Z”字扫描图像压缩函数
%
% 参数:
% oldbuf 原图像数组
% DCTch DCT 8*8 块“Z”扫描当前系数选择值
% newbuf 存放处理后的图像二维数组
%
% 说明:
% 计算图像的8×8子块DCT变换,按“Z”字扫描顺序,根据DCTch参数,只保留64个
% DCT系数中的前DCTch个系数,对修改后的DCT系数用逆DCT变换重建图像,得到DCT变
% 换的压缩图像。计算重建图像的均方根误差RMSE ;显示误差图像和误差直方图。
% *************************************************************************
zigzag=[1 2 6 7 15 16 28 29 %设置z扫描顺序
3 5 8 14 17 27 30 43
4 9 13 18 26 31 42 44
10 12 19 25 32 41 45 54
11 20 24 33 40 46 53 55
21 23 34 39 47 52 56 61
22 35 38 48 51 57 60 62
36 37 49 50 58 59 63 64];
tbuf=ones(8);
maskbuf=tbuf .* zigzag<=DCTch; %模板:保留前DCTch个数据,其余置零
x=double(oldbuf);
t=dctmtx(8);
dctfre=blkproc(x,[8 8],'P1 * x * P2',t,t'); %正变换
y=blkproc(dctfre,[8 8],' x.* P1',maskbuf); %保留每个块的前DCTch个数据,其余置零
newbuf=blkproc(y,[8 8],'P1 * x * P2',t',t); %反变换,重构图像
subplot(2,2,2),imshow(uint8(newbuf));
ch= num2str(DCTch);
strch = strcat('取',ch,'个DCT系数时的压缩图像');
title(strch);
eimag(oldbuf,newbuf);
DCTch=DCTch+1;
if DCTch==11 DCTch=1; end
%-------------------------------------------------------------------------
function Scale=JpegCode(oldbuf,Scale);
% *************************************************************************
% 函数名称:
% JpegCode() JPEG近似基准编码函数
%
% 参数:
% oldbuf 原图像数组
% newbuf 存放处理后的图像二维数组
% Scale 乘积因子,通过对标准量化表AC系数的Q倍乘,对图像作不同的量化,得到不同的压缩比。
%
% 说明:
% 实现JPEG压缩编码。进行 8×8 子块DCT变换,JPEG量化矩阵的量化与反量化,8×8子块DCT的
% 图像重建。计算重建图像的均方根误差RMSE ;显示误差图像和误差直方图。该函数没有进行熵编码,
% 只是一个近似JPEG的编解码处理。
% *************************************************************************
Z = [16 11 10 16 24 40 51 61. %亮度量化矩阵
12 12 14 19 26 58 60 55
14 13 16 24 40 57 69 56
14 17 22 29 51 87 80 62
18 22 37 56 68 109 103 77
24 35 55 64 81 104 113 92
49 64 78 87 103 121 120 101
72 92 95 98 112 100 103 99] * Scale ;
%Z(1)=16;
x=double(oldbuf);
t=dctmtx(8);
dctfre=blkproc(x,[8 8],'P1 * x * P2',t,t'); %8*8分块、变换后组成图像
quacoe=blkproc(dctfre,[8 8],'round(x ./ P1)',Z); %对8*8块用亮度量化矩阵量化、取整后组合成图像
iquacoe=blkproc(quacoe,[8 8],' x .* P1',Z); %反量化
newbuf=blkproc(iquacoe,[8 8],'P1 * x * P2',t',t); %反变换
subplot(2,2,2),imshow(uint8(newbuf));
ch= num2str(Scale);
strch = strcat('Scale为',ch,'时的JPEG压缩图像');
title(strch);
eimag(oldbuf,newbuf); %计算误差
Scale=Scale+1;
if Scale==6 Scale=1; end
%-------------------------------------------------------------------------
function eimag(oldbuf,newbuf)
% *************************************************************************
% 函数名称:
% eimag()
% 说明:
% 计算重建图像的均方根误差RMSE ;显示误差图像和误差直方图。
% *************************************************************************
e = double(oldbuf)-newbuf; %误差图像
[m,n]=size(e);
RMSE=sqrt(sum(e(:).^2) / (m*n)); %计算均方根误差
if RMSE
emax = max(abs(e(:))); % 误差极值
[h,x] = hist(e(:),emax) %(对误差列直方图,以emax为灰度级)直方图(纵、横坐标)
if length(h) >= 1 % 归一化。。。
s=max(h(:));
subplot(2,2,3),bar(x,h/s); %绘图,横坐标x,纵坐标h/s (归一化)
RMSE = num2str(RMSE); %转换成字符串
strRMSE = strcat('图像差值直方图 均方根误差RMSE= ',RMSE); %接成长串
title(strRMSE);
e = mat2gray(e,[-emax,emax]); %误差化成灰度图像:emax对应1,-emax对应0
subplot(2,2,4),imshow(e); %显示误差灰度图像
title('原图像与压缩图像的差值图像');
end
%figure(1),plot(h)
end;
%-------------------------------------------------------------------------
评论0