




已阅读5页,还剩13页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
JPEG Joint Photographic Experts Group 是联合图像专家小组的英文缩写 它由国际电话与电报咨询委员会 CCITT The International Telegraph and Telephone Consultative Committee 与国际标准化组织 ISO 于 1986 年联合 成立的一个小组 负责制定静态数字图像的编码标准 小组一直致力于标准化工作 开发研制出连续色调 多级灰度 静止图像的 数字图像压缩编码方法 即 JPEG 算法 JPEG 算法被确定为国际通用标准 其适用范围广泛 除用于静态图像编码外 还推广到电视图像序列的帧 内图像压缩 而用 JPEG 算法压缩出来的静态图片文件称为 JPEG 文件 扩展名通常为 jpg jpe jpeg JPEG 专家组开发了两种基本的压缩算法 两种数据编码方法 四种编码模 式 具体如下 压缩算法 有损的离散余弦变换 Discrete Cosine Transform DCT 无损的预测技术压缩 数据编码方法 哈夫曼编码 算术编码 编码模式 基于 DCT 顺序模式 编 解码通过一次扫描完成 基于 DCT 递进模式 编 解码需要多次扫描完成 扫描效果从粗糙到精 细 逐级递进 无损模式 基于 DPCM 保证解码后完全精确恢复到原图像采样值 层次模式 图像在多个空间多种分辨率进行编码 可以根据需要只对低 分辨率数据作解码 放弃高分辨率信息 在实际应用中 JPEG 图像使用的是离散余弦变换 哈夫曼编码 顺序模式 JPEG 压缩编码算法的主要计算步骤如下 0 8 8 分块 1 正向离散余弦变换 FDCT 2 量化 quantization 3 Z 字形编码 zigzag scan 4 使用差分脉冲编码调制 DPCM 对直流系数 DC 进行编码 5 使用行程长度编码 RLE 对交流系数 AC 进行编码 6 熵编码 笔者在实践过程中查阅了大量的资料 发现大多数书籍资料和网上资料都是 从编码角度分析 JPEG 的编 解码方式 并且都只是介绍编码过程中的主要方法 所以 本文从解码角度详细分析 JPEG 的编 解码过程 并且加入许多笔 者实践过程中遇到的问题和解决方法 希望从另一个角度说明问题 以更好帮助读者结合其他资料解决问题 不过 介绍解码过程之前 首先要了解 JPEG 文件中数据的存储格式 一 一 JPEG 文件格式介绍文件格式介绍 JPEG 文件使用的数据存储方式有多种 最常用的格式称为 JPEG 文件交换 格式 JPEG File Interchange Format JFIF 而 JPEG 文件大体上可以分成两个部分 标记码 Tag 和压缩数据 标记码由两个字节构成 其前一个字节是固定值 0 xFF 后一个字节则根据 不同意义有不同数值 在每个标记码之前 还可以添加数目不限的无意义的 0 xFF 填充 也就说连续的多个 0 xFF 可以被理解为一个 0 xFF 并表示一个标记码 的开始 而在一个完整的两字节的标记码后 就是该标记码对应的压缩数据流 记录了关于文件的诸种信息 常用的标记有SOI APP0 DQT SOF0 DHT DRI SOS EOI 注意 SOI 等都是标记的名称 在文件中 标记码是以标记代码形式出现 例如 SOI 的标记代码为 0 xFFD8 即在 JPEG 文件中的如果出现数据 0 xFFD8 则表示此处为一个 SOI 标记 本文附录列出一张完整的 JPEG 定义的标记表 供读者查阅 这里仅列出几个常用标记的标记代码 占用字 节长度和表示的意义 SOI Start of Image 图像开始 标记代码 2 字节 固定值 0 xFFD8 APP0 Application 应用程序保留标记 0 标记代码 2 字节 固定值 0 xFFE0 包含 9 个具体字段 数据长度 2 字节 9 个字段的总长度 即不包括标记代码 但包括本字段 标识符 5 字节 固定值 0 x4A46494600 即字符串 JFIF0 版本号 2 字节 一般是 0 x0102 表示 JFIF 的版本号 1 2 可能会有其他数值代表其他版本 X 和 Y 的密度单位 1 字节 只有三个值可选 0 无单位 1 点数 英寸 2 点数 厘米 X 方向像素密度 2 字节 取值范围未知 Y 方向像素密度 2 字节 取值范围未知 缩略图水平像素数目 1 字节 取值范围未知 缩略图垂直像素数目 1 字节 取值范围未知 缩略图 RGB 位图 长度可能是 3 的倍数 缩略图 RGB 位图数据 本标记段可以包含图像的一个微缩版本 存为 24 位的 RGB 像素 如果 没有微缩图像 这种情况更常见 则 字段 缩略图水平像素数目 和字段 缩略图垂直像素数目 的值均为 0 APPn Application 应用程序保留标记 n 其中 n 1 15 任选 标记代码 2 字节 固定值 0 xFFE1 0 xFFF 包含 2 个具体字段 数据长度 2 字节 2 个字段的总长度 即不包括标记代码 但包括本字段 详细信息 数据长度 2 字节 内容不定 例如 Adobe Photoshop 生成的 JPEG 图像中就用了 APP1 和 APP13 两 个标记段分别存储了一幅图像的副本 DQT Define Quantization Table 定义量化表 标记代码 2 字节 固定值 0 xFFDB 包含 9 个具体字段 数据长度 2 字节 字段 和多个字段 的总长度 即不包括标记代码 但包括本字段 量化表 数据长度 2 字节 a 精度及量化表 ID 1 字节 高 4 位 精度 只有两个可选值 0 8 位 1 16 位 低 4 位 量化表 ID 取值范围为 0 3 b 表项 64 精度 1 字节 例如 8 位精度的量化表 其表项长度为 64 0 1 64 字节 本标记段中 字段 可以重复出现 表示多个量化表 但最多只能出现 4 次 SOF0 Start of Frame 帧图像开始 标记代码 2 字节 固定值 0 xFFC0 包含 9 个具体字段 数据长度 2 字节 六个字段的总长度 即不包括标记代码 但包括本字段 精度 1 字节 每个数据样本的位数 通常是 8 位 一般软件都不支持 12 位和 16 位 图像高度 2 字节 图像高度 单位 像素 如果不支持 DNL 就必须 0 图像宽度 2 字节 图像宽度 单位 像素 如果不支持 DNL 就必须 0 颜色分量数 1 字节 只有 3 个数值可选 1 灰度图 3 YCrCb 或 YIQ 4 CMYK 而 JFIF 中使用 YCrCb 故这里颜色分量数恒为 3 颜色分量信息 颜色分量数 3 字节 通常为 9 字节 a 颜色分量 ID 1 字节 b 水平 垂直采样因子 1 字节 高 4 位 水平采样因子 低 4 位 垂直采样因子 曾经看到某资料把这两者调转了 c 量化表 1 字节 当前分量使用的量化表的 ID 本标记段中 字段 应该重复出现 有多少个颜色分量 字段 就 出现多少次 一般为 3 次 DHT Difine Huffman Table 定义哈夫曼表 标记代码 2 字节 固定值 0 xFFC4 包含 2 个具体字段 数据长度 2 字节 字段 和多个字段 的总长度 即不包括标记代码 但包括本字段 哈夫曼表 数据长度 2 字节 a 表 ID 和表类型 1 字节 高 4 位 类型 只有两个值可选 0 DC 直流 1 AC 交流 低 4 位 哈夫曼表 ID 注意 DC 表和 AC 表分开编码 b 不同位数的码字数量 16 字节 c 编码内容 16 个不同位数的码字数量之和 字节 本标记段中 字段 可以重复出现 一般 4 次 也可以致出现 1 次 例如 Adobe Photoshop 生成 的 JPEG 图片文件中只有 1 个 DHT 标记段 里边包含了 4 个哈夫曼表 而 Macromedia Fireworks 生成 的 JPEG 图片文件则有 4 个 DHT 标记段 每个 DHT 标记段只有一个哈夫曼表 DRI Define Restart Interval 定义差分编码累计复位的间隔 标记代码 2 字节 固定值 0 xFFDD 包含 2 个具体字段 数据长度 2 字节 固定值 0 x0004 两个字段的总长度 即不包括标记代码 但包括本字段 MCU 块的单元中的重新开始间隔 2 字节 设其值为 n 则表示每 n 个 MCU 块就有一个 RSTn 标记 第一个标记是 RST0 第二个是 RST1 等 RST7 后再从 RST0 重复 如果没有本标记段 或间隔值为 0 时 就表示不存在重开始间隔和标记 RST SOS Start of Scan 扫描开始 12 字节 标记代码 2 字节 固定值 0 xFFDA 包含 2 个具体字段 数据长度 2 字节 两个字段的总长度 即不包括标记代码 但包括本字段 颜色分量数 1 字节 应该和 SOF 中的字段 的值相同 即 1 灰度图是 3 YCrCb 或 YIQ 4 CMYK 而 JFIF 中使用 YCrCb 故这里颜色分量数恒为 3 颜色分量信息 a 颜色分量 ID 1 字节 b 直流 交流系数表号 1 字节 高 4 位 直流分量使用的哈夫曼树编号 低 4 位 交流分量使用的哈夫曼树编号 压缩图像数据 a 谱选择开始 1 字节 固定值 0 x00 b 谱选择结束 1 字节 固定值 0 x3F c 谱选择 1 字节 在基本 JPEG 中总为 00 本标记段中 字段 应该重复出现 有多少个颜色分量 字段 就 出现多少次 一般为 3 次 本段结束后 紧接着就是真正的图像信息了 图像信息直至遇到一个标记代码就自动结束 一般就是以 EOI 标记表示结束 EOI End of Image 图像结束 2 字节 标记代码 2 字节 固定值 0 xFFD9 这里补充说明一下 由于在 JPEG 文件中 0 xFF 具有标志性的意思 所以 在压缩数据流 真正的图像信息 中 出现 0 xFF 就需要作特别处理 具体方法是 在数据 0 xFF 后添加一个没有意义的 0 x00 换句话说 如果在图像数 据流中遇到 0 xFF 应该检测其紧接着的字符 如果是 1 0 x00 则表示 0 xFF 是图像流的组成部分 需要进行译码 2 0 xD9 则与 0 xFF 组成标记 EOI 则图像流结束 同时图像文件结束 3 0 xD0 0 xD7 则组成 RSTn 标记 则要忽视整个 RSTn 标记 即不对当前 0 xFF 和紧接的 0 xDn 两个字节进行译码 并按 RST 标记的规则调整译码 变量 3 0 xFF 则忽视当前 0 xFF 对后一个 0 xFF 再作判断 4 其他数值 则忽视当前 0 xFF 并保留紧接的此数值用于译码 二 二 JPEG 解码过程详解解码过程详解 下面来详细讲述 JPEG 文件的解码过程 1 读入文件的相关信息 读入文件的相关信息 按照上述的 JPEG 文件数据存储方式 把要解码的文件的相关信息一一读出 为接下来的解码工作做好准备 参考方法是 设计一系列的结构体对应各个标记 并存储标记内表示的信息 其中图像长宽 多个量化 表和哈夫曼表 水平 垂直采样因子等多项信息比较重要 以下给出读取过程中的两个问题 1 整个文件的大体结构 JFIF 格式的 JPEG 文件 jpg 的一般顺序为 SOI 0 xFFD8 APP0 0 xFFE0 APPn 0 xFFEn 可选 DQT 0 xFFDB SOF0 0 xFFC0 DHT 0 xFFC4 SOS 0 xFFDA 压缩数据 EOI 0 xFFD9 2 字的高低位问题 JPEG 文件格式中 一个字 16 位 的存储使用的是 Motorola 格式 而不 是 Intel 格式 也就是说 一个字的 高字节 高 8 位 在数据流的前面 低字节 低 8 位 在数据流的后面 与平时习惯的 Intel 格式不一样 3 读出哈夫曼表数据 a 理论说明 在标记段 DHT 内 包含了一个或者多个的哈夫曼表 对于单一个哈夫曼表 应该包括了三部分 哈夫曼表 ID 和表类型 这个字节的值为一般只有四个 0 x00 0 x01 0 x10 0 x11 0 x00 表示 DC 直流 0 号表 0 x01 表示 DC 直流 1 号表 0 x10 表示 AC 交流 0 号表 0 x11 表示 AC 交流 1 号表 不同位数的码字数量 JPEG 文件的哈夫曼编码只能是 1 16 位 这个字段的 16 个字节分别表 示 1 16 位的编码码字在哈夫曼树中的个数 编码内容 这个字段记录了哈夫曼树中各个叶子结点的权 所以 上一字段 不 同位数的码字数量 的 16 个数 值之和就应该是本字段的长度 也就是哈夫曼树中叶子结点个数 b 举例说明 以下面一段哈夫曼表数据举例说明 数据全部以 16 进制表示 11 00 02 02 00 05 01 06 01 00 00 00 00 00 00 00 00 00 01 11 02 21 03 31 41 12 51 61 71 81 91 22 13 32 红色部分 第 1 字节 为哈夫曼表 ID 和表类型 其值 0 x11 表示此部分数据 描述的是 AC 交流 1 号表 蓝色部分 2 17 字节 为不同位数的码字的数量 这 16 个数值实际意义为 没有 1 位和 4 位的哈夫曼码字 2 位和 3 位的码字各有 2 个 5 位码字有 5 个 6 位和 8 位码字各有 1 个 7 位码字各有 6 个 没有 9 位或以 上的码字 绿色部分 18 34 字节 为编码内容 由蓝色部分数据知道 此哈夫曼树有 0 2 2 0 5 1 6 1 17 个叶子结点 即本字段应该有 17 个字节 这段数据表示 17 个叶子结点按从小到大排列 其权值依次为 0 1 11 2 21 3 31 41 4 建立哈夫曼树 a 理论说明 在读出哈夫曼表的数据后 就要建立哈夫曼树 具体方法为 1 第一个码字必定为 0 如果第一个码字位数为 1 则码字为 0 如果第一个码字位数为 2 则码字为 00 如此类推 2 从第二个码字开始 如果它和它前面的码字位数相同 则当前码字为它前面的码字加 1 如果它的位数比它前面的码字位数大 则当前码字是前面的码字加 1 后 再在后边添若干个 0 直至满足位数长度为止 b 举例说明 继续以上边的例子说明问题 由于没有 1 位的码字 所以第一个码字的位数为 2 即码字为 00 由于 2 位的码字有两个 所以第二个码字位数仍为 2 即码字为 00 1 01 第三个码字为 3 位 比第二个码字长 1 位 所以第三个码字为 01 1 10 然后再添 1 个 0 得 100 如此类推 最后得到这个哈夫曼树如下 序 号 码字长 度 码字权值 12000 x00 22010 x01 331000 x11 431010 x02 55110000 x21 65110010 x03 75110100 x31 85110110 x41 95111000 x12 1061110100 x51 11711101100 x61 12711101110 x71x81x91x22 16711110110 x13 178111110000 x32 特别注意的是 如果中间有某个位数的码字缺失 例如没有 4 位码字 则应 该在 3 位码字加 1 后 添加 00 补足 5 位 形成下一个 5 位码字 在准备好所有的图片信息后 就可以对图片数据进行解码了 2 初步了解图像数据流的结构初步了解图像数据流的结构 1 理论说明 分析图像数据流的结构 笔者准备以一个从宏观到微观的顺序为读者详细剖析 即 数据流 最小编码单元 数据单元与颜色分量 a 在图片像素数据流中 信息可以被分为一段接一段的最小编码单元 Minimum Coded Unit MCU 数据流 所谓 MCU 是图像中一个正方矩阵像素的数据 矩阵的大小是这样确定的 查阅标记 SOF0 可以得到图像不同颜色分量的采样因子 即 Y Cr Cb 三个分量各自的水平采样因子和垂直采 样因子 大多图片的采样因子为 4 1 1 或 1 1 1 其中 4 1 1 即 2 2 1 1 1 1 1 1 1 即 1 1 1 1 1 1 记三个分量中水平采样因子最大值为 Hmax 垂直采样因子最大值为 Vmax 那么 单个 MCU 矩阵的宽就是 Hmax 8 像素 高就是 Vmax 8 像素 如果 整幅图像的宽度和高度不是 MCU 宽度和高度的整数倍 那么编码时会用某些数值填充进去 保证解码过程中 MCU 的完整性 解码完成后 可直接 忽视图像宽度和高度外的数据 在数据流中 MCU 的排列方法是从左到右 从上到下 b 每个 MCU 又分为若干个数据单元 数据单元的大小必定为 8 8 所以每个 MCU 的数据单元个数为 Hmax Vmax 另外 JPEG 的压缩方法与 BMP 文件有所不同 它不是把每个像素的颜色分量连续存储在一起的 而是把图片分成 Y Cr Cb 三张子图 然后分 别压缩 而三个颜色分量的采样密度 即采样因子 可能一样 例如 1 1 1 也可能不一样 例如 4 1 1 每个 MCU 内部 数据的顺序是 Y Cr Cb 如果一个颜色分量有多个数据 单元 则顺序是从左到右 从上到下 2 举例说明 下面通过一幅 32 35 的图像 对上面两个问题列出两种采样因子的具体说明 图 1 整张完整的图像 4 1 1 图 2 将图像的 MCU1 放大 图 1 及图 3 中灰色部分为实际图像大小 32px 35px 粗虚线表示各个 MCU 的分界 细虚线表示 MCU 内部数据单元的分界 a 采样因子为 4 1 1 此时 Hmax max 2 1 1 2 Vmax max 2 1 1 2 所以 MCU 的宽为 Hmax 8 16 像素 高为 Vmax 8 16 像素 图像实际的宽刚好是 2 个 MCU 但高则稍稍大于 2 个 MCU 的高度 所以要补足 3 行 MCU 在数据流中 MCU 的顺序是 MCU1 MCU2 MCU3 MCU4 MCU5 MCU6 每个 MCU 又分为 Hmax Vmax 2 2 4 个数据单元 由于采样因子是 4 1 1 即 2 2 1 1 1 1 所以 Y 分量的水平和垂直方向都是每 2 个像素采样 2 次 Cr 分量和 Cb 分量的水平和垂直方向都是每 2 个像素采样 1 次 因此 在一个 MCU 来里边 Y 分量有 256 个采样点 即 4 个完整的数据单元 Cr 分量和 Cb 分量各自只有 64 个采样点 如果以 MCU1 说明 MCU 数据的次序 则依次为 Y1 Y2 Y5 Y6 Cr1256 Cb1256 图 2 中全部 256 个点均是 Y 的采样点 红色部分为 Cr 分量和 Cr 分量的采样点 换句话说 对于整张图片来说 数据流的数据依次是 Y1 Y2 Y5 Y6 Cr1256 Cb1256 Y3 Y4 Y7 Y8 Cr3478 Cb3478 Y9 Y10 Y13 Y14 Cr9101314 Cb9101314 图 3 整张完整的图像 1 1 1 b 采样因子为 1 1 1 如图 3 Hmax max 1 1 1 1 Vmax max 1 1 1 2 所以 MCU 的宽为 Hmax 8 8 像素 高为 Vmax 8 8 像素 图像实际的宽刚好是 4 个 MCU 但高则稍稍大于 4 个 MCU 的高度 所以要补足 5 行 MCU 在数据流中 MCU 的顺序是 MCU1 MCU2 MCU3 MCU4 MCU18 MCU19 MCU20 每个 MCU 又分为 Hmax Vmax 1 1 1 个数据单元 也就是一个数据单 元就是一个 MCU 由于采样因子是 1 1 1 即 1 1 1 1 1 1 所以 Y 分量 Cr 分量和 Cb 分量的水平和垂直方向都是每 1 个像素采样 1 次 也就是 图象的每一个像素都是采样点 因此 在一个 MCU 来里边 Y 分量 Cr 分量和 Cb 分量各自有 64 个采样点 有 因此 对于整张图片来说 数据流的数据依次是 Y1 Cr1 Cb1 Y2 Cr2 Cb2 Y3 Cr3 Cb3 Y19 Cr19 Cb19 Y20 Cr20 Cb20 3 颜色分量单元的内部解码 颜色分量单元的内部解码 1 理论说明 颜色分量单元 是笔者为说明问题而建立的概念 指的是 MCU 中某 个颜色分量中的一个 8 8 数据块 例如上面提到的 Y1 Cr1 Cb1 都是一个 颜色分量单元 图像数据流是以位 bit 为单位存储信息的 并且内部的数据都是在编 码时通过正向离散余弦变换 FDCT 进 行时空域向频率域变换而得到的结果 所以对于每个颜色分量单元都应该由两部分组成 1 个直流分量和 63 个交流分量 解码的过程其实就是哈夫曼树的查找过程 首先查阅标记段 SOS 中的颜色分量信息 可以得出各个颜色分量对应使 用的直流分量和交流分量使用的哈夫曼树编号 一般来说 Y 分量 直流分量 直流 0 号哈夫曼树 交流分量 交流 0 号哈夫曼树 Cr 分量 直流分量 直流 1 号哈夫曼树 交流分量 交流 1 号哈夫曼树 Cb 分量 直流分量 直流 1 号哈夫曼树 交流分量 交流 1 号哈夫曼树 颜色分量单元内部综合运用了 RLE 行程编码和哈夫曼编码来压缩数据 每 个像素的数据流由两部分构成 编码和数值 并且 两者基本以互相隔开方式出现 除非该编码的权值为零 具体读入单个颜色分量单元的步骤如下 a 从此颜色分量单元数据流的起点开始一位一位的读入 直到读入的编码与该 分量直流哈夫曼树的某个码字 叶子结点 一 致 然后用直流哈夫曼树查得该码字对应的权值 权值 共 8 位 表示该直流分量数值的二进制位数 也就是接下来需要读入 的位数 b 继续读入位数据 直到读入的编码与该分量交流哈夫曼树的某个码字 叶子 结点 一致 然后用交流哈夫曼树查得该码字 对应的权值 权值的高 4 位表示当前数值前面有多少个连续的零 低 4 位表示该交流分量数值的二进制位数 也就是接下来需 要读入的位数 c 不断重复步骤 b 直到满足交流分量数据结束的条件 而结束条件有两个 只要满足其中一个即可 当读入码字的权值为零 表示往后的交流变量全部为零 已经读入 63 个交流分量 d 各个数值的译码是按下表进行的 实际数值编 码 长 度 编码 0 0 1 110 1 3 2 2 3 200 01 10 11 7 6 5 4 4 5 6 7 3000 001 010 011 100 101 110 111 15 8 8 15 4 0000 0111 1000 1111 31 16 16 31 5 00000 01111 10000 11111 63 32 32 63 6 127 64 64 127 7 255 128 128 255 8 511 256 256 511 9 1023 512 512 1023 10 2047 1024 1024 2047 11 4095 2048 2048 4095 12 8191 4096 4096 8191 13 16383 8192 8192 16383 14 32767 16384 16384 32767 15 2 举例说明 下面举例说明以上几点 某个颜色分量单元数据如下 D3 5E 6E 4D 35 f5 8A 若以二进制表示 则为 1101 0011 0101 1110 0110 1110 0100 1101 0011 0101 1111 0101 1000 1010 假设该颜色分量单元对应以下直流哈夫曼树和交流哈夫曼树 则可将各 个以位为单位的数据流拆分如下 110 1001101 01 1 11001 101 11001 001 101 00 11010 1 1111010 11 00 01010 直流哈夫曼树 交流哈夫曼树 序 号 码字长 度 码字权值 12000 x00 22010 x01 32100 x02 431100 x07 5411100 x1e 65111100 x2e 序 号 码字长 度 码字权值 12000 x00 22010 x01 331000 x11 详细说明一下 读入数据流并对照直流哈夫曼树 第一 个哈夫曼编码为 110 其权值为 6 所以往 后读入 6 位数据 1001101 译码成数值 为 77 因为每个颜色分量单元只有一个直 流分量 所以下一个就是第一个交流分量了 继续读入数据流并对照交流哈夫曼树 得哈夫曼编码为 01 其权值为 1 所以它的 前面没有零 并往后读如 1 位数据 1 译码成数值为 1 如此往复 最后读到哈夫 曼编码 00 其权值为 0 所以满足交流 变量结束条件 最后剩余的 01010 对本 颜色分量单元来说是冗余的 它可能属于下 一个颜色分量单元 实际上 这段数据译码为 77 0 1 0 5 0 6 0 3 5 1 2 3 因此 把它置于 1 个 8 8 的矩阵中应为 7715 6 3000 00100300 00000000 00000000 00000000 00000000 00000000 00000000 4 直流系数的差分编码 直流系数的差分编码 把所有的颜色分量单元按颜色分量 Y Cr Cb 分类 每一种颜色分 量内 相邻的两个颜色分量单元的直流变 量是以差分来编码的 也就是说 通过步骤 3 解码出来的直流变量数值只是当前颜色分量单元的实际直流变量减去 前一个颜色分量单元的实际直流变量 也就是说 当前直流变量要通过前一个颜色分量单元的实际 非解码 直流分量来校正 431010 x02 55110000 x21 65110010 x03 75110100 x31 85110110 x41 95111000 x12 1061110100 x51 11711101100 x61 12711101110 x71x81x91x22 16711110110 x13 178111110000 x32 DCn DCn 1 Diff 其中 Diff 为差分校正变量 也就是直接解码出来的直流系数 但如果当 前颜色分量单元是第一个单元 则解码出来的直流数值就是真正的直流变量 再次提醒的是 3 个颜色分量的直流变量是分开进行差分编码的 也就 是说 为 1 张图片解码时应设置 3 个独立的直 流校正变量 另一个问题是 当数据流中出现标记 RSTn 则 3 个颜色分量的直流差分校正变量 Diff 都需要重新复位到 0 5 反量化 反量化 不同的颜色分量使用不同的量化表 这个可以从标记段 SOF 中的颜色分 量信息字段查得 一般是 Y 分量使用量化表 0 而 Cr Cb 两个分量共同使 用量化表 1 反量化的过程比较简单 只需要对 8 8 的颜色分量单元的 64 个值逐一乘 以对应的量化表内位置相同的值则可 图像内全部的颜色分量单元都要进行 反量化 6 反反 Zig zag 编码编码 如果将反量化后的每个 8 8 颜色分量单元的每个元素编号 如下图 4 那么各反 Zig zag 编码的过程就是把矩阵元素按图 5 重新排列 图 4 将颜色分量单元元素编码 图 5 反 Zig zag 编码 关于量化和反 Zig zag 编码的先后顺序 笔者查阅的几份资料有不同的见 解 经过实践试验 解码的过程中 是应该直 接用文件提供的量化表反量化矩阵数据 再将其反 Zig zag 编码才能正确解码 7 隔行的正负纠正 隔行的正负纠正 这个问题比较特别 因为在笔者认真阅读的几份资料中都没有提及此问 题 而是笔者通过对已知图像进行 JPEG 编码压缩 然后和该图的 JPEG 文件数据对比发现的问题 具体原因不明 实际上 就是必须对每个颜色分量单元的奇数行 每个颜色分量单元有 8 行 假设把它按 0 1 6 7 编出行号 即 1 3 5 7 行 进行取相反数操作 正的变负 负的变正 8 反离散余弦变换 反离散余弦变换 之前提到 文件中的数据是在编码时通过正向离散余弦变换 FDCT 进 行时空域向频率域变换而得到的结果 所以 现在解码就必须将其反向离散余弦变换 IDCT 就是把颜色分量单元矩阵中的频率域数值向时空域转换 并且 原 来的频率域的矩阵大小为 8 8 则经过反向离散余弦变换后 时空域的矩阵仍然是 8 8 设正负纠正后的频率域矩阵为 F u v 而反向离散余弦变换后的矩阵为 f i j 其中 0 u v i j 7 具体使用的公式如下 其中 C u 当 u 0 C u 1 当 u 0 C v 当 v 0 C u 1 当 v 0 另外补充一下正向离散余弦变换的公式 用于编码 9 YCrCb 向向 RGB 转换转换 要在屏幕上显示图像 就必须以 RGB 模式表示图像的颜色 所以 解码 时需要把 YCrCb 模式向 RGB 模式转换 正如前面提到 并不是每种颜色分量的采样因子都一样 所以转换时需 要注意 如果采样因子是 1 1 1 则每一个 像素点的 3 个颜色分量都被采样 所以没有问题 但 4 1 1 的采样因子就不一样了 由 初步了解图像数据流的结构 一节中对 4 1 1 的采样因子的分析 可以知道一个 MCU 里有 4 个 Y 分量单元 而 Cr 分量和 Cb 分量各自只有 1 个分量单元 以图 2 为例 仅有的一个 Cr 分量单元 红色的 64 个采样点 应该平铺用于 4 个 Y 分量单元 即左上角 16 个值用于 Y1 右 上角 16 个值用于 Y2 左下角 16 个值用于 Y5 右下角 16 个值用于 Y6 换句话说 一个 Cr 采样点服务于 4 个 Y 采样点 对 于 Cb 分量 道理一样 另外 由于离散余弦变化要求定义域的对称 所以在编码时把 RGB 的数 值范围从 0 255 统一减去 128 偏移成 128 127 因此解码时必须为每个分量加上 128 具体公式如下 R Y 1 402 Cb 128 G Y 0 34414 Cr 0 71414 Cb 128 B Y 1 772 Cb 128 还有一个问题 通过变换得出的 R G B 值可能超出了其定义域 所以 要作出检查 如果大于 25
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 并购中的文化融合-洞察及研究
- 2025北京大兴区委老干部局招聘临时辅助用工人员1人笔试参考题库附答案解析
- 2025四川资阳产业投资集团招聘28人考试模拟试题及答案解析
- 2025北京建工集团有限责任公司建筑工程总承包部招聘笔试模拟试题及答案解析
- 2025广西南宁江南区苏圩镇政府招聘机关事业单位外聘工作人员1人笔试参考题库附答案解析
- 2025年咸阳秦都区博雅学校教师招聘(10人)考试参考题库附答案解析
- 2025下半年衢州市柯城区属事业单位招聘15人-统考笔试模拟试题及答案解析
- 2025四川德阳市旌阳区事业单位引进博士12人笔试备考题库及答案解析
- 2025四川内江隆昌市黄家镇桂花井幼儿园见习岗位需求1人考试模拟试题及答案解析
- 2025舟山嵊泗县同舟客运轮船有限公司招聘3人笔试参考题库附答案解析
- 测量班部门管理制度
- 吉林:用水定额(DB22-T 389-2019)
- CJ/T 327-2010球墨铸铁复合树脂检查井盖
- 产品售后服务方案模板
- 防雷防静电培训考试试题及答案
- 混凝土索赔协议书
- 社保返还协议书
- 2025年湖南省国际工程咨询集团有限公司招聘笔试参考题库附带答案详解
- 变电站施工考试试题及答案
- 2025年农机修理工岗位职业技能资格考试练习题库(附答案)
- 中小学违规办学行为治理典型案例与规范要求
评论
0/150
提交评论