首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

FPGA无损压缩实现

FPGA无损压缩实现

本帖最后由 look_w 于 2017-10-20 21:37 编辑

,需要将目前的图像传输数据量提高,即提高传输效率,在有限的带宽下传输更多的图像数据。当前的图像压缩算法有很多种,例如JPEG,JPEG2000,MPEG等等,最初的想法是实现一个MJPEG(Motion Joint Photographic Experts Group),其核心实际上就是jpeg压缩。JPEG压缩算法的主要步骤如下:![jpeg压缩]具体步骤就不细说了。从图中可以看到,原始图像必须分为8x8的小块来处理,这样就导致在FPGA实现的时候必须缓存至少7行的图像原始数据,如果FPGA接收的图像宽度太大,例如1920x1080,8bit的灰度图像,那么需要1920x7x8=107520bit的memory来存储,对于不想外挂sdram存储器(节省硬件成本),同时FPGA内部RAM块资源吃紧的情况下,jpeg压缩在第一步的时候就注定无法实现。JPEG压缩为啥必须是分为8x8的小块来处理呢,而不是64x1这样的单行形式? 是因为后续DCT以及量化时,8x8的数据是更加相关的,这样提取出来的低频能量更加集中,因此压缩效率会更高。既然所需的存储资源受限,只能寻找基于图像行扫描的压缩算法来实现需求。JPEG-LS压缩算法完美符合了这个需求。简单介绍下JPEG-LS压缩标准。JPEG-LS是静止图像无损/近无损编码的国际标准。它不是JPEG的一个简单扩充或修正,是一种新的压缩方法。支持无损和近无损图像压缩,不使用离散余弦变换,也不使用算术编码,仅在近无损压缩模式下有限地使用量化。JPEG-LS图像压缩算法主要有两种工作模式:常规编码模式和游程编码模式,其核心算法涉及上下文建模、预测编码、游程编码和Golomb编码等基本理论。整体编码框图如下图所示:程中遇到的几个疑惑和不解。(备注,下文中,前缀I表示原像素值,前缀R表示像素重建值,重建值的意思就是原像素I经过算法的一些步骤计算后的结果R,替换掉原像素I,因此叫做像素的重建。)①算法的预测模板是当前像素Ix点的周边四个像素A、B、C、D,在有些文章中它们标的符号为Ra、Rb、Rc、Rd,而有些文章中标的是Ia、Ib、Ic、Id,这是为何? 其原因就是取决于是使用无损压缩模式还是近无损压缩模式,如果是无损压缩模式,重建值是等于原像素值的(例Ra=Ia);而在近无损压缩模式中,重建值与原像素值可能有差别,那么是必须使用重建值进行计算的(否则解码端无法正确解码)。②整个算法到底是怎么进行压缩的,这些个步骤到底有什么用? 这个问题对于不太了解压缩原理的童鞋应该都存在,在没学习这个算法前,我也是新手。现在用通俗点的话来大致描述下整个压缩过程:图像是按照如下顺序扫描的,以左上点为(0,0)点,从左到右,到行尾后继续下一行的从左到右来进行扫描编码。第一步,首先经过预测模板,计算像素周边的梯度值,可以判断出当前像素是处于哪种状态,平坦区域还是细节丰富区域(有人可能会想,单凭这些信息,能否判断准确呢,如果有图像噪声的影响,那岂不是更不准了?这个后面再讲)。第二步,选择编码模式,常规模式或者游程模式二选一。这里主要介绍下常规模式,游程模式很多其他文章是一笔带过的,但其中也有较多的疑惑点,后续另写一篇文章专门详细介绍游程模式。第三步,根据A、B、C点的像素值来计算预测值Px,修正后与原像素值Ix做差计算,得到了一个预测残差Errval,该Errval是有正有负的。第四步,预测残差Errval通过上下文模型修正,并转化为符合后续哥伦布Golomb-rice编码的MErrval值。与此同时,通过上下文模型计算出k值。(此处MErrval就是被编码的值,因为是预测差值,理论上是接近零的,因此相比原像素要小,所占空间因此变小)第五步,将MErrval进行Golomb-rice编码输出,k就是编码时需要使用到的参数值。编码完成。上下文模板的原理目前还不是很懂,共有四个上下文参数组:A[]、B[]、C[]、N[],它们使用Q值来进行索引。每次一个像素编码完成后,就更新当前Q值所对应的四个上下文参数值A[Q]、B[Q]、C[Q]、N[Q]。下面着重介绍下在FPGA硬件逻辑实现的时候的难点之处:细心的童鞋可以发现,这个JPEG-LS算法存在两个反馈逻辑环路,第一个是上下文参数组的更新是前后像素具有强依赖关系的;第二个是近无损压缩模式下重建值Ra和Ix是强依赖关系的,Ra是上一个Ix计算所得的重建值。假设FPGA不对图像进行帧缓存,摄像头发送过来的像素一般都是前后像素紧挨着的,那么这意味着需要在一个时钟周期内就必须完成大量的串行逻辑计算,显然这样会使得整个JPEG-LS硬件编码模块的最高时钟频率大大受约束。我使用Altera的中低端FPGA做了测试,不做优化,按照C算法的串行逻辑进行实现的设计,最高时钟频率大约在40MHz左右。严重制约了硬件模块的可用性。针对上述第一点,有几种方法可以解决,一种是使用前向预测的方式,打破串行逻辑。第二种是使用两套编码逻辑,对前后像素进行分开压缩。第一种方法,在资源占用上显然更加少,我采用了第一种方式。前向预测机制,是针对预测残差Px修正时的计算需要使用C[Q]的值,而C[Q]的值在一次像素编码时,只可能有三种变化情况:-1、0、+1。那么使用三个分支,将这三种情况全部进行计算,然后在下级流水线进行选择,可以完美的打破这个串行逻辑,提高综合主频。如下图所示:![预测残差的前向预测]反馈逻辑的第二点并没有想到好的解决办法,还在思考中。最终FPGA的硬件模块设计运行频率可达120MHz,能够对摄像头输入的1920x1200@25fps的视频流进行实时压缩,无损压缩率大约在2.5倍左右。有损模式还未进行实现,
返回列表