FPGA图像处理之三行缓存

文章目录

  • 一、前言
  • 二、FPGA实现三行缓存的架构
  • 三、Verilog代码实现
  • 四、仿真验证
  • 五、输入图像数据进行仿真验证


一、前言

  在 FPGA 做图像处理时,行缓存是一个非常重要的一个步骤,因为图像输入还有输出都是一行一行进行的,即处理完一行后再处理下一行。行缓存可以存储当前行和前一行的数据以及多行的数据,使得在处理当前行时能够方便地访问周围像素。许多图像处理的算法都需要几行的图像数据进行处理,因此行缓存是非常重要的,本文实现三行缓存,多行缓存的思想也是一致的。

二、FPGA实现三行缓存的架构

  由于图像数据一般都是从上到下从左到右一个一个输入进来,因此我们优先考虑使用FIFO,先进先出。按照一般想法,我们只需要三个FIFO,每个FIFO存储一行数据即可实现三行缓存,这里可以节省资源只使用两个FIFO实现,具体实现框框架如下:

在这里插入图片描述

  开始时,图像数据的第0行写入到FIFO1中,图像数据的第1行写入到FIFO2中。

在这里插入图片描述
  当第2行数据到来时写入到FIFO2中,同时输出写入的数据作为第二行;同时读出FIFO2中的数据写入到FIFO1中,并输出作为第一行,同时读出FIFO1中的数据输出作为第0行。

在这里插入图片描述
  同理,当第三行数据来临时写入到FIFO2中,同时输出写入数据作为第二行,再同时读出FIFO2中的数据写入到FIFO1中并输出作为第一行,同时读出FIFO2中的数据输出作为第0行。后面的行以此类推。

三、Verilog代码实现

  先看输入接口,输入为像素数据和有效信号,输出为三行数据以及有效信号。

 	input                                               sys_clk ,input                                               sys_rst ,input           [23:0]                              i_img_data  ,input                                               i_img_data_valid    ,output          [23:0]                              o_img_data_1line  ,output          [23:0]                              o_img_data_2line  ,output          [23:0]                              o_img_data_3line  ,output                                              o_img_data_valid    

  再次例化两个FIFO,位宽就为一个像素位宽,深度为一行中最多的像素数量。

img_line_buffer_fifo u0_img_line_buffer_fifo (.clk  (sys_clk        ),  // input wire clk.srst (sys_rst        ),  // input wire srst.din  (fifo1_wr_data  ),  // input wire [23 : 0] din.wr_en(fifo1_wr_en    ),  // input wire wr_en.rd_en(rd_en          ),  // input wire rd_en.dout (fifo1_q        ),  // output wire [23 : 0] dout.full (),                 // output wire full.empty()                  // output wire empty
);img_line_buffer_fifo u1_img_line_buffer_fifo (.clk  (sys_clk        ),  // input wire clk.srst (sys_rst        ),  // input wire srst.din  (fifo2_wr_data  ),  // input wire [23 : 0] din.wr_en(fifo2_wr_en    ),  // input wire wr_en.rd_en(rd_en          ),  // input wire rd_en.dout (fifo2_q        ),  // output wire [23 : 0] dout.full (),                 // output wire full.empty()                  // output wire empty
);

  然后根据架构图编写出剩下的代码,编写仿真代码。

四、仿真验证

  仿真我们先设置图像宽度为50*50,这样仿真可以跑快一点,然后写入数据流为每次都是0-49循环。就像一幅图像的第0行数据是0-49,第1行的数据也是0-49,每一行的数据都是0-49。按照想法,我们每次输出的数据就是前三行的像素,也就是3行的 0-49数据,仿真代码如下:

`timescale 1ns / 1psmodule tb_img_3line_buffer();reg                                                 sys_clk ;
reg                                                 sys_rst ;
reg                                                 i_img_data_valid    ;
reg             [23:0]                              i_img_data  ;
reg             [12:0]                              cnt ;
wire            [23:0]                              o_img_data_1line    ;
wire            [23:0]                              o_img_data_2line    ;
wire            [23:0]                              o_img_data_3line    ;
wire                                                o_img_data_valid    ;initial beginsys_clk =0;sys_rst = 1;i_img_data_valid = 0;i_img_data = 'd0;#200;sys_rst = 0;
endalways #5 sys_clk = ~sys_clk;always @(posedge sys_clk) beginif(sys_rst == 1'b1)i_img_data_valid <= 1'b0;else if(cnt == 49)i_img_data_valid <= 1'b0;elsei_img_data_valid <= 1'b1;
endalways @(posedge sys_clk) beginif(sys_rst == 1'b1)cnt <= 'd0;else if(cnt == 49)cnt <= 'd0;else if(i_img_data_valid == 1'b1)cnt <= cnt + 1'b1;elsecnt <= cnt;
endalways @(posedge sys_clk) beginif(sys_rst == 1'b1)i_img_data <= 'd0;else if(i_img_data == 49)i_img_data <= 'd0;else if(i_img_data_valid == 1'b1)i_img_data <= i_img_data + 1'b1;elsei_img_data <= i_img_data;
endimg_3line_buffer#(.IMG_WIDTH         ( 50 ),.IMG_HEIGHT        ( 50 )
)u_img_3line_buffer(.sys_clk           ( sys_clk           ),.sys_rst           ( sys_rst           ),.i_img_data        ( i_img_data        ),.i_img_data_valid  ( i_img_data_valid  ),.o_img_data_1line  ( o_img_data_1line  ),.o_img_data_2line  ( o_img_data_2line  ),.o_img_data_3line  ( o_img_data_3line  ),.o_img_data_valid  ( o_img_data_valid  )
);endmodule

  运行仿真

在这里插入图片描述
  可以看到写入的每一行数据都是0-49,写入两行后,开始输出数据。

在这里插入图片描述
  我们可以看到输出的三行数据都是0-49的数据。符合预期。我们修改一下仿真代码,写入2500个数据,对应50*50的图像大小,数据为0-2499,这样第0行的数据就是0-49,第1行的数据就是50-99,第2行的数据就是100-149,第3行的数据就是150-199。输出的数据就应该是(0,50,100),(1,51,101)以此类推,仿真代码如下:

`timescale 1ns / 1psmodule tb_img_3line_buffer();reg                                                 sys_clk ;
reg                                                 sys_rst ;
reg                                                 i_img_data_valid    ;
reg             [23:0]                              i_img_data  ;
reg             [12:0]                              cnt ;
wire            [23:0]                              o_img_data_1line    ;
wire            [23:0]                              o_img_data_2line    ;
wire            [23:0]                              o_img_data_3line    ;
wire                                                o_img_data_valid    ;initial beginsys_clk =0;sys_rst = 1;i_img_data_valid = 0;i_img_data = 'd0;#200;sys_rst = 0;
endalways #5 sys_clk = ~sys_clk;always @(posedge sys_clk) beginif(sys_rst == 1'b1)i_img_data_valid <= 1'b0;else if(cnt == 2499)i_img_data_valid <= 1'b0;elsei_img_data_valid <= 1'b1;
endalways @(posedge sys_clk) beginif(sys_rst == 1'b1)cnt <= 'd0;else if(cnt == 2499)cnt <= 'd0;else if(i_img_data_valid == 1'b1)cnt <= cnt + 1'b1;elsecnt <= cnt;
endalways @(posedge sys_clk) beginif(sys_rst == 1'b1)i_img_data <= 'd0;else if(i_img_data == 2499)i_img_data <= 'd0;else if(i_img_data_valid == 1'b1)i_img_data <= i_img_data + 1'b1;elsei_img_data <= i_img_data;
endimg_3line_buffer#(.IMG_WIDTH         ( 50 ),.IMG_HEIGHT        ( 50 )
)u_img_3line_buffer(.sys_clk           ( sys_clk           ),.sys_rst           ( sys_rst           ),.i_img_data        ( i_img_data        ),.i_img_data_valid  ( i_img_data_valid  ),.o_img_data_1line  ( o_img_data_1line  ),.o_img_data_2line  ( o_img_data_2line  ),.o_img_data_3line  ( o_img_data_3line  ),.o_img_data_valid  ( o_img_data_valid  )
);endmodule

  运行仿真

在这里插入图片描述
在这里插入图片描述
  验证完成和预期一致,后续一些图像处理算法需要用到这个行缓存。

五、输入图像数据进行仿真验证

  现在我们在仿真中输入一张图片,然后通过三行缓存输出,每次只取出第一行的数据写入到新的图片中:

在这里插入图片描述
  可以看出输出的图像和输入图像一模一样,文件大小也是一模一样,因此三行缓存是没问题的。

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

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

相关文章

Linux 安装 JDK 环境

最近有小伙伴不怎么会在 Linux 服务器安装 JDK 环境&#xff0c;小格子给大家总结分享一下&#xff0c;下次直接看这篇文章就可以了。下面以 CentOS 为例。 1. 下载 JDK 安装包 由于 JDK1.8.202 是最后一个免费版本&#xff0c;建议下载此版本。由于在 Oracle 官方网站下载需…

JS | JS之元素偏移量 offset 系列属性详解

目录 一、offset 概述 定位父级 offsetParent 偏移量 offsetWidth offsetHeight offsetLeft offsetTop 计算页面偏移 注意事项 二、offset 与 style 区别 偏移offset 样式style 三、案例 ★ 案例&#xff1a;获取鼠标在盒子内的坐标 ★ 案例&#xff1a;模态框…

软件测试学习笔记丨Pytest的使用

本文转自测试人社区&#xff0c;原文链接&#xff1a;https://ceshiren.com/t/topic/22158 1. 简介 pytest是一个成熟的全功能python测试框架测试用例的skip和xfail&#xff0c;自动失败重试等处理能够支持简单的单元测试和复杂的功能测试&#xff0c;还可以用来做selenium/ap…

2024互联网大厂营收排名:京东/阿里/华为前三,超多技术岗都在热招!

2024年已经过去一大半&#xff0c;各大互联网大厂的竞争如火如荼&#xff0c;营收都取得了不俗的成绩&#xff0c;京东、阿里、华为分别占领前三&#xff01; 第四第五名则为华为和拼多多。 根据排行榜里的公司名单&#xff0c;小码特意为大家整理了一批各大厂的招聘岗位。 阿…

【论文#快速算法】Fast Intermode Decision in H.264/AVC Video Coding

目录 摘要1.前言2.帧间模式决策概览2.1 H.264/AVC中的帧间模式决策2.2 发现和动机 3.同质性和平稳性的确定3.1 同质性区域的确定3.2 稳定性区域的决定3.3 整体算法 4.实验结果4.1 IPPP序列的测试4.2 IBBP序列测试 5.结论 《Fast Intermode Decision in H.264/AVC Video Coding》…

基础数据结构——数组(动态数组,二维数组,缓存与局部性原理)

1.概述 在计算机科学中&#xff0c;数组是由一组元素&#xff08;值或变量&#xff09;组成的数据结构&#xff0c;每个元素有至少一个索引或键来标识 因为数组内的元素是连续存储的&#xff0c;所以数组中元素的地址&#xff0c;可以通过其索引计算出来&#xff0c;例如&…

生产力工具|vscode for mac的安装python库和使用虚拟环境(一)

一、在vscode中运行python代码&#xff08;mac或windows&#xff09; &#xff08;一&#xff09;在vscode中安装Python插件 若想在vscode中高效率的编辑Python代码&#xff0c;需要安装Python插件&#xff0c;点击下图中红框内的按钮&#xff1a; 然后在左上角的搜索框中输入…

Vue前端开发2.1 单文件组件

文章目录 一、单文件组件概念二、单文件组件构成1. 模板&#xff08;Template&#xff09;2. 样式&#xff08;Style&#xff09;3. 逻辑&#xff08;Script&#xff09; 三、单文件组件演示1. 创建Vue项目2. 启动Vue项目3. 用VS Code打开项目4. 清空样式文件代码5. 创建欢迎组…

【redis】热点key问题

【redis】热点key问题 【一】什么是热点key问题【二】什么样的key被称为热key【三】热点Key问题的危害【四】如何监控发现热点key【五】热点Key的解决方案【1】使用二级缓存【2】将热key分散到不同的服务器中【3】热key拆分【4】将核心/非核心业务做Redis的隔离 【六】业界已有…

Nature 正刊丨细菌免疫蛋白直接感知两种不同的噬菌体蛋白

01摘要 真核先天免疫系统使用模式识别受体通过检测病原体相关的分子模式来感知感染&#xff0c;然后触发免疫反应。细菌也进化出了类似的免疫蛋白&#xff0c;可以感知其病毒捕食者的某些成分&#xff0c;即噬菌体1,2,3,4,5,6。尽管不同的免疫蛋白可以识别不同的噬菌体编码的触…

log4j2.xml

log4j2.xml 1、log4j2.xml使用2、日志器的流程解析2.1、几个重要的类2.2、整体流程图 3、部分源码3.1、通过简单例子看源码3.2、log4j2.xml配置指导 如侵权&#xff0c;请联系&#xff0c;无心侵权&#xff5e; 如有错误&#xff0c;也请指正。 1、log4j2.xml使用 <?xml v…

Anaconda虚拟环境安装cuda和pytorch

首先电脑上要有Anaconda&#xff0c;使用conda创建一个虚拟环境,并激活 conda create yolov8 conda activate yolov8winR输入cmd&#xff0c;在命令窗口输入 NVIDIA-smi可以查看到自己电脑支持的cuda环境&#xff0c;如下图 再打开torch的官网 pytorch官网 查看目前支持的版…

目标检测——Cascade R-CNN算法解读

论文&#xff1a; Cascade R-CNN: Delving into High Quality Object Detection (2017.12.3) 链接&#xff1a;https://arxiv.org/abs/1712.00726 Cascade R-CNN: High Quality Object Detection and Instance Segmentation (2019.6.24) 链接&#xff1a;https://arxiv.org/abs…

Z 字形变换(6)

这道题之前一直不会做&#xff0c;明白他是什么意思&#xff0c;但是找不到方法或者方法过于繁琐 方法1&#xff1a; 这是我在力扣评论区看到的方法&#xff0c;太精彩了。 虽然我实现起来效率并不高&#xff0c;可能是我代码的问题&#xff0c;但是他的思路很巧妙。 字符串的…

Spring--1

spring是一个轻量级的&#xff0c;采用IOC与AOP编程思想的java后端开发框架&#xff0c;简化了企业级的应用开发。 Spring体系 数据访问层&#xff0c;Web层&#xff0c;配置中心&#xff0c;测试区 IOC 控制反转&#xff0c;将创建对象的控制权交由Spring框架&#xff0c;需…

音频分割:长语音音频 分割为 短语音音频 - python 实现

在做语音任务时&#xff0c;有是会用到的语音音频是长音频&#xff0c;这就需要我们将长音频分割为短音频。 该示例将声音的音量和静默时间结合作为语音的分割条件。 使用音量和静默时间结合的分割条件&#xff0c;能够比较好的进行自然断句&#xff0c;不会话语没有说完就切断…

Spring声明式事务管理:深入探索XML配置方式

前言 Spring的事务管理&#xff0c;无论是基于xml还是注解实现&#xff0c;本质上还是实现数据库的事务管理机制&#xff0c;因此要注意发送SQL的连接是否为同一个&#xff0c;这是实现声明式事务的关键。 以下案例和实现基于SSM整合框架完成&#xff0c;不知道如何整合SSM&…

【K8S系列】Kubernetes Pod 状态详细介绍及异常状态解决方案

在 Kubernetes 中&#xff0c;Pod 是最小的可调度单元&#xff0c;负责运行一个或多个容器。Pod 的状态能够反映其生命周期中的不同阶段&#xff0c;帮助用户了解当前的运行状况。本文将详细介绍 Kubernetes Pod 的各种状态及其可能的异常状态解决方案。 一、Pod 状态概览 Po…

查缺补漏----数据结构树高总结

① 对于平衡二叉树而言&#xff0c;树高的规律&#xff1a; 高度为h的平衡二叉树的含有的最少结点数&#xff08;所有非叶节点的平衡因子均为1&#xff09;&#xff1a; n01&#xff0c;n11&#xff0c;n22 含有的最多结点数&#xff1a; (高度为h的满二叉树含有的结点数) ②…

Flutter在 iOS 中实现无弹窗获取剪切板内容

前言 在最新的项目需求中&#xff0c;我们需要在获取剪切板内容时避免弹出授权提示。这一功能是基于竞品的实现&#xff0c;旨在优化用户体验&#xff0c;特别是在推广获取跳转链接的场景下非常有用。 解决方案 通过查阅资料&#xff0c;我们发现对于 iOS 16 及以上的系统&a…