车牌识别项目(3)sobel算法边缘检测

sobel算法边缘检测

小梅哥书上的教程讲得很好

《小梅哥-FPGA系统设计与验证实战指南_V24》P836 7.11
在这里插入图片描述在这里插入图片描述
sobel算法做边缘检测其实也是一种二值化的预操作,在完成sobel处理后,与阈值进行比较,即完成了二值化,但这个阈值可以通过OTSU算法来计算出

简单定义:卷积是分析数学中一种重要的运算。

设:f(x),g(x)是R1上的两个可积函数,作积分:

可以证明,关于几乎所有的实数x,上述积分是存在的。这样,随着x的不同取值,这个积分就定义了一个新函数h(x),称为函数f与g的卷积,记为h(x)=(f*g)(x)。

容易验证,(f * g)(x) = (g * f)(x),并且(f * g)(x)仍为可积函数。这就是说,把卷积代替乘法,L1(R1)空间是一个代数,甚至是巴拿赫代数。

卷积与傅里叶变换有着密切的关系。利用一点性质,即两函数的傅里叶变换的乘积等于它们卷积后的傅里叶变换,能使傅里叶分析中许多问题的处理得到简化。

由卷积得到的函数f*g一般要比f和g都光滑。特别当g为具有紧致集的光滑函数,f为局部可积时,它们的卷积f * g也是光滑函数。利用这一性质,对于任意的可积函数f,都可以简单地构造出一列逼近于f的光滑函数列fs,这种方法称为函数的光滑化或正则化。
在这里插入图片描述

Sobel算子的理解

sobel算子主要用于获得数字图像的一阶梯度,常见的应用和物理意义是边缘检测。

原理

算子使用两个33的矩阵(图1)算子使用两个33的矩阵(图1)去和原始图片作卷积,分别得到横向G(x)和纵向G(y)的梯度值,如果梯度值大于某一个阈值,则认为该点为边缘点

Gx方向的相关模板:
在这里插入图片描述

Gy方向的相关模板:

在这里插入图片描述

在这里插入图片描述

看了网上的很多资料,都把卷积和相关的概念给弄糊了,书上给的Sobel的模板不是卷积模板,而是相关模板,因为卷积的话要先将模板旋转180****度以后再与图像做相关的操作。

所以Sobel的卷积模板是:

在这里插入图片描述
在这里插入图片描述

体计算如下:

图像的每一个像素的横向及纵向灰度值通过以下公式结合,来计算该点灰度的大小:

在这里插入图片描述

通常,为了提高效率使用不开平方的近似值:
在这里插入图片描述

然后可用以下公式计算梯度方向:
在这里插入图片描述

OpenCV还提供了一个scharr函数,比Sobel算子更为精准,也是3x3的模板。

在这里插入图片描述

hu/),比Sobel算子更为精准,也是3x3的模板。

因为Sobel算子只是求取了导数的近似值,当内核大小为3时,以上Sobel内核可能产生比较明显的误差。为解决这一问题,OpenCV提供了 Scharr 函数,但该函数仅作用于大小为3的内核,该函数的运算与Sobel函数一样快,但结果却更加精确

4.代码
module sobel (
	input                       rst,
	input                       pclk,
	
	input                       ycbcr_hs,
	input                       ycbcr_vs,
	input                       ycbcr_de,
	input        [7:0]          fazhi,
	output reg                  data_out,
	output                      sobel_hs,
	output                      sobel_vs,
	output                      sobel_de,
	 input  [7:0]               p1,
	input  [7:0]                p3,
	input  [7:0]                p2,
	input    [1:0]              zt,
	output reg                  data_out_pd
	
);
reg  [7:0]  p11,p12,p13;
reg  [7:0]  p21,p22,p23;
reg  [7:0]  p31,p32,p33;

reg  [9:0]  x1,x3;
reg  [9:0]  y1,y3;
reg  [9:0]  abs_x,abs_y;
reg  [10:0] abs_g;

reg [8:0] hs_buf ;
reg [8:0] vs_buf ;
reg [8:0] de_buf ;
reg [7:0] fazhi_;
always fazhi_=fazhi;
always@(posedge pclk)//9个8位reg做移位计算,每次移入3个,并移出3个
begin
	p11 <= p1;
	p21 <= p2; 
	p31 <= p3;
	
	p12 <= p11;
	p22 <= p21;
	p32 <= p31;
	
	p13 <= p12;
	p23 <= p22;
	p33 <= p32;
end

always@(posedge pclk)//sobel做卷积的核心代码
begin
	x1 <= {2'b00,p11} + {2'b00,p31} + {1'b0,p21,1'b0};
	x3 <= {2'b00,p13} + {2'b00,p33} + {1'b0,p23,1'b0};
	
	y1 <= {2'b00,p11} + {2'b00,p13} + {1'b0,p12,1'b0};
	y3 <= {2'b00,p31} + {2'b00,p33} + {1'b0,p32,1'b0};
end

always@(posedge pclk)
begin
	abs_x <= (x1 > x3) ? x1 - x3 : x3 - x1;
	abs_y <= (y1 > y3) ? y1 - y3 : y3 - y1;
	abs_g <= abs_x + abs_y;
end

always@(posedge pclk)
begin
/*if(zt==2'b11)
data_out <= (abs_g >65)? 1:0;
else
*/
	data_out <= (abs_g >fazhi_)? 1:0;
	
	
end
//hs vs de delay 9 clock
always@(posedge pclk or negedge rst)
begin
  if (!rst)
  begin
    hs_buf <= 9'd0 ;
    vs_buf <= 9'd0 ;
    de_buf <= 9'd0 ;
  end
  else
  begin
    hs_buf <= {hs_buf[7:0], ycbcr_hs} ;
	 vs_buf <= {vs_buf[7:0], ycbcr_vs} ;
	 de_buf <= {de_buf[7:0], ycbcr_de} ;
  end
end

assign sobel_hs = hs_buf[8] ;
assign sobel_vs = vs_buf[8] ;
assign sobel_de = de_buf[8] ;
	 
endmodule
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值