前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >视频处理之Sobel【附源码】

视频处理之Sobel【附源码】

作者头像
瓜大三哥
发布2020-06-09 11:29:16
9240
发布2020-06-09 11:29:16
举报
文章被收录于专栏:瓜大三哥

边缘检测是检测图像中的一些像素点,它们周围的像素点的灰度发生了急剧的变化,我们认为在这过程中,图像中的物体不同导致了这一变化,因此可以将这些像素点作为一个集合,可以用来标注图像中不同物体的边界。边缘区域的灰度剖面可以看作是一个阶跃,即图像的灰度在一个很小的区域内变化到另一个相差十分明显的区域。边缘是图像中的重要的结构性特征,边缘往往存在于目标和背景之间,不同的区域之间,因此它可以作为图像分割的重要依据。在边缘检测中,它提取的是图像中不连续部分的特征,将闭合的边缘提取出来便可以作为一个区域。与区域划分相比,边缘检测不需要逐个的对像素进行比较,比较适合大图像的处理.

图像边缘是图像最基本的特征,所谓边缘(Edge) 是指图像局部特性的不连续性。灰度或结构等信息的突变处称之为边缘。例如,灰度级的突变、颜色的突变,、纹理结构的突变等。这些突变会导致梯度很大。图像的梯度可以用一阶导数和二阶偏导数来求解。但是图像以矩阵的形式存储的,不能像数学理论中对直线或者曲线求导一样,对一幅图像的求导相当于对一个平面、曲面求导。对图像的操作,我们采用模板对原图像进行卷积运算,从而达到我们想要的效果。而获取一幅图像的梯度就转化为:模板(Roberts、Prewitt、Sobel、Lapacian算子)对原图像进行卷积。本文主要描述Sobel算子的实现原理和实现过程。

Sobel算子简介

Sobel算子 是一种用于边缘检测的离散微分算子,它结合了高斯平滑和微分求导。该算子用于计算图像明暗程度近似值,根据图像边缘旁边明暗程度把该区域内超过某个数的特定点记为边缘。Sobel算子在Prewitt算子的基础上增加了权重的概念,认为相邻点的距离远近对当前像素点的影响是不同的,距离越近的像素点对应当前像素的影响越大,从而实现图像锐化并突出边缘轮廓。

Sobel算子根据像素点上下、左右邻点灰度加权差,在边缘处达到极值这一现象检测边缘。对噪声具有平滑作用,提供较为精确的边缘方向信息。因为Sobel算子结合了高斯平滑和微分求导(分化),因此结果会具有更多的抗噪性,当对精度要求不是很高时,Sobel算子是一种较为常用的边缘检测方法。Sobel算子的边缘定位更准确,常用于噪声较多、灰度渐变的图像。

Sober算法基础

其算法模板如下面的公式所示,其中dx表示水平方向,dy表示垂直方向。

用数学公式表示如下

图像的每一个像素的横向及纵向梯度近似值可用以下的公式结合,来计算梯度的大小。

FPGA实现

硬件框图如下

如下图所示,首先需要缓存两行图像用于计算(第三行可以用寄存器存储一个像素即可计算)。

然后加入sobel算子模块将所得到的9个像素按照sobel算子进行运算。

接着把输出的Gx和Gy做平方,所以需要一个乘法器模块。

然后将Gx,Gy和Gxy(分别为水平梯度,垂直梯度,水平和垂直梯度)做平方根输出。

最后再用一个输出模块来整合整个视频流,可以选择阈值和边缘模式。

缓存模块

小编是一个懒人,能不写代码就尽量不写代码,既然要缓存了,首先看看有没有IP,查看了一下based shift register 这个IP,发现最大深度只有1088,所以没办法,小编只能自己写了。

为了考虑后期还会继续使用这种缓存的应用场景,小编在这个模块使用RAM的原语进行设计,因为是基于视频的应用,所以设置的缓存深度为1行,如果需要缓存多行,把这个模块级联即可。

仿真结果如下图

梯度计算模块

按照sobel算子给出源码如下

代码语言:javascript
复制
// GX = (A13+2 *A23 + A33 ) - (A11 +2 *A21 + A31 )

// GY = (A31+2* A32 + A33 ) - (A11 +2* A12 + A13 )

// | G | =(GX^2+ GY^2)^1/2

    always @ (posedge clk) begin
        if(pixel_en_d3)begin
            GX_right    <=(A13+2 *A23 + A33 ) ;
            GX_left     <=(A11 +2 *A21 + A31);
        end
        if(pixel_en_d3)begin
            GY_up       <=(A31+2* A32 + A33 );
            GY_down     <=(A11 +2* A12 + A13 );
        end
        add_en<=pixel_en_d3;
    end 
    always @ (posedge clk) begin
        if(add_en)begin
            if(GX_right>GX_left)    GX<=GX_right-GX_left;
            else                    GX<=GX_left-GX_right;

            if(GY_up>GY_down)       GY<=GY_up-GY_down;
            else                    GY<=GY_down-GY_up;
        end
        GX_GY_valid <=  add_en;
    end

乘法器模块

使用Multiplier IP:输入两个乘法因子为无符号数8bit

配置其latency为3 clock cycle(便于时序收敛)

平方根模块

计算平方根,这里用到了Cordic IP,如下图所示选择实现功能为:Square Root

选择Data Fomat为unsigned interger,输入的值限制到(0,2^n)

选择输入位宽为24bit。

实现结果

仿真程序层次图

仿真结果

实现结果

调节阈值

参考链接

https://www.jianshu.com/p/bed4ffe996a1

https://blog.csdn.net/zaishuiyifangxym/article/details/89840396

关注公众号后台回复【Sobel】可获取相关资料

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 瓜大三哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Sobel算子简介
  • Sober算法基础
  • FPGA实现
    • 硬件框图如下
      • 缓存模块
        • 梯度计算模块
          • 乘法器模块
            • 平方根模块
              • 实现结果
              • 参考链接
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档