|
| 1 | +- [Matlab实现图像压缩](#matlab实现图像压缩) |
| 2 | + - [目的](#目的) |
| 3 | + - [原理](#原理) |
| 4 | + - [图像压缩原理](#图像压缩原理) |
| 5 | + - [离散余弦变换(DCT)图像压缩原理](#离散余弦变换dct图像压缩原理) |
| 6 | + - [行程编码(RLE)原理](#行程编码rle原理) |
| 7 | + - [步骤](#步骤) |
| 8 | + - [MATLAB 中的变长码映射](#matlab-中的变长码映射) |
| 9 | + - [离散余弦变换(DCT)图像压缩](#离散余弦变换dct图像压缩) |
| 10 | + - [利用离散余弦变换进行JPEG 图像压缩](#利用离散余弦变换进行jpeg-图像压缩) |
| 11 | + |
| 12 | + |
| 13 | +# Matlab实现图像压缩 |
| 14 | + |
| 15 | +## 目的 |
| 16 | + |
| 17 | +1. 理解图像压缩的相关概念及图像压缩的主要原则和目的; |
| 18 | +2. 掌握霍夫曼编码 |
| 19 | +3. 掌握几种常见的图像压缩编码方法 |
| 20 | +4. 利用 MATLAB 程序进行图像压缩 |
| 21 | + |
| 22 | +## 原理 |
| 23 | + |
| 24 | +### 图像压缩原理 |
| 25 | + |
| 26 | +图像压缩主要目的是为了节省存储空间,增加传输速度。图像压缩的理想标准是信息丢失最少,压缩比例最大。不损失图像质量的压缩称为无损压缩,无损压缩不可能达到很高的压缩比;损失图像质量的压缩称为有损压缩,高的压缩比是以牺牲图像质量为代价的。压缩的实现方法是对图像重新进行编码,希望用更少的数据表示图像。 |
| 27 | + |
| 28 | +信息的冗余量有许多种,如空间冗余,时间冗余,结构冗余,知识冗余,视觉冗余等,数据压缩实质上是减少这些冗余量。高效编码的主要方法是尽可能去除图像中的冗余成分,从而以最小的码元包含最大的图像信息。 |
| 29 | + |
| 30 | +编码压缩方法有许多种,从不同的角度出发有不同的分类方法,从信息论角度出发可分为两大类。 |
| 31 | + |
| 32 | +(1)冗余度压缩方法,也称无损压缩、信息保持编码或嫡编码。具体说就是解码图像和压缩编码前的图像严格相同,没有失真,从数学上讲是一种可逆运算。 |
| 33 | + |
| 34 | +(2)信息量压缩方法,也称有损压缩、失真度编码或烟压缩编码。也就是说解码图像和原始图像是有差别的,允许有一定的失真。 |
| 35 | + |
| 36 | +应用在多媒体中的图像压缩编码方法,从压缩编码算法原理上可以分为以下 3 类: |
| 37 | + |
| 38 | +(1)无损压缩编码种类 |
| 39 | +哈夫曼(Huffman)编码,算术编码,行程(RLE)编码,Lempel zev 编码。 |
| 40 | + |
| 41 | +(2)有损压缩编码种类 |
| 42 | + |
| 43 | ++ 预测编码,DPCM,运动补偿 |
| 44 | + |
| 45 | ++ 频率域方法:正交变换编码(如DCT),子带编码; |
| 46 | + |
| 47 | ++ 空间域方法:统计分块编码; |
| 48 | + |
| 49 | ++ 模型方法:分形编码,模型基编码; |
| 50 | + |
| 51 | ++ 基于重要性:滤波,子采样,比特分配,向量量化; |
| 52 | + |
| 53 | +(3)混合编码。 有 JBIG,H261,JPEG,MPEG 等技术标准。 |
| 54 | + |
| 55 | +### 离散余弦变换(DCT)图像压缩原理 |
| 56 | + |
| 57 | +离散余弦变换 DCT 在图像压缩中具有广泛的应用,它是JPEG、MPEG 等数据压缩标准的 |
| 58 | +重要数学基础。 |
| 59 | + |
| 60 | +和相同图像质量的其他常用文件格式(如GIF(可交换的图像文件格式),TIFF(标签图像文件格式),PCX(图形文件格式))相比,JPEG 是目前静态图像中压缩比最高的。JPEG 比其他几种压缩比要高得多,而图像质量都差不多(JPEG 处理的图像只有真彩图和灰度图)。正是由于其高压缩比,使得JPEG 被广泛地应用于多媒体和网络程序中。JPEG 有几种模式,其中最常用的是基于DCT 变换的顺序型模式,又称为基本系统(Baseline)。 |
| 61 | + |
| 62 | +用DCT 压缩图像的过程为: |
| 63 | + |
| 64 | +(1)首先将输入图像分解为8×8 或16×16 的块,然后对每个子块进行二维DCT变换。 |
| 65 | +(2)将变换后得到的量化的DCT 系数进行编码和传送,形成压缩后的图像格式。 |
| 66 | + |
| 67 | +用 DCT 解压的过程为: |
| 68 | + |
| 69 | +(1)对每个8×8 或16×16 块进行二维DCT 反变换。 |
| 70 | +(2)将反变换的矩阵的块合成一个单一的图像。 |
| 71 | + |
| 72 | +余弦变换具有把高度相关数据能量集中的趋势,DCT 变换后矩阵的能量集中在矩阵的 |
| 73 | +左上角,右下的大多数的DCT 系数值非常接近于0。对于通常的图像来说,舍弃这些接近 |
| 74 | +于0 的DCT 的系数值,并不会对重构图像的画面质量带来显著的下降。所以,利用DCT |
| 75 | +变换进行图像压缩可以节约大量的存储空间。压缩应该在最合理地近似原图像的情况下使用 |
| 76 | +最少的系数。使用系数的多少也决定了压缩比的大小。 |
| 77 | + |
| 78 | +在压缩过程的第 2 步中,可以合理地舍弃一些系数,从而得到压缩的目的。在压缩 |
| 79 | +过程的第2 步,还可以采用RLE 和Huffman 编码来进一步压缩。 |
| 80 | + |
| 81 | +### 行程编码(RLE)原理 |
| 82 | + |
| 83 | +例如如下这幅的二值图像, |
| 84 | + |
| 85 | + |
| 86 | + |
| 87 | +如果采用行程编码可以按如下格式保存 |
| 88 | + |
| 89 | + |
| 90 | + |
| 91 | +其中10 和8 表示图像的宽和高。在这个小例子中行程编码并没有起到压缩图像的作用。这是由于这个图的尺寸过小,当图像尺寸较大时行程编码还是不错的无损压缩方法。对于灰度图像和二值图像,用行程编码—般都有很高的压缩率。行程编码方法实现起来很容易,对于具有长重复值的串的压缩编码很有效,例如:对于有大面积的阴影或颜色相同的图像,使用这种方法压缩效果很好。很多位图文件格式都采用行程编码,如TIFF,PCX,GEM,BMP等。 |
| 92 | + |
| 93 | +## 步骤 |
| 94 | + |
| 95 | +### MATLAB 中的变长码映射 |
| 96 | + |
| 97 | +```matlab |
| 98 | +clear all |
| 99 | +clc |
| 100 | +
|
| 101 | +
|
| 102 | +f2=uint8([2 3 4 2;3 2 4 4;2 2 1 2;1 1 2 2]) |
| 103 | +whos('f2') |
| 104 | +c=huffman(hist(double(f2(:)),4)) |
| 105 | +h1f2=c(f2(:))' |
| 106 | +whos('h1f2') |
| 107 | +%h2f2=char(h1f2)' |
| 108 | +h2f2=[1 0 1 0 0 1 1 0 0 0 0 1 1 0 1 1;... |
| 109 | +' ' 1 ' ' 1 1 ' ' 1 0 0 1 ' ' 0 ' ';... |
| 110 | +' ' 0 ' ' 1 0 ' ' 1 ' ' 1 ' '] |
| 111 | +whos('h2f2') |
| 112 | +
|
| 113 | +h2f2=h2f2(:); |
| 114 | +h2f2(h2f2==' ')=[]; |
| 115 | +whos('h2f2') |
| 116 | +
|
| 117 | +h3f2=mat2huff(f2) |
| 118 | +whos('h3f2') |
| 119 | +
|
| 120 | +hcode=h3f2.code; |
| 121 | +whos('hcode') |
| 122 | +dec2bin(double(hcode)) |
| 123 | +
|
| 124 | +%-----------------------------------------% |
| 125 | +function CODE=huffman(p) |
| 126 | +
|
| 127 | +error(nargchk(1,1,nargin)); |
| 128 | +if(ndims(p)~=2)|(min(size(p))>1)|~isreal(p)|~isnumeric(p) |
| 129 | + error('p must be a real numeric vector'); |
| 130 | +end |
| 131 | +
|
| 132 | +global CODE |
| 133 | +CODE=cell(length(p),1);%init the global cell array |
| 134 | +if (length(p)>1) %when more than one symbol.... |
| 135 | + p=p/sum(p);%Normalize the input probabilities |
| 136 | + s=reduce(p);%Do Huffman source symbol reductions |
| 137 | + makecode(s,[]);%Recursively(递归) generate the code |
| 138 | +else |
| 139 | + CODE={'1'};%else, trivial(普通的) one symbol case |
| 140 | +end; |
| 141 | +%---------------------------------------------------------% |
| 142 | +
|
| 143 | +function s=reduce(p); |
| 144 | +s=cell(length(p),1); |
| 145 | +for i=1:length(p) |
| 146 | + s{i}=i; |
| 147 | +end |
| 148 | +
|
| 149 | +while size(s)>2 |
| 150 | + [p,i]=sort(p);%sort the symbol probabilities |
| 151 | + p(2)=p(1)+p(2);%Merge the 2 lowest probabilities |
| 152 | + p(1)=[];% and prune(,剪除、删除) the lowest one |
| 153 | +
|
| 154 | + s=s(i); |
| 155 | + s{2}={s{1},s{2}}; |
| 156 | + s(1)=[]; |
| 157 | +end |
| 158 | +%------------------------------------------------------------% |
| 159 | +function makecode(sc,codeword) |
| 160 | +
|
| 161 | +global CODE |
| 162 | +if isa(sc,'cell') |
| 163 | + makecode(sc{1},[codeword 0]); |
| 164 | + makecode(sc{2},[codeword 1]); |
| 165 | +else |
| 166 | + CODE{sc}=char('0'+codeword); |
| 167 | +End |
| 168 | +%-----------------------------------------------------------% |
| 169 | +function y=mat2huff(x) |
| 170 | +
|
| 171 | +if ndims(x)~=2|~isreal(x)|(~isnumeric(x) & ~islogical(x)) |
| 172 | + error('x must be a 2-D real numeric or logical matrix'); |
| 173 | +end |
| 174 | +
|
| 175 | +y.size=uint32(size(x)); |
| 176 | +x=round(double(x)); |
| 177 | +xmin=min(x(:)); |
| 178 | +xmax=max(x(:)); |
| 179 | +pmin=double(int16(xmin)); |
| 180 | +pmin=uint16(pmin+32768);% |
| 181 | +y.min=pmin; |
| 182 | +x=x(:)'; |
| 183 | +h=histc(x,xmin:xmax); |
| 184 | +if max(h)>65535 |
| 185 | + h=65535*h/max(h); |
| 186 | +end |
| 187 | +h=uint16(h); |
| 188 | +y.hist=h; |
| 189 | +
|
| 190 | +%code the input matrix and store the result |
| 191 | +map=huffman(double(h)); |
| 192 | +hx=map(x(:)-xmin+1) |
| 193 | +hx = ['1' ' ' '1' '0' ' ' '1' '1' '0' ' ' ' '... |
| 194 | + '0' '1' '1' ' ' '1' '1']'; |
| 195 | +%hx=char(hx); |
| 196 | +hx=hx(:)'; |
| 197 | +hx(hx==' ')=[]; |
| 198 | +ysize=ceil(length(hx)/16); |
| 199 | +hx16=repmat('0',1,ysize*16); |
| 200 | +hx16(1:length(hx))=hx; |
| 201 | +hx16=reshape(hx16,16,ysize); |
| 202 | +hx16=hx16' - '0'; |
| 203 | +twos=pow2(15:-1:0); |
| 204 | +y.code=uint16(sum(hx16.*twos(ones(ysize,1),:),2))'; |
| 205 | +%-----------------------------------------------------------------------% |
| 206 | +``` |
| 207 | + |
| 208 | +### 离散余弦变换(DCT)图像压缩 |
| 209 | + |
| 210 | +在图像的变换和压缩中,常常用到离散余弦变换(DCT)。DCT 具有能使图像的最重要的信息集中在DCT 的几个系数上的性能。正是基于此,DCT 通常应用于图像的压缩。 |
| 211 | + |
| 212 | +```matlab |
| 213 | +clear all |
| 214 | +clc |
| 215 | +I=imread('D:\pic\DIP3E_CH11_Original_Images\Fig1137(b)(painting_translated_padded).tif','tif'); |
| 216 | +
|
| 217 | +I=im2double(I); |
| 218 | +T=dctmtx(8); |
| 219 | +B=blkproc(I,[8,8],'P1*x*P2',T,T'); |
| 220 | +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;... |
| 221 | + 1 0 0 0 0 0 0 0;0 0 0 0 0 0 0 0;0 0 0 0 0 0 0 0;... |
| 222 | + 0 0 0 0 0 0 0 0;0 0 0 0 0 0 0 0]; |
| 223 | +B2=blkproc(B,[8,8],'P1.*x',mask); |
| 224 | +I2=blkproc(B2,[8,8],'P1*x*P2',T',T); |
| 225 | +imshow(I),title('原图象'); |
| 226 | +figure,imshow(I2),title('变换后的图象'); |
| 227 | +``` |
| 228 | + |
| 229 | +### 利用离散余弦变换进行JPEG 图像压缩 |
| 230 | + |
| 231 | +```matlab |
| 232 | +clear all |
| 233 | +clc |
| 234 | +I=imread('D:\pic\DIP3E_CH11_Original_Images\Fig1137(b)(painting_translated_padded).tif'); %读入原图像; |
| 235 | +I=im2double(I); %将原图像转为双精度数据类型; |
| 236 | +T=dctmtx(8); %产生二维DCT 变换矩阵 |
| 237 | +B=blkproc(I,[8 8],'P1*x*P2',T,T'); %计算二维DCT,矩阵T 及其转置T’是DCT 函数 |
| 238 | +%P1*x*P2 的参数 |
| 239 | +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;... |
| 240 | + 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]; |
| 241 | +%二值掩膜,用来压缩DCT 系数,只留下DCT 系数中左上角的10 个 |
| 242 | +B2=blkproc(B,[8 8],'P1.*x',mask); %只保留DCT 变换的10 个系数 |
| 243 | +I2= blkproc(B2,[8,8],'P1*x*P2',T',T); %逆DCT,重构图像 |
| 244 | +Subplot(1,2,1); |
| 245 | +Imshow(I);title('原图像');%显示原图像 |
| 246 | +Subplot(1,2,2); |
| 247 | +Imshow(I2);title('压缩图像');%显示压缩后的图像。对比原始图像和压缩后的图像,虽然 |
| 248 | +%舍弃了85%的DCT 系数,但图像仍然清晰(当然有一些质量损失) |
| 249 | +``` |
| 250 | + |
| 251 | +参考文献: |
| 252 | + |
| 253 | +[1] [Rafael C. Gonzalez, Richard E. Woods, and Steven L. Eddins. 2003. Digital Image Processing Using MATLAB. Prentice-Hall, Inc., USA.](https://github.com/timerring/digital-image-processing-matlab/blob/main/reference/Digital_Image_Processing_Using_Matlab.pdf) |
| 254 | + |
| 255 | +[2] [阮秋琦. 数字图像处理(MATLAB版)[M]. 北京:电子工业出版社, 2014.](https://github.com/timerring/digital-image-processing-matlab/blob/main/reference/Digital_Image_Processing_(MATLAB_version).pdf) |
| 256 | + |
| 257 | +[3] [冈萨雷斯. 数字图像处理(第三版)[M]. 北京:电子工业出版社, 2011.](https://github.com/timerring/digital-image-processing-matlab/blob/main/reference/Digital_Image_Processing_(Third_Edition).pdf) |
| 258 | + |
| 259 | +[返回首页](https://github.com/timerring/digital-image-processing-matlab) |
0 commit comments