一种基于MATLAB的JPEG图像压缩具体实现方法
基于Matlab的JPEG图像压缩编码仿真实现

基于Matlab的图像压缩实现_曹玉茹

29982009,30(12)计算机工程与设计Computer Engineering and Design0引言虽然表示图像需要大量的数据,但图像数据是高度相关的,或者说存在冗余信息,去掉这些冗余信息后可以有效压缩图像,同时又不会损害图像的有效信息。
数字图像的冗余主要表现为以下几种形式:空间冗余、时间冗余、视觉冗余、信息熵冗余、符号冗余、结构冗余和知识冗余。
由于在图像数据中存在如此多的冗余信息,因此,这为图像压缩编码提供了依据。
经过压缩之后的图像,其容量可以大大减少,更加方便存储和传输。
我们平常所拍摄的数码图像都含有非常大的数据量,它与通信网容量的矛盾及其传输和存储的困难都极大地制约了数字图像的发展。
图像压缩编码最根本的目的就是要以尽量少的比特数来表征图像,同时要保持解压缩后图像的质量,使之符合拍摄者的要求。
与此同时,由于拍摄者的水平参差不齐,往往拍摄的图像会不尽如人意。
因此,对原始图像的二次处理也成为一个非常引人注目的课题。
传统的图像压缩方法主要是基于DCT 变换的压缩。
由于DCT 除了具有一般的正交变换性质外,它的变换阵的基向量能很好地描述人类语音信号和图像信号的相关特征。
因此,在对语音信号、图像信号的变换中,DCT 变换被认为是一种准最佳变换。
近年颁布的一系列视频压缩编码的国际标准建议中,都把DCT 作为其中的一个基本处理模块。
除此之外,DCT 还是一种可分离的变换。
现在新型的图像压缩有了这样一个趋势,即从基于DCT 变换的压缩转向基于小波信号进行压缩。
由于小波的种类繁多,利用不同的小波可以进行不同图像的压缩,而且相对于DCT 压缩,小波图像对彩色图像的压缩更加方便简单(在以后的实验将会提到)。
因此,运用小波进行图像压缩越来越广泛,最新的JEPG2000图像压缩格式就开始基于小波对图像进行压缩编码。
本文就数码图像压缩进行研究,运用Matlab 软件在DCT 域和小波域上实现图像压缩编码理论算法及其仿真实验的实现。
matlab实现jpeg算法进行图像压缩的源代码

function jpeg %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% THIS WORK IS SUBMITTED BY:%%%% OHAD GAL%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%close all;% ==================% section 1.2 + 1.3% ==================% the following use of the function:%% plot_bases( base_size,resolution,plot_type )%% will plot the 64 wanted bases. I will use "zero-padding" forincreased resolution% NOTE THAT THESE ARE THE SAME BASES !% for reference I plot the following 3 graphs:% a) 3D plot with basic resolution (64 plots of 8x8 pixels) using "surf" function% b) 3D plot with x20 resolution (64 plots of 160x160 pixels) using "mesh" function% c) 2D plot with x10 resolution (64 plots of 80x80 pixels) using "mesh" function% d) 2D plot with x10 resolution (64 plots of 80x80 pixels) using "imshow" function%% NOTE: matrix size of pictures (b),(c) and (d), can support higher frequency = higher bases% but I am not asked to draw these (higher bases) in this section ! % the zero padding is used ONLY for resolution increase !%% get all base pictures (3D surface figure)plot_bases( 8,1,'surf3d' );% get all base pictures (3D surface figure), x20 resolutionplot_bases( 8,20,'mesh3d' );% get all base pictures (2D mesh figure), x10 resolutionplot_bases( 8,10,'mesh2d' );% get all base pictures (2D mesh figure), x10 resolutionplot_bases( 8,10,'gray2d' );% ==================% section 1.4 + 1.5% ==================% for each picture {'0'..'9'} perform a 2 dimensional dct on 8x8 blocks.% save the dct inside a cell of the size: 10 cells of 128x128 matrix% show for each picture, it's dct 8x8 block transform.for idx = 0:9% load a pictureswitch idxcase {0,1}, input_image_128x128 =im2double( imread( sprintf( '%d.tif',idx ),'tiff' ) );otherwise, input_image_128x128 =im2double( imread( sprintf( '%d.tif',idx),'jpeg' ) );end% perform DCT in 2 dimension over blocks of 8x8 in the given picture dct_8x8_image_of_128x128{idx+1} =image_8x8_block_dct( input_image_128x128 );if (mod(idx,2)==0)figure;endsubplot(2,2,mod(idx,2)*2+1);imshow(input_image_128x128);title( sprintf('image #%d',idx) );subplot(2,2,mod(idx,2)*2+2);imshow(dct_8x8_image_of_128x128{idx+1});title( sprintf('8x8 DCT of image #%d',idx) );end% ==================% section 1.6% ==================% do statistics on the cell array of the dct transforms% create a matrix of 8x8 that will describe the value of each "dct-base"% over the transform of the 10 given pictures. since some of the values are% negative, and we are interested in the energy of the coefficients, we will% add the abs()^2 values into the matrix.% this is consistent with the definition of the "Parseval relation" in Fourier Coefficients% initialize the "average" matrixmean_matrix_8x8 = zeros( 8,8 );% loop over all the picturesfor idx = 1:10% in each picture loop over 8x8 elements (128x128 = 256 * 8x8 elements)for m = 0:15for n = 0:15mean_matrix_8x8 = mean_matrix_8x8 + ...abs( dct_8x8_image_of_128x128{idx}(m*8+[1:8],n*8+[1:8]) ).^2;endendend% transpose the matrix since the order of the matrix is elements along the columns,% while in the subplot function the order is of elements along the rows mean_matrix_8x8_transposed = mean_matrix_8x8';% make the mean matrix (8x8) into a vector (64x1)mean_vector = mean_matrix_8x8_transposed(:);% sort the vector (from small to big)[sorted_mean_vector,original_indices] = sort( mean_vector );% reverse order (from big to small)sorted_mean_vector = sorted_mean_vector(end:-1:1);original_indices = original_indices(end:-1:1);% plot the corresponding matrix as asked in section 1.6figure;for idx = 1:64subplot(8,8,original_indices(idx));axis off;h = text(0,0,sprintf('%4d',idx));set(h,'FontWeight','bold');text(0,0,sprintf('\n_{%1.1fdb}',20*log10(sorted_mean_vector(idx)) ));end% add a title to the figuresubplot(8,8,4);h = title( 'Power of DCT coefficients (section 1.6)' );set( h,'FontWeight','bold' );% ==================% section 1.8% ==================% picture 8 is chosen% In this section I will calculate the SNR of a compressed image againts% the level of compression. the SNR calculation is defined in the header% of the function: <<calc_snr>> which is given below.%% if we decide to take 10 coefficients with the most energy, we will% zeros to the other coefficients and remain with a vector 64 elements long% (or a matrix of 8x8)% load the original imageoriginal_image = im2double( imread( '8.tif','jpeg' ) );% I will use this matrix to choose only the wanted number ofcoefficients% the matrix is initialized to zeros -> don't choose any coefficient at allcoef_selection_matrix = zeros(8,8);% compressed picture set (to show the degrading)compressed_set = [1 3 5 10 15 20 30 40];% this loop will choose each time, the "next-most-energetic"coefficient,% to be added to the compressed image -> and thus to improove the SNRfor number_of_coefficient = 1:64% find the most energetic coefficient from the mean_matrix[y,x] = find(mean_matrix_8x8==max(max(mean_matrix_8x8)));% select if for the compressed imagecoef_selection_matrix(y,x) = 1;% replicate the selection matrix for all the parts of the dct transform% (remember that the DCT transform creates a set of 8x8 matrices, where% in each matrix I need to choose the coefficients defined by the % <<coef_selection_matrix>> matrix )selection_matrix = repmat( coef_selection_matrix,16,16 );% set it as zero in the mean_matrix, so that in the next loop, we will% choose the "next-most-energetic" coefficientmean_matrix_8x8(y,x) = 0;% choose the most energetic coefficients from the original image% (total of <<number_of_coefficient>> coefficients for this run in the loop)compressed_image = image_8x8_block_dct(original_image) .*selection_matrix;% restore the compressed image from the given set of coeficientsrestored_image = image_8x8_block_inv_dct( compressed_image );% calculate the snr of this image (based on the original image)SNR(number_of_coefficient) =calc_snr( original_image,restored_image );if ~isempty(find(number_of_coefficient==compressed_set))if (number_of_coefficient==1)figure;subplot(3,3,1);imshow( original_image );title( 'original image' );endsubplot(3,3,find(number_of_coefficient==compressed_set)+1);imshow( restored_image );title( sprintf('restored image with %dcoeffs',number_of_coefficient) );endend% plot the SNR graphfigure;plot( [1:64],20*log10(SNR) );xlabel( 'numer of coefficients taken for compression' );ylabel( 'SNR [db] ( 20*log10(.) )' );title( 'SNR graph for picture number 8, section 1.8' );grid on; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%% --------------------------------------------------------------------------------%% I N N E R F U N C T I O N I M P L E M E N T A T I O N%% --------------------------------------------------------------------------------%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%% ---------------------------------------------------------------------------------% pdip_dct2 - implementation of a 2 Dimensional DCT%% assumption: input matrix is a square matrix !% ---------------------------------------------------------------------------------function out = pdip_dct2( in )% get input matrix sizeN = size(in,1);% build the matrixn = 0:N-1;for k = 0:N-1if (k>0)C(k+1,n+1) = cos(pi*(2*n+1)*k/2/N)/sqrt(N)*sqrt(2);elseC(k+1,n+1) = cos(pi*(2*n+1)*k/2/N)/sqrt(N);endendout = C*in*(C');% ---------------------------------------------------------------------------------% pdip_inv_dct2 - implementation of an inverse 2 Dimensional DCT%% assumption: input matrix is a square matrix !% ---------------------------------------------------------------------------------function out = pdip_inv_dct2( in )% get input matrix sizeN = size(in,1);% build the matrixn = 0:N-1;for k = 0:N-1if (k>0)C(k+1,n+1) = cos(pi*(2*n+1)*k/2/N)/sqrt(N)*sqrt(2);elseC(k+1,n+1) = cos(pi*(2*n+1)*k/2/N)/sqrt(N);endendout = (C')*in*C;% ---------------------------------------------------------------------------------% plot_bases - use the inverse DCT in 2 dimensions to plot the base pictures%% Note: we can get resolution be zero pading of the input matrix% that is by calling: in = zeros(base_size*resolution)% where: resolution is an integer > 1% So I will use zero pading for resolution (same as in the fourier theory)% instead of linear interpolation.% ---------------------------------------------------------------------------------function plot_bases( base_size,resolution,plot_type )figure;for k = 1:base_sizefor l = 1:base_sizein = zeros(base_size*resolution);in(k,l) = 1; % "ask" for the "base-harmonic (k,l)"subplot( base_size,base_size,(k-1)*base_size+l );switch lower(plot_type)case'surf3d', surf( pdip_inv_dct2( in ) );case'mesh3d', mesh( pdip_inv_dct2( in ) );case'mesh2d', mesh( pdip_inv_dct2( in ) ); view(0,90);case'gray2d', imshow( 256*pdip_inv_dct2( in ) );endaxis off;end% add a title to the figuresubplot(base_size,base_size,round(base_size/2));h = title( 'Bases of the DCT transform (section 1.3)' );set( h,'FontWeight','bold' );% ---------------------------------------------------------------------------------% image_8x8_block_dct - perform a block DCT for an image% ---------------------------------------------------------------------------------function transform_image = image_8x8_block_dct( input_image )transform_image = zeros( size( input_image,1 ),size( input_image,2 ) ); for m = 0:15for n = 0:15transform_image( m*8+[1:8],n*8+[1:8] ) = ...pdip_dct2( input_image( m*8+[1:8],n*8+[1:8] ) );endend% ---------------------------------------------------------------------------------% image_8x8_block_inv_dct - perform a block inverse DCT for an image% ---------------------------------------------------------------------------------function restored_image = image_8x8_block_inv_dct( transform_image ) restored_image =zeros( size( transform_image,1 ),size( transform_image,2 ) );for m = 0:15for n = 0:15restored_image( m*8+[1:8],n*8+[1:8] ) = ...pdip_inv_dct2( transform_image( m*8+[1:8],n*8+[1:8] ) );endend% ---------------------------------------------------------------------------------% calc_snr - calculates the snr of a figure being compressed%% assumption: SNR calculation is done in the following manner:% the deviation from the original image is considered% to be the noise therefore:%% noise = original_image - compressed_image%% the SNR is defined as:%% SNR = energy_of_image/energy_of_noise%% which yields:% SNR = energy_of_image/((original_image-compressed_image)^2)% ---------------------------------------------------------------------------------function SNR = calc_snr( original_image,noisy_image )original_image_energy = sum( original_image(:).^2 );noise_energy = sum( (original_image(:)-noisy_image(:)).^2 );SNR = original_image_energy/noise_energy;以下是1-9号原图像,放到matlab的.m文件目录里,重命名9个图像名为1、2、3、4、5、6、7、8、9。
使用Matlab进行图像压缩的技巧

使用Matlab进行图像压缩的技巧引言图像是一种重要的信息表达方式,广泛应用于数字媒体、通信和计算机视觉等领域。
然而,由于图像所占用的存储空间较大,如何有效地进行图像压缩成为了一个重要的问题。
Matlab作为一种强大的数学计算和数据处理工具,可以提供多种图像压缩的技巧,本文将介绍一些常用且有效的图像压缩技巧。
一、离散余弦变换(Discrete Cosine Transformation, DCT)离散余弦变换是一种将空间域中图像转换为频域中的图像的技术。
在Matlab中,可以通过dct2函数实现离散余弦变换。
该函数将图像分块,并对每个块进行DCT变换,然后将变换后的系数进行量化。
通过调整量化步长,可以实现不同程度的压缩。
DCT在图像压缩中的应用广泛,特别是在JPEG压缩中得到了广泛的应用。
二、小波变换(Wavelet Transformation)小波变换是一种将时域信号转换为时频域信号的技术。
在图像压缩中,小波变换可以将图像表示为不同尺度和频率的小波系数。
通过对小波系数进行量化和编码,可以实现图像的有效压缩。
Matlab提供了多种小波变换函数,如wavedec2和waverec2。
这些函数可以对图像进行多尺度小波分解和重构,从而实现图像的压缩。
三、奇异值分解(Singular Value Decomposition, SVD)奇异值分解是一种将矩阵分解为三个矩阵乘积的技术。
在图像压缩中,可以将图像矩阵进行奇异值分解,并保留较大的奇异值,从而实现图像的压缩。
Matlab提供了svd函数,可以方便地实现奇异值分解。
通过调整保留的奇异值个数,可以实现不同程度的图像压缩。
四、量化(Quantization)量化是将连续数值转换为离散数值的过程。
在图像压缩中,量化用于将变换后的图像系数转换为整数值。
通过调整量化步长,可以实现不同程度的压缩。
在JPEG压缩中,量化是一个重要的步骤,通过调整量化表的参数,可以实现不同质量的压缩图像。
基于Matlab环境的JPEG图像压缩算法

量 化
便 于传输 、 存储和译码器进 行译码 , 这样组织 的数据通常 称 为 JE P G位数据流(P G bt t a 。图像 的离散余弦变换 JE i sem) r
具 有把 高 度 相关 数 据 能 量 集 中 的趋 势 , 正 是 他 用 于 图 像 压 这 缩 的优 点 所 在 , 这 一点 被 广 泛 应 用 于 图 像 压 缩 。对 通 常 的 故 图像 来 说 , 多 数 D T系 数 的值 非 常 接 近 0 如 果 舍 弃 这 些 大 C 。
接近零 的 D T系数 值 , 重构 图像 是并 不会带来 画面质量 C 在
(, =0 d H , I u ) r n ” ul
,
() 5
的 显著 下 降 。所 以 , 用 D T进 行 图 像 压 缩 可 以节 约 大 量 利 C
的存储空间 。压缩应 该在最合 理的近似原 图像 的情 况下使
JE (o t it eepr gop , P G ji c r xe ru ) 即联 合 图像 专家 组 。 np u t
JE P G算法 中首先对 图像进行 分块处理 , 在对 每一 快进行 二 维离散余 弦变换 , 变换后 的系数基 本不相关 , 系数矩 阵的 且
Fu ) c )( ∑ ∑f , ・ (, = ( c ) (y x)
一
于空间线性 预测技术 ( 即差分脉冲编码调制) 算法 , 该算法 属
于无失真压缩算法 ; 2种算 法是基 于离散余 弦变换 、 程 第 行 编码 、 熵编码 的有 失真 压缩算 法。 目前 比较 流行后 一种算 法, 即有失真 D T压缩编码 。 C
基于MATLAB的JPEG压缩编码

本文对 J PEG 压缩 算法进行 了初步的研 究, 并编程 实现 了相应 的算法 , 实验结果进 对 行了分析研究 , 出结论 。 得
1 图像压缩技术的现 状
图像 压缩 技术是 数 字时 代的产 物和 重要 组成部 分 , 它的进步对整个社会 的数字化和信 息化都 有不 可估量 的推 动作用 。 然而 , 尽管各种通信媒介容量越来越大并 且各种 通信 协议不断升级 , 随着通 信量爆 炸式 此 , 图像压缩技术得 到国际上学术界 和工程 界极高 的重视 , 由此得到飞 速发展 。 并 各种 图像和 视频 压缩 国际标 准 己出现并 得到 广泛应用 , 中 J G( 其 PE 用于静态图像压缩) 和 MP G( E 用于动态图像压缩) 应用最广。 图像压缩技术的发展趋势是 : 算法更复杂 , 压 缩率更高 , E J G的压缩率在 1 o P : 左右, E 2 0 2 J G 0o P 的压缩率更高 , E 压缩标准也己经几代的发 MP G
个的进 行的 , 则称 标准量化 , 若量化 是成组的 进行 的, 则称矢量 量化 , 量化总会造成 某些信 息丢失 , 形成失真 , 即量化失真或量化噪声 , 为 使失真小 , 应量化的精细 , 但压缩比就高不 了, 这是一对矛盾 , 应选 用恰当的量化级数和 量化 曲线形状来缓解这对 矛盾 , 量化 器的引入是图 像编码产生失真的根源 , 在要求复原 图像 与原 图完全 一致 的无 失真 编码 器中必 须不 用量化 器, 但这样一来 , 压缩 比难以提 高, 在多数应用 中, 存在少量 失真并不 可怕 , 只要把失真 的程 度和性 质控 制在允许的范 围内 , 也就是把 复原 图像 的主观 质量控制在允许 的程 度内 , 可以 就 在满足 应用要 求的前提下提高 压缩 比 , 得注 值 意 的是 , 对于 同样的量化 失真 , 同的映射变 不 换和 反变换反映不 同性质 的复原图像的失 真 , 人 眼对某 些性 质的 失真 敏感而 对 另一些性 质
jpeg算法实验报告
jpeg算法实验报告JPEG算法实验报告摘要:本实验旨在研究和分析JPEG(Joint Photographic Experts Group)算法的原理和应用。
通过实验,我们对JPEG算法的压缩效果、图像质量和压缩比进行了评估,并对其优缺点进行了探讨。
实验结果表明,JPEG算法在图像压缩方面具有较高的效率和广泛的应用前景。
一、引言JPEG算法是一种广泛应用于图像压缩的算法,它通过对图像进行离散余弦变换(DCT)和量化处理来实现压缩。
JPEG算法以其高效的压缩率和较好的图像质量而在图像处理领域得到广泛应用。
本实验将通过实际操作和实验数据来验证JPEG算法的有效性和优势。
二、实验方法和步骤1. 实验环境和工具:使用MATLAB软件进行实验,选择合适的图像进行处理和压缩。
2. 实验步骤:a. 选择一幅高分辨率的彩色图像作为实验对象。
b. 将图像转换为YCbCr颜色空间,以便进行离散余弦变换。
c. 对图像进行离散余弦变换,得到频域图像。
d. 对频域图像进行量化处理,降低高频分量的精度。
e. 对量化后的图像进行反量化和反离散余弦变换,得到压缩后的图像。
f. 计算压缩后图像与原始图像之间的均方差(MSE)和峰值信噪比(PSNR),评估图像质量。
g. 计算压缩比,评估压缩效果。
三、实验结果和分析在实验中,我们选择了一张分辨率为1920x1080的彩色图像进行处理和压缩。
经过JPEG算法的处理,我们得到了压缩后的图像,并计算了MSE、PSNR和压缩比等指标。
1. 图像质量评估通过计算MSE和PSNR,我们可以评估压缩后图像的质量。
实验结果显示,经过JPEG算法压缩后的图像,MSE较小,PSNR较高,表明图像质量较好。
这是因为JPEG算法通过量化处理,减少了高频分量的细节信息,但保留了图像的主要特征,使得图像在视觉上仍然保持较高的质量。
2. 压缩效果评估通过计算压缩比,我们可以评估JPEG算法的压缩效果。
实验结果显示,JPEG 算法在保持较高图像质量的前提下,能够实现较高的压缩比。
基于Matlab的JPEG图像压缩编码仿真实现
用 Ma a t b做 仿真 实验 , l 方法 简单 而且误 差小 , 大大提 高 了图像 压 缩的效 率和精 度 。 关键 词 : 合 图像 专 家组 ; 联 图像 压 缩算 法 ; 离散 余 弦变换 ; f a Hu m n编码 ; f 峰值 信 噪 比 中图分类 号 :P 1 T 32 文 献标识 码 : A 文章编 号 :01 45(07 1 09 — 3 10 — 5 120 )0— 07 0
( o e eo c a i l n l t c l n ier g H b C l g oaina d Tc n l y H b 4 8 3 ,C ia C l g l fMeh n a a d Ee r a E gn ei , ei ol eo V c t n eh oo , ei 5 0 0 h ) c ci n e f o g n
Ke r s on h tga hee p rsgo p( P ywo d :jitp oolp i x et ru J EG);i g o rsin ag r h 。 ma ec mpe s loi m;dsrt o iet n fr ( Ct o t i e, s r s m D —);lu - c  ̄c n a o l f
S mul to m p e n a i n o i a i n i l me t to fJPEG m a e c mpr s in b s d o a lb i g o e so a e n M ta
Z HA0 W e . ..D nj u ONG Hu— n.Z h. n imi HU Z imi
基于Matlab环境的JPEG图像压缩算法
F( u, v) = C( u) C( v)
y) · ∑ ∑ f( x,
x =0 y =0
π( 2 x + 1 ) u π( 2 y + 1 ) v cos cos 2M 2N
( 1)
收稿日期:2011 - 03 - 15 作者简介:程丽( 1982 —) , 女, 硕士研究生, 讲师, 主要从事系统工程研究 。
21 世纪以来, 随着计算机软硬件以及操作系统的不断 “多媒体技术 ” 发展, 人们对 一词已经耳熟能详, 它有非常重 要的存在必要性, 如图形和图像处理的需要 、 大量数据存储 。“多媒体技术” 的需要等 定义为利用个人计算机对文字 、 图 逻辑关系和人机交互作用的产物 像、 图形、 动3 ] 。 多媒体技术应运而
2011 年 5 月 第 32 卷 第 5 期 四 川 兵 工 学 报 【自动化技术】
基于 Matlab 环境的 JPEG 图像压缩算法
程 丽, 王聪丽, 侯著荣, 王 凯
( 军械工程学院 计算机工程系 , 石家庄 050003 ) 摘要:压缩是多媒体技术得到长足发展的关键技术 , 而图像是多媒体信息的重要组成部分 。 针对图像压缩问题, 分 析了 JPEG 图像压缩系统的原理, 提出了一种基于 DCT 的 JPEG 图像压缩技术, 并在 Matlab 环境下实现了编码和解 演示了一幅图像压缩后的效果 。 码的几个关键步骤, 关键词:图像压缩; DCT; JPEG 图像压缩算法 中图分类号:TP751 文献标识码:A 文章编号:1006 - 0707 ( 2011 ) 05 - 0100 - 03 通过保留低频区部分系数 , 去掉高频区 能量集中在低频区, 的部分, 从而达到压缩目的, 余弦变换时经典谱分析的工具 , 它考察的是整个时域过程中的频域特性 , 或者整个频域过程 中的时域特性, 该算法具有较强的块内去相关的能力 , 适于 较平坦的压缩, 它的特点是没有利用图像中局域间的相关特 性, 在压缩倍数高时, 恢复图像出现明显的方块效应 。 JPEG2000 是由 ISO / IEC JTC1SC29 标准化组织负责的全 新静止图像压缩标准, 一个最大的改进是他采用小波变换代 它既能考查局 替了余弦变换。小波变换是现代谱分析工具 , 部时域过程的频域特性 , 又能考查局部频域过程中的时域问 。 JPEG2000 几何算法在高压缩比下跟传统的 JPEG 压 题 用 缩方式相比, 图像质量并没有明显的降低 , 来自 RAPH LEVIEN 于 2000 年三月所作的对比测试报告表明 : 在中度与低度 的压缩比率下, 传统的 JPEG 表现的更为出色, 但是在较高的 压缩比率下传统的 JPEG 方式就不那么让人满意 , 与传统的 JPEG 压缩方式对比, JPEG2000 的表 在较高的压缩比率小, 现更为优秀。
JPEG图像压缩Matlab程序
% function ReconImage=func_DCTJPEG(I,q)%% 1.This function tests the DCTJPEG codec%% ReconImage=DCTJPEG(I,q),I为待压缩图像,q为量化因子,ReconImage为解压缩重建图像。
%% 2.This function calls:%% blkproc.m,DCHuffmanEncoding.m,ACHuffmanEncoding.m,zigzag.m,PSNR.m, %% 对灰度图像进行DCT变换,量化,ZigZag扫描,Huffman编解码,反量化,反DCT 变换而重建图像。
%% 其中,blkproc.m为分块DCT变换函数;%% DCHuffmanEncoding.m,ACHuffmanEncoding.m分别为DC和AC变换系数的Huffman码表函数;%% zigzag.m为ZigZag扫描函数;PSNR.m为求图像峰值信噪比函数。
%% Copyright 2008 Reserved @ Wang Chengyou @ Tianjin University, P.R.China.%%******************************************************************* *******************%%%%Testclose all;clear all;clc;% fname=input('Please input the bmp image name:','s');%%读一幅bmp灰度图像% [I,map]=imread(fname,'bmp');I=imread('lena512.bmp');%%读bmp灰度图像q=1;%%设定量化因子OriginalImage=I;Q=q;OriginalImage=double(OriginalImage);%%图像数据类型转换ImageSub=OriginalImage-128;%%电平平移128[Row,Col]=size(OriginalImage);%%图像的大小BlockNumber=Row*Col/64;%%8*8分块数%% dct2变换:把ImageSub分成8*8像素块,分别进行dct2变换,得变换系数矩阵CoefCoef=blkproc(ImageSub,[8,8],'dct2(x)');%% 量化:用量化矩阵L量化Coef得CoefAfterQ%% JPEG建议量化矩阵L=Q*[16 11 10 16 24 40 51 6112 12 14 19 26 58 60 5514 13 16 24 40 57 69 5614 17 22 29 51 87 80 6218 22 37 56 68 109 103 7724 35 55 64 81 104 113 9249 64 78 87 103 121 120 10172 92 95 98 112 100 103 99];CoefAfterQ=blkproc(Coef,[8,8],'round(x./P1)',L);%%向靠近的整数取圆整%% 把CoefAfterQ分成8*8的块得分块矩阵CoefBlockm=0;for row=1:Row/8for col=1:Col/8m=m+1;CoefBlock(:,:,m)=CoefAfterQ(((row-1)*8+1):(row*8),((col-1)*8+1):(col*8));endendm;%% 把量化后各个分块的DC系数存放到行矩阵DC中DC(m)=0;for i=1:mDC(i)=CoefBlock(1,1,i);endDC;%% 求由各个DC系数的差值组成的行矩阵DCdifDCdif(BlockNumber)=0;DCdif(1)=DC(1);for i=2:BlockNumberDCdif(i)=DC(i)-DC(i-1);endDCdif;%% 用行矩阵DCdif中的差值替换原来系数矩阵CoefBlock中各个分块的DC系数m=0;for i=1:Row/8for j=1:Col/8m=m+1;CoefBlock(1,1,m)=DCdif(m);endendm;%% 把分块矩阵CoefBlock放到变换系数大矩阵CoefDCchanged中n=0;forrow=1:Row/8for col=1:Col/8n=n+1;CoefDCchanged(((row-1)*8+1):(row*8),((col-1)*8+1):(col*8))=CoefBlock(:,:,n);endendn;%%******************************************************************* *******************************%% 至此,完成了所有块中DC系数的替换(除第一个分块以外),为以后的DC系数差分编码做好了准备%%******************************************************************* *******************************%%*********************** the first--end blocks ************************%% 以下对每个分块进行量化,ZigZag扫描和编码(分别对DC系数和AC系数)%%******************************************************************* ***%% 整个图像编码后的bit序列以及bit序列的长度ImageBitSeq=[];ImageBitLen=[];%% 调试用,用来记循环的次数rowloop=0;for row=1:Row/8colloop=0;for col=1:Col/8m(1:8,1:8)=CoefDCchanged((row-1)*8+1:(row-1)*8+8,(col-1)*8+1:(col-1)*8+8);k= round(m); %% 就近取整%k;%% k为变换系数矩阵经量化并就近取整后的矩阵%% ZigZag Scaning%%*********************************************************t=zigzag(k);%t;%% t为zigzag扫描结果。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一种基于MATLAB的JPEG图像压缩具体实现方法说明:该方法主要是对FPGA硬件实现编码的一个验证,MATLAB处理时尽量选择了简单化和接近硬件实现需要。
JPEG编码解码流程:BMP图像输入、8*8分块、DCT变换、量化、Zig_Zag 扫描、获取DC/AC系数中间格式、Huffman熵编码、DC/AC系数Huffman熵解码,反zig_zag扫描、反量化、反DCT变换、8*8组合、解码图像显示。
下面根据具体代码解释实现过程。
1.BMP图像输入A=imread('messi_b.bmp'); %读取BMP图像矩阵R=int16(A(:,:,1))-128; %读取RGB矩阵,由于DCT时输入为正负输入,G=int16(A(:,:,2))-128; %使得数据分布围-127——127B=int16(A(:,:,3))-128;通过imread函数获取BMP图像的R、G、B三原色矩阵,因为下一步做DCT 转换,二DCT函数要求输入为正负值,所以减去128,使得像素点分布围变为-127~127,函数默认矩阵A的元素为无符号型(uint8),所以如果直接相减差值为负时会截取为0,所以先用int16将像素点的值转为带符号整数。
网上很多都提到了第一步的YUV转换,但是由于MATLAB在实验时YUV转换后色差失真比较严重,这里没有进行YUV转换。
个人理解为YUV转换后经过非R/G/B原理显示器显示效果可能会比较好,或者如果图像有色差可以选择YUV调整。
为了方便,读入的图像像素为400*296,是8*8的50*37倍,所以代码里没有进行8*8的整数倍调整。
2. 8*8分块R_8_8=R(1:8,1:8);%取出一个8*8块这里以R色压缩解码为例,后边解释均为R色编码解码过程,最后附全部代码。
R_8_8为:3.DCT变换R_DCT=dct2(R_8_8);使用MATLAB函数dct2进行DCT变换,也可使用DCT变换矩阵相乘的方法,即R_DCT=A* R_8_8*A T,其中A为DCT变换矩阵。
R_DCT为:4.量化R_dct_s=round(R_DCT./S);使用JPEG标准亮度量化表S量化并取整,S为:R_dct_s为:其中第一个数-14为DC系数,剩余63个数为AC系数,左上角低频,右下角高频,可以看出量化后已经将多数高频量丢弃,从而实现数据压缩。
5.Zig_Zag扫描Rdcts_c=reshape(R_dct_s',1,64);Rdcts_c_z=Rdcts_c(zig);利用reshape函数将量化后的矩阵转为[1,64]行向量,利用zig向量按位取值,进行Zig_Zag扫描。
其中Rdcts_c为:11~64位均为0;zig为:zig=[0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5,12,19,26,33,40,48,41 ,34,27,20,13,6,7,14,21,28,35,42,49,56,57,50,43,36,29,22,15,23,30,37,4 4,51,58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63];Zig_Zag扫描后的向量Rdcts_c_z为:11~64位均为0;可以看出通过zig向量按位取值准确实现了对量化后DC,AC系数的Zig_Zag 扫描。
6.获取DC/AC系数的中间格式r_dc_diff=Rdcts_c_z(1)-r_dc;用当前DC系数减去上一个8*8子块的DC系数得到两DC系数的差值作为DC 系数中间值,因为图像相邻像素具有很大的相关性,这样做可以减小DC编码长度,进一步压缩代码,在解码的时候通过该差值依次获得各8*8子块DC系数。
r_dc=Rdcts_c_z(1);解码之后用该代码将当前DC系数赋给r_dc作为下一次编码时求差值的参考值。
for i=2:1:64;if Rdcts_c_z(i)==0&&r_n<15&&i~=64r_n=r_n+1;elseif Rdcts_c_z(i)==0&&r_n<15&&i==64r_ac_cnt=r_ac_cnt+1;r_AC(1,2*r_ac_cnt-1)=r_n;r_AC(1,2*r_ac_cnt)=Rdcts_c_z(i);r_n=0;elseif Rdcts_c_z(i)~=0&&r_n<15r_ac_cnt=r_ac_cnt+1;r_AC(1,2*r_ac_cnt-1)=r_n;r_AC(1,2*r_ac_cnt)=Rdcts_c_z(i);r_n=0;elseif Rdcts_c_z(i)~=0&&r_n==15r_ac_cnt=r_ac_cnt+1;r_AC(1,2*r_ac_cnt-1)=r_n;r_AC(1,2*r_ac_cnt)=Rdcts_c_z(i);r_n=0;elseif Rdcts_c_z(i)==0&&r_n==15r_ac_cnt=r_ac_cnt+1;r_AC(1,2*r_ac_cnt-1)=r_n;r_AC(1,2*r_ac_cnt)=Rdcts_c_z(i);r_n=0;endend该for循环用来获取AC系数的中间格式,因为第一个数为DC系数,所以循环从2开始。
因为63个AC系数中有很多值为0,所以采用行程编码可以很大的减小编码长度。
行程编码是指记录两个非0数之间0的个数,以及非零数的数值,非零数个数和数值为一组中间格式,这里为了计数方便,连续16个0出现时,用(15,0)表示,继续获取下一个AC系数中间格式,也就是说行程编码压缩的最大长度设为16bit,例如数列:1、0、0、-1、0、0、0、0、0、3、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、0、2;对该列数通过形成编码获取中间格式即为:(0,1)、(2,-1)、(5,3)、(15,0)、(5,2)。
第一个数为0的个数,第二个数为数值,特殊情况(15,0)指16个0。
通过该for循环获取AC系数中间格式并保存在向量Rdcts_c_z中,奇数表示0的个数,偶数表示AC系数数值。
表示前两个数是1,后边共有16*3+13=61个0,与量化表相同。
7. Huffman熵编码熵编码可以根据Huffman算法对每个量化后的矩阵进行现场编码,但是这样会增加传输数据(需要传输编码表),所以这里采用标准HuffmanVLI编码表进行编码,现,这里没有涉及到Huffman亮度表,而是依据VLI编码表,通过DC/AC系数的数值确定位数和编码(编码原理),熵编码由上表中的位数和编码两部分组成,即压缩后的编码包括两部分,然后再依据VLI编码表,通过位数和编码返回DC/AC 系数(解码原理),编码中还包含了AC系数中0的个数。
0的个数和位数均用4bit 二进制数表示。
r_huff=cell(r_ac_cnt+1,3);%%建立三列矩阵保存压缩后的编码,第一例为0的个数,第二列为编码长度,第三例为编码for j=0:1:r_ac_cnt;if j==0[siz,code]=vli(r_dc_diff); %%通过vli编码函数对DC差值进行编码,获得DC差值编码长度和编码,vli函数见附录。
%[siz,code]=vli(r_dc);%%通过vli函数获取AC系数编码及编码长度 r_huff(1,1)=cellstr(dec2bin(0)); %%cellstr将二进制字符串转为cell格式放入矩阵r_huff(1,2)=cellstr(dec2bin(siz,4));%%将哈夫曼编码长度存为4bitr_huff(1,3)=cellstr(dec2bin(code,siz));%%将哈夫曼编码转为二进制r_code_bit=r_code_bit+siz; %%计算编码长度elseif r_AC(2*j)==0r_huff(j+1,1)=cellstr(dec2bin(r_AC(2*j-1),4));%%将0的个数写入第一列r_huff(j+1,2)=cellstr(dec2bin(0));r_huff(j+1,3)=cellstr(dec2bin(0));elser_huff(j+1,1)=cellstr(dec2bin(r_AC(2*j-1),4));[siz,code]=vli(r_AC(2*j));r_huff(j+1,2)=cellstr(dec2bin(siz,4)); %%AC编码长度写入第二列r_huff(j+1,3)=cellstr(dec2bin(code,siz)); %%AC编码写入第三列r_code_bit=r_code_bit+siz; %%计算编码长度endendend压缩后的编码表r_huff如下:此时已将8*8*8=512bit压缩为4+6*8+2+1+1=56bit。
8.DC/AC系数Huffman熵解码i_n=1;for k=1:1:r_ac_cnt+1;if k==1[i_value]=i_vli(r_huff(1,2),r_huff(1,3)) %%i_vli函数解码,i_vli通过编码长度和编码恢复DC/AC系数真值,函数见附录。
i_Rdcts_c_z(1,i_n)=r_dc+i_value;%i_Rdcts_c_z(1,i_n)=r_huff(1,3);i_n=i_n+1;r_dc=Rdcts_c_z(1);elseif bin2dec(r_huff(k,1))==15&&bin2dec(r_huff(k,2))==0i_Rdcts_c_z(1,i_n:i_n+15)=0;%%出现中间格式(15,0)返16个0i_n=i_n+16;elseif bin2dec(r_huff(k,1))==0&&bin2dec(r_huff(k,2))==0 i_Rdcts_c_z(1,i_n)=0; %%出现中间格式(0,0)反1个0,没有具体分析这种情况到底是否存在,但是如果最后一位恰好为0,此时恰好开始新的中间格式计算,i=64时终止计算,则中间格式为(0,0)i_n=i_n+1;elsei_Rdcts_c_z(1,i_n:i_n+bin2dec(r_huff(k,1))-1)=0;%%哈夫曼编码矩阵r_huff中为二进制数,所以用到了bin2deci_n=i_n+bin2dec(r_huff(k,1)); %%通过第一列分解重复的0 i_value=i_vli(r_huff(k,2),r_huff(k,3)); %%通过第二三列,编码长度和编码解出AC系数真值i_Rdcts_c_z(1,i_n)=i_value;%%将解码后的DC/AC系数放入向量i_Rdcts_c_zi_n=i_n+1;endendend9.反Zig_Zag扫描i_Rdcts_c=i_Rdcts_c_z(i_zig); %%反zig_zag扫描i_Rdct_s(1,1:8)=i_Rdcts_c(1:8); %%变为矩阵形式i_Rdct_s(2,1:8)=i_Rdcts_c(9:16);i_Rdct_s(3,1:8)=i_Rdcts_c(17:24);i_Rdct_s(4,1:8)=i_Rdcts_c(25:32);i_Rdct_s(5,1:8)=i_Rdcts_c(33:40);i_Rdct_s(6,1:8)=i_Rdcts_c(41:48);i_Rdct_s(7,1:8)=i_Rdcts_c(49:56);i_Rdct_s(8,1:8)=i_Rdcts_c(57:64);通过按位取值的方法进行反Zig_Zag扫描,并将扫描获得的向量转为8*8矩阵,其中:i_zag为:i_zig=[1,2,6,7,15,16,28,29,3,5,8,14,17,27,30,43,4,9,13,18,26,31,4 2,44,10,12,19,25,32,41,45,54,11,20,24,33,40,46,53,55,21,23,34,39,47,5 2,56,61,22,35,38,48,51,57,60,62,36,37,49,50,58,59,63,64];i_Rdct_s为:(可见该矩阵与量化后的矩阵相同)10.反量化、反DCT变换i_Rdct=round(i_Rdct_s.*S); %%反量化并取整i_R_8_8=round(idct2(i_Rdct)); %%逆DCT变换其中i_R_8_8为:(可见与DCT变换前差别不大)11.解码图像显示for i_r=1:1:37;for i_c=1:1:50;endend用这样一个嵌套for循环将所有8*8子块进行基于DCT变换的JPEG编码解码处理,i_R(i_r*8-7:i_r*8,i_c*8-7:i_c*8)=i_R_8_8; 在循环最后通过该语句将每一个8*8子块放到i_R矩阵中,然后i_R加128得到解码后R色像素矩阵i_RR。