该项目将展示如何实施完整的端到端图像处理管道,以实施能够以 30fps 的速度运行的边缘检测视觉算法,以检测道路车道。
要实现实时车道检测,我们的想法是拍摄图像并将其传递给边缘检测器 IP。最著名的一种是 Sobel 边缘检测器。然而,Canny 边缘检测器具有可编程阈值的优势。即时修改阈值可以适应不同的光照条件。
https://en.wikipedia.org/wiki/Canny_edge_detector
视觉处理流水线在逻辑上可以分为三个部分。图像源、图像处理管道和图像接收器。
从高层次的角度来看,需要一个图像源(可以是相机传感器或图像模式生成器)和一个接收器(可以是显示器)。
首先,必须将所有原型硬件部件放在一起。在这种情况下,系统硬件仅由五个组件组成。
a) MiniZed ZYNQ 开发板
b) OV7670 相机
c) Arduino 屏蔽穿孔板
d) 10pin 0.1inch 母头
e) VGA PMOD
OV7670 相机安装在一个 10 针 0.1 英寸母接头上,该接头本身焊接到原型板上。VGA PMOD 连接到 MiniZed 双 PMOD 接头连接器。最后一步是将 VGA 电缆连接到显示器。
一旦硬件系统组装在一起,下一步就是使用 Vivado 在 FPGA (PL) 上设计硬件。
有许多相机接口,但最简单的是使用并行总线的 CMOS 传感器,例如古老的 OV7670 相机传感器。然而,要使用这样的传感器,必须实现一个相机捕获模块,该模块将从传感器传输的字节流转换为适当的协议,在我们的例子中是 AXIS 总线。
此外,必须通过在 PL 中将配置模块实现为从 BRAM 读取配置的 I2C 模块或在 PS 中将配置模块实现为通用相机驱动程序来配置相机。PS 配置显然更灵活,所以我选择了这个选项。
Vivado 设计中的图像源是与 OV7690 CMOS 相机接口的定制 IP。相机使用并行八位接口。此外,还有两个同步信号HSYNC和VSYNC,其选通模式分别表示行和帧。相机使用输出像素时钟 PCLK。像素速率与 PCLK 同步。OV7690 相机还需要一个 24 MHz (XCLK) 相机时钟作为输入。
OV7690 每个像素输出 2 个字节。根据配置代码,相机可以配置为使用不同的色彩空间。IP 配置为使用 RGB565 色彩空间。相机的控制是通过 AXI 接口完成的。摄像机 IP 在内存中分配了一个位置。要启动相机,必须设置位以启用相机输出数据。数据本身使用 AXIS (AXI Stream) 协议打包。
来自相机的 AXIS 输出被发送到异步 FIFO。这是需要跨越两个不同时钟域时使用的一种方法。
FIFO 的从端连接到 PCLK,而 FIFO 的主端连接到工作频率为 50MHz 的 AXI 主时钟域。主时钟必须始终高于从时钟,否则 FIFO 将溢出导致丢失像素。
在像素流穿过时钟域后,它通过子集转换器发送。这是一个 AXIS IP 块,可将 RGB565 数据重新映射为 24 位数据包。图像处理 IP 使用 24 位,因为每种颜色都分配了 8 位。
下一个元素是 AXIS 开关。该 IP 作为 AXIS 流的简单多路复用器运行。它可以通过 AXI lite 接口或利用 AXIS 频闪信号自动配置。在此特定应用中,启用了 AXIS 开关的 AXI Lite 接口。然而,这需要实施 SDK 驱动程序来配置开关多路复用器。
Canny 边缘检测器 IP 是使用 Vivado HLS 构建的。它是用 C 语言编写的。HLS 的主要优点是允许快速部署 IP。缺点是生成的逻辑是模糊的,通常不如手工制作的 Verilog 代码高效,尽管它可以接近它。在任何情况下,生成 Canny IP 都涉及使用 Vivado HLS 2013 和 2018.3 版本的 xfopencv。这是一组 C++ 库,复制了用于 FPGA 逻辑的众所周知的 OpenCV 库。
Xilinx 最近发布了 Vivado 2019.1 以及 HLS 2019.1。这需要使用带有非免费修订框架的 SDSOC。
已实施的修订代码的主要更改是修改功能以支持 AXIS 协议的输入和输出。此外,AXI Lite 总线用于将所有可编程变量捆绑在一个集合中,并通过连接到 GP0 ZYNQ 总线的 AXI 互连将它们暴露给 PS 内存映射。
最后,为了在两个不同的 IP 之间切换,使用了 AXI 开关。
VDMA 配置为三重缓冲模式。VDMA 需要在运行前通过 AXI lite 接口进行配置,该接口将其连接到主 AXI 互连。
下面的代码显示了针对 VGA 分辨率的 VDMA 配置。
Xil_DCacheFlush();
Xil_ICacheInvalidate();
/* Start of VDMA Configuration */
Xil_Out32(XPAR_VDMA_S2MM_BASEADDR + 0x30, 0x8B);
Xil_Out32(XPAR_VDMA_S2MM_BASEADDR + 0xAC, 0x10000000);
Xil_Out32(XPAR_VDMA_S2MM_BASEADDR + 0xB0, 0x100F0000);
Xil_Out32(XPAR_VDMA_S2MM_BASEADDR + 0xB4, 0x101E0000);
Xil_Out32(XPAR_VDMA_S2MM_BASEADDR + 0xA8, WIDTH*2);
Xil_Out32(XPAR_VDMA_S2MM_BASEADDR + 0xA4, WIDTH*2);
Xil_Out32(XPAR_VDMA_S2MM_BASEADDR + 0xA0, HEIGHT);
Xil_Out32(XPAR_VDMA_S2MM_BASEADDR + 0x00, 0x8B);
Xil_Out32(XPAR_VDMA_S2MM_BASEADDR + 0x5C, 0x10000000);
Xil_Out32(XPAR_VDMA_S2MM_BASEADDR + 0x60, 0x100F0000);
Xil_Out32(XPAR_VDMA_S2MM_BASEADDR + 0x64, 0x101E0000);
Xil_Out32(XPAR_VDMA_S2MM_BASEADDR + 0x58, WIDTH*2);
Xil_Out32(XPAR_VDMA_S2MM_BASEADDR + 0x54, WIDTH*2);
Xil_Out32(XPAR_VDMA_S2MM_BASEADDR + 0x50, HEIGHT);
。。
VTC 本身配置为 VGA 分辨率。
这基本上是一个 R2RDAC,它采用数字数据总线以及行和帧同步信号 HSYNCS 和 VSYNC,并将数据发送到监视器。
正如您在下面看到的,应用程序在正常 VGA 模式、灰色模式(看起来更像蓝色)和边缘检测模式之间不断切换。
该项目展示了如何在 ZYNQ FPGA SoC 上实现完整的端到端视觉处理流水线。硬件能够以 30 fps 的速度进行实时边缘检测。
其他想法包括:
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
全部0条评论
快来发表一下你的评论吧 !