JPEG编解码分析及调试

本文深入探讨JPEG的编解码过程,包括零偏置电平下移、离散余弦变换、量化、差分编码、游程编码和Huffman编码。同时,分析JPEG文件格式,介绍程序调试中的结构体和代码框架,并展示实验输出,如量化矩阵、Huffman表、DC和AC值图像及其概率分布。
摘要由CSDN通过智能技术生成

一、编解码原理

编码原理 

(1)零偏置电平下移(Level Offset)
对于灰度级为2^n 的像素,通过减去2^(n-1),将无符号整数变为有符号数,即值域变为正负对称。将绝对值大的数出现的概率大大减小,提高编码效率。

(2)离散余弦变换(8×8 DCT)
先将图像分为8×8的像块,如果图像的宽(高)不是8的整数倍,使用图像边缘像素填充,以不改变频谱分布。然后对每一个子块进行DCT(Discrete Cosine Transform)。DCT变换使用下式计算,C为变换核矩阵:


实现能量集中和去相关,便于去除空间冗余,提高编码效率。DCT是一种无损变换,不压缩图像(输出的是系数)这样做是在为下一步的量化做准备。

(3)量化(Quantization)
量化是编码流程中唯一会引入误差也是唯一会带来压缩效果的步骤,决定压缩质量,因此是JPEG压缩编码算法的核心。JPEG标准中采用中平型均匀量化,输入DCT系数,输出量化系数。

量化表有建议量化表真正使用的量化表 之分。

  • 建议量化表:基于人的生理感知阈值实验,对人眼敏感的低频部分采取较细的量化,对不太敏感的高频部分采取较粗的量化,减少了视觉冗余。
  • 真正的量化表:
    • 质量因子≤ 50:缩放因子= 50 / 质量因子
    • 质量因子> 50:缩放因子 = 2 – 质量 因子/ 50

(4)DC系数——差分编码(Differential indices)
8×8像块经过DCT后得到的DC系数有两个特点:一是系数的值较大;二是相邻像块的DC系数存在相关性(即存在冗余)。根据这个特点,JPEG标准采用了DPCM(差分脉冲编码调制),以对相邻图像块之间量化DC系数的差值DIFF进行编码: ​​DIFF_{k}=DC_{k}-DC_{k-1}

(5) AC系数——之字形扫描和游程编码(Zig-Zag+RLE)

  • 之字形扫描

经过DCT变换后,AC系数大多集中在左上角的低频分量区。因此采用Z字形按频率的高低顺序读出,可以出现很多连零的情况,便于使用RLE(Run Length Encoding,游程编码),若最后的数据均为0,则直接给出EOB(End of Block)。

  • 游程编码

当遇到很多连续的0时,为缩短数据长度,编码【非零系数level和它之前0的个数run】,(Run,level)。

如:0,-2,0,0,3,2,-4–>游程编码:(1,-2),(2,3),(0,2),(0,-4),EOB

(6)Huffman编码

对DC系数DPCM的结果和AC系数RLE的结果进行Huffman编码:

  • 类别ID采用一元码编码。
  • 类内索引采用定长码编码。共有亮度DC、亮度AC、色差DC、色差AC四张码表

 解码原理

① 解码huffman数据、② 解码DC差值、③ 重构量化后的系数、④ DCT逆变换

⑤ 丢弃填充的行/列、⑥ 反0偏置、⑦ 对丢弃的CbCr分量进行插值、⑧ YCbCr–>RGB

二、JPEG文件格式 

 JPEG文件以segment的形式组织,其中每个segment以一个marker开始(marker均以0xFF+一个marker的标识符),随后为2字节的marker长度(不包含marker的起始两字节)和对应的payload(SOI和EOI marker只有2字节的标识符)。

注意,连续的0xFF字节并不是marker的起始标志,而是用来填充的特殊字符。此外,部分中,0xFF后若为0x00,则跳过此字节不予处理。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值