基于FPGA的图像sobel边缘提取算法开发,包括tb测试文件以及matlab验证代码
1.算法运行效果图预览
2.算法运行软件版本
vivado2019.2
matlab2022a
3.算法理论概述
图像边缘检测大幅度地减少了数据量,并且剔除了可以认为不相关的信息,保留了图像重要的结构属性。有许多方法用于边缘检测,它们的绝大部分可以划分为两类:基于查找一类和基于零穿越的一类。基于查找的方法通过寻找图像一阶导数中的最大和最小值来检测边界,通常是将边界定位在梯度最大的方向。基于零穿越的方法通过寻找图像二阶导数零穿越来寻找边界,通常是Laplacian过零点或者非线性差分表示的过零点。
Soble边缘检测算法比较简,实际应用中效率比canny边缘检测效率要高,但是边缘不如Canny检测的准确,但是很多实际应用的场合,sobel边缘却是首选,尤其是对效率要求较高,而对细纹理不太关心的时候。Soble边缘检测通常带有方向性,可以只检测竖直边缘或垂直边缘或都检测。所以我们先定义两个梯度方向的系数:
然后我们来计算梯度图像,我们知道边缘点其实就是图像中灰度跳变剧烈的点,所以先计算梯度图像,然后将梯度图像中较亮的那一部分提取出来就是简单的边缘部分。
Sobel算子用了一个3*3的滤波器来对图像进行滤波从而得到梯度图像,这里面不再详细描述怎样进行滤波及它们的意义等。
竖起方向的滤波器:y_mask=op = [-1 -2 -1;0 0 0;1 2 1]/8;
水平方向的滤波器:op的转置:x_mask=op’;
定义好滤波器后,我们就开始分别求垂直和竖起方向上的梯度图像。用滤波器与图像进行卷积即可:
bx = abs(filter2(x_mask,a));
by = abs(filter2(y_mask,a));
上面bx为水平方向上的梯度图像,by为垂直方向上的梯度图像。为了更清楚的说明算法过程,下面给出一张示例图像的梯度图像。
4.部分核心程序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | `timescale 1ns / 1ps // // Company: // Engineer: // // Create Date: 2023/07/31 // Design Name: // Module Name: sobel // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // // module tops( input i_clk, input i_rst, input [7:0]i_I, output reg[7:0]o_sobel ); parameter LEN = 256; parameter th = 255; ........................................................ reg signed[10:0]x1; reg signed[10:0]x2; reg signed[10:0]y1; reg signed[10:0]y2; reg signed[11:0]x12; reg signed[11:0]y12; reg signed[11:0]x_; reg signed[11:0]y_; reg signed[12:0]edge_; always @(posedge i_clk or posedge i_rst) begin if (i_rst) begin x1 <=11'd0; x2 <=11'd0; y1 <=11'd0; y2 <=11'd0; x12<=12'd0; y12<=12'd0; x_<=11'd0; y_<=11'd0; edge_ <=13'd0; end else begin ......................................................... edge_<= x_ + y_; // 计算Sobel算子响应的绝对值和 end end always @(posedge i_clk or posedge i_rst) begin if (i_rst) begin o_sobel <= 8'd0; end else begin if (edge_>=th) //判断绝对值和是否大于阈值 o_sobel <= 8'd255; else o_sobel <= 8'd0; end end endmodule |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下