本文转载自:OpenFPGA
基于 MicroBlaze V 的 FPGA 视觉平台:通过以太网实时捕获、调试和传输 MIPI 相机数据,支持全帧或高速 ROI 范围。

介绍
图像处理是FPGA的常见应用之一。其灵活的I/O接口使其能够与各种摄像头和传感器进行交互,包括MIPI、Camera Link、并行接口以及DVI/HDMI接口。
可编程逻辑的并行特性使得图像处理流水线能够直接并行实现,从而提高确定性并降低延迟。
在开发图像处理算法时,我们通常可以使用更高级别的框架,例如 Vitis HLS 或 MathWorks Simulink。
虽然看到算法在模拟环境中运行很棒,但最好还是看到它们在实际硬件上运行,才能确定自己设计的算法是否合理。
所以决定创建一个图像处理系统,方便随时添加新的图像处理核心。该系统能够利用多个MIPI摄像头。
图像处理流程对图像执行简单的处理阶段,例如去马赛克,然后通过以太网提供图像,以便检查算法性能。
由于目的是评估算法性能,因此通过以太网链路发送的图像数据没有进行压缩。
为了能够评估来自摄像机的实时视频,该设计将能够从整体图像中抽取较小的窗口进行流式传输。
硬件选择
在这个项目中,将使用 Artix UltraScale+ 15P FPGA,以及 2GB DDR4、10/100 以太网、SFP+ 插槽和 HDMI Rx 和 Tx。
在外部连接方面,还会利用 FMC LPC(https://camerafmc.com/)。

为了使 FPGA 板上最多可连接两个 MIPI 摄像头,我们使用了摄像头 FMC模块。该 FMC 模块最多可连接四个 MIPI 摄像头到 AMD 开发板上,具体数量取决于所用开发板,因为不同开发板的 I/O 引脚排列方式不同。
架构
该解决方案的整体架构如下所示。其中包括树莓派摄像头、Demosaic 和 AXI VDMA,后者将图像存储在 DDR4 帧缓冲区中。

然后,MicroBlaze V 处理器将使用 LWIP 从帧缓冲区读取图像,并通过 AXI Ethernet Lite 以以太网方式输出。
MicroBlaze V 还将负责启用和配置 树莓派 摄像头。为此,它使用了 AXI IIC 和 GPIO 模块。
帧的抓取、显示和控制流帧由运行在客户端 PC 上的 Python 应用程序控制。
硬件设计
该项目以 MicroBlaze V 处理器为核心构建,该处理器本身连接到以下 IP 核。
完整的设计如下所示,也可在Github上找到(链接在最后)。

图像处理流程包括:
时钟频率分配很简单,MicroBlaze V 的时钟频率为 300 MHz,由 DDR MIG 输出(图中以绿色显示)。DPHY 和视频流水线使用 200 MHz(图中以粉色显示),100 MHz(图中以蓝色显示)也需要使用。
下一步是设计运行在 MicroBlaze V 上的嵌入式软件。
嵌入式软件
该应用软件其中最重要的包括配置 RPI 摄像头和运行用于以太网通信的 LWIP 协议栈。
软件应用程序的概览如下所示,其结构简单明了:首先初始化 LWIP 和相机,然后再启动图像处理流程。流程初始化完成后,程序将采集图像,并运行主 LWIP 处理器,等待 Python 应用程序的指令。

应用程序软件已上传至GitHub(链接在最后) ,其中包含四个主要文件:app.c、app.h、imx_219_cam.c 和 imx219_cam.h。
imx219_cam.c 和 imx219_cam.h
通过 AXI IIC 处理 IMX219 相机传感器的启动。
初始化序列通过 AXI GPIO 对摄像头进行断电重启,并初始化 AXI IIC 内核。然后,它通过读取型号 ID (0x0219) 来验证传感器是否响应 IIC 命令。
app.c和app.h
该主要应用程序包含五个主要要素:
UDP帧协议使用带有每个数据包序列号和字节偏移量的格式,以便即使数据包丢失,接收方也能正确放置数据。
每个数据包包含一个 12 字节的头部,后跟最多 1460 字节的像素数据。帧头部包含数据包总数和帧大小,以便接收器了解预期接收的数据。由于 AXI Ethernet Lite 只有一个发送缓冲区,因此数据包以 2 毫秒的间隔发送。

这种方法可以实现更强大的应用程序,并防止除丢包之外的图像损坏(在这种配置下,丢包的情况很少见)。

Python应用程序
Python 应用程序旨在抓取帧并将其存储为 PNG 或流式传输可选择感兴趣区域的图像。
在流式传输过程中,Python 应用程序将每 10 秒抓取一次全帧图像,并进行更新,以便随着场景的变化更新感兴趣的区域。
Python客户端是一个单文件程序,它通过UDP协议与MicroBlaze-V通信,并使用OpenCV将接收到的像素数据重新组装成可查看的图像。它有三种运行模式,这些模式的设计都考虑到了100Mbps链路和单缓冲区以太网MAC的限制。

首先要进行的是Socket建立。客户端创建一个具有 8 MB 接收缓冲区的 UDP Socket。
接收引擎 是客户端的核心。它等待 FRMB 头部数据包,提取帧尺寸、数据包总数和快照大小,然后预先分配一个大小恰好为该值的零字节数组。当数据包到达时,每个数据包都会被放置在其声明的字节偏移量处。这使得整个系统具有容错能力。
每种模式的关键设计选择都归结于相同的限制,AXI Ethernet Lite 的单个 TX 缓冲区在 100 Mbps 时无法处理连续的密集传输。
GRAB 模式通过重试机制解决这个问题,最多尝试三次,并保留完成度最高的尝试。
窗口模式通过减小传输帧的大小来解决这个问题,是速度最快的传输方式。一个 128×128 的窗口只有 16 KB,大约相当于 12 个数据包。
流模式通过不断地从图像中传输完整帧来解决这个问题,但是帧速率受到限制。

测试
在硬件上运行 pythn 应用程序,结果显示应用程序运行正常,符合预期。
窗口模式下运行时帧率约为 20-30 FPS,对于 100 MBps 的以太网连接来说还不错。

总结
该项目演示了如何创建一个简单的帧捕获解决方案,使我们能够在硬件上测试图像处理算法,并将处理后的帧存储起来以进行进一步分析。
本项目采用了纯FPGA方案。还可以添加一些扩展功能,例如使用PCIe进行帧采集。