tag 标签: sobel;边缘检测

相关博文
  • 热度 14
    2015-9-17 13:59
    1983 次阅读|
    6 个评论
    将学习过程记录下来,结合自己的理解,并附上代码,目的是为了使更多像我一样的初学者可以收益,少走弯路。以下是笔者总结,仅供参考,如有错误,望指正! 一.定义 Sobel算子是计算机视觉领域的一种重要处理方法。多用于图像的边缘检测 。 二.原理 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 三.通过一个实例来说明,并附上代码 该实例将一 200*200的灰度图像 通过 串口 发送给FPGA,调用FIFO做卷积运算,运算结果存入ram中,最后通过VGA显示出来。 首先送上实验效果 原始图像(bmp)   处理后图像     流程如下: RS232   -     FIFO    -   SOBEL   -   RAM   -  VGA 具体步骤如下: 1)Matlab生成数据图像 将图像矩阵变换成1*m*n大小(m:图像行数 n:图像列数)写入txt文本,以两位十六进制(%02x)格式保存数据。 matlab代码: 2)串口模块接收数据rx_data 串口数据是一位一位接收,接收的数据每8位保存在rx_data中,rx_data的位宽为8. 接收模块接口如下:(由于篇幅限制,这里只给出接口与内部变量)    3)利用FIFO同时取图像三行,Sobel算子参与运算    控制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主要变量的时序图(手写)    4.创建一个双口ram,将Gxy保存到双口ram中 这里值得注意的是,保存到ram中的图像大小实际上是198*198(原始图像是200*200),图像周围边框没有处理。 写使能控制好拉高的时间,通过计数器来控制。 5.读出ram中的数据,并在VGA中显示   实验过程中出现的问题: 1.再次发送图像,图像会偏移。 观察仿真波形图发现,使能信号拉高时间错误。