一、简述
边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。图像边缘检测大幅度地减少了数据量,并且剔除了可以认为不相关的信息,保留了图像重要的结构属性。所谓边缘是指其周围像素灰度急剧变化的那些像素的集合,它是图像最基本的特征。边缘存在于目标、背景和区域之间,所以,它是图像分割所依赖的最重要的依据。由于边缘是位置的标志,对灰度的变化不敏感,因此,边缘也是图像匹配的重要的特征。边缘大致可以分为两种,一种是阶跃状边缘,边缘两边像素的灰度值明显不同;另一种为屋顶状边缘,边缘处于灰度值由小到大再到小的变化转折点处。索贝尔算子(Sobel operator)主要用作边缘检测,在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰度之近似值。在图像的任何一点使用此算子,将会产生对应的灰度矢量或是其法矢量。
sobel卷积因子:
该算子包含两组 3x3 的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。如果以 A 代表原始图像,Gx 及 Gy 分别代表经横向及纵向边缘检测的图像灰度值,其公式如下:
图像的每一个像素的横向及纵向灰度值通过以下公式结合,来计算该点灰度的大小:
通常,为了提高效率,使用不开平方的近似值,但这样做会损失精度,迫不得已的时候可以如下这样子:
如果梯度 G 大于某一阀值,则认为该点(x,y)为边缘点。
二、实现方法
首先通过获取33矩阵(在前面博客中有介绍)来得到相应模板与视频图像做融合,再将相应的横、纵像素值与卷积模板相乘,再将得到的Gx与Gy求取绝对值(该方法在计算上相对易于实现,减少时钟周期,也可以通过平方开根号的方法得到该值),最后将Gx与Gy相加,得到相应G值,再将该值与阈值做判断,得到边界线。
三、实现过程
首先对33矩阵内的值与卷积核相乘,此处将横、纵轴同时计算可节省时钟周期。
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginGx1 <= 'd0;Gx3 <= 'd0;Gy1 <= 'd0;Gy3 <= 'd0; endelse beginGx1 <= matrix_11 + (matrix_21 << 1) + matrix_31;Gx3 <= matrix_13 + (matrix_23 << 1) + matrix_33;Gy1 <= matrix_11 + (matrix_12 << 1) + matrix_13;Gy3 <= matrix_31 + (matrix_32 << 1) + matrix_33; end
end
再求取Gx和Gy的绝对值:
if(!rst_n) beginGx <= 'd0;Gy <= 'd0;endelse begin //也可判断bit[7]来确定Gx <= (Gx1 > Gx3) ? (Gx1 - Gx3) : (Gx3 - Gx1);Gy <= (Gy1 > Gy3) ? (Gy1 - Gy3) : (Gy3 - Gy1);end
end
最后再求取该3*3模板的G值,并将其与阈值作比较:
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginG <= 'd0;endelse beginG <= Gx + Gy;end
endassign sobel_data = (G > value) ? 24'h000000 : 24'hffffff;
对sobel的处理总共耗费三个时钟周期,所以要对其他信号做延迟处理:
always @(posedge clk or negedge rst_n) beginif(!rst_n) beginvideo_de_r <= 4'b0;video_href_r <= 4'b0;video_vsync_r <= 4'b0;endelse begin video_de_r <= {video_de_r[1:0], video_de};video_href_r <= {video_href_r[1:0], video_href};video_vsync_r <= {video_vsync_r[1:0], video_vsync};end
endassign sobel_de = video_de_r[2];
assign sobel_href = video_href_r[2];
assign sobel_vsync = video_vsync_r[2];
四、实验总结
本次实验效果较好,能够准确识别相应物体的边界线。
五、参考资料
正点原子领航者sdk——ov7725的sobel边缘检测
博客园——咸鱼IC
(本博客用于学习记录,如有侵权请告知)