基于sobel算法的边缘检测设计与实现(一)

1、知识点

(1)边缘检测

        边缘是图像的基本特征,包含了用于图像识别的有用信息,在计算机视觉、图像分析和图像处理等应用中起着重要作用。所谓边缘是指其周围像素灰度急剧变化的那些象素的集合,它是图像最基本的特征。边缘存在于目标、背景和区域之间,所以,它是图像分割所依赖的最重要的依据。由于边缘是位置的标志,对灰度的变化不敏感,因此,边缘也是图像匹配的重要的特征。

        边缘检测,针对的是灰度图像,顾名思义,检测图像的边缘,是针对图像像素点的一种计算,目的是标识数字图像中灰度变化明显的点,图像的边缘检测,在保留了图像的重要结构信息的同时,剔除了可以认为不相关的信息,大幅度减少了数据量,便于图像的传输和处理。图像属性中的显著变化通常反映了属性的重要事件和变化。 这些包括(i)深度上的不连续、(ii)表面方向不连续、(iii)物质属性变化和(iv)场景照明变化。 

        边缘检测和区域划分是图像分割的两种不同的方法,二者具有相互补充的特点。在边缘检测中,是提取图像中不连续部分的特征,根据闭合的边缘确定区域。而在区域划分中,是把图像分割成特征相同的区域,区域之间的边界就是边缘。由于边缘检测方法不需要将图像逐个像素地分割,因此更适合大图像的分割。边缘大致可以分为两种,一种是阶跃状边缘,边缘两边像素的灰度值明显不同;另一种为屋顶状边缘,边缘处于灰度值由小到大再到小的变化转折点处。边缘检测的主要工具是边缘检测模板。

        边缘检查的方法大致可以分为两类:基于查找的一类,通过寻找图像一阶导数中最大值和最小值来检测边界,包括 Sobel 算法、 Roberts Cross 算法、Prewitt 算法,Kirsch 算法,罗盘算法等;基于零穿越的一类,通过寻找图像二阶导数零穿越来寻找边界,包括 Canny 算法, Laplacian 算法、Marr-Hildreth算法等。

(2) Sobel 算法

        Sobel 边缘检测算法比较简单,虽然准确度较低,但在实际应用中效率较高,在很多实际应用场合,Sobel 算法却是首选,尤其是对效率要求较高,对纹理不太关心的时候。在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰度之近似值。在图像的任何一点使用此算子,将会产生对应的灰度矢量或是其法矢量。

        所谓的Sobel算法,就是将得到像素点乘以一个3*3矩阵(Sobel算子)得到一个该点的灰度矢量值或者其法矢量值。Sobel算子根据像素点上下、左右邻点灰度加权差,在边缘处达到极值这一现象检测边缘。所以整个算法的核心就是Sobel算子,下面简单介绍下该算子。

        索贝尔算子(Sobel operator)主要用作边缘检测, 在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰度之近似值。

        Sobel 卷积因子为:

        对于图像而言,取 3 行 3 列的图像数据,将图像数据与对应位置的算子的值相乘再相加,得到 x 方向的 Gx ,和 y 方向的 Gy , Gx 及 Gy 分别代表经横向及纵向边缘检测的图像灰度值。将得到的 Gx 和 Gy ,平方后相加,再取算术平方根,得到 Gxy ,近似值为 Gx 和 Gy 绝对值之和, Gxy 代表该点灰度的大小。将计算得到的 Gxy 与我们设定的阈值相比较,Gxy 如果大于阈值,表示该点为边界点,此点显示黑点,否则显示白点。

 2、实战演练

        要实现Sobel算法首先要利用FIFO 3行数据求和,其次掌握上述的边缘检测和算法的具体理论,结合这两个部分来实现算法就比较简单了。我们把整个过程分为下面四个步骤:

        1)通过Gx、Gy的计算公式结合FIFO求和算法求取Gx、Gy的值。
        2)求得Gx、Gy的绝对值。
        3)将Gx、Gy带入Gxy计算公式,求得Gxy的值。
        4)将求得的Gxy与设定的阈值相比较,当Gxy大于等于阈值,赋值rgb为黑色,否则赋值rgb为白色。
        需要注意的是,图片经过Sobel算法之后,输出的图片相比输入的图片会少2行2列数据,这是因为使用FIFO求和算法时这一算法只有当第2行或第2列数据输入时才开始执行。所以会丢失。
在这里插入图片描述        将图像用软件转成灰度图像,然后将灰度图像的高三位取出进行保存,通过串口将图像数据传给FPGA,随后FPGA通过Sobel算法检测图像轮廓,然后将处理后的图片通过VGA显示640*480@60,图像大小为100*100。

图片预处理:

        在Sobel算法之前我们首先要把彩色图片转化为灰度图,之后将灰度图的高三位取出来存放到txt中,这一个预处理选择用matlab来实现,相关.m文件代码如下

clc;                            %清理命令行窗口
clear all;                      %清理工作区
image = imread('tupian.png');     %使用imread函数读取图片数据
figure;
imshow(image);                  %窗口显示图片
R = image(:,:,2);               %提取图片中的红色层生成灰度图像
figure;
imshow(R);                      %窗口显示灰色图像
[ROW,COL] = size(R);            %灰色图像大小参数
data = zeros(1,ROW*COL);        %定义一个初值为0的数组,存储转换后的图片数据
for r = 1:ROW
    for c = 1 : COL
        data((r-1)*COL+c) = bitshift(R(r,c),-5);    %红色层数据右移5位
    end
end
fid = fopen('tupian.txt','w+');                       %打开或新建一个txt文件
for i = 1:ROW*COL;
    fprintf(fid,'%02x ',data(i));                   %写入图片数据
end
fclose(fid);

 原始图片:灰度图像:

  整体框图:

在这里插入图片描述

        Sobel算法进行边缘检测的整个实验工程如下图所示,其中clk_gen为PLL IP核产生25MHz和50MHz的时钟,rxtx为uart串口通信部分,VGA为显示部分,sobel_ctrl为整个工程的核心部分包含了Sobel算法的具体实现。

具体工作流程:

        1)开发板系统时钟为25Mhz,系统上电后,时钟信号传入PLL分频产生25Mhz和50Mhz的时钟,其中50Mhz的时钟用于串口收发、Sobel求和、RAM写的工作时钟;25MHz时钟用于图像生成模块和VGA时序控制模块的工作时钟。
        2)PC 机将图片数据通过串口 RS232 传输给 FPGA,数据在 uart_rx 模块中完成拼接传给 sobel_ctrl 模块进行 Sobel 运算,输出结果同时传给 vga 模块和 uart_tx 模块;vga 模块将接收到的经 sobel 算法处理后的图像数据存入图像数据生成模块中的RAM 中;uart_tx 模块将输出结果回传给 PC 机验证数据完整性。
        3)图像数据生成模块以 VGA 时序控制模块传入的像素点坐标(pix_x,pix_y)为约束条件,生成待显示图像的色彩信息(pix_data),图像色彩信息包括彩条背景和经 sobel算法处理后的图片信息。
        4)图像数据生成模块生成的图像色彩信息传入VGA时序控制模块,在模块内部使用使能信号滤除掉非图像显示有效区域的图像数据,产生RGB色彩信息(rgb),在行、场同步信号(hsync、vsync)的同步作用下,将RGB色彩信息扫描显示到VGA显示器,显示出经Sobel算法处理过的图像。

sobel_ctrl控制模块:

在这里插入图片描述

这个模块的设计主要包含两个部分:

  1. 图片数据自输入模块到数据写入fifo
  2. 数据从FIFO读出经过Sobel运算进行输出

第一个部分(参考FIFO三行求和的工程)

        本功能模块的作用是对输入的图片进行 sobel 算法处理并输出处理后的数据,由前文可知,要实现 sobel 算法的求解,要使用 sobel 算子求出 Gx、Gy,进而求出 Gxy,求解后的 Gxy 与设定阈值比较,确定图像边界,完成 sobel 算法处理。
        Gx、Gy 的求解分别是对图形 3 行、3 列图形数据的处理,我们可以参考FIFO 求和实验对 3 行数据的处理方式,实现 Gx、Gy 数据的求解。
        与 FIFO 求和实验类似,sobel_ctrl 模块内部同样调用两个 FIFO 用作数据缓存。使用同样的方式将串口接收模块传入的图片数据按要求暂存到两个 FIFO 中。
        两 FIFO 的时钟信号为系统时钟 sys_clk 与串口接收模块时钟相同;我们需要在模块内部声明 FIFO 写使能信号,声明 fifo1 写使能信号为 wr_en1,数据输入信号为 data_in1,声明 fifo2 写使能信号为 wr_en2,数据输入信号为 data_in2;声明两 FIFO 共用读使能信号rd_en。
       1)wr_en1:当第 0 行数据输入,wr_en1 写使能信号由数据标志信号 pi_flag 赋值,滞后
pi_flag 信号 1 个时钟周期,第 1 行数据输入时,wr_en1 写使能信号保持无效,自第 2 行数据输入到数据输入结束,wr_en1 写使能信号由数据标志信号 dout_flag 赋值,滞后dout_flag 信号 1 个时钟周期;
        2)data_in1:当第 0 行数据输入且写使能有效时, 将第 0 行数据写入 fifo1:当第 2-98 行数据写入且写使能有效时,将 fifo2 读出的 1-97 行数据写入 fifo1;
        3)wr_en2:当第 1-98 行数据输入时,wr_en2 写使能信号由数据标志信号 pi_flag 赋值,滞后 pi_flag 信号 1 个时钟周期,其他时刻写使能信号 wr_en2 均无效;
        4)data_in2:当 fifo2 的写使能信号 wr_en2 有效时,将传入的 pi_data 赋值给 data_in2,数据写入 fifo2,写使能无效时,data_in2 保持原有状态;
        5)rd_en:fifo1 和 fifo2 共用读使能信号,该使能信号在第 0 行和第 1 行数据输入是始终保持无效状态,自第 2 行数据开始输入到数据输入完成,读使能信号 rd_en 由 pi_flag 赋值,滞后 pi_flag 信号 1 个时钟周期;
        6)dout_flag 信号只有在 wr_en2 信号和 rd_en 信号均有效时才有效,其他时刻均无效,目的是赋值给在第 2 行数据输入后的 wr_en1 使能信号。
时序图如下:
在这里插入图片描述

第二个部分

        实现 sobel 算法就要求出 Gxy,Gxy 由 Gx、Gy 运算得到,Gx、Gy 由 sobel算子与图像数据运算得到。参与运算的图像数据要包含图像 3 行 3 列的像素信息。这就表示只有在图像的第 2 行的第 2 个数据传入模块时,才能开始 Gx、Gy 的运算。要准确定位运算开始的时刻,我们需要声明计数器,用来计数读出数据个数,判断 Gx、Gy 的运算时刻,之后根据公式来进行运算。

  • 2
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发光中请勿扰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值