Hard-PNG/README.md
2022-03-05 13:48:08 +08:00

8.6 KiB
Raw Blame History

test docs platform

Hard-PNG

基于FPGA的流式的png图象解码器

特点

  • 支持宽度不大于4000像素的png图片对图片高度没有限制。
  • 支持所有颜色类型: 灰度、灰度透明、RGB、索引RGB、RGBA。
  • 仅支持8bit深度大多数png图片都是8bit深度
  • 完全使用SystemVerilog实现,方便移植和仿真。
框图
图1 : Hard-PNG 原理框图

背景知识

png是仅次于jpg的第二常见的图象压缩格式,相比于jpgpng支持透明通道,支持无损压缩。在色彩丰富的数码照片中,无损压缩的png只能获得1~4倍的压缩比,低失真有损压缩的png能获得4~20倍的压缩比。在色彩较少的人工合成图(例如框图、平面设计)中,无损压缩的png就能获得10倍以上的压缩比。因此,png更适合压缩人工合成图,jpg更适合压缩数码照片。

png 图片的文件扩展名为 .png 。以我们提供的文件 test1.png 为例,它包含98字节,称为原始码流。我们可以使用WinHex软件查看它:

0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, ...... , 0xAE, 0x42, 0x60, 0x82

该图象文件解压后只有4列2行,共8个像素16进制表示如下表。其中R, G, B, A分别代表像素的绿透明通道。

列 1 列 2 列 3 列 4
行 1 R:FF G:F2 B:00 A:FF R:ED G:1C B:24 A:FF R:00 G:00 B:00 A:FF R:3F G:48 B:CC A:FF
行 2 R:7F G:7F B:7F A:FF R:ED G:1C B:24 A:FF R:FF G:FF B:FF A:FF R:FF G:AE B:CC A:FF

Hard-PNG 的使用

Hard-PNG是一个能够输入原始码流,输出解压后的像素的硬件模块,它的代码在 hard_png.sv 中。其中 hard_png 是顶层模块,它的接口如图2所示

接口图
图2 : hard_png 接口图

它的使用方法很简单,首先需要给 clk 信号提供时钟(频率不限),并将 rst 信号置低,解除模块复位。 然后将原始码流原始码流输入接口 输入,就可以从图象基本信息输出接口像素输出接口中得到解压结果。

test1.png为例,我们应该以图3的时序把原始码流98个字节输入hard_png中。 该输入接口类似 AXI-stream ,其中 ivalid=1 时说明外部想发送一个字节给 hard_pngiready=1 时说明 hard_png 已经准备好接收一个字节。只有 ivalidiready 同时 =1 时,ibyte 才被成功的输入 hard_png 中。

输入时序图
图3 : hard_png 输入时序图,以 test1.png 为例

在输入的同时,解压结果从模块中输出,如图4。在新的一帧图象输出前,newframe 信号会出现一个时钟周期的高电平脉冲,同时 colortype, width, height 保持有效直到该图象的所有像素输出完为止。其中 width, height 分别为图象的宽度和高度, colortype 的含义如下表。另外, ovalid=1 代表该时钟周期有一个像素输出该像素的R,G,B,A通道分别出现在 opixelr,opixelg,opixelb,opixela 信号上。

colortype 2'd0 2'd1 2'd2 2'd3
颜色类型 灰度图 灰度+透明 RGB / 索引RGB RGBA
含义 RGB通道相等, A通道=0xFF RGB通道相等 RGB通道不等, A通道=0xFF RGBA通道均不等
输出时序图
图4 : hard_png 输出时序图,以 test1.png 为例

当一个图象完全输入结束后,我们可以紧接着输入下一个图象进行解压。如果一个图象输入了一半,我们想打断当前解压进程并输入下一个图象,则需要将 rst 信号拉高至少一个时钟周期进行复位。

仿真

tb_hard_png.sv 是仿真的顶层,它从指定的 .png 文件中读取原始码流输入hard_png中,再接收解压后的像素并写入一个 .txt 文件。

仿真前,请将 tb_hard_png.sv 中的PNG_FILE宏名改为 .png 文件的路径,将OUT_FILE宏名改为 .txt 文件的路径。然后运行仿真。 .png 文件越大,仿真的时间越长。当ivalid信号出现下降沿时,仿真完成。然后你可以从 .txt 文件中查看解压结果。

我们在 images文件夹 下提供了多个 .png 文件,它们尺寸各异,且有不同的颜色类型,你可以用它们进行仿真。以 test3.png 为例,仿真得到的 .txt 文件如下:

frame  type:2  width:83  height:74 
f4d8c3ff f4d8c3ff f4d8c3ff f4d8c3ff f4d8c3ff f4d9c3ff ......

这代表图片的尺寸是83x74 colortype 是2RGB第1行第1列的像素是RGBA=(0xf4, 0xd8, 0xc3, 0xff)第1行第2列的像素是RGBA=(0xf4, 0xd8, 0xc3, 0xff)......

正确性验证

为了验证解压结果是否正确,我们提供了Python程序 validation.py ,它对 .png 文件进行软件解压,并与仿真得到的 .txt 文件进行比较,若比较结果相同则验证通过。为了准备必要的运行环境,请安装Python3以及其配套的 numpyPIL 库。运行环境准备好后,打开 validation.py ,将变量 PNG_FILE 改为要验证的 .png 文件的路径,将 TXT_FILE 改为仿真输出的 .txt 文件的路径,然后用命令运行它:

python validation.py

若验证通过,则打印 "validation successful!!" 。目前我们测试了几十张不同的 .png 图片,均验证通过。

性能测试

  • 测试平台: 在 Altera Cyclone IV EP4CE40F23C6 上运行 Hard-PNG 进行png解压,时钟频率= 50MHz (正好时序收敛)。
  • 对比平台: 使用MSVC++编译器O3优化级别编译upng库,在笔记本电脑(Intel Core I7 8750H)上运行png解压。

测试结果如下表,Hard-PNG的性能接近对比平台。由此可以推断,Hard-PNG的性能好于大部分ARM嵌入式处理器

png文件名 颜色类型 图象尺寸 对比平台耗时 Hard-PNG 耗时
test9.png RGB 631x742 83 ms 204 ms
test10.png 索引RGB 631x742 不支持 48 ms
test11.png RGBA 1920x1080 402 ms 993 ms
test12.png 索引RGB 1920x1080 不支持 204 ms
test13.png RGB 1819x1011 321 ms 655 ms
test14.png 黑白 1819x1011 135 ms 227 ms
wave2.png 索引RGB 1427x691 不支持 27 ms

FPGA 资源消耗

下表是hard_png模块综合后占用的FPGA资源量。

FPGA 型号 LUT LUT(%) FF FF(%) Logic Logic(%) BRAM BRAM(%)
Xilinx Artix-7 XC7A35T 2581 13% 2253 5% - - 792kbit 44%
Altera Cyclone IV EP4CE40F23C6 - - - - 4551 11% 427kbit 37%

参考链接

感谢以下链接为我们提供参考。

  • upng: 一个轻量化的 C 语言 png 解码库
  • TinyPNG: 一个利用索引 RGB 对 png 图片进行有损压缩的工具
  • PNG Specification: png 标准手册