手撕包菜 mysql_视频处理之Sobel【附源码】

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

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

Sobel算子简介

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

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

Sober算法基础

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

496644f1c38950d046f4e1da8600b64f.png

用数学公式表示如下

bcfe377fbbb1d97a97b67ae8d6d10b50.png

357e4f832746a18cc37ce101d0612cc4.png

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

90d1295cf48afdc0d73f7f80309c7652.png

FPGA实现

硬件框图如下

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

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

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

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

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

b990da84d9ea7972688ddf2d5f47c659.png

缓存模块

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

67022701e180bd236101ea71e9de4bbf.png

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

8ad79993f3c01a5fe233caa3f41d3024.png

仿真结果如下图

2778cc6524528195a95198683a0f9617.png

梯度计算模块

2a0e02fd16c7af51e1e9a4be03d161c8.png

按照sobel算子给出源码如下

// 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

2302d4dfcd70d64f632522ef635994d2.png

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

a4387967331e1d09d53c8d3998fc5830.png

平方根模块

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

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

选择输入位宽为24bit。

fa46501befa222e52a8bd64773be753c.png

实现结果

仿真程序层次图

2b73447d23b37213b5d6ba351798c9a8.png

仿真结果

fd851ae9b56e92d2ab02402a09aa428a.png

实现结果

be61501a947b85081a9cb0a7efe611db.png

84588cd616db3bdbeeb4a56ad9081a72.png

调节阈值

参考链接

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

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

资料获取

062836c6cd3d9dea72f5fc8771e89e35.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值