GPU PRO 4 - 6.2 Real-Time JPEG Compression Using DirectCompute 笔记

本笔记仅为个人的理解,如果有误欢迎指出。

Real-Time JPEG Compression Using DirectCompute 使用DirectCompute实时JPEG压缩

本文基于C++ 和 Direct3D 11.0 ,利用DirectCompute 对RGB数据进行JPEG压缩。

整个文章分为两个部位:

1,JPEG的主要流程以及原理

2,DX11实现实例

1,JPEG的主要流程以及原理

图像的RGB数据主要通过图示的流程进行压缩,分别是颜色空间转换、色度降采样、离散余弦变换、量化以及最后的数据编码。

1.1 颜色空间转换

图片的每个像素的数据首先通过颜色转化公式从RGB格式转换到YCbCr格式,公式数据如下:

这个转换将红绿蓝数据转换为光照强度,红色以及蓝色,Y为光照强度

1.2 色度降采样

基于人眼对亮度的感知敏感度高于对色彩变化的敏感度,在JPEG的压缩中会对Cb和Cr的数值进行取平均处理,图像的Cb和Cr通道的数据会被划分成几个区块,每个区块的颜色都取平均处理。降采样是图片数据压缩的关键之一,这一步处理会导致图片的数据被修改。

文章举例了三种处理模板如下图所示

处理模板通常表示为 W : H : V ,其中 W 表示采样宽度,H 表示水平方向的采样数,V 表示垂直方向的采样数。

这里的宽度不是很理解,但基本思路就只是选定范围,对范围的所有值求平均值,Cb通道和Cr通道各做一次。

1.3 正向离散余弦变换

色度降采样之后,会对每个通道的数据进行8 x 8 的区块划分,并应用正向离散余弦变换(FDCT),在进行变化前会将数值范围从【0~255】减去128,转换到【-128~127】。转换之后8x8的矩阵区块记为M,FDCT的转换实际为矩阵计算,公式为(2.3),矩阵F和F^T的定义为(2.2)。计算后得到的结果为D。

矩阵D被称为DCT系数。

FDCT转换作用是能将图像的颜色信息转为频域,图像的分量被分解为不同的强度频率,具体原理文章没有给出详细说明,个人理解这个转换能够将图像中色度强度不高的部分筛选处理方便后续过滤处理。

1.4 量化

人的视觉对高强度中的微小变化不敏感,因此可以在不显著影响视觉效果的情况下丢弃DCT系数中部分数据的精度。

具体操作是每个DCT系数都会与一个预先定义好的量化表里的数据相除,并将所得的结果四舍五入。

所以整个量化的过程是有损的,并影响最终的JPEG数据的大小,JPEG 标准为亮度和色度分量提供了可选的标准量化表。量化也是图片数据压缩的关键之一,这一步处理会导致图片的数据被修改。

(左边是亮度图(Y)的量化表,右边是色度图(CbCr)的量化表)

同时不同质量等级的量化表可以通过下面的公式进行生成:

量化完成后,所有系数都会按照Z字形顺序重新排序,这种排序的方式能够使得低频系数放在高频系数之前。

1.5 编码

量化之后会把矩阵里的每个系数都进行编码,压缩成一个比特流。具体编码规律可以简单参考下图:

在量化排序完成后,先按照顺序统计完数字,再用Huffman 编码对统计完的数据编码。

需要注意的是,在这篇文章中对编码算法有一些改动。

编码时是无损压缩,这里虽然会减少数据大小但是数据不会缺失。

2,DX11实现例子

在处理JPEG压缩的时候,GPU会将线程划分出线程组,每组有8x8个线程执行任务,分配的线程组数量取决于图像的尺寸和色度降采样的模式。

Direct3D 的以下特性对实现JPEG压缩编码有利:

1,与所有 Direct3D 资源的完全互操作性。

2,组内线程的同步性

3,计算任务可以访问组的共享内存

4,可以无序的对资源进行读写

5,读写资源的时候自动对边界进行检查,防止溢出

6,内置函数具有原子性

7,在硬件层面上对纹理进行缩放

输出图像尺寸与源图像尺寸不一致的可能原因:

1,缺乏着色器资源

2,多重采样未启用

3,图像尺寸非8或16的倍数

在JPEG实现中的流程中同时涉及到GPU和CPU的处理,GPU负责大部分的编码和计算工作,CPU负责凭借最终的JPEG数据。下图展示了单个线程组的执行流程,最终输出一个经过Huffman编码的比特流。

整个流程的伪代码:

ComputeColorTransform 中将RGB颜色转换到YCbCr和色度降采样这两个操作整合在了一起。

Copy to device memory 中会将最终的处理数据复制到设备的内存中, 同时会因为色度降采样的模板不同,数据的排序也会不同。如下图所示

在GPU计算完成所有数据后,CPU会将这些数据整合在起义,在最后附加EOI标记表明图像结束标记。在这个过程中CPU会把相关的编码数据存储到JFIF头中:

1,量化表

2,Huffman 标

3,色度降采样模板因子

4,图像尺寸

5,颜色分量数量

6,采样精度

个人总结:这篇文章主要价值还是JPEG压缩算法,算是一个科普文

参考资料:

【PEG算法原理 jpeg图片是如何压缩的】

【有趣的霍夫曼编码】

相关推荐
努力学习的小廉2 小时前
redis学习笔记(三)—— hash数据类型
redis·笔记·学习
Coisinilove2 小时前
MATLAB学习笔记——第一章
笔记·学习·matlab
努力学习的小廉2 小时前
redis学习笔记(四)—— list数据类型
redis·笔记·学习
承渊政道3 小时前
C++学习之旅【C++继承概念指南与核心内容介绍】
c语言·开发语言·c++·笔记·学习·visual studio
GeminiJM3 小时前
LangGraph 源码学习笔记
linux·笔记·学习·langchain
charlie1145141913 小时前
RK3568跑Ubuntu 24.04全路程指南(以正点原子的RK3568开发板为例子)
linux·笔记·ubuntu·rootfs·教程·环境配置·rk3568
小龙3 小时前
【学习笔记】视频抽帧方法大全
笔记·学习·计算机视觉·视频·视频抽帧
一只小小的芙厨3 小时前
寒假集训·子集枚举2
c++·笔记·算法·动态规划
求真求知的糖葫芦3 小时前
巴伦学习(三.一)一种可以实现阻抗变换的平面Marchand巴伦的公式推导学习笔记(下)(自用)
笔记·学习·平面