FPGA 通过 UDP 以太网传输 JPEG 压缩图片

FPGA 通过 UDP 以太网传输 JPEG 压缩图片

08ade5d13c9d6321413ce8eca6953ec6.jpeg

简介

在 FPGA 上实现了 JPEG 压缩和 UDP 以太网传输。从摄像机的输入中获取单个灰度帧,使用 JPEG 标准对其进行压缩,然后通过UDP以太网将其传输到另一个设备(例如计算机),所有这些使用FPGA(Verilog)实现。

本文是常春藤盟校Cornell University 康奈尔大学的FPGA项目,仅供参考学习~

理论背景

JPEG 图像压缩是一种有损压缩标准,它使用 DCT 变换及其相关属性来减少用于表示图像的位数。编码过程涉及许多步骤,在我们的设计中将其分解为几个独立模块。此外,为了验证压缩的正确性,还为系统设计了UDP以太网传输。

离散余弦变换

离散余弦变换 (Discrete Cosine Transform, DCT)类似于傅里叶变换将周期函数表示为不同频率的正弦之和,其可以将有限长度的数字序列表示为不同频率的余弦项的总和。DCT,更具体地说是DCT-II,由于其高能量压缩特性而被用于图像压缩。简而言之,大部分数据(或原始信息)可以被压缩为更少的比特数。

JPEG 压缩的第一步是将相关图像分割成 8x8 的像素块。然后将 2D-DCT 应用于每个 8x8 块。2-D DCT 的结果表示原始块在与矩阵索引相对应的离散频率处的空间频率信息。变换后,左上系数给出空间DC信息,右下系数给出最高空间频率(水平和垂直方向)信息。空间频率表示如下图所示。

d7b66a8e58aadf2bedc5bfee1602d1e2.png

注意,左上元素在水平和垂直方向上的空间频率较低,而右下元素的频率较高。使用 DCT,大多数原始信息可以从较低频率系数(靠近左上角的系数)重建,因为这些系数中的高能量压缩。此外,人类视觉系统对高频空间内容中的错误的感知能力较差。这两个原因叠加在一起意味着低频系数中的误差比高频元素中的误差对人类来说更加明显。

2-D DCT 运算是可分离的,意味着它可以通过对正在分析的块(8x8)应用两次 1-D DCT 来获得。首先对块的每一行执行一维变换,然后对行变换结果的列再执行一维变换。一维 DCT 系数可以使用以下等式获得:

e143a2188a2fb2d281195f7975e85656.png

其中 k 是系数的索引。对于 JPEG 变换的情况,因为变换应用于图像的 8x8 像素块,所以 N 始终等于 8。

量化

DCT 应用于 8x8 块时,量化因子会应用于系数。简而言之,此步骤使用与能量密度相关的步长对系数进行离散化。低频系数以较小的步长量化,因此比以较大步长量化的误差更小。频率越高,步长越大,从而降低了不太重要元素的精度。这是压缩过程中的有损步骤。

3c53d33a0e0e880a75749ab819e81e30.png

尽管 JPEG 压缩标准没有指定要使用的量化矩阵,但上面建议的矩阵之一。为了量化 2-D DCT 的结果,每个系数除以上面矩阵中的适当值,并四舍五入到最接近的整数。

Zig-Zag 测序

量化后,二维矩阵被重新排列成一维数组。以给出具有高能量密度的系数的方式读取元素。排序以之字形方法完成,使得系数以递增的空间频率顺序排列。使用这种方法,更重要的系数出现在序列中较早的位置,而不太重要的系数则出现在较晚的位置。

6f0f37d43a953f5791d68b51d1943314.png

可变大小、行程长度编码

假设高频系数使用较大的步长进行量化,这些系数为零的可能性比低频系数高得多。这对零值系数的候选进行了分组,使我们能够假设一系列零的可能性。

JPEG 标准压缩的主要来源是可变大小和行程长度编码。压缩中的此步骤使用霍夫曼编码和可变长度编码的组合。每个非零系数都被转换为可变长度的位串或代码。该代码包含其数量和长度信息(即 0 与 00 不同)。

如前所述,之字形组织增加了连续零的可能性,尤其是在数组末尾附近。为了避免发送连续的零,前面的零的行程长度被编码到每个非零系数的转换中。每个非零系数都被编码为可变长度代码,以及指示前面的零游程的“标头”霍夫曼代码以及 VL 代码的长度。链接(https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/f2009/jl589_jbw48/jl589_jbw48/trans_tables.html)显示了像素转换表和霍夫曼表 。这些转换表仅适用于图像的亮度值。由于我们的系统处理灰度图像,所以无需改变方案,但是对于彩色图像使用的色度值有不同的转换方案。

无论长度如何,霍夫曼码都是唯一可识别的,因此在不知道长度的情况下始终可以识别新非零值的零行程和大小。然后,使用霍夫曼给出的大小,可以提取以下 VL 位并将其转换回适当的非零系数。除非事先知道代码的长度,否则 VL 代码无法唯一识别。

DC与AC系数

DC 系数的编码与 AC 系数略有不同。由于 DC 系数不会有前面的零(这些零不会在块之间传递),因此霍夫曼码仅反映 VL 码的长度。

以太网

在开放系统互连参考模型(Open System Interconnection Reference Model,OSI 模型)中,以太网位于链路层和物理层。在物理层,以太网描述了线路如何互连。在链路层,以太网指定以太网帧应如何格式化以及帧应如何传送。

由于以太网本质上是一种广播协议,可能有许多设备连接到同一物理线路,因此一次只能有一个设备进行广播。如果线路发生冲突,以太网控制器能够检测到冲突并执行随机退避。随机退避仅仅意味着在检测到冲突时,在尝试另一次发送之前等待随机的时间。以太网帧由前导码、帧起始定界符、MAC 目标、MAC 源、以太网类型、有效负载和校验和组成。

关于以太网的介绍可以查看《基于FPGA的网口通信实例设计总结》。

用户数据报协议/互联网协议

用户数据报协议 (UDP) 和互联网协议 (IP) 分别位于 OSI 模型的接下来两层:传输层和网络层。UDP/IP 协议与以太网一样,不保证可靠的数据包接收,只能保证尽力传送。IP 协议的主要目的是在链路层之上提供一个抽象层。这样,如果底层链路层不是以太网,则不需要更改应用层软件。IP 协议通过另一对源地址和目标地址、分段偏移、标头校验和以及有效负载中使用的协议来提供此抽象。

设计

代码高度模块化,输出馈送到successive模块的输入中。编码步骤分为以下步骤(每个步骤都在单独的模块中实现):1-D DCT、2-D DCT/量化、zig-zag 组织、VL 转换、Huffman 转换和比特流构建。该系统目前可以实现 256x256 图像,但可以扩展分析更多像素。数据架构图如下所示:

6c61887ccd8a349d3d213c1ba414c6fe.png

因为仅涉及灰度成像,所以只需要彩色系统所需的三分之一的内存和处理能力。对于处理彩色图像的系统,需要将上述整个压缩过程单独应用于每个颜色通道。该项目通过选择每个像素的绿色值来获得灰度图像,而不是从 RGB 到 YUV 的转换。这种简化虽然并不完全正确,但该项目的重点不是图像,而是压缩,因此没有必要在转换操作上浪费额外的计算。

1-D DCT

1-D DCT 使用快速算法实现,需要八个周期才能完成。该算法主要需要输入和结果总和的连续相加,其中三个中间步骤期间发生五次乘法。该算法产生 DCT 结果,结果是根据实际 DCT 结果按某个因子缩放的。然而,可以在量化步骤中考虑比例,从而产生正确的量化变换矩阵。系数的比例因子如下:

21316886653d6bb29ed814e498d366ef.png

算法数据流如下图所示。

fbc714102a5e6cc0ff420ef62c8b68d6.png 2fa38da4a505c686ad7ae09cc4a20153.png

该模块是按照流水线设计,所以每个时钟周期都可以输入新的输入值,并在八个周期后输出新的输出。这使得模块能够更快地进行数据处理。

2-D DCT

2-D DCT 是可分离运算,意味着它可以通过对 8x8 块的每一行应用 1-D DCT,然后再将其应用于 8x8 块的列来获得最终结果。使我们能够使用流水线 1-D DCT 非常快速地执行 2-D DCT,方法是将块的行馈送到 1-D 模块中 8 个周期,然后获取结果并将这些列反馈回同一模块。

在将结果写回内存之前,也会在此 2D 模块中执行量化。由于算法的缩放与量化相结合的方式,整个操作仅需要对二维算法结果进行移位。

Zig-Zag

通过适当的顺序从内存中读取值来实现Zig-Zag。块的元素存储在直接从图像内像素坐标获得的地址中。存储器的输出以每周期一个像素的速率直接馈送到转换器中。

VL 和 RL

从像素的量化值到可变长度代码的转换是使用查找表完成的。该表包含代码的值和长度(以bit为单位)。然后这两个值被发送到霍夫曼翻译器。霍夫曼转换器采用前面的零数量和系数代码的大小。这两个数字被馈送到另一个查找表,该查找表给出霍夫曼代码作为非零系数的“标头”。

硬件以太网控制器

硬件以太网控制器用于初始化 DM9000A 控制芯片、向 DM9000A 推送数据包、从 DM9000A 抓取接收到的数据以及从 DM9000A 接收中断。

控制器分为两个独立的状态机,一个处理发往 DM9000A 和来自 DM9000A 的命令(包括中断),另一个处理发送和接收序列。

发送序列包括:

  1. 等待输入 FIFO 不为空。将第一个值存储为有效负载中的字节数。

  1. 告诉硬件控制器将存储多少字节,包括以太网标头。

  1. 将以太网帧作为数据发送到DM9000A。

  1. 将负载发送到DM9000A。

  1. 通过中断等待传输完成。返回空闲状态。

UDP

使用FIFO数据结构,UDP Wrapper 首先获取有效负载中的字节总数,然后一次获取 16 位的有效负载。Wrapper 使用状态机执行以下步骤来发送单个 UDP 数据包:

  1. 等待输入 FIFO 不为空。将第一个值存储为有效负载中的字节数。

  1. 告诉硬件控制器将存储多少字节,包括 UDP/IP 标头。

  1. 将以太网帧作为数据发送到硬件控制器。

  1. 将IP 标头作为数据发送到硬件控制器。IP 校验和是在发送标头之前计算的。

  1. 将UDP 标头作为数据发送到硬件控制器。

  1. 将所有数据发送到硬件控制器。

由于 UDP Wrapper 的目的是让 FPGA 能够与通过以太网直接连接的单台计算机进行通信,因此许多值都被硬编码到 Verilog 中。硬编码值包括目标和源 MAC 地址、目标和源 IP 地址以及目标端口。这四个硬编码值均设置为广播地址,MAC 地址为 FF:FF:FF:FF:FF:FF,IP 地址为 255.255.255.255。目标端口被硬编码为 31373。其他值(例如 IP 标头校验和)是动态计算的,因为标头值不一定每次都相同。完成后,控制寄存器复位并返回等待状态。

结论

尽管我们无法让最终所需的系统运行,但我们确实创建了可以与各种其他应用程序相关的可用功能模块。UDP 包装器和硬件以太网控制器在任何网络通信项目中都非常有用。流水线式一维 DCT 算法可用于信号和图像处理项目。

附录

代码

https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/f2009/jl589_jbw48/jl589_jbw48/dct_to_ethernet.v

https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/f2009/jl589_jbw48/jl589_jbw48/zz_to_ethernet.v

1-D DCT 算法

https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/f2009/jl589_jbw48/jl589_jbw48/dct_algorithm.v

2-D DCT

https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/f2009/jl589_jbw48/jl589_jbw48/dct2d.v

Zig-Zag 控制

https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/f2009/jl589_jbw48/jl589_jbw48/zigzag.v

可变长度代码转换器

https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/f2009/jl589_jbw48/jl589_jbw48/translate_to_vl.v

霍夫曼转换器

https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/f2009/jl589_jbw48/jl589_jbw48/translate_to_huffman.v

比特流缓冲区

https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/f2009/jl589_jbw48/jl589_jbw48/bitstream_buffer.v

UDP 包装器

https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/f2009/jl589_jbw48/jl589_jbw48/udp_wrapper.zip

参考

https://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/f2009/jl589_jbw48/jl589_jbw48/index.html

http://www.cs.cmu.edu/~dongw/final_fantasy/545FinalReport.html

http://en.wikipedia.org/wiki/Jpeg

http://www.impulseadventure.com/photo/jpeg-snoop.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/247272.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Element-Plus如何实现表单校验和表单重置

一&#xff1a;页面布局介绍&#xff1a; 这是我刚刚用基于vue3element-plus写好的一个部门管理的页面 基本的增删改查已经写好&#xff0c;下面我只提供页面的template和style的代码&#xff1a; template <template><el-card class"box-card"><…

【YOLO系列算法俯视视角下舰船目标检测】

YOLO系列算法俯视视角下舰船目标检测 数据集和模型YOLO系列算法俯视视角下舰船目标检测YOLO系列算法俯视视角下舰船目标检测可视化结果 数据集和模型 数据和模型下载&#xff1a; YOLOv6俯视视角下舰船目标检测训练好的舰船目标检测模型舰船目标检测数据YOLOv7俯视视角下舰船…

贝锐蒲公英全新网页认证,保障企业访客无线网络安全

随着企业规模的不断扩大、人员的增长、无线终端数量/类型的增加&#xff0c;传统WiFi无线网络会暴露出越来越多的问题&#xff0c;导致无线网络管理困难。 比如&#xff1a;采用弱密码、安全防护不到位的默认设置、员工缺乏信息安全意识、未经授人员权访问无线网络…… 这些问…

【Redis】Redis有哪些适合的场景

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Redis ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 &#xff08;1&#xff09;会话缓存&#xff08;Session Cache&#xff09; &#xff08;2&#xff09;全页缓存&#xff08;FPC…

【极数系列】Flink配置参数如何获取?(06)

文章目录 gitee码云地址简介概述01 配置值来自.properties文件1.通过路径读取2.通过文件流读取3.通过IO流读取 02 配置值来自命令行03 配置来自系统属性04 注册以及使用全局变量05 Flink获取参数值Demo1.项目结构2.pom.xml文件如下3.配置文件4.项目主类5.运行查看相关日志 gite…

Linux 网络流量相关工具

本文聚焦于网络流量的查看、端口占用查看。至于网络设备的管理和配置&#xff0c;因为太过复杂且不同发行版有较大差异&#xff0c;这里就不赘述&#xff0c;后面看情况再写。 需要注意的是&#xff0c;这里列出的每一个工具都有丰富的功能&#xff0c;流量/端口信息查看只是其…

探索Pyecharts之美-绘制多彩旭日图的艺术与技巧【第37篇—python:旭日图】

文章目录 引言准备工作绘制基本旭日图调整颜色和样式添加交互功能定制标签和标签格式嵌套层级数据高级样式与自定义进阶主题&#xff1a;动态旭日图数据源扩展&#xff1a;外部JSON文件总结 引言 数据可视化在现代编程中扮演着重要的角色&#xff0c;而Pyecharts是Python中一个…

数据结构——链式二叉树(3)

本篇文章我们依然讲解链式二叉树的OJ题&#xff1b; 一、二叉树的层序遍历 层序遍历即从根节点开始一层一层的遍历。我们可以运用队列的先进先出特性实现&#xff01; //层序遍历 void a(BTNode* root) {Que qhead;Queueinit(&qhead);//先入队根节点if(root)QueuePush(&…

三维重建(7)--运动恢复结构SfM系统解析

目录 一、SfM系统&#xff08;两视图&#xff09; 1、特征提取 2、特征匹配 3、RANSAC求解基础矩阵F 4、完整的欧式结构恢复算法流程 二、基于增量法的SfM系统&#xff08;以OpenMVG为例&#xff09; 1、预处理 2、图像特征点提取与匹配 3、两视图重构点云 4、增加…

LPC系列一个定时器不同频率

1.背景 最近研究的LPC804里只有一个ctimer&#xff0c;很多时候用的捉襟见肘的&#xff0c;官方给了一份双匹配的参考例程&#xff0c;不过实际用处不大。不过我花了一晚上的时间&#xff0c;终于研究出来将一个定时器拆成四个定时器用的办法了。这个方法适用于用回调函数的LP…

RabbitMQ(一)

1、相关概念 1.1、消息队列&#xff08;MQ&#xff09; MQ(message queue)&#xff0c;从字面意思上看&#xff0c;本质是个队列&#xff0c;FIFO 先入先出&#xff0c;只不过队列中存放的内容是message 而已&#xff0c;还是一种跨进程的通信机制&#xff0c;用于上下游传递消…

移动Web——平面转换-多重转换

1、平面转换-多重转换 多重转换技巧&#xff1a;先平移再旋转 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content"IEedge" /><meta name&qu…

数据结构——链式二叉树

目录 &#x1f341;一、二叉树的遍历 &#x1f315;&#xff08;一&#xff09;、前序遍历(Preorder Traversal 亦称先序遍历) &#x1f315;&#xff08;二&#xff09;、中序遍历(Inorder Traversal) &#x1f315;&#xff08;三&#xff09;、后序遍历(Postorder Traver…

scrapy的入门使用

1 安装scrapy 命令: sudo apt-get install scrapy或者&#xff1a; pip/pip3 install scrapy2 scrapy项目开发流程 创建项目: scrapy startproject mySpider生成一个爬虫: scrapy genspider itcast itcast.cn提取数据:     根据网站结构在spider中实现数据采集相关内…

centos系统安装Ward服务器监控工具

简介 Ward是一个简约美观多系统支持的服务器监控面板 安装 1.首先安装jdk yum install java-1.8.0-openjdk-devel.x86_64 2.下载jar wget 3.启动 java -jar ward-1.8.8.jar 体验 浏览器输入 http://192.168.168.110:4000/ 设置服务名设置为:myserver 端口号:5000 点击…

WSL2 Debian系统添加支持SocketCAN

本人最近在使用WSL2&#xff0c;Linux系统选择的是Debian&#xff0c;用起来很不错&#xff0c;感觉可以代替VMware Player虚拟机。 但是WSL2 Debian默认不支持SocketCAN&#xff0c;这就有点坑了&#xff0c;由于本人经常要使用SocketCAN功能&#xff0c;所以决定让Debian支持…

开始学习第二十五天(番外)

今天分享一下写的小游戏啦 头文件game.h #include<stdio.h> #include<time.h> #include<stdlib.h> #define H 3 #define L 3 void InitBoard(char Board[H][L], int h, int l); void DisplayBoard(char Board[H][L], int h, int l); void playermove(cha…

【LeetCode: Z 字形变换 + 模拟】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

5G_RACH(一)

什么是RACH RACH 代表 Random Access Channel。这是开机时UE发给eNB的第一条消息。 为什么选择RACH &#xff1f;&#xff08;RACH 的功能是什么&#xff1f; 当你第一次听到RACH或RACH Process这个词时&#xff0c;你脑海中浮现的第一个问题是“为什么是RACH&#xff1f;”…

Windows XP x86 sp3 安装 Google Chrome 49.0.2623.112 (正式版本) (32 位)

1 下载地址&#xff1b; https://dl.google.com/release2/h8vnfiy7pvn3lxy9ehfsaxlrnnukgff8jnodrp0y21vrlem4x71lor5zzkliyh8fv3sryayu5uk5zi20ep7dwfnwr143dzxqijv/49.0.2623.112_chrome_installer.exe 2 直接 双击 49.0.2623.112_chrome_installer.exe 安装&#xff1b; 3 …