基于 FPGA 的低成本成像系统

点击蓝字关注我们

关注、星标公众号,精彩内容每日送达
来源:网络素材

介绍

开发嵌入式视觉系统不需要使用昂贵的 FPGA 或 SoC、大型帧缓冲存储器和外部摄像头。

我们可以使用直接与 CMOS 传感器连接的成本优化的 FPGA / SoC 来开发非常强大的图像处理系统。这允许创建一种解决方案,该解决方案不仅可以实现成本目标,而且还可以实现紧凑和节能。

直接与传感器接口是带有照相机的接口,因为我们已经做了不同的先前。当我们与相机接口时,我们通过 HDMI、CameraLink 等接收视频信号,这是相当直接的。

当我们与图像传感器连接时,我们通常会以不同的格式接收图像,例如 MIPI 或并行格式,在接收视频之前,我们需要首先配置成像器以按照我们的需要进行操作。

通常,成像器需要通过 I2C 或 SPI 进行配置,并且通过接口发送的命令数量可能很大。

为了演示我们如何将传感器与成本优化的 FPGA 集成到该项目中,我们将研究集成

TDNext 1.26 兆像素 Pmod

艺术S7-50

由于 Arty S7 不直接在板上提供 HDMI 或其他视频输出,因此本示例将使用 Avnet 10 英寸触摸屏。然而,这是可选的输出最终图像的另一个选项是Digilent Pmod VGA。该 Pmod 还可用于实施成本非常低的解决方案。

与 TDNext Pmod 的接口非常简单,可以分为视频和配置两个元素。

视频接口由 10 位像素(拆分 8 位和 2 位 LSB)帧和行有效、像素时钟和参考时钟 (24 MHz) 组成。

配置接口由连接到成像设备的 I2C 和 I2C IO 扩展器组成,用于生成对成像器的复位。

该解决方案的架构如下,将使用软核处理器通过 I2C 配置成像器。然而,虽然图像处理路径将在 FPGA 内实现,但由于这是一个低成本应用,该解决方案不会在 DDR 存储器中实现外部帧缓冲器,而是图像处理流水线将完全在 FPGA 中实现。

该设计还将使用软核处理器来控制视频时序和图像处理路径的其他相关配置任务。

背景

TDNext 是一种彩色成像器,这意味着该成像器应用了拜耳模式,可以过滤每个像素的波长。这意味着在积分期间,每个像素仅累积红色、绿色或蓝色波长的光子。

061835aabd5169521979f1006f1e7a61.png

在积分时间完成时,每个像素被读出为 8 位或 10 位像素。该像素值称为 RAW8 或 RAW10 像素。为了重新创建彩色图像,使用去拜耳算法组合包含不同波长像素的周围像素的值。

Vivado 构建

我们需要做的第一件事是创建 Vivado 平台,这将接收来自 TDNext Pmod 的图像。

为了创建框图,我们将主要使用 Vivado 库中的 IP 核,但我们将使用摄像头接口块和 Avnet 库中的输出块。

第一步是安装板定义文件,这使 Vivado 能够了解 Arty S7 的配置。

下载后,这些文件应安装在以下路径下的 Vivado 目录中:

<安装路径>/Vivado/<版本>/data/boards/board_files/

这将允许您选择 Arty S7 板作为创建新 Vivado 项目的目标板。

安装好电路板后,下一步是创建新项目、框图并创建 MicroBlaze 系统。

随着 MicroBlaze 系统的启动和运行,下一步是添加视频处理管道。处理链将使用以下 IP 块

CAM 接口 - 与 TDNext 视频接口接口

Video to AXIS - 将并行视频转换为 AXI Streaming 格式

Sensor Demosaic - 将代表 R、G 或 B 的 RAW 像素值转换为 24 位 RGB 格式

Video Timing Generator - 生成输出格式的视频时序信号

AXI Stream to Video Out - 将 AXI Stream 转换为并行视频

ZED ALI3 控制器 - 驱动 10 英寸触摸屏的 IP 模块

AXI IIC - 连接到 MicroBlaze 这将用于配置成像器

AXI UART - 连接到 MicroBlaze,用于向用户报告系统状态

如果我们使用 Pmod VGA,我们不需要使用 ZED ALI3 控制器 IP 块。

在我们添加 Zed ALI3 和 CAM 接口之前,我们需要重新配置 IP 核,以便能够包含在 Spartan 7 设计中。我们从 IP 目录视图执行此操作,选择所需的 IP 核并单击 packager 中的编辑 IP。

这将打开一个新项目并使您能够选择可比性选项卡并添加对 Spartan 7 设备的支持。重新打包设计并更新 Vivado 项目中的 IP 库。

88d09d85e7a7bb3301090bc5027a14d8.png

一旦 IP 升级为支持 Spartan 7,我们就可以完成设计。完整的方框图应如下所示。

d5bdf48e49cf1a55b91207d1c534fdc3.png

与之前基于异构 SoC 的示例不同,该示例使用外部帧缓冲区。此示例不会使用 VDMA 从外部帧缓冲区读取和写入,这种方法需要 AXIS 到 Video 和 VTC 的不同配置。

通常情况下,AXIS to video 配置为主控,VTC 不受控制。然而,在这种方法中,AXIS to video 被配置为从设备,并且 VTC 发生器时钟使能受到控制。

152e21174f8bb631eaa9623c7debc0d2.png

这种方法允许 AXIS 到视频 IP 模块通过启用和禁用 VTC 来控制同步的时序,因此它们与处理管道中的同步时序相匹配。

在 AXI Stream 中,帧的开始由 TUser 指示,行尾由 TLast 指示。

IP 块的关键定制是:-

视频输入到 AXI 4 流

89d9743490b6e0b38f8e5a4638ed3183.png

传感器去马赛克设置

de8102a77062637a7d879287c70e51c3.png

AXI IIC 设置

f32629ad3521a66f70b8976f0fd892fd.png

在设计中我还加入了几个集成逻辑分析仪(ILA),以实现系统状态的内部监控和调试。

项目完成后Arty S7-50的总利用率如下图所示。

c5a59b5497a915dfefd09c055c11f531.png

我们可以使用额外的资源来实现使用 HLS 的图像处理算法是必要的。如果我们想节省资源,我们可以使用 MicroBlaze 的最小占用空间并移除 ILA。

在 SDK 中编写软件

生成 Vivado 硬件后,下一步是编写应用软件,该软件将在视频处理内核上配置成像器和 IP 内核。

因此,该软件将执行以下操作

初始化 AXI IIC、VTC 和中断控制器

设置中断控制器以生成 AXI 相关中断 - 这包括三个中断服务例程。IIC 发送、接收和状态各一个。

为 10 英寸显示器配置 VTC 上的计时

通过 I2C 重置相机并点亮 PMOD 上的 LED

通过 I2C 检测摄像头,我们正在寻找检测 MT9M114

通过 I2C 链接初始化相机 - 这将需要几秒钟来编写所有命令

为了初始化成像器,我已将 TDM114 示例设计提供的基于 Zynq 的库转换为可用于 AXI IIC 的格式。

相机初始化后,我们将能够在连接到 AXI 流组件的视频流的 ILA 上看到视频。

3e5b2a91ca55170ce2498d5e2d040a9b.png

监控TDNext Pmod 背面的I2C 通信显示Arty S7 和TDNext 之间的通信。

检测到摄像头后,应用程序将下载多个 I2C 摄像头配置设置。

将使用 AXI UART 报告进度

5ef40fc698743ae04558a63877ef89a2.png

一旦相机被初始化,我们就可以使用 ILA 来验证成像器正在生成视频,并且它是我们配置的分辨率。

我们通过使用 ILA 并直接检查在 FPGA 中接收到的视频来做到这一点。

da9c8e24dda3b55aca45f190d49b6730.png

上图显示了 1280 像素的线宽,这正是我们所期望的。

接收到的像素从并行格式转换为 AXI 流。

AXI Stream 是一种单向总线,用于将数据从主机传输到从机,作为数据流,它不包含地址通道。为了控制流和通过 AXI 流传输视频时序信息,使用以下信号

TReady - 准备好接收数据时由下游外设置位

TValid - 当输出数据有效时由发送外设断言

TUser - 为帧开始发出

TLast - 为行尾发布

第二个 ILA 可用于确保正确生成 AXI 流。

由于我们没有 VDMA,重要的是 AXIS 流上的视频输出是一个连续块,并且 TValid 在活动像素期间不会断言和取消断言。

09764400db5a812286e1a1c233b79584.png

我们可以通过将像素时钟用于图像处理链来确保 Tvalid 是连续的。

c39316f843c1ffef9329f680ab79289f.png

该项目中使用的库 API 如下,但包含 IIC 配置数据的 camera_initial.h 除外。Xilinx 根据硬件配置提供所有其他头文件。

844fb1a9ceea0037630686cb274aa437.png

设备地址和标识符

65f22750fc1ff6324ce7e5f510da5a2e.png

应用程序的主循环可以在下面看到

int main()

{

u32 Status;

XIic_Config *iic_conf;

XVtc VtcInst;

XVtc_Config *vtc_config;

XVtc_Timing vtcTiming;

XVtc_SourceSelect SourceSelect;

XV_demosaic_Config *mosaic_config;

init_platform();

printf("www.adiuvoengineering.com S7 Imager example\n\r");

mosaic_config = XV_demosaic_LookupConfig(XPAR_XV_DEMOSAIC_0_DEVICE_ID);

XV_demosaic_CfgInitialize(&mosaic,mosaic_config,mosaic_config->BaseAddress);

XIntc_Initialize(&InterruptController, int_dev);

SetUpInterruptSystem();

iic_conf = XIic_LookupConfig(IIC_dev);

Status = XIic_CfgInitialize(&iic, iic_conf, iic_conf->BaseAddress);

if (Status != XST_SUCCESS) {

printf("XIic initial is fail \n \r") ;

return XST_FAILURE;

}

XIic_SetSendHandler(&iic, &iic, (XIic_Handler) SendHandler);

XIic_SetRecvHandler(&iic, &iic, (XIic_Handler) ReceiveHandler);

XIic_SetStatusHandler(&iic, &iic,(XIic_StatusHandler) StatusHandler);

vtc_config = XVtc_LookupConfig(XPAR_VTC_0_DEVICE_ID);

XVtc_CfgInitialize(&VtcInst, vtc_config, vtc_config->BaseAddress);

vtcTiming.HActiveVideo = 1280;

vtcTiming.HFrontPorch = 65;

vtcTiming.HSyncWidth = 55;

vtcTiming.HBackPorch = 40;

vtcTiming.HSyncPolarity = 0;

vtcTiming.VActiveVideo = 800;

vtcTiming.V0FrontPorch = 7;//8;

vtcTiming.V0SyncWidth = 4;

vtcTiming.V0BackPorch = 12;

vtcTiming.V1FrontPorch = 7;

vtcTiming.V1SyncWidth = 4;

vtcTiming.V1BackPorch = 12;

vtcTiming.VSyncPolarity = 0;

vtcTiming.Interlaced = 0;

memset((void *)&SourceSelect, 0, sizeof(SourceSelect));

SourceSelect.VBlankPolSrc = 1;

SourceSelect.VSyncPolSrc = 1;

SourceSelect.HBlankPolSrc = 1;

SourceSelect.HSyncPolSrc = 1;

SourceSelect.ActiveVideoPolSrc = 1;

SourceSelect.ActiveChromaPolSrc= 1;

SourceSelect.VChromaSrc = 1;

SourceSelect.VActiveSrc = 1;

SourceSelect.VBackPorchSrc = 1;

SourceSelect.VSyncSrc = 1;

SourceSelect.VFrontPorchSrc = 1;

SourceSelect.VTotalSrc = 1;

SourceSelect.HActiveSrc = 1;

SourceSelect.HBackPorchSrc = 1;

SourceSelect.HSyncSrc = 1;

SourceSelect.HFrontPorchSrc = 1;

SourceSelect.HTotalSrc = 1;

XVtc_RegUpdateEnable(&VtcInst);

XVtc_SetGeneratorTiming(&VtcInst,&vtcTiming);

XVtc_SetSource(&VtcInst, &SourceSelect);

XVtc_EnableGenerator(&VtcInst);

XIic_Reset(&iic);

PCA9534_CTRL ();

Detect_Camera();

Soft_Reset_Camera();

Initial_Camera();

XV_demosaic_Set_HwReg_width(&mosaic,0x500);

XV_demosaic_Set_HwReg_height(&mosaic,0x31f);

XV_demosaic_Set_HwReg_bayer_phase(&mosaic,0x1);

XV_demosaic_EnableAutoRestart(&mosaic);

XV_demosaic_Start(&mosaic);

while(1){

}

cleanup_platform();

return 0;

}

运行整个软件应用程序使我捕捉到了我的会议徽章收藏的下面的图像。

95df191de03243eafa125c6814af486f.png

我需要调整一些设置以增加集成时间,但是,基本图像处理管道正在按我们的预期工作。

结论

很容易创建一个视觉处理系统,它直接与成像器一起工作,而不是相机。随着处理链的显着减少,这通常允许更具成本效益和潜在的响应更快的解决方案。

e2d62297697c3693f5e2d9ae9e5c9799.jpeg

想要了解FPGA吗?这里有实例分享,ZYNQ设计,关注我们的公众号,探索

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我来介绍一款我所熟知的FPGA开发板——Digilent Arty S7。 Digilent Arty S7是一款基于Xilinx Spartan-7系列FPGA开发板。它具有灵活性高、性价比优良、易用性强等特点,因此在学术研究、原型设计、开发调试等领域得到了广泛的应用。 硬件架构方面,Digilent Arty S7采用了一些常见的电路设计,包括FPGA、时钟、存储、通信等模块。下面我将分别对这些模块进行介绍。 1. FPGA模块 Digilent Arty S7采用了Xilinx Spartan-7系列FPGA芯片,型号为XC7S50。这款FPGA芯片具有50,000个逻辑单元、1,800个千兆位传输率(GTP)通道、5,200个数字信号处理(DSP)单元、1.3 Mb的Block RAM等硬件资源,可以满足大部分应用场景的需求。 此外,FPGA模块还包括了与其他模块进行通信的接口,如JTAG、UART、SPI、GPIO等。 2. 时钟模块 时钟模块是Digilent Arty S7的重要组成部分,它为整个系统提供了统一的时序。时钟模块由两个晶振和一个时钟分配器组成。其中,一个晶振为100 MHz,用于FPGA内部逻辑的时钟;另一个晶振为32.768 kHz,用于实时时钟(RTC)。 时钟分配器可以为FPGA提供多个时钟信号,包括50 MHz、100 MHz、125 MHz、150 MHz等。此外,时钟分配器还可以通过可编程时钟源(PLL)产生任意频率的时钟信号。 3. 存储模块 存储模块包括了闪存和DDR3 SDRAM两部分。闪存用于存储FPGA的配置文件,它可以通过JTAG或者USB进行编程。DDR3 SDRAM用于存储系统的数据。 Digilent Arty S7采用了128 Mb的DDR3 SDRAM,工作频率为333 MHz,带宽达到10.6 GB/s。此外,DDR3 SDRAM还具有ECC功能,可以提高系统的可靠性。 4. 通信模块 通信模块包括了以太网、USB、UART、SPI等接口,用于与外部设备进行通信。其中,以太网接口采用了10/100/1000 Mbps自适应速率,可以实现高速网络通信;USB接口可以用于FPGA的编程、数据传输等;UART和SPI接口可以用于与其他设备进行串行通信。 总体来说,Digilent Arty S7的硬件架构设计合理,具有良好的性能和易用性。它可以作为一个强大的开发平台,用于各种应用领域的原型设计、系统开发、算法验证等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值