JPEG之颜色空间转换、DCT变换

  • Post author:
  • Post category:其他




JPEG


编码之颜色空间变换


BMP


图转换为


JPEG


图,首先要进行颜色空间的转换。即把


RGB


转换为


YUV





YIQ


,并进行二次采样。因为亮度分量(


Y


)和色度分量(


U





V





I





Q


)用不同的比率。这是因为人眼对亮度比较敏感而对色度相对较弱。这些是我从书上看来的,但是,它没讲到底怎么二次采样,我只能以自己的理解来。




读取


BMP


图的像素数据(


24


色),用


unsigned char *


来存储。然后,是分块:


Y


用公式直接计算,与每个像素一一对应;而


U





V


则采用


4*4


的小块计算出


U


的平均、


V


的平均(我采用的是


4:2:0


)。


BMP


每行都是偶数(


4n


),但是并不是每个都存储满的,所以还是要用长、宽来处理颜色空间的色度转换。如果行


/


列不是偶数,那么就要进行边角料处理了。这是个很麻烦的东西。我想到是先偶数部分,然后对边角料处理:假设长宽都是奇数,那么则最后一列(


2*1


)进行处理(


/2


来求平均),同理对最后一行进行处理。最后,剩下一个像素(右下角的,


BMP


的存储坐标来看)。所以,如果行为奇数,则只要对最后一列进行处理,而列为奇数则对行进行处理,行列都为奇数则行、列处理完之后还有右下角的一个像素点要处理。




那么,


Y





U





V


是绑定存储还是分开存储呢?我看书上说是绑定存储的,比如


4:2:0


则存储为


4





Y


一个


U


和一个


V


,如此反复。




但是,我个人觉得是之后的


JPEG


的处理,是把


Y





U





V


分开的,可以简化操作。但是没有深入的思考过。这里,大家可以来讨论一下。



附注:




这里,还有写注意点。之前学习了一些处理


BMP


图的方法,用惯了


BYTE*


来存储像素值。在这里进行彩色空间转换的时候,许多都是


0


,后来才想起来,我进行的是


float


计算,用


BYTE


会使得精度损失比较大。另外,我试了一下,从


RGB





>YUV





>RGB


,发现有些失真(跟原来的颜色不大一样,绿色向黄色偏移)。




还发现一个东西,就是用


fstream


来写文件,写


BYTE*


的时候,如果多个数据中间有


0


,则会写到


0


后就不再写了。比如


BYTE* p={1





2





3





0





4





5





6}


;则写了


1





2





3





0


,就结束了。而


4





5





6


则没有写。




JPEG


编码之


DCT


变换







DCT


变换之前,先要进行分块处理。还是老问题:


8*8


之后像素矩阵的边角料处理。处理跟上面差不多,但是之前都是进行的


8*8





DCT


变换,所以要把它扩充为


8*8


的矩阵。那么,用什么数据来进行填充呢?我发现用


0


来填充是对原来的数据没有影响的。因为把


0


代入就是


* f ( i ,j )


就是


*0






之后就是


DCT


变换了。代入公式,是最适合计算机做的,问题是有没有更高效的方法。我看到一个,就是转换为一维的


DCT


变换——先行变换,再列变换。我还发现,各个


cos


的值,在行系数(或列系数)确定的时候,就只跟


i


相关(该行所在位置)。即每一行有


8





cos


值。那么,


8


行就是


8*8


的矩阵。


1            1            1            1            1            1            1            1


0.98        0.83        0.55        0.19        -0.19       -0.55       -0.83       -0.98


0.92        0.38        -0.38       -0.92       -0.92       -0.38       0.38        0.92


0.83        -0.19       -0.98       -0.5        0.55        0.98        0.19        -0.83


0.70        -0.70       -0.70       0.70        0.70        -0.70       -0.70       0.70


0.55        -0.98       0.19        0.83        -0.83       -0.19       0.98        -0.55


0.38        -0.92       0.92        -0.38       -0.38       0.92        -0.9        0.38


0.19        -0.55       0.83        -0.98       0.98        -0.83       0.55        -0.19


(以上的数据是我省略了一些位,为了清楚)


而各个像素值也是


8*8


的矩阵,所以


DCT


的行变换正好是两个


8*8


的矩阵相乘。



附注:




书上用的是蝶形变换,有些是直接代入傅里叶变换中进行,有些是列了很多的变量解决的,完全看不清楚。后来我查到了一些资料,见图


33





34





35






图片33



图片34



版权声明:本文为cainiaohhf原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。