png 是仅次于jpg的第二常见的图象压缩格式。png支持透明通道(A通道),支持无损压缩,支持索引RGB(基于调色板的有损压缩)。在色彩丰富的数码照片中,png只能获得1~4倍的压缩比。在人工合成图(例如平面设计)中,png能获得10倍以上的压缩比。
本设计使用system verilog语言设计了一个png图片解码器,输入数据为8位的流式数据,输出数据为解码后的32位数据,其中高24位为RGB数据,低8位为透明度数据,实用性和灵活性很高;一并提供了加速器的仿真源文件,可通过vivado或其他软件进行仿真,文章后面有详细的仿真教程;
本文详细描述了png图片解码器及其仿真的设计方案,工程代码可综合编译上板调试,但目前只做到了仿真层面,可直接项目移植,适用于在校学生、研究生项目开发,也适用于在职工程师做项目开发,可应用于医疗、军工等行业的数字成像和图像压缩领域;
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式放在了文章末尾,请耐心看到最后;
我这里目前已有的视频图像编解码方案如下:
1:FPGA实现H264视频解码方案,工程源码和设计说明参考链接:点击直接前往
2:FPGA实现MPEG2视频压缩方案,工程源码和设计说明参考链接:点击直接前往
3:FPGA实现JPEG图像解码方案,工程源码和设计说明参考链接:点击直接前往
4:FPGA实现JPEG-LS图像压缩方案,工程源码和设计说明参考链接:点击直接前往
5:FPGA实现png图片解码方案,即本文。。。
png图片解码算法介绍可以百度一下或者csdn或者知乎搜一下看看,专业的讲解我不擅长,我只擅长用fpga实现算法,专业讲原理的大佬比我讲得好,这里可以推荐一篇阅读量很大的文章:直接点击前往
1:基于FPGA的流式的 png 图象解码器,输入 png 码流,输出原始像素;
2:支持图像宽度<4000,高度不限;
3:支持所有颜色类型:灰度、灰度+A、RGB、索引RGB、RGB+A;
4:仅支持8bit深度(大多数 png 图像都是8bit深度);
5:资源消耗少,首先看看在Xilinx Artix-7 xc7a35tcsg324-2 上综合和实现的资源消耗:
6:解码延时低
在 Xilinx Artix-7 xc7a35tcsg324-2 上部署 png图片解码器,时钟频率= 50MHz (正好时序收敛)。根据仿真时每个图像消耗的时钟周期数,可以算出压缩图像时的性能,举例如下:
上表中的测试图片我会在工程文件中一并给出,感兴趣的也可以重新测试一遍延时。。。
png图片解码器的使用方法很简单,以 我给出的测试图片文件夹test_image/img01.png 这张图像为例,如下时序图,在输入一张图象的码流前,先要令 istart 上产生一个高电平脉冲(宽度至少为一个时钟周期),然后通过 ivalid 和 ibyte 信号来输入码流(这张图象的 png 码流有 98 字节,这 98 字节都要逐一输入给 png图片解码器),其中 ivalid 和 iready 构成了握手信号: ivalid=1 时说明外部想发送一个字节给png图片解码器。iready=1 时说明png图片解码器已经准备好接收一个字节。只有 ivalid 和 iready 同时=1 时握手才成功,ibyte 才被成功的输入png图片解码器中。
在输入码流的同时,这张图象的解压结果(也就是图像基本信息和原始像素)会从模块中输出,如下图,在图象的像素输出前,ostart 信号会出现一个时钟周期的高电平脉冲,同时 colortype, width, height 会有效。其中:
width, height 分别是图象的宽度和高度;
colortype 是 png 图像的颜色类型,含义如下:
然后,ovalid=1 代表该时钟周期有一个像素输出,该像素的 R,G,B,A 通道会分别出现在opixelr,opixelg,opixelb,opixela 信号上。
png图片解码器原理框图如下:
其中顶层的数据输入输出如下:
具体设计的代码层级讲解这里不多说,要把代码讲清楚写几本书也未必能说清楚,还是拿到代码去仔细品味吧。。。
开发板FPGA型号:Xilinx xc7k325tffg676-2;
开发环境:Vivado2019.1;
输入:14张png图片;
输出:txt文件;
输出显示:我用的Matlab读取txt显示图片;
运行:Vivado在线仿真;
仿真流程为:
第一步:
添加源码并开启行为仿真:
第二步:
点击开始仿真:
该仿真需要运行30分钟;
仿真的输入我准备了共14张png图片,分辨率不一样,基本可以完美的模拟绝大多数类型的png图片了,输入图片文件夹位置如下:
经过漫长的仿真后会结束,并跑完波形如下:
此时也生成了对应的14个txt文件,位置如下:
以out14.txt为例,打开文件:
使用Matlab将输出的txt文件转为图片显示,再和源png图片做对比,当然,还可以用Python等验证,方法自己喜欢就好。。。
以out14.txt为例,打开out14.txt,并去掉首行字符,如下:
另存为out14_matlab.txt,位置如下:
将此文件复制到Matlab源码文件夹下,运行如下Matlab源码即可显示输出RGB图像;Matlab源码如下:
clear;clear all;clc;
col = 1920;
row = 1080;
n = 3;
image_sim_pass = uint8(zeros(row,col,n));
fid = fopen('out14_matlab.txt','r');
for x = 1:row
for y = 1:col
RGB = fscanf(fid,'%s',1);
image_sim_pass(x,y,1) = uint8(hex2dec(RGB(1:2)));
image_sim_pass(x,y,2) = uint8(hex2dec(RGB(3:4)));
image_sim_pass(x,y,3) = uint8(hex2dec(RGB(5:6)));
end
end
fclose(fid);
imshow(image_sim_pass),title('png解码后的RGB图片');
imwrite(image_sim_pass,'img14_simout.jpg');
打开源png图片和Matlab输出的解码后的RGB图做对比如下:
福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送,
资料获取方式:私,或者文章末尾的V名片。
网盘资料如下: