【Codecs】JPEG原理详解

2024-01-16 18:18
文章标签 详解 原理 jpeg codecs

本文主要是介绍【Codecs】JPEG原理详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

###Date: 2018.4.22

===========================================================


JPEG 是 Joint Photographic Experts Group 的缩写,即 ISO 和 IEC 联合图像专家组,负责静态图像压缩标准的制定,这个专家组开发的算法就被称为 JPEG 算法,并且已经成为了大家通用的标准,即 JPEG 标准。 JPEG 压缩是有损压缩,但这个损失的部分是人的视觉不容易察觉到的部分,它充分利用了人眼对计算机色彩中的高频信息部分不敏感的特点,来大大节省了需要处理的数 据信息。 
  人眼对构成图像的不同频率成分具有不同的敏感度,这个是由人眼的视觉生理特性所决定的。如人的眼睛含有对亮度敏感的柱状细胞1.8亿个,含有对色彩敏感的椎状细胞0.08亿个,由于柱状细胞的数量远大于椎状细胞,所以眼睛对亮度的敏感程度要大于对色彩的敏感程度。
  总体来说,一个原始图像信息,要对其进行 JPEG 编码,过程分两大步:
  1、 去除视觉上的多余信息,即空间冗余度
  2、 去除数据本身的多余信息,即结构(静态)冗余度
  1、去除视觉上的多余信息
  当你拿到一个原始未经处理的图像,是由各种色彩组成的,即在一个平面上,有各种色彩,而这个平面是由水平和垂直方向上的很多点组成的。实际上,每个点 的色彩,也即计算机能表示的每个像素点的色彩,能分解成红、绿、蓝,即 RGB 三元色来表示,即这三种颜色的一定比例的混合就能得到一个实际的色彩值。

所以,实际上,这个平面的图像,可以理解为除了水平 X 和垂直 Y 以外,还有一个色彩值的 Z 的三维的系统。Z 代表了三元色中各个分支 R/G/B 的混合时所占的具体数值大小,每个像素的 RGB 的混合值可能都有所不同,各个值有大有小,但临近的两个点的 R/G/B 三个值会比较接近。

由于这个原始图像是由很多个独立的像素点组成的,也就是说它们都是分散的,离散的。比如有些图像的尺寸为640X480,就表示水平有640个像素点,垂直有480个像素点。
  从上面的内容,我们可以知道两个相邻的点,会有很多的色彩是很接近的,那么如何能在最后得到的图片中,尽量少得记录这些不需要的数据,也即达到了压缩的效果。
  这个就要涉及到图像信号的频谱特性了。
  图像信号的频谱线一般在0-6MHz范围内,而且一幅图像内,包含了各种频率的分量。但包含的大多数为低频频谱线,只在占图像区域比例很低的图像边缘的信号中才含有高频的谱线。这个是对 JPEG 图像压缩的理论依据。
  因此具体的方法就是,在对图像做数字处理时,可根据频谱因素分配比特数:对包含信息量大的低频谱区域分配较多的比特数,对包含信息量低的高频谱区域分配较少的比特数,而图像质量并没有可察觉的损伤,达到数据压缩的目的。
  将原始图像这个色彩空间域,转换为频谱域,怎么转呢,这个就用到了数学上的离散余弦变换,即 DCT(Discrete Cosine Transform) 变换。
  DCT 是可逆的、离散的正交变换。变换过程本身虽然并不产生压缩作用,但是变换后的频率系数却非常有利于码率压缩。即这个变换过程得到一个 DCT 变换系数,而对这个系数可以再进行更进一步的处理,即所谓的量化。经过量化,就能达到数据压缩的作用了。
总体说来,这第一步,对图像进行编码,去除多余的信息,要用到 DCT 变换中的正向 DCT(FDCT),然后再对变换的系数做量化(Quantization),这个过程就是依据的经验值,来处理人眼视觉系统所不敏感的高频数据,从而极 大地减少了需要处理的数据量,这个是结合数学方法与经验值而做的处理。 
  2、去除数据本身的多余信息
  利用 Huffman 编码,来将最后的数据用无损的方式做压缩,这个是纯数学上的处理方式。
  总体来说,上面的两步即:
  如果处理的是彩色图像,JPEG 算法首先将 RGB 分量转化成亮度分量和色差分量,同时丢失一半的色彩信息(空间分辨率减半)。然后,用 DCT 来进行块变换编码,舍弃高频的系数,并对余下的系数进行量化以进一步减小数据量。最后,使用 RLE 行程编码和 Huffman 编码来完成压缩任务。 
  三、JPEG 原理详细分析
  下面将更加详细地介绍这两步中的各个细节。
  JPEG 编码中主要涉及到的内容主要包括:
  1. Color Model Conversion (色彩模型)
  2. DCT (Discrete Cosine Transform 离散余弦变换)
  3. 重排列 DCT 结果
  4. 量化
  5. RLE 编码
  6. 范式 Huffman 编码
  7. DC 的编码

1、色彩空间 color space 
  在图像处理中,为了利用人的视角特性,从而降低数据量,通常把 RGB 空间表示的彩色图像变换到其他色彩空间。
  现在采用的色彩空间变换有三种:YIQ,YUV 和 YCrCb。
  每一种色彩空间都产生一种亮度分量信号和两种色度分量信号,而每一种变换使用的参数都是为了适应某种类型的显示设备。 


YUV 不是哪个英文单词的缩写,而只是符号,Y 表示亮度,UV 用来表示色差,U、V 是构成彩色的两个分量;
  YUV 表示法的重要性是它的亮度信号(Y)和色度信号(U、V)是相互独立的,也就是 Y 信号分量构成的黑白灰度图与用 U、V 信号构成的另外两幅单色图是相互独立的。由于 Y、U、V 是独立的,所以可以对这些单色图分别进行编码。此外,黑白电视能接收彩色电视信号也就是利用了 YUV 分量之间的独立性。
  举例来说明一下:
  要存储 RGB 8∶8∶8的彩色图像,即 R、G 和 B 分量都用8位二进制数(1个字节)表示,图像的大小为640×480像素,那么所需要的存储容量为640×480×(1+1+1)=921 600字节,即900KB,其中(1+1+1)表示 RGB 各占一个字节。 


如果用 YUV 来表示同一幅彩色图像,Y 分量仍然为640×480,并且 Y 分量仍然用8位表示,而对每四个相邻像素(2×2)的 U、V 值分别用相同的一个值表示,那么存储同样的一幅图像所需的存储空间就减少到640×480×(1+1/(2*2)+1/(2*2))=460 800字节,即450KB。也就是把数据压缩了一半。


无论是用 YIQ、YUV 和 YCrCb 还是其他模型来表示的彩色图像,由于现在所有的显示器都采用 RGB 值来驱动,这就要求在显示每个像素之前,须要把彩色分量值转换成 RGB 值。
对电视机,在考虑人的视觉系统和电视阴极射线管(CRT)的非线性特性之后,RGB 和 YUV 的对应关系可以近似地用下面的方程式表示: 


即:
  Y=0.3R+0.59G+0.11B
  U=B-Y
  V=R-Y
  对计算机而言,计算机用的数字域的色彩空间变换与电视模拟域的色彩空间变换不同,它们的分量使用 Y、Cr 和 Cb 来表示,与 RGB 空间的转换关系如下:


从这里,就可以看出,计算出来的 Y、Cr 和 Cb 分量,会出现大量的小数,即浮点数,从而导致了在 JPEG 编码过程中会出现大量的浮点数的运算,当然经过一定的优化,这些浮点数运算可以用移位与加法这些计算机能更快速处理的方式来对其进行编码。
  RGB 与 YCrCb 之间的逆变换关系可写成如下的形式:


总体来说,上面讲的这些内容,主要就是对原始图片,可以先进行色彩空间的处理,使采集到的图像数据有所减少。
  请注意,实际上,JPEG 算法与色彩空间无关,色彩空间是涉及到图像采样的问题,它和数据的压缩并没有直接的关系。
  因此“RGB 到 YUV 变换”和“YUV 到 RGB 变换”不包含在 JPEG 算法中。JPEG 算法处理的彩色图像是单独的彩色分量图像,因此它可以压缩来自不同色彩空间的数据,如 RGB,YcbCr 和 CMYK。 
2、色彩深度 color depth
  在图像中,它是由很多个点来组成的,那么存储每个像素点所用的位数就叫做像素深度。对一个图片,这个值是可以有所不同的,从而会使得图片的数据有多和少的区别。
  一幅彩色图像的每个像素用 R,G,B 三个分量表示,若每个分量用8位,那么一个像素共用3X8=24位表示,就说像素的深度为24 bit,每个像素可以是2的24次方=16 777 216种颜色中的一种。表示一个像素的位数越多,它能表达的颜色数目就越多。
  在用二进制数表示彩色图像的像素时,除 R,G,B 分量用固定位数表示外,往往还增加1位或几位作为属性(Attribute)位。例如,RGB 5∶5∶5表示一个像素时,用2个字节共16位表示,其中 R,G,B 各占5位,剩下一位作为属性位。在这种情况下,像素深度为16位,而图像深度为15 位。
  在用32位表示一个像素时,若 R,G,B 分别用8位表示,剩下的8位常称为 alpha 通道(alpha channel)位,或称为覆盖(overlay)位、中断位、属性位。它的用法可用一个预乘 α 通道(premultiplied alpha)的例子说明。假如一个像素(A,R,G,B)的四个分量都用归一化的数值表示,(A,R,G,B)为(1,1,0,0)时显示红色。当像素为 (0.5,1,0,0)时,预乘的结果就变成(0.5,0.5,0,0),这表示原来该像素显示的红色的强度为1,而现在显示的红色的强度降了一半。
  这个 alpha 值,在这里就用来表示该像素如何产生特技效果。
  总体来说,图像的宽高、分辨率越高,就是组成一幅图的像素越多,则图像文件越大;像素深度越深,就是表达单个像素的颜色和亮度的位数越多,图像文件就越大。
  只有黑白两种颜色的图像称为单色图像(monochrome),每个像素的像素值用1位存储,它的值只有“0”或者“1”,一幅640×480的单色图像需要占据37.5 KB的存储空间。
而灰度图像,即有色深的黑白图像,如果每个像素的像素值用一个字节表示,而不是仅仅只有一位,那么灰度值级数就等于256级,每个像素可以是0~255之间的任何一个值,一幅640×480的灰度图像就需要占用300 KB的存储空间,类似上面说到过的 Y 分量。 
  3、离散余弦变换 DCT
  将图像从色彩域转换到频率域,常用的变换方法有:


DCT变换的公式为:

f(i,j) 经 DCT 变换之后,F(0,0) 是直流系数,其他为交流系数。
  还是举例来说明一下。
  8x8的原始图像: 


推移128后,使其范围变为 -128~127:

使用离散余弦变换,并四舍五入取最接近的整数:

上图就是将取样块由时间域转换为频率域的 DCT 系数块。
DCT 将原始图像信息块转换成代表不同频率分量的系数集,这有两个优点:其一,信号常将其能量的大部分集中于频率域的一个小范围内,这样一来,描述不重要的分量 只需要很少的比特数;其二,频率域分解映射了人类视觉系统的处理过程,并允许后继的量化过程满足其灵敏度的要求。
  当u,v = 0 时,离散余弦正变换(DCT)后的系数若为F(0,0)=1,则离散余弦反变换(IDCT)后的重现函数 f(x,y)=1/8,是个常 数值,所以将 F(0,0) 称为直流(DC)系数;当 u,v≠0 时,正变换后的系数为 F(u,v)=0,则反变换后的重现函数 f(x,y) 不是常数,此时 正变换后的系数 F(u,v) 为交流(AC)系数。
  DCT 后的64个 DCT 频率系数与 DCT 前的64个像素块相对应,DCT 过程的前后都是64个点,说明这个过程只是一个没有压缩作用的无损变换过程。
  单独一个图像的全部 DCT 系数块的频谱几乎都集中在最左上角的系数块中。
  DCT 输出的频率系数矩阵最左上角的直流 (DC)系数幅度最大,图中为-415;以 DC 系数为出发点向下、向右的其它 DCT 系数,离 DC 分量越远,频率越高,幅度值越小,图中最右下角为2,即图像信息的大部分集中于直流系数及其附近的低频频谱上,离 DC 系数越来越远的高频频谱几乎不含图像信息,甚至于只含杂波。
  DCT 本身虽然没有压缩作用,却为以后压缩时的"取"、"舍" 奠定了必不可少的基础。 
  4、量化
  量化过程实际上就是对 DCT 系数的一个优化过程。它是利用了人眼对高频部分不敏感的特性来实现数据的大幅简化。
  量化过程实际上是简单地把频率领域上每个成份,除以一个对于该成份的常数,且接着四舍五入取最接近的整数。
  这是整个过程中的主要有损运算。
以这个结果来说,经常会把很多高频率的成份四舍五入而接近0,且剩下很多会变成小的正或负数。
  整个量化的目的是减小非“0”系数的幅度以及增加“0”值系数的数目。
  量化是图像质量下降的最主要原因。
  因为人眼对亮度信号比对色差信号更敏感,因此使用了两种量化表:亮度量化值和色差量化值。


使用这个量化矩阵与前面所得到的 DCT 系数矩阵:

如,使用?415(DC系数)且四舍五入得到最接近的整数

总体上来说,DCT 变换实际是空间域的低通滤波器。对 Y 分量采用细量化,对 UV 采用粗量化。
  量化表是控制 JPEG 压缩比的关键,这个步骤除掉了一些高频量;另一个重要原因是所有图片的点与点之间会有一个色彩过渡的过程,大量的图像信息被包含在低频率中,经过量化处理后,在高频率段,将出现大量连续的零。 
  5、“Z”字形编排
  量化后的数据,有一个很大的特点,就是直流分量相对于交流分量来说要大,而且交流分量中含有大量的0。这样,对这个量化后的数据如何来进行简化,从而再更大程度地进行压缩呢。
这就出现了“Z”字形编排,如图:

对于前面量化的系数所作的 “Z”字形编排结果就是: 
  底部 ?26,?3,0,?3,?3,?6,2,?4,1 ?4,1,1,5,1,2,?1,1,?1,2,0,0,0,0,0,?1,?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,这样很有利于使用简单而直观的行程编码(RLE:Run Length Coding)对它们进行编码。
  8×8图像块经过 DCT 变换之后得到的 DC 直流系数有两个特点,一是系数的数值比较大,二是相邻8×8图像块的 DC 系数值变化不大。根据这个特点,JPEG 算法使用了差分脉冲调制编码(DPCM)技术,对相邻图像块之间量化 DC 系数的差值(Delta)进行编码。即充分利用相邻两图像块的特性,来再次简化数据。
  即上面的 DC 分量-26,需要单独处理。
  而对于其他63个元素采用zig-zag(“Z”字形)行程编码,以增加行程中连续0的个数。 
  6、行程编码
  Run Length Coding,行程编码又称“运行长度编码”或“游程编码”,它是一种无损压缩编码。
  例如:5555557777733322221111111
  这个数据的一个特点是相同的内容会重复出现很多次,那么就可以用一种简化的方法来记录这一串数字,如
  (5,6)(7,5)(3,3)(2,4)(l,7)
即为它的行程编码。
  行程编码的位数会远远少于原始字符串的位数。
  对经过“Z”字形编排过的数据,即可以用行程编码来对其进行大幅度的数据压缩。
  我们来用一个简单的例子来详细说明一下:
  57,45,0,0,0,0,23,0,-30,-16,0,0,1,0,0,0,0 ,0 ,0 ,0,..,0
  可以表示为
  (0,57) ; (0,45) ; (4,23) ; (1,-30) ; (0,-16) ; (2,1) ; EOB
  即每组数字的头一个表示0的个数,而且为了能更有利于后续的处理,必须是 4 bit,就是说,只能是 0~15,这是的这个行程编码的一个特点。 
  7、范式 Huffman 编码
  在直流 DC 系数经过上面的 DPCM 编码,交流 AC 系数经过 RLE 编码后,得到的数据,还可以再进一补压缩,即使用 Huffman 编码来处理。
  范式 Huffman 编码即 Canonical Huffman Code,现在流行的很多压缩方法都使用了范式哈夫曼编码技术,如 GZIB、ZLIB、PNG、JPEG、MPEG 等。
  对上面的例子中 RLC 后的结果,对它的存储,JPEG 里并不直接保存这个数值,这样主要是为了提高效率。 

对上面的例子内容,就可以得到:
  57 为第 6 组的,实际保存值为 111001,编码为 (6,111001)
  45编码为 (6,101101)
  23为(5,10111)
  -30为(5,00001)
  这个时候前面的例子就变为:
  (0,6),111001 ; (0,6),101101 ; (4,5),10111; (1,5),00001; (0,4) ,0111 ; (2,1),1 ; (0,0)
  这样,括号里的数值正好再合成一个字节,高4位是前面0的个数,低4位描述了后面数字的位数;后面被编码的数字表示范围是 -32767..32767。


参考:

http://www.360doc.com/content/12/0606/19/10144181_216456484.shtml

这篇关于【Codecs】JPEG原理详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/613473

相关文章

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

K8S(Kubernetes)开源的容器编排平台安装步骤详解

K8S(Kubernetes)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。以下是K8S容器编排平台的安装步骤、使用方式及特点的概述: 安装步骤: 安装Docker:K8S需要基于Docker来运行容器化应用程序。首先要在所有节点上安装Docker引擎。 安装Kubernetes Master:在集群中选择一台主机作为Master节点,安装K8S的控制平面组件,如AP

hdu4407容斥原理

题意: 有一个元素为 1~n 的数列{An},有2种操作(1000次): 1、求某段区间 [a,b] 中与 p 互质的数的和。 2、将数列中某个位置元素的值改变。 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.Inpu

hdu4059容斥原理

求1-n中与n互质的数的4次方之和 import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWrit

嵌入式Openharmony系统构建与启动详解

大家好,今天主要给大家分享一下,如何构建Openharmony子系统以及系统的启动过程分解。 第一:OpenHarmony系统构建      首先熟悉一下,构建系统是一种自动化处理工具的集合,通过将源代码文件进行一系列处理,最终生成和用户可以使用的目标文件。这里的目标文件包括静态链接库文件、动态链接库文件、可执行文件、脚本文件、配置文件等。      我们在编写hellowor

LabVIEW FIFO详解

在LabVIEW的FPGA开发中,FIFO(先入先出队列)是常用的数据传输机制。通过配置FIFO的属性,工程师可以在FPGA和主机之间,或不同FPGA VIs之间进行高效的数据传输。根据具体需求,FIFO有多种类型与实现方式,包括目标范围内FIFO(Target-Scoped)、DMA FIFO以及点对点流(Peer-to-Peer)。 FIFO类型 **目标范围FIFO(Target-Sc