Sobel算子-边缘检测(含工程代码)

将学习过程记录下来,结合自己的理解,并附上代码,目的是为了使更多的初学者可以收益,少走弯路。以下是笔者总结,仅供参考,如有错误,望指正!

1.定义

Sobel算子是计算机视觉领域的一种重要处理方法。多用于图像的边缘检测。

2.原理

Sobel算子利用离散的一阶差分(离散函数中连续相邻两项之差,定义X(k),则Y(k)=X(k+1)-X(k)就是此函数的一阶差分)算子,模拟图像亮度函数一阶梯度(可以近似理解为导数,具体内容自己去百度)的近似值。
一阶差分其实是一阶导数的近似,那么求边缘为什么要用到导数呢?我们先回归一下导数的概念,还记得我们第一次接触导数就在什么时候吗,老师会告诉我们,导数反映的是函数变化的快慢(大小)。图像中的每个像素点可以类比函数图像中一个个点,那么图像的导数(如果可以求导)反映的就是图像像素值的变化吗。那么变化大的(比如,连续的三个像素点从20->200->20)像素点就是所谓的边界点。而变化大小的标准可以根据实际的图像设定一个阈值。这就是为什么可以用差分算子来做边缘检测。那么该算子究竟是什么呢?
该算子包含两组3*3的矩阵,一个是x方向、一个是y方向,如下图Gx,Gy所示。利用目标图像分别与这两个算子做卷积(两个变量在某范围内相乘后求和的结果),就得到了图像亮度在x、y方向的差分近似值。

-1 0 1 1 2 1
-2 0 2 0 0 0
-1 0 1 -1 -2 -1
Gx Gy

3…通过一个实例来说明,并附上代码

该实例将一 200*200的灰度图像 通过 串口 发送给FPGA,调用FIFO做卷积运算,运算结果存入ram中,最后通过VGA显示出来。
首先送上实验效果
原始图像(bmp)
1.jpg
处理后图像
2.jpg

流程如下:
RS232 -> FIFO -> SOBEL -> RAM -> VGA
具体步骤如下:
1.Matlab生成数据图像
将图像矩阵变换成1mn大小(m:图像行数 n:图像列数)写入txt文本,以两位十六进制(%02x)格式保存数据。
matlab代码:
5.gif

2.串口模块接收数据rx_data
串口数据是一位一位接收,接收的数据每8位保存在rx_data中,rx_data的位宽为8.
接收模块接口如下:(由于篇幅限制,这里只给出接口与内部变量)
6.gif

3.利用FIFO同时取图像三行,Sobel算子参与运算
7.gif

控制FIFO的输出,使得同时控制三行数据,将每行读出的数据依次保存在a、b、c中,a、b、c组成的3*3的矩阵,我们叫做A,A与Gx,Gy分别作卷积,分别得到目标图像在Gx,Gy方向的边界。卷积公式如下:
Gx = a1-c1+(a2-c2)<<1+a3-c3;
Gy = a1-a3+(b1-b3)<<1+c1-c3;
Gxy = |Gx| + |Gy|;
Gxy表示两个方向差分绝对值的和。
Sobel主要变量的时序图(手写)
8.gif

4.创建一个双口ram,将Gxy保存到双口ram中
这里值得注意的是,保存到ram中的图像大小实际上是198198(原始图像是200200),图像周围边框没有处理。
写使能控制好拉高的时间,通过计数器来控制。
5.读出ram中的数据,并在VGA中显示

实验过程中出现的问题:
1.再次发送图像,图像会偏移。
观察仿真波形图发现,使能信号拉高时间错误。

工程代码:sobel边缘检测verilog实现

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

下一个雨天

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

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

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

打赏作者

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

抵扣说明:

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

余额充值