Files
thejinchao.github.io/docs/blog/2025/02/JPEG001.md
T
2025-02-22 19:54:50 +08:00

67 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "JPEG算法解密(一)"
tags: 压缩 图像 程序 算法
next:
text: JPEG算法解密(二)
link: JPEG002.md
---
# JPEG算法解密(一)
图片压缩有多重要,可能很多人可能并没有一个直观上的认识,举个例子,一张800X800大小的普通图片,如果未经压缩,大概在1.7MB左右,这个体积如果存放文本文件的话足够保存一部92万字的鸿篇巨著《红楼梦》,现如今互联网上绝大部分图片都使用了JPEG压缩技术,也就是大家使用的jpg文件,通常JPEG文件相对于原始图像,能够得到1/8的压缩比,如此高的压缩率是如何做到的呢?
JPEG能够获得如此高的压缩比是因为使用了有损压缩技术,所谓有损压缩,就是把原始数据中不重要的部分去掉,以便可以用更小的体积保存,这个原理其实很常见,比如485194.200000000001这个数,如果我们用485194.2来保存,就是一种“有损”的保存方法,因为小数点后面的那个“0.000000000001”属于不重要的部分,所以可以被忽略掉。JPEG整个压缩过程基本上也是遵循这个步骤:
1. 把数据分为“重要部分”和“不重要部分”
2. 滤掉不重要的部分
3. 保存
### 步骤一:图像分割
----
JPEG算法的第一步,图像被分割成大小为8X8的小块,这些小块在整个压缩过程中都是单独被处理的。后面我们会以一张非常经典的图为例,这张图片名字叫做Lenna,据说是世界上第一张JPG图片,这张图片自从诞生之日开始,就和图像处理结下渊源,陪伴了无数理工宅男度过了的一个个不眠之夜,可谓功勋卓著,感兴趣的朋友可以在[这里](http://en.wikipedia.org/wiki/Lenna)了解到这张图片的故事。
<p align="center">
<img src="/images/2014/08/Lenna.png" width="40%">
<img src="/images/2014/08/jpeg_01.jpg" width="40%">
</p>
### 步骤二:颜色空间转换RGB->YCbCr
----
所谓“颜色空间”,是指表达颜色的数学模型,比如我们常见的“RGB”模型,就是把颜色分解成红绿蓝三种分量,这样一张图片就可以分解成三张灰度图,数学表达上,每一个8X8的图案,可以表达成三个8X8的矩阵,其中的数值的范围一般在[0,255]之间。
![](/images/2014/08/RGB_YCBCR.png)
不同的颜色模型各有不同的应用场景,例如RGB模型适合于像显示器这样的自发光图案,而在印刷行业,使用油墨打印,图案的颜色是通过在反射光线时产生的,通常使用CMYK模型,而在JPEG压缩算法中,需要把图案转换成为YCbCr模型,这里的Y表示亮度(Luminance),Cb和Cr分别表示绿色和红色的“色差值”。
“色差”这个概念起源于电视行业,最早的电视都是黑白的,那时候传输电视信号只需要传输亮度信号,也就是Y信号即可,彩色电视出现之后,人们在Y信号之外增加了两条色差信号以传输颜色信息,这么做的目的是为了兼容黑白电视机,因为黑白电视只需要处理信号中的Y信号即可。
根据三基色原理,人们发现红绿蓝三种颜色所贡献的亮度是不同的,绿色的“亮度”最大,蓝色最暗,设红色所贡献的亮度的份额为$K_R$,蓝色贡献的份额为$K_B$,那么亮度为
$$
Y=K_R\cdot R+(1-K_R-K_B)\cdot G+K_B\cdot B
$$
根据经验,$K_R=0.299$,$K_B=0.114$,那么
$$
Y=0.299R+0.587G+0.114B
$$
蓝色和红色的色差的定义如下
$$
C_b=\large{\frac{1}{2}\frac{B-Y}{1-K_B}}
$$
$$
C_r=\large{\frac{1}{2}\frac{R-Y}{1-K_R}}
$$
最终可以得到RGB转换为YCbCr的数学公式为
$$
\begin{aligned}
Y&=0.299R+0.5870G+0.114B\\
C_b&=-0.1687R-0.3313G+0.5B\\
C_r&=0.5R-0.4187G-0.0813B
\end{aligned}
$$
YCbCr模型广泛应用在图片和视频的压缩传输中,比如你可以留意一下电视或者DVD后面的接口,就可以发现色差接口。
<p align="center">
<img src="/images/2014/08/jpeg_14.jpg">
</p>
这是有道理的,还记得我们在文章开始时提到的有损压缩的基本原理吗?有损压缩首先要做的事情就是“把重要的信息和不重要的信息分开”,YCbCr恰好能做到这一点。对于人眼来说,图像中明暗的变化更容易被感知到,这是由于人眼的构造引起的。视网膜上有两种感光细胞,能够感知亮度变化的视杆细胞,以及能够感知颜色的视锥细胞,由于视杆细胞在数量上远大于视锥细胞,所以我们更容易感知到明暗细节。比如说下面这张图
![](/images/2014/08/jpeg_15.jpg)
<p align="center">
<img src="/images/2014/08/jpeg_16.png" width="30%">
<img src="/images/2014/08/jpeg_17.png" width="30%">
<img src="/images/2014/08/jpeg_18.png" width="30%">
</p>
可以明显看到,亮度图的细节更加丰富。JPEG把图像转换为YCbCr之后,就可以针对数据得重要程度的不同做不同的处理。这就是为什么JPEG使用这种颜色空间的原因。