【数字图像处理】边缘检测

边缘检测是一种图像处理技术,用于在图像中识别和提取物体边缘的信息,广泛应用于计算机视觉和图像分析领域。本文主要介绍数字图像边缘检测的基本原理,并记录在紫光同创 PGL22G FPGA 平台的布署与实现过程。

目录

1 边缘检测原理

2 FPGA 布署与实现

2.1 功能与指标定义

2.2 模块设计

2.3 上板调试


1 边缘检测原理

        边缘检测是一种数字图像处理技术,用于在图像中识别和提取物体边缘的信息,广泛应用于计算机视觉和图像分析领域。

        边缘检测的基本原理是利用图像中的亮度、颜色、纹理等差异,以及对象形状的不连续性,来检测图像中的边缘。常见的边缘检测算法包括 Prewitt、Sobel、Laplacian 等,这些算法可以生成一个边缘响应,图中每个像素点的值表示该位置周围边缘的强度。

        在边缘检测算法中,使用被称为算子的矩阵,例如 Prewitt 算子、Sobel 算子、Laplacian 算子等。算子在输入图像上移动时,重叠的区域进行卷积运算,得到输出图像上某个位置的响应。

Prewitt 算子

Prewitt_x = \begin{bmatrix} -1 & 0 & 1 \\ -1 & 0 & 1 \\ -1 & 0 & 1 \end{bmatrix}, Prewitt_y = \begin{bmatrix} -1 & -1 & -1 \\ 0 & 0 & 0 \\ 1 & 1 & 1 \end{bmatrix}

Sobel 算子

Sobel_x = \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{bmatrix}, Sobel_y = \begin{bmatrix} -1 & -2 & -1 \\ 0 & 0 & 0 \\ 1 & 2 & 1 \end{bmatrix}

        Prewitt 边缘检测算法的优势在于它对噪声有一定的抑制作用,同时能够检测到图像中的水平和垂直边缘。然而,它对于其他方向的边缘检测效果较差。Sobel 检测算法对灰度渐变和噪声较多的边缘处理效果较好,但是对边缘的定位不够准确。

2 FPGA 布署与实现

2.1 功能与指标定义

        使用紫光同创 FPGA 平台实现边缘检测功能,FPGA 需要实现的功能与指标如下:

(1)与电脑的串口通信,用于接收上位机下发的图像数据,波特率为 256000 Bd/s;

(2)RGB 转灰度图处理,使用 3 个乘法器对接收到的图像进行灰度转换,用于后续的边缘检测;

(3)Prewitt 边缘检测,使用 FPGA 内部的 RAM 资源缓存 3 行图像数据,对 3 × 3 邻域内的数据进行 Prewitt 边缘检测;

(4)DDR3 读写控制,将处理前后的图像数据分别写入 DDR3 的不同区域,实现图像的拼接;

(5)HDMI 输出,输出一路 HDMI 信号源,用于将拼接后的图像显示在外接显示器上,分辨率为 1024×768。

2.2 模块设计

        边缘检测工程主要的设计模块层次与功能说明如下:

模块名称功能说明
top_uartuart_rx_slice串口接收驱动模块
uart_rx_parse串口数据解析模块,从上位机接收 8bit 原始图像,以及 Gamma 曲线数据
top_vidinvidin_pipelinepipeline 单元模块,缓存两行图像数据,并将数据提交到 ddr3 数据调度模块
vidin_pipeline_spipeline 单元简化模块,只缓存两行图像数据,无需产生与提交 ddr3 写命令
conv_rgb2grayRGB 转灰度图处理模块,使用乘法器进行灰度转换
conv_prewitt边缘检测模块,运用 Prewitt 算子对 3 × 3 领域内的数据进行处理
merge_outdvi_timing_genHDMI 视频时序产生模块
dvi_ddr_rd根据 HDMI 控制信号,提交读指令到 ddr3 数据调度模块
dvi_encoderHDMI 输出编码(8b10b 编码)与输出驱动模块

其中,conv_rgb2gray 模块实现灰度变换,conv_prewitt 模块实现边缘检测功能,conv_prewitt 实现水平边缘检测的思路为:

(1)对输入行数据进行打拍,得到 3 × 3 区域的数据;

(2)使用加法器电路,分别计算 3 × 3 区域内第 1 列、第 3 列的数据之和;

(3)使用比较器和减法器电路,计算第 1 列与第 3 列数据和的差。

对于垂直边缘检测,需要将列方向的数据求和,修改为行方向的数据求和。

conv_prewitt 模块代码如下:

`timescale 1 ns/ 1 psmodule conv_prewitt (input          reset,input          clock,input          load,input  [7:0]   ina,input  [7:0]   inb,input  [7:0]   inc,output [7:0]   edge_x,output [7:0]   edge_y
);// internal signal declarations
reg               load_r1;
reg               load_r2;
reg       [23:0]  pipeline_data1;
reg       [23:0]  pipeline_data2;
reg       [23:0]  pipeline_data3;reg       [15:0]  sum_of_col0;
reg       [15:0]  sum_of_col1;
reg       [15:0]  sum_of_col2;
reg       [15:0]  sum_of_row0;
reg       [15:0]  sum_of_row1;
reg       [15:0]  sum_of_row2;reg       [15:0]  buf_edge_x;
reg       [15:0]  buf_edge_y;// load 信号打两拍,用于边沿检测
always @(posedge reset or posedge clock) beginif (reset) beginload_r1 <= 1'b0;load_r2 <= 1'b0;endelse beginload_r1 <= load;load_r2 <= load_r1;end
end// 异步复位,同步复位
always @(posedge reset or posedge clock) beginif (reset) beginpipeline_data1 <= {3{8'h00}};pipeline_data2 <= {3{8'h00}};pipeline_data3 <= {3{8'h00}};endelse if (~load) beginpipeline_data1 <= {3{8'h00}};pipeline_data2 <= {3{8'h00}};pipeline_data3 <= {3{8'h00}};endelse beginpipeline_data1 <= {inc, inb, ina};pipeline_data2 <= pipeline_data1;pipeline_data3 <= pipeline_data2;end
end// 行、列求和
always @(posedge reset or posedge clock) beginif (reset) beginsum_of_col0 <= 16'd0;sum_of_col1 <= 16'd0;sum_of_col2 <= 16'd0;sum_of_row0 <= 16'd0;sum_of_row1 <= 16'd0;sum_of_row2 <= 16'd0;endelse beginsum_of_col0 <= pipeline_data1[0*8+:8] + pipeline_data1[1*8+:8] + pipeline_data1[2*8+:8];sum_of_col1 <= pipeline_data2[0*8+:8] + pipeline_data2[1*8+:8] + pipeline_data2[2*8+:8];sum_of_col2 <= pipeline_data3[0*8+:8] + pipeline_data3[1*8+:8] + pipeline_data3[2*8+:8];sum_of_row0 <= pipeline_data3[0*8+:8] + pipeline_data2[0*8+:8] + pipeline_data1[0*8+:8];sum_of_row1 <= pipeline_data3[1*8+:8] + pipeline_data2[1*8+:8] + pipeline_data1[1*8+:8];sum_of_row2 <= pipeline_data3[2*8+:8] + pipeline_data2[2*8+:8] + pipeline_data1[2*8+:8];end
endalways @(posedge reset or posedge clock) beginif (reset) beginbuf_edge_x <= 16'd0;buf_edge_y <= 16'd0;endelse beginif (sum_of_col2 >= sum_of_col0) buf_edge_x <= sum_of_col2 - sum_of_col0;else buf_edge_x <= sum_of_col0 - sum_of_col2;if (sum_of_row2 >= sum_of_row0) buf_edge_y <= sum_of_row2 - sum_of_row0;else buf_edge_y <= sum_of_row0 - sum_of_row2;end
endassign edge_x = buf_edge_x[0+:8];
assign edge_y = buf_edge_y[0+:8];endmodule

2.3 上板调试

        使用 PyQt5 和 OpenCV 库编写上位机程序,通过串口发送原始图像数据。连接 HDMI 线和串口线,选择与发送图像,就可以看到 FPGA 的处理效果了 ~

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

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

相关文章

UI自动化Selenium find_elements和find_element的区别

# 如果获取的element是list&#xff0c;那么需要用find_elements方法&#xff1b;此方法会返回list&#xff0c;然后使用len() 方法&#xff0c;计算对象的个数&#xff1b; # find_element方法返回的不是list对象&#xff0c;所以导致没办法计算对象个数 # 1.返回值类型不同…

WebUI自动化学习(Selenium+Python+Pytest框架)005

基础知识学习完毕&#xff0c;接下来我们开始学习测试框架啦&#xff01;&#xff01;&#xff01; 首先来回顾一下python自带的Unittest框架&#xff1a; Python基础学习016__UnitTest-CSDN博客文章浏览阅读97次。Testcase:测试用例:这个测试用例是UnitTest的组成部分,不是手…

csp 现值计算 C语言

号&#xff1a; 202212-1 试题名称&#xff1a; 现值计算 时间限制&#xff1a; 1.0s 内存限制&#xff1a; 512.0MB 问题描述&#xff1a; 问题描述 评估一个长期项目的投资收益&#xff0c;资金的时间价值是一个必须要考虑到的因素。简单来说&#xff0c;假设…

Tomcat 漏洞修复

1、去掉请求响应中Server信息 修复方法&#xff1a; 在Tomcat的配置文件的Connector中增加 server" " &#xff0c;server 的值可以改成你任意想返回的值。

为XiunoBBS4.0开启redis缓存且支持密码验证

修改模块文件1 xiunoPHP/cache_redis.class.php: <?phpclass cache_redis {public $conf array();public $link NULL;public $cachepre ;public $errno 0;public $errstr ;public function __construct($conf array()) {if(!extension_loaded(Redis)) {return $thi…

CentOS7根分区扩容之二

Centos根分区快接近100%&#xff0c;如果根分区是逻辑卷&#xff0c;那么可以增加额外的磁盘&#xff0c;通过逻辑卷扩容的方式增加到根分区空间。 1.检查当前根分区大小 df -Th2.检查额外的磁盘 3.把磁盘格式化为lvm类型的文件分区。 [rootlocalhost ~]# fdisk /dev/sdb We…

【数据结构和算法】找出叠涂元素

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 三、代码 四、复杂度分析 前言 这是力扣的2661题&#xff0c;难度为中等&#xff0c;解题方案有很多种&…

element中el-table表头通过header-row-style设置样式

文章目录 一、知识点二、设置全部表头2.1、方式一2.2、方式二 三、设置某个表头四、最后 一、知识点 有些时候需要给element-ui表头设置不同样式&#xff0c;比如居中、背景色、字体大小等等&#xff0c;这时就可以用到本文要说的属性header-row-style。官网说明如下所示&…

量子光学的进步:光子学的“下一件小事”

量子光学是量子力学和光学交叉领域中发展迅速的一门学科&#xff0c;探索光的基本特性及其与物质在量子水平上的相互作用。通过利用光的独特特性&#xff0c;量子光学为通信、计算、密码学和传感等各个学科的变革性进步铺平了道路。 如今&#xff0c;量子光学领域的研究人员和工…

基于springboot 图书馆管理系统

qq&#xff08;2829419543&#xff09;获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;springboot 前端&#xff1a;采用vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xf…

Inference with C# BERT NLP Deep Learning and ONNX Runtime

目录 效果 测试一 测试二 测试三 模型信息 项目 代码 下载 Inference with C# BERT NLP Deep Learning and ONNX Runtime 效果 测试一 Context &#xff1a;Bob is walking through the woods collecting blueberries and strawberries to make a pie. Question …

前端入门(五)Vue3组合式API特性

文章目录 Vue3简介创建Vue3工程使用vite创建vue-cli方式 常用 Composition API启动项 - setup()setup的执行时机与参数 响应式原理vue2中的响应式vue3中的响应式ref函数reactive函数reactive与ref对比 计算属性 - computed监视属性 - watchwatchEffect Vue3生命周期自定义hook函…