FPGA—YOLO

卷积、窗口运算之滑动窗口模块设计

     在图像处理中,卷积、窗口运算是非常基础且常用的操作。这些基于图像滑动窗口的运算非常适合在FPGA中进行流水线实时高效处理,也是FPGA图像算法实现的一个热点。其中,最基础的工作就是在FPGA中设计一个滑动窗口模块。

设计一个完备的滑动窗口模块首先要解决以下3个问题:

  • 图像行缓存机制
  • 行、场等同步信号的延迟
  • 图像边界的扩展

图像行缓存机制

        有2种实现方案:

        (1)使用FIFO或RAM按行缓存图像。

        网上很多的博客和教程都是采用这种方案。例如,生成3×3的窗口需要缓存2行图像,消耗2个FIFO/RAM,FIFO/RAM最终都是消耗FPGA的块存储资源,消耗量与缓存行数成正比。每个FIFO/RAM都需要通过逻辑单独控制读写。FIFO/RAM都可在FPGA开发软件中例化IP核实现。

        (2)使用单个RAM缓存所有行

        例如,3×3的窗口通过1个RAM缓存2行图像。这种方案有2个优点。

        首先,可以简化逻辑设计,因为无论需要缓存多少行图像,FPGA都只需要操作1个RAM的读写。

        另外,充分利用FPGA块存储器位宽和深度的可变性。当位宽和总缓存量在单个块存储器的范围内,则仅使用1个块存储器就可以缓存多行图像,从而降低块存储器资源的消耗,尤其是当窗口尺寸较大时效果明显。

        例如,Xilinx 7系列FPGA的块存储器block ram可配置为1K×36bit的模式,可以缓存4行像素深度为8bit,宽为1024的图像,实现5×5滑动窗口的行缓存。2个1K×36bit模式的block ram就可以最多缓存9行8bit×1024的图像,以此类推。

        所以,推荐使用这种方案。

行、场等同步信号的延迟

由于滑动窗口行缓存机制的存在,滑动窗口的输出相对于图像的输入存在一部分固定行数的延时,其对应的行、场同步信号也需要与之保持一致的延时。例如,3×3滑动窗口的输出至少会延时1行图像的时间,5×5窗口输出至少延时2行图像,以此类推,至少延时(窗口尺寸-1)/2行图像。

        同步信号的延时方法通常有2种。

        (1)与行缓存方式类似,通过FIFO或RAM将输入的同步信号整体延时。

        这种方案的优点在于,输入和输出同步信号可以保持完全一致。缺点是需要消耗额外的FPGA块存储资源。

        (2)通过逻辑生成延时的同步信号。

        这样不需要消耗FPGA块存储资源,但是需要设计单独的逻辑,而且也无法保证输出和输入同步信号完全一致。

        对于大多数应用场景,输入和输出同步信号不一致并不影响数据流和处理结果,对于FPGA而言块存储器资源比逻辑资源更稀缺。因此,实际应用中第2种方法更为常用。如果对同步信号时序有严格要求,那只能采用第1种方案。

图像边界的扩展

边界扩展原理

        图像卷积或窗口运算,在涉及图像4周边界点位置的滑动窗口会出现部分像素点缺失,需要进行特殊处理。常用的策略包括忽略,补固定值,边界复制,边界镜像等等。

        (1)忽略

        就是不对滑动窗口中缺失的像素点进行处理,直接用来进行计算,由于缺失像素点对应的FPGA触发器可能为任意值,所以边界像素点区域的运算结果会受到影响。但对于小窗口来说,影响较小,不容易察觉,可以采用。

        (2)补固定值

        同样会直接影响边界像素点区域的运算结果。但对于小窗口或者某些特定场景来说,也可以采用。

        (3)边界复制

        就是直接复制4个边界的像素点到缺失的位置,对应的行列位置缺多少个就复制多少次。这是最常用的一种方法,matlab和opencv里也经常被使用。这种方式对边界点的计算结果影响很小。

        (4)边界镜像

        就是以边界为对称轴,以镜像的方式复制边界区域的像素点。这种方式同样对边界点的计算结果影响很小,在matlab和opencv里也会被使用。

  在FPGA中进行边界像素点扩展有2种方式。

        (1)动态扩展。

        就是当窗口在边界滑动时,动态补全缺失的像素点,整个操作是在原图上直接进行的。这种方法有个明显的缺点,当窗口比较大时,动态补全部分会使用很多组合逻辑,资源消耗量大,且不利于时序收敛,一般不推荐使用这种方法。

        (2)先扩展后滑动。

        就是先对图像进行边界扩展,然后在扩展后的图像上进行滑动窗口输出。边界扩展需要在图像进行行缓存时完成。这种方式在滑动窗口生成时无需对边界像素点作判断和处理,不需要消耗逻辑资源。缺点是,边界扩展会增大输入图像的尺寸,同时改变输入行、场同步信号的时序关系,行间和帧间的消隐期被压缩。如果窗口尺寸较大或输入图像消隐时间较短,导致扩展的列数超过行间消隐时间,或图像下方扩展的行数超过了帧间消隐时间,则无法使用这种方案。但是在绝大多数场景下,第这种方案完全可用。

        从FPGA实现角度和窗口运算结果而言,边界复制是最佳的选择。既能保证运算结果,又便于在FPGA中实现。边界镜像方法由于镜像复制机制设计更为复杂,会消耗更多的FPGA资源,因此不作为首选。

   滑动窗口模块在FPGA图像算法实现中会被经常使用,若将其设计成一个通用模块,则可以有效提高代码编写效率。设计成通用模块时可以考虑以下几个功能的实现。

  • 像素bit位宽可配置
  • 窗口大小可配置,且长宽尺寸可不同
  • 输入图像尺寸可动态改变
  • 行缓存所消耗的存储资源量可配置
  • 支持单时钟周期多个相邻像素点并行输入输出,且并行像素点数可配置

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注