实验三 图像的DCT变化及量化
一、问题描述
利用matlab,将road.tif彩色图像的分辨率转换为256*256,将图片转化为double数据类型,再利用T=dctmtx(8)建立一个8*8的DCT变换矩阵。将图像I划分为多个8*8的图像块B,对每一个图像块B进行DCT变换(D=T*B*T’),接着对结果采用四种量化方案:只保留直流系数;保留直流系数和前9个交流系数;保留直流系数和前35个交流系数;保留直流系数和前53个交流系数。再对这四种方案分别进行逆DCT变化(I2=T’*D*T)。最后显示出原图像I,重构后的图像I2,和差值I-I2。
二、问题分析
JPEG压缩标准中,需要对图像作DCT变换,这一步能够对图片进行压缩,同时,根据量化系数的不同,压缩质量也不同。
DCT变换,即离散余弦变换,是一种广泛应用的变换编码方法,它能够以数据无关的方式解除输入信号之间的相关性,因而应用广泛。在进行变换时,首先将图片分割为8*8的小块,分别对小块进行各自的DCT变换。变换的矩阵可调用函数dctmtx,得到余弦基函数作为变换基T。T*B*T’是变换的操作,接着对矩阵块进行量化。根据人眼对低频信号更为敏感的特性,建立合适的量化矩阵(存在广为接受的版本),接着对矩阵的每个元素进行除以对应的量化值。接着按照实验要求,对DCT系数进行遮罩,建立四个不同的遮罩矩阵,分别对左上角赋值为0,对小块的元素进行四种量化方案。这样就完成了DCT变换。进行逆变换时,直接用T’*B*T得到结果矩阵,转化为图像形式,得到最终的结果。需要注意的是,在对RGB图像进行DCT变换时,需要对三个颜色通道分别进行操作,因为DCT变换不是三维的。此外,在逆DCT变换之后,需要将每个通道的矩阵数值转化为uint8格式,再利用cat函数合并三个通道,得到重构的图像以及差值图像。
其实,在JPEG编码格式中,将RGB转化为YUV颜色空间,再对通道进行DCT变换,而不是直接对RGB三个通道进行变换,这是因为人眼对色度的敏感度低于对灰度的敏感度。
三、算法分析与详细设计
DCT基的第一个系数为恒定的直流系数,其余为AC系数,按照要求构建四种遮罩矩阵:
mask0=[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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]; mask9=[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]; mask35=[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 1 1 1 1 1 0 0 0 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]; mask53=[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 1 1 0 0 1 1 1 1 1 0 0 0 1 1 1 1 0 0 0 0];
|
调用彩色图像DCT变换的函数,参数为RGB图像和遮罩矩阵。
亮度量化表可以乘以一个系数,用来控制压缩率。系数越大,压缩率越高,得到的图像质量越差。遮罩矩阵保留的AC系数越多,得到的图像质量越高。
function %进行彩色图像的DCT变换 % 返回重构的图像
%亮度量化表 m=0.5*[ 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]; %RGB图分层处理 得到3个分量图 R = RGB(:,:,1); G = RGB(:,:,2); B = RGB(:,:,3); %转换为双精度 IR = double(R); IG = double(G); IB = double(B); %建立8*8的DCT变换矩阵 T=dctmtx(8); %进行DCT变换 RR = blkproc(IR,[8,8],'P1*x*P2',T,T'); GG = blkproc(IG,[8,8],'P1*x*P2',T,T'); BB = blkproc(IB,[8,8],'P1*x*P2',T,T');
%量化 LR = blkproc(RR,[8 8], 'round(x./P1)',m); LG = blkproc(GG,[8 8], 'round(x./P1)',m); LB = blkproc(BB,[8 8], 'round(x./P1)',m); %对DCT系数进行遮罩处理 mR=blkproc(LR,[8 8],'x.*P1.*P2',mask,m); mG=blkproc(LG,[8 8],'x.*P1.*P2',mask,m); mB=blkproc(LB,[8 8],'x.*P1.*P2',mask,m);
%反DCT变化 IDCT YR =blkproc(mR,[8 8],'P1*x*P2',T',T); YG =blkproc(mG,[8 8],'P1*x*P2',T',T); YB =blkproc(mB,[8 8],'P1*x*P2',T',T);
%转换为uint8 YR = uint8(YR); YG = uint8(YG); YB = uint8(YB);
%计算重构图像和差值 RGB_rec =cat(3,YR,YG,YB); miss=RGB-RGB_rec;
end |
灰度图像的处理类似,只是不需要对三个通道进行操作。
四、实验结果分析
实验结果如下,分别是灰度图像和彩色RGB图像的DCT变换结果,可以看到,保留的AC系数越多,得到的图像质量越好,与原图的差值越小。这是因为高频信号也进行了一定的保留,量化误差较小,因此逆DCT变换得到的图像质量也较好。图像的质量损失产生于量化过程,量化系数是根据人眼对不同亮度的敏感程度进行设计的,左上角数值小,右下角数值大,这样高频信息损失大一些,人眼很难有所察觉,低频信号损失小,对人眼观察造成的影响较小。
灰度图像的实验结果。
彩色图像的实验结果。
使用第一种遮罩矩阵、也就是只保留直流系数的矩阵,量化损失最大,逆变换后得到的图像能够看到明显的锯齿,保留9个AC系数时,质量变高,但仍能看到一些锯齿。保留35个AC系数和53个AC系数得到的结果非常相似,人眼几乎看不出差别,误差图像也几乎为全黑,证明了人眼确实对高频信号敏感度很低。
DCT变换本身不会对图片的质量造成影响,大小不会改变,但是量化的过程会给图片质量带来损失,量化矩阵的系数大小也影响着压缩率,值越大,压缩率越高,得到的图片质量也越低,相应地,图片所占的空间也较小。保留35个系数已经能够较好地还原图片,肉眼很难辨识出区别。
五、实验总结
通过本次实验,了解了DCT变换的基本原理和过程和量化矩阵对图片质量产生的影响,分别对灰度图和RGB图进行了DCT变换,其中彩色图像需要对三个通道分别进行变换。如果想要得到更好的效果,可以先将RGB颜色转化到YUV或YIQ空间(并进行二次采样,对亮度值全采样,其余的进行半采样),因为人眼对亮度的敏感度远高于对色度的敏感度。这也是JPEG图像压缩的原理。
同时,除了对原理的了解,还熟悉了matlab的函数使用,能够进行简单的图像分块,调用DCT变换矩阵的函数,和对小块进行量化操作使用的blkproc函数。
附资源链接:点我