基于FPGA的图像边缘检测系统设计

边缘检测算法的实现

Sobel和Prewitt算子都是基于3*3模板的,所以我们再进行边缘检测的时候,也需要产生一个3*3的模板。本次毕业设计产生3*3的模板的办法是,用RAM来存储图像的前两行数据,当前输入的数据作为第三行。详细的办法为,第三行数据到来时,我们先读出寄存在RAM的前两行数据,这样就获得了一个为一列三行的数据,再将这个一列三行的数据寄存三次,也就获得了3*3的数据模板。在此模块中,我们例化了两个双端RAM,其详细设置如图4-13、图4-14、图4-15所示。

基于FPGA的图像边缘检测系统设计_第1张图片

图4-13 RAM配置页面

Figure 4-13 RAM configuration page

基于FPGA的图像边缘检测系统设计_第2张图片

图4-14 RAM时钟设置

Figure 4-14 RAM Clock Settings

基于FPGA的图像边缘检测系统设计_第3张图片

图4-15 RAM输出配置

Figure 4-15 RAM output configuration

然后我们先求x方向的偏导数,再求y方向的偏导数,其中Prewitt和Sobel算子是靠sel信号来区别的,当sel=0时,进行Prewitt算法,当sel=1时,进行Sobel算法。然后两个方向偏导数的平方相加,再开根号,计算出来的值就是梯度向量的大小。再将这个值与我们所设置的阈值相比较,本次毕业设计设置的为20,大于它,表示为边缘,即为1,反之,为0。其中,所需要的开方计算可调用SQRT,详细配置如图4-16所示。

基于FPGA的图像边缘检测系统设计_第4张图片

图4-16 SQRT配置界面

Figure 4-16 SQRT configuration interface

压缩包里包含源程序、仿真、AD原理图、PDF文档(具体内容见下图目录)、答辩PPT、调取仿真的视频介绍。(说明:本人FPGA开发板用的是某某原子新起点V1开发板,如果是此开发板源程序直接下载就可以用。)

基于FPGA的图像边缘检测系统设计_第5张图片

设计具有创新点,也就是可以用按键在Sobel算子和Prewitt算子边缘检测间进行切换,也就是下板子时是Sobel边缘检测,再摁一下key0,就变成Prewitt边缘检测,再摁一下变成Sobel边缘检测。网上的资源基本只有单个的,如Sobel的边缘检测或者Canny的边缘检测,这样的话,可以与别人形成差异。检测效果如下图所示。

基于FPGA的图像边缘检测系统设计_第6张图片

仿真仅仅展示Prewitt边缘检测的,其他的还包括Sobel、VGA、PLL、摄像头配置等。

基于FPGA的图像边缘检测系统设计_第7张图片

PDF文档的查重率为18.65。

基于FPGA的图像边缘检测系统设计_第8张图片

边缘检测代码

//1.首先计算x方向的偏导数
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        Gy_temp1 <= 10'd0;
        Gy_temp2 <= 10'd0;end
    else case(sel)
			0:begin//prewitt算法
				Gy_temp1 <= matrix_p13 + (matrix_p23 ) + matrix_p33; 
				Gy_temp2 <= matrix_p11 + (matrix_p21 ) + matrix_p31; 
		     end
			1:begin//soble算法
				Gy_temp1 <= matrix_p13 + (matrix_p23 << 1) + matrix_p33; 
				Gy_temp2 <= matrix_p11 + (matrix_p21 << 1) + matrix_p31; 
		     end
			default:begin
					Gy_temp1 <= Gy_temp1;
					Gy_temp2 <= Gy_temp2;
					end
	endcase
	

end

assign  	Gy_data = (Gy_temp1 >= Gy_temp2) ? 	Gy_temp1 - Gy_temp2 	: 
															(Gy_temp2 - Gy_temp1)	;

//2.再计算y方向的偏导数
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        Gx_temp1 <= 10'd0;
        Gx_temp2 <= 10'd0;
    end
    else case(sel)
			0:	begin//prewwit算法
				 Gx_temp1 <= matrix_p11 + (matrix_p12 ) + matrix_p13; 
				 Gx_temp2 <= matrix_p31 + (matrix_p32 ) + matrix_p33; 
				end
			1:begin//soble算法
				 Gx_temp1 <= matrix_p11 + (matrix_p12 << 1) + matrix_p13; 
				 Gx_temp2 <= matrix_p31 + (matrix_p32 << 1) + matrix_p33; 
				end
			default:begin
					Gx_temp1 <= Gx_temp1;
					Gx_temp2 <= Gx_temp2;end
	endcase	
end


assign Gx_data = (Gx_temp1 >= Gx_temp2) ? Gx_temp1 - Gx_temp2 : 
													(Gx_temp2 - Gx_temp1);

//3.计算x和y平方和
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
        Gxy_square <= 21'd0;
    else
        Gxy_square <= (Gx_data * Gx_data) + (Gy_data * Gy_data);
end

//4.平方和开平方(梯度向量的大小)
SQRT  u_SQRT
(
    .radical   (Gxy_square),
    .q         (Dim),
    .remainder ()
);
assign gry=Dim[10:3];
//5.将开平方后的数据与预设阈值比较(阈值所设为20)
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)
        post_img_Bit_r <= 1'b0; //初始值
    else if(Dim >= SOBEL_THRESHOLD)
        post_img_Bit_r <= 1'b1; //检测到边缘1
    else
			post_img_Bit_r <= 1'b0; //不是边缘 0
end

毕设或者课设,如果需要此资源,请私信我。

你可能感兴趣的:(fpga开发,边缘计算)