本帖最后由 UT发布 于 2025-4-2 16:06 编辑
软件版本:Anlogic -TD5.6.1-64bit 操作系统:WIN10 64bit 硬件平台:适用安路(Anlogic)FPGA 1概述本文简述了图像拉普拉斯边缘提取的算法,讲解如何进行Verilog的算法实现,并进行上板实验。 2算法原理简介边缘检测是图像处理和计算机视觉中的基本问题,边缘检测的目的是标识数字图像中亮度变化明显的点。图像属性中的显著变化通常反映了属性的重要事件和变化。 这些包括: 1、图像深度上的不连续 2、二维面方向不连续 3、物质属性变化 4、场景照明变化 边缘检测是图像处理和计算机视觉中,尤其是特征提取中的一个研究领域。 图像边缘检测大幅度地减少了数据量,并且剔除了可以认为不相关的信息,保留了图像重要的结构属性。有许多方法用于边缘检测,它们的绝大部分可以划分为两类:基于查找一类和基于零穿越的一类。基于查找的方法通过寻找图像一阶导数中的最大和最小值来检测边界,通常是将边界定位在梯度最大的方向。基于零穿越的方法通过寻找图像二阶导数零穿越来寻找边界,通常是Laplacian过零点或者非线性差分表示的过零点。 3工程实现
3.1Verilog代码分析
- reg [2:0] i_hsyn_d;
- reg [2:0] i_vsyn_d;
- reg [2:0] i_en_d;
-
- wire [11:0] sum_r;
- wire [11:0] sum_g;
- wire [11:0] sum_b;
-
- reg [11:0] sum_r1;
- reg [11:0] sum_g1;
- reg [11:0] sum_b1;
-
- reg [11:0] sum_r2;
- reg [11:0] sum_g2;
- reg [11:0] sum_b2;
-
- reg [7:0] lap_r;
- reg [7:0] lap_g;
- reg [7:0] lap_b;
-
- wire [7:0] r_temp_11;
- wire [7:0] r_temp_12;
- wire [7:0] r_temp_13;
- wire [7:0] r_temp_21;
- wire [7:0] r_temp_22;
- wire [7:0] r_temp_23;
- wire [7:0] r_temp_31;
- wire [7:0] r_temp_32;
- wire [7:0] r_temp_33;
-
- wire [7:0] g_temp_11;
- wire [7:0] g_temp_12;
- wire [7:0] g_temp_13;
- wire [7:0] g_temp_21;
- wire [7:0] g_temp_22;
- wire [7:0] g_temp_23;
- wire [7:0] g_temp_31;
- wire [7:0] g_temp_32;
- wire [7:0] g_temp_33;
-
- wire [7:0] b_temp_11;
- wire [7:0] b_temp_12;
- wire [7:0] b_temp_13;
- wire [7:0] b_temp_21;
- wire [7:0] b_temp_22;
- wire [7:0] b_temp_23;
- wire [7:0] b_temp_31;
- wire [7:0] b_temp_32;
- wire [7:0] b_temp_33;
复制代码
输出赋值 - assign o_hs = i_hsyn_d[2];
- assign o_vs = i_vsyn_d[2];
- assign o_en = i_en_d[2] ;
- assign o_r = lap_r;
- assign o_g = lap_g;
- assign o_b = lap_b;
复制代码
信号同步化 - always@(posedge i_clk )
- begin
- i_hsyn_d <= {i_hsyn_d[1:0],i_hsyn};
- i_vsyn_d <= {i_vsyn_d[1:0],i_vsyn};
- i_en_d <= {i_en_d[1:0],i_en};
-
- end
复制代码
调用3x3模板 - image_template u_r_template
- (
- .i_clk (i_clk ),
- .i_rst_n (i_rst_n ),
- .i_en (i_en ),
- .i_data (i_r ),
- .o_en ( ),
- .o_temp_11 (r_temp_11 ),
- .o_temp_12 (r_temp_12 ),
- .o_temp_13 (r_temp_13 ),
- .o_temp_21 (r_temp_21 ),
- .o_temp_22 (r_temp_22 ),
- .o_temp_23 (r_temp_23 ),
- .o_temp_31 (r_temp_31 ),
- .o_temp_32 (r_temp_32 ),
- .o_temp_33 (r_temp_33 )
- );
复制代码
调用3x3模板 - image_template u_g_template
- (
- .i_clk (i_clk ),
- .i_rst_n (i_rst_n ),
- .i_en (i_en ),
- .i_data (i_g ),
- .o_en ( ),
- .o_temp_11 (g_temp_11 ),
- .o_temp_12 (g_temp_12 ),
- .o_temp_13 (g_temp_13 ),
- .o_temp_21 (g_temp_21 ),
- .o_temp_22 (g_temp_22 ),
- .o_temp_23 (g_temp_23 ),
- .o_temp_31 (g_temp_31 ),
- .o_temp_32 (g_temp_32 ),
- .o_temp_33 (g_temp_33 )
- );
复制代码
调用3x3模板 - image_template u_b_template
- (
- .i_clk (i_clk ),
- .i_rst_n (i_rst_n ),
- .i_en (i_en ),
- .i_data (i_b ),
- .o_en ( ),
- .o_temp_11 (b_temp_11 ),
- .o_temp_12 (b_temp_12 ),
- .o_temp_13 (b_temp_13 ),
- .o_temp_21 (b_temp_21 ),
- .o_temp_22 (b_temp_22 ),
- .o_temp_23 (b_temp_23 ),
- .o_temp_31 (b_temp_31 ),
- .o_temp_32 (b_temp_32 ),
- .o_temp_33 (b_temp_33 )
- );
复制代码
执行加法运算 - always@(posedge i_clk or negedge i_rst_n)
- begin
- if(!i_rst_n)
- begin
- sum_r1 <= 12'd0;
- sum_g1 <= 12'd0;
- sum_b1 <= 12'd0;
- sum_r2 <= 12'd0;
- sum_g2 <= 12'd0;
- sum_b2 <= 12'd0;
- end
- else
- begin
- sum_r1 <= r_temp_12 + r_temp_21 + r_temp_23 + r_temp_32;
- sum_r2 <= {2'd0,r_temp_22,2'd0};
-
- sum_g1 <= g_temp_12 + g_temp_21 + g_temp_23 + g_temp_32;
- sum_g2 <= {2'd0,g_temp_22,2'd0};
-
- sum_b1 <= b_temp_12 + b_temp_21 + b_temp_23 + b_temp_32;
- sum_b2 <= {2'd0,b_temp_22,2'd0};
- end
- end
复制代码
执行减法运算 - assign sum_r = sum_r2 - sum_r1;
- assign sum_g = sum_g2 - sum_g1;
- assign sum_b = sum_b2 - sum_b1;
复制代码
求取r通道的拉普拉斯边缘 - always@(posedge i_clk or negedge i_rst_n)
- begin
- if(!i_rst_n)
- begin
- lap_r <= 8'd0;
- end
- else if(sum_r[11:8] > 0)
- begin
- lap_r <= 8'd255;
- end
- else if(sum_r2 < sum_r1)
- begin
- lap_r <= 8'd0;
- end
- else
- begin
- lap_r <= sum_r[7:0];
- end
- end
复制代码
求取g通道的拉普拉斯边缘 - always@(posedge i_clk or negedge i_rst_n)
- begin
- if(!i_rst_n)
- begin
- lap_g <= 8'd0;
- end
- else if(sum_g[11:8] > 0)
- begin
- lap_g <= 8'd255;
- end
- else if(sum_g2 < sum_g1)
- begin
- lap_g <= 8'd0;
- end
- else
- begin
- lap_g <= sum_g[7:0];
- end
- end
复制代码
求取b通道的拉普拉斯边缘 - always@(posedge i_clk or negedge i_rst_n)
- begin
- if(!i_rst_n)
- begin
- lap_b <= 8'd0;
- end
- else if(sum_b[11:8] > 0)
- begin
- lap_b <= 8'd255;
- end
- else if(sum_b2 < sum_b1)
- begin
- lap_b <= 8'd0;
- end
- else
- begin
- lap_b <= sum_b[7:0];
- end
- end
复制代码
3.2工程结构工程结构如图所示: 图像数据通过摄像头采集进来,先缓存在fifo中,然后通过写状态机,将图像数据送进DDR进行缓存,缓存后的图像数据从DDR中取出,通过读状态机送出到fifo中,然后算法处理模块在fifo中取出数据,完成数据处理后送到LCD进行显示输出。 4上板实验点击下载后,可以看到正常的输出如下所示,摄像头的分辨率为640x480
|