FPGA 图像边缘检测(Canny算子)

1 顶层代码

`timescale 1ns / 1ps
//边缘检测二阶微分算子:canny算子module image_canny_edge_detect (input clk,input reset, //复位高电平有效input [10:0] img_width,input [ 9:0] img_height,input [ 7:0] low_threshold,input [ 7:0] high_threshold,input valid_i,input [15:0] rgb_565_i,  // 输入的16位RGB图像数据output        valid_o,output [15:0] rgb_565_o  // 输出的16位RGB图像数据
);//变量声明wire valid_gray;wire [7:0] img_data_gray;wire valid_gf;wire [7:0] img_data_gf;wire valid_sbl;wire [7:0] grad_mag;wire [10:0] grad_dx;wire [10:0] grad_dy;wire valid_nms;wire [7:0] img_data_nms;wire valid_db;wire [7:0] img_data_db;wire [23:0] img_data_i, img_data_o;assign img_data_i = {rgb_565_i[15:11], 3'b000, rgb_565_i[10:5], 2'b00, rgb_565_i[4:0], 3'b000};assign rgb_565_o  = {{img_data_o[23:19], img_data_o[15:10], img_data_o[7:3]}};//彩色图像灰度化image_rgb2gray u_image_rgb2gray (.clk       (clk),.reset     (reset),.valid_i   (valid_i),.img_data_i(img_data_i),.valid_o   (valid_gray),.img_data_o(img_data_gray));///高斯滤波image_gaussian_filter u_image_gaussian_filter (.clk       (clk),.reset     (reset),.img_width (img_width),.img_height(img_height),.valid_i   (valid_gray),.img_data_i(img_data_gray),.valid_o   (valid_gf),.img_data_o(img_data_gf));///Sobel算子image_sobel_edge u_image_sobel_edge (.clk       (clk),.reset     (reset),.img_width (img_width),.img_height(img_height),.valid_i   (valid_gf),.img_data_i(img_data_gf),.valid_o   (valid_sbl),.grad_mag  (grad_mag),.grad_dx   (grad_dx),.grad_dy   (grad_dy));///非极大值计算non_maximum_suppression u_non_maximum_suppression (.clk       (clk),.reset     (reset),.img_width (img_width),.img_height(img_height),.valid_i   (valid_sbl),.grad_mag  (grad_mag),.grad_dx   (grad_dx),.grad_dy   (grad_dy),.valid_o   (valid_nms),.img_data_o(img_data_nms));双阈值//根据输入的低阈值和高阈值来判断,如果这个像素点大于高阈值,则赋值为255;如果低于低阈值,则赋值为0;double_threshold u_double_threshold (.clk           (clk),.reset         (reset),.img_width     (img_width),.img_height    (img_height),.low_threshold (low_threshold),.high_threshold(high_threshold),.valid_i       (valid_nms),.img_data_i    (img_data_nms),.valid_o       (valid_db),.img_data_o    (img_data_db));assign valid_o = valid_db;assign img_data_o = {3{img_data_db}};endmodule

2 彩色图变灰度图代码

`timescale 1ns / 1ps
//彩色图像灰度化module image_rgb2gray (input clk,input reset,input valid_i,input [23:0] img_data_i,output valid_o,output [7:0] img_data_o
);//常量parameter MODE = 0;  //0表示加权平均法,1表示平均法 //Y=0.299*R十0.587*G+0.114*Bparameter C0 = 9'd306;  //0.299*1024;parameter C1 = 10'd601;  //0.587*1024;parameter C2 = 7'd117;  //0.114*1024;//参数声明wire [7:0] R, G, B;assign {R, G, B} = img_data_i;generateif (MODE) beginreg valid_d1;reg [9:0] RGB_avr;reg valid_d2;reg [16:0] RGB_avr_m;reg valid_d3;reg [7:0] RGB_new;//平均法//1/3 * 512 = 171always @(posedge clk) beginif (reset) beginvalid_d1 <= 'b0;RGB_avr  <= 'b0;end else beginvalid_d1 <= valid_i;RGB_avr  <= R + G + B;endend//最大值不可能超过255*3*171 = 17'd130815always @(posedge clk) beginRGB_avr_m <= RGB_avr * 8'd171;endalways @(posedge clk) beginif (reset) beginvalid_d2 <= 'b0;end else beginvalid_d2 <= valid_d1;endend//最大值不可能超过255always @(posedge clk) beginif (reset) beginvalid_d3 <= 'b0;RGB_new  <= 'b0;end else beginvalid_d3 <= valid_d2;RGB_new  <= RGB_avr_m[16:9];endendassign valid_o = valid_d3;assign img_data_o = {3{RGB_new}};end else begin//加权平均法reg valid_d1;reg [16:0] Y_R_m;reg [17:0] Y_G_m;reg [14:0] Y_B_m;reg valid_d2;reg [17:0] Y_s;//最大值,当RGB都等于255时,(C0 + C1 + C2)*255 = 1024*255;不会出现负数reg valid_d3;reg [7:0] Y;always @(posedge clk) beginY_R_m <= R * C0;Y_G_m <= G * C1;Y_B_m <= B * C2;endalways @(posedge clk) beginif (reset) beginvalid_d1 <= 0;end else beginvalid_d1 <= valid_i;endendalways @(posedge clk) beginif (reset) beginY_s <= 0;valid_d2 <= 0;end else beginif (valid_d1) beginY_s <= Y_R_m + Y_G_m + Y_B_m;endvalid_d2 <= valid_d1;endendalways @(posedge clk) beginif (reset) beginY <= 0;valid_d3 <= 0;end else beginif (valid_d2) beginY <= Y_s[17:10];endvalid_d3 <= valid_d2;endendassign valid_o = valid_d3;assign img_data_o = Y;endendgenerateendmodule

3 3行缓存代码

`timescale 1ns / 1ps
//FIFO实现3行图像缓存module image_line_buffer #(parameter W = 8
) (input wire clk,input wire reset,input wire [10:0] img_width,input wire [ 9:0] img_height,input wire valid_i,input wire [W-1:0] img_data_i,output reg valid_o,output reg [W-1:0] prev_line_data_o,output reg [W-1:0] cur_line_data_o,output reg [W-1:0] next_line_data_o
);//常量声明localparam N = 3;  //窗口大小//变量声明genvar i;integer j;wire [0:0] valid[0:N-1];wire [W-1:0] data[0:N-1];reg [10:0] out_data_cnt;reg [9:0] out_line_cnt;reg ch_valid;reg [W-1:0] ch_data[0:N-1];assign valid[0] = valid_i;assign data[0]  = img_data_i;//行缓存模块, 只需要缓存N-1个fifo即可generatefor (i = 1; i < N; i = i + 1) begin : lbline_buffer #(.W(W)) u_line_buffer (.clk      (clk),.reset    (reset),.img_width(img_width),.valid_i  (valid[i-1]),.data_i   (data[i-1]),.valid_o  (valid[i]),.data_o   (data[i]));endendgenerate//模式1,按照上一行、当前行、下一行输出//特殊情况,可根据需求设定,是复制还是给0//第1个行缓存,是整个画面的第1行时, 上一行数据不存在,复制第1个行缓存或者直接为0输出//第1个行缓存,是整个画面的最后1行时,下一行数据不存在,复制第1个行缓存输出always @(posedge clk) beginif (reset) beginfor (j = 0; j < 3; j = j + 1) ch_data[j] <= 0;end else if (valid[N-2]) beginch_data[1] <= data[1];if (out_line_cnt == 0) beginch_data[2] <= 0;ch_data[0] <= data[0];end else if (out_line_cnt == img_height - 1) beginch_data[2] <= data[2];ch_data[0] <= 0;end else beginch_data[2] <= data[2];ch_data[0] <= data[0];endendendalways @(posedge clk) beginif (reset) beginch_valid <= 0;out_data_cnt <= 0;out_line_cnt <= 0;end else beginch_valid <= valid[N-2];out_data_cnt <= valid[N-2] ? ((out_data_cnt == img_width - 1) ? 0 : out_data_cnt + 1) : out_data_cnt;out_line_cnt <= valid[N-2]&&(out_data_cnt == img_width - 1) ? ((out_line_cnt == img_height - 1) ? 0 : out_line_cnt + 1) : out_line_cnt;endend//单路输出always @(posedge clk) beginif (reset) beginvalid_o <= 0;prev_line_data_o <= 0;cur_line_data_o <= 0;next_line_data_o <= 0;end else beginvalid_o <= ch_valid;prev_line_data_o <= ch_data[2];cur_line_data_o <= ch_data[1];next_line_data_o <= ch_data[0];endendendmodule

4 1行缓存代码

`timescale 1ns / 1ps
//FIFO实现1行图像缓存module line_buffer #(parameter W = 8
) (input wire clk,input wire reset,input wire [10:0] img_width,input wire valid_i,input wire [W-1:0] data_i,output wire valid_o,output wire [W-1:0] data_o
);//变量声明reg [10:0] wr_data_cnt;wire rd_en;wire [11:0] fifo_data_count_w;//写入数据计数always @(posedge clk or posedge reset) beginif (reset) beginwr_data_cnt <= 0;end else beginwr_data_cnt <= valid_i && (wr_data_cnt < img_width) ? (wr_data_cnt + 1'b1) : wr_data_cnt;endend//assign rd_en = valid_i&&(wr_data_cnt == img_width) ? 1'b1 : 1'b0;//等价于assign rd_en   = valid_i && (fifo_data_count_w == img_width) ? 1'b1 : 1'b0;assign valid_o = rd_en;generateif (W == 8) beginfifo_line_buffer_w8 u_fifo_line_buffer_w8 (.clk       (clk),               // input wire clk.srst      (reset),             // input wire srst.din       (data_i),            // input wire [7 : 0] din.wr_en     (valid_i),           // input wire wr_en.rd_en     (rd_en),             // input wire rd_en.dout      (data_o),            // output wire [7 : 0] dout.full      (),                  // output wire full.empty     (),                  // output wire empty.data_count(fifo_data_count_w)  // output wire [11 : 0] data_count);end else beginfifo_line_buffer u_fifo_line_buffer (.clk       (clk),               // input wire clk.srst      (reset),             // input wire srst.din       (data_i),            // input wire [22 : 0] din.wr_en     (valid_i),           // input wire wr_en.rd_en     (rd_en),             // input wire rd_en.dout      (data_o),            // output wire [22 : 0] dout.full      (),                  // output wire full.empty     (),                  // output wire empty.data_count(fifo_data_count_w)  // output wire [11 : 0] data_count);endendgenerateendmodule

 

 

 

 

5 高斯滤波代码

`timescale 1ns / 1ps
//  高斯滤波module image_gaussian_filter (input wire clk,input wire reset,input wire [10:0] img_width,input wire [ 9:0] img_height,input wire valid_i,input wire [7:0] img_data_i,output reg valid_o,output reg [7:0] img_data_o
);//常量声明localparam MODE = 1;  //0表示彩色图像输出,1表示灰度图像输出//变量声明wire valid;wire [7:0] prev_line_data;wire [7:0] cur_line_data;wire [7:0] next_line_data;reg valid_d1;reg [7:0] prev_line_data_d1;reg [7:0] cur_line_data_d1;reg [7:0] next_line_data_d1;reg [7:0] prev_line_data_d2;reg [7:0] cur_line_data_d2;reg [7:0] next_line_data_d2;reg [7:0] x_cnt;reg valid_s;reg [7:0] prev_line_data_d2_s;reg [7:0] cur_line_data_d2_s;reg [7:0] next_line_data_d2_s;reg [7:0] prev_line_data_d1_s;reg [7:0] cur_line_data_d1_s;reg [7:0] next_line_data_d1_s;reg [7:0] prev_line_data_s;reg [7:0] cur_line_data_s;reg [7:0] next_line_data_s;wire [7:0] Y0, Y1, Y2;wire [7:0] Y3, Y4, Y5;wire [7:0] Y6, Y7, Y8;reg valid_s_d1;reg [9:0] Y_sum0;reg [10:0] Y_sum1;reg [9:0] Y_sum2;reg valid_s_d2;reg [14:0] Y_sum;wire [15:0] RGB_sum;wire [7:0] gray;image_line_buffer u_image_line_buffer (.clk             (clk),.reset           (reset),.img_width       (img_width),.img_height      (img_height),.valid_i         (valid_i),.img_data_i      (img_data_i),.valid_o         (valid),.prev_line_data_o(prev_line_data),.cur_line_data_o (cur_line_data),.next_line_data_o(next_line_data));always @(posedge clk) beginif (reset) beginvalid_d1 <= 0;prev_line_data_d1 <= 0;cur_line_data_d1 <= 0;next_line_data_d1 <= 0;prev_line_data_d2 <= 0;cur_line_data_d2 <= 0;next_line_data_d2 <= 0;end else beginvalid_d1 <= valid;prev_line_data_d1 <= prev_line_data;cur_line_data_d1 <= cur_line_data;next_line_data_d1 <= next_line_data;prev_line_data_d2 <= prev_line_data_d1;cur_line_data_d2 <= cur_line_data_d1;next_line_data_d2 <= next_line_data_d1;endend//边界数据处理always @(posedge clk) beginif (reset) beginx_cnt <= 0;end else beginx_cnt <= valid_d1 ? ((x_cnt == img_width - 1) ? 0 : x_cnt + 1) : x_cnt;endendalways @(posedge clk) beginif (reset) beginvalid_s <= 0;prev_line_data_d2_s <= 0;cur_line_data_d2_s <= 0;next_line_data_d2_s <= 0;prev_line_data_d1_s <= 0;cur_line_data_d1_s <= 0;next_line_data_d1_s <= 0;prev_line_data_s <= 0;cur_line_data_s <= 0;next_line_data_s <= 0;end else beginvalid_s <= valid_d1;prev_line_data_d1_s <= prev_line_data_d1;cur_line_data_d1_s <= cur_line_data_d1;next_line_data_d1_s <= next_line_data_d1;if (x_cnt == 0) beginprev_line_data_d2_s <= prev_line_data_d1;cur_line_data_d2_s <= cur_line_data_d1;next_line_data_d2_s <= next_line_data_d1;prev_line_data_s <= prev_line_data;cur_line_data_s <= cur_line_data;next_line_data_s <= next_line_data;endif (x_cnt == img_width - 1) beginprev_line_data_d2_s <= prev_line_data_d2;cur_line_data_d2_s <= cur_line_data_d2;next_line_data_d2_s <= next_line_data_d2;prev_line_data_s <= prev_line_data_d1;cur_line_data_s <= cur_line_data_d1;next_line_data_s <= next_line_data_d1;end else beginprev_line_data_d2_s <= prev_line_data_d2;cur_line_data_d2_s <= cur_line_data_d2;next_line_data_d2_s <= next_line_data_d2;prev_line_data_s <= prev_line_data;cur_line_data_s <= cur_line_data;next_line_data_s <= next_line_data;endendendassign Y0 = prev_line_data_d2_s;assign Y1 = cur_line_data_d2_s;assign Y2 = next_line_data_d2_s;assign Y3 = prev_line_data_d1_s;assign Y4 = cur_line_data_d1_s;assign Y5 = next_line_data_d1_s;assign Y6 = prev_line_data_s;assign Y7 = cur_line_data_s;assign Y8 = next_line_data_s;//高斯滤波模版/************[1. 2. 1.][2. 4. 2.][1. 2. 1.]
*************/always @(posedge clk) beginif (reset) beginvalid_s_d1 <= 0;{Y_sum0, Y_sum1, Y_sum2} <= 0;end else if (valid_s) beginvalid_s_d1 <= 1;Y_sum0 <= Y0 + {Y1, 1'b0} + Y2;Y_sum1 <= {Y3, 1'b0} + {Y4, 2'b0} + {Y5, 1'b0};Y_sum2 <= Y6 + {Y7, 1'b0} + Y8;end else valid_s_d1 <= 0;end//彩色图像 直接求和//灰度图像 1/3,扩大4bit,即16/3约等于5 = 4 + 1always @(posedge clk) beginif (reset) beginvalid_s_d2 <= 0;Y_sum <= 0;end else if (valid_s_d1) beginvalid_s_d2 <= 1;Y_sum <= Y_sum0 + Y_sum1 + Y_sum2;end else valid_s_d2 <= 0;endalways @(posedge clk) beginif (reset) beginvalid_o <= 0;img_data_o <= 0;end else if (valid_s_d2) beginvalid_o <= 1;img_data_o <= Y_sum[11:4];end else beginvalid_o <= 0;endendendmodule

6 sobel边缘检测代码

`timescale 1ns / 1ps
//边缘检测一阶微分算子:Sobel算子module image_sobel_edge (input wire clk,input wire reset,input wire [10:0] img_width,input wire [ 9:0] img_height,input wire valid_i,input wire [7:0] img_data_i,output reg valid_o,output reg [7:0] grad_mag,output reg [10:0] grad_dx,output reg [10:0] grad_dy
);//常量声明localparam N = 16;//变量声明wire valid;wire [7:0] prev_line_data;wire [7:0] cur_line_data;wire [7:0] next_line_data;reg valid_d1;reg [7:0] prev_line_data_d1;reg [7:0] cur_line_data_d1;reg [7:0] next_line_data_d1;reg [7:0] prev_line_data_d2;reg [7:0] cur_line_data_d2;reg [7:0] next_line_data_d2;reg [10:0] x_cnt;reg valid_s;reg [7:0] prev_line_data_d2_s;reg [7:0] cur_line_data_d2_s;reg [7:0] next_line_data_d2_s;reg [7:0] prev_line_data_d1_s;reg [7:0] cur_line_data_d1_s;reg [7:0] next_line_data_d1_s;reg [7:0] prev_line_data_s;reg [7:0] cur_line_data_s;reg [7:0] next_line_data_s;wire [7:0] Y0;wire [7:0] Y1;wire [7:0] Y2;wire [7:0] Y3;wire [7:0] Y4;wire [7:0] Y5;wire [7:0] Y6;wire [7:0] Y7;wire [7:0] Y8;reg valid_s_d1;wire [9:0] Gx_Y0_a;wire [9:0] Gx_Y1_a;wire [9:0] Gy_Y0_a;wire [9:0] Gy_Y1_a;reg Gx_Y_sign;reg [9:0] Gx_Y;reg Gy_Y_sign;reg [9:0] Gy_Y;reg valid_s_d2;reg Gx_Y_sign_d1;reg [19:0] Gx_Y_square;reg Gy_Y_sign_d1;reg [19:0] Gy_Y_square;wire [20:0] Gx_Gy_sum;reg [N-1:0] Gx_Y_sign_shift;reg [10*N-1:0] Gx_Y_shift;reg [N-1:0] Gy_Y_sign_shift;reg [10*N-1:0] Gy_Y_shift;wire valid_sqr;wire [10:0] data_sqr;image_line_buffer u_image_line_buffer (.clk             (clk),.reset           (reset),.img_width       (img_width),.img_height      (img_height),.valid_i         (valid_i),.img_data_i      (img_data_i),.valid_o         (valid),.prev_line_data_o(prev_line_data),.cur_line_data_o (cur_line_data),.next_line_data_o(next_line_data));always @(posedge clk) beginif (reset) beginvalid_d1 <= 0;prev_line_data_d1 <= 0;cur_line_data_d1 <= 0;next_line_data_d1 <= 0;prev_line_data_d2 <= 0;cur_line_data_d2 <= 0;next_line_data_d2 <= 0;end else beginvalid_d1 <= valid;prev_line_data_d1 <= prev_line_data;cur_line_data_d1 <= cur_line_data;next_line_data_d1 <= next_line_data;prev_line_data_d2 <= prev_line_data_d1;cur_line_data_d2 <= cur_line_data_d1;next_line_data_d2 <= next_line_data_d1;endend//边界数据处理always @(posedge clk) beginif (reset) beginx_cnt <= 0;end else beginx_cnt <= valid_d1 ? ((x_cnt == img_width - 1) ? 0 : x_cnt + 1) : x_cnt;endendalways @(posedge clk) beginif (reset) beginvalid_s <= 0;prev_line_data_d2_s <= 0;cur_line_data_d2_s <= 0;next_line_data_d2_s <= 0;prev_line_data_d1_s <= 0;cur_line_data_d1_s <= 0;next_line_data_d1_s <= 0;prev_line_data_s <= 0;cur_line_data_s <= 0;next_line_data_s <= 0;end else beginvalid_s <= valid_d1;prev_line_data_d1_s <= prev_line_data_d1;cur_line_data_d1_s <= cur_line_data_d1;next_line_data_d1_s <= next_line_data_d1;if (x_cnt == 0) beginprev_line_data_d2_s <= prev_line_data_d1;cur_line_data_d2_s <= cur_line_data_d1;next_line_data_d2_s <= next_line_data_d1;prev_line_data_s <= prev_line_data;cur_line_data_s <= cur_line_data;next_line_data_s <= next_line_data;endif (x_cnt == img_width - 1) beginprev_line_data_d2_s <= prev_line_data_d2;cur_line_data_d2_s <= cur_line_data_d2;next_line_data_d2_s <= next_line_data_d2;prev_line_data_s <= prev_line_data_d1;cur_line_data_s <= cur_line_data_d1;next_line_data_s <= next_line_data_d1;end else beginprev_line_data_d2_s <= prev_line_data_d2;cur_line_data_d2_s <= cur_line_data_d2;next_line_data_d2_s <= next_line_data_d2;prev_line_data_s <= prev_line_data;cur_line_data_s <= cur_line_data;next_line_data_s <= next_line_data;endendendassign Y0 = prev_line_data_d2_s;assign Y1 = cur_line_data_d2_s;assign Y2 = next_line_data_d2_s;assign Y3 = prev_line_data_d1_s;assign Y4 = cur_line_data_d1_s;assign Y5 = next_line_data_d1_s;assign Y6 = prev_line_data_s;assign Y7 = cur_line_data_s;assign Y8 = next_line_data_s;/Sobey算子/************[-1.  0.  1]  [-2.  0.  2]
Gx= [-1.  0.  1][ 1.  2.  1][ 0.  0.  0]
Gy= [-1. -2. -1]
*************/assign Gx_Y0_a = Y0 + {Y3, 1'b0} + Y6;assign Gx_Y1_a = Y2 + {Y5, 1'b0} + Y8;assign Gy_Y0_a = Y0 + {Y1, 1'b0} + Y2;assign Gy_Y1_a = Y6 + {Y7, 1'b0} + Y8;always @(posedge clk) beginif (reset) beginvalid_s_d1 <= 0;{Gx_Y, Gy_Y} <= 0;{Gx_Y_sign, Gy_Y_sign} <= 0;end else if (valid_s) beginvalid_s_d1 <= 1;Gx_Y <= (Gx_Y0_a > Gx_Y1_a) ? Gx_Y0_a - Gx_Y1_a : Gx_Y1_a - Gx_Y0_a;Gx_Y_sign <= (Gx_Y0_a > Gx_Y1_a) ? 1 : 0;Gy_Y <= (Gy_Y0_a > Gy_Y1_a) ? Gy_Y0_a - Gy_Y1_a : Gy_Y1_a - Gy_Y0_a;Gy_Y_sign <= (Gy_Y0_a > Gy_Y1_a) ? 1 : 0;end else valid_s_d1 <= 0;end//求平方always @(posedge clk) beginif (reset) beginvalid_s_d2  <= 0;Gx_Y_square <= 0;Gy_Y_square <= 0;end else beginvalid_s_d2  <= valid_s_d1;Gx_Y_square <= Gx_Y * Gx_Y;Gy_Y_square <= Gy_Y * Gy_Y;endendassign Gx_Gy_sum = Gx_Y_square + Gy_Y_square;//平方根cordic_square_root u_cordic_square_root (.aclk                   (clk),         // input wire aclk.s_axis_cartesian_tvalid(valid_s_d2),  // input wire s_axis_cartesian_tvalid.s_axis_cartesian_tdata (Gx_Gy_sum),   // input wire [23 : 0] s_axis_cartesian_tdata.m_axis_dout_tvalid     (valid_sqr),   // output wire m_axis_dout_tvalid.m_axis_dout_tdata      (data_sqr)     // output wire [15 : 0] m_axis_dout_tdata);always @(posedge clk) beginif (reset) beginGx_Y_sign_shift <= 0;Gx_Y_shift <= 0;Gy_Y_sign_shift <= 0;Gy_Y_shift <= 0;end else beginGx_Y_sign_shift <= {Gx_Y_sign_shift, Gx_Y_sign};Gx_Y_shift <= {Gx_Y_shift, Gx_Y};Gy_Y_sign_shift <= {Gy_Y_sign_shift, Gy_Y_sign};Gy_Y_shift <= {Gy_Y_shift, Gy_Y};endendalways @(posedge clk) beginif (reset) beginvalid_o  <= 0;grad_mag <= 0;grad_dx  <= 0;grad_dy  <= 0;end else if (valid_sqr) beginvalid_o  <= 1;grad_mag <= data_sqr;grad_dx  <= {Gx_Y_sign_shift[N-1], Gx_Y_shift[N*10-1:(N-1)*10]};grad_dy  <= {Gy_Y_sign_shift[N-1], Gy_Y_shift[N*10-1:(N-1)*10]};end else beginvalid_o <= 0;endendendmodule

 

7 非极大值抑制代码

`timescale 1ns / 1ps
//  非极大值抑制module non_maximum_suppression (input clk,input reset,input wire [10:0] img_width,input wire [ 9:0] img_height,input valid_i,input [7:0] grad_mag,input [10:0] grad_dx,input [10:0] grad_dy,output reg valid_o,output reg [7:0] img_data_o
);//常量localparam N = 24;//参数声明wire valid;wire [7:0] prev_line_data;wire [7:0] cur_line_data;wire [7:0] next_line_data;reg valid_d1;reg [7:0] prev_line_data_d1;reg [7:0] cur_line_data_d1;reg [7:0] next_line_data_d1;reg [7:0] prev_line_data_d2;reg [7:0] cur_line_data_d2;reg [7:0] next_line_data_d2;reg [10:0] x_cnt;reg valid_s;reg [7:0] prev_line_data_d2_s;reg [7:0] cur_line_data_d2_s;reg [7:0] next_line_data_d2_s;reg [7:0] prev_line_data_d1_s;reg [7:0] cur_line_data_d1_s;reg [7:0] next_line_data_d1_s;reg [7:0] prev_line_data_s;reg [7:0] cur_line_data_s;reg [7:0] next_line_data_s;wire [7:0] Y0, Y1, Y2;wire [7:0] Y3, Y4, Y5;wire [7:0] Y6, Y7, Y8;wire grad_valid;wire [21:0] grad_cur_line_data;reg valid_s_d1;reg grad_dx_sign;reg [9:0] grad_dx_abs;reg grad_dy_sign;reg [9:0] grad_dy_abs;reg [1:0] mode;reg [9:0] dividend, divisor;wire div_valid;wire [23:0] div_data;reg [2*N-1:0] mode_shift;wire mode_s;reg [72*N-1:0] Y_shift;wire [7:0] Y0_s, Y1_s, Y2_s;wire [7:0] Y3_s, Y4_s, Y5_s;wire [7:0] Y6_s, Y7_s, Y8_s;reg div_valid_d1;reg [7:0] grad1, grad2, grad3, grad4;reg [7:0] weight;reg [8:0] one_sub_weight;reg [7:0] Y4_s_d1;reg div_valid_d2;reg [15:0] grad1_m, grad2_m;reg [16:0] grad3_m, grad4_m;reg [7:0] Y4_s_d2;wire [16:0] t1, t2;/行视频数据缓存image_line_buffer u_image_line_buffer (.clk             (clk),.reset           (reset),.img_width       (img_width),.img_height      (img_height),.valid_i         (valid_i),.img_data_i      (grad_mag),.valid_o         (valid),.prev_line_data_o(prev_line_data),.cur_line_data_o (cur_line_data),.next_line_data_o(next_line_data));always @(posedge clk) beginif (reset) beginvalid_d1 <= 0;prev_line_data_d1 <= 0;cur_line_data_d1 <= 0;next_line_data_d1 <= 0;prev_line_data_d2 <= 0;cur_line_data_d2 <= 0;next_line_data_d2 <= 0;end else beginvalid_d1 <= valid;prev_line_data_d1 <= prev_line_data;cur_line_data_d1 <= cur_line_data;next_line_data_d1 <= next_line_data;prev_line_data_d2 <= prev_line_data_d1;cur_line_data_d2 <= cur_line_data_d1;next_line_data_d2 <= next_line_data_d1;endend//边界数据处理always @(posedge clk) beginif (reset) beginx_cnt <= 0;end else beginx_cnt <= valid_d1 ? ((x_cnt == img_width - 1) ? 0 : x_cnt + 1) : x_cnt;endendalways @(posedge clk) beginif (reset) beginvalid_s <= 0;prev_line_data_d2_s <= 0;cur_line_data_d2_s <= 0;next_line_data_d2_s <= 0;prev_line_data_d1_s <= 0;cur_line_data_d1_s <= 0;next_line_data_d1_s <= 0;prev_line_data_s <= 0;cur_line_data_s <= 0;next_line_data_s <= 0;end else beginvalid_s <= valid_d1;prev_line_data_d1_s <= prev_line_data_d1;cur_line_data_d1_s <= cur_line_data_d1;next_line_data_d1_s <= next_line_data_d1;if (x_cnt == 0) beginprev_line_data_d2_s <= prev_line_data_d1;cur_line_data_d2_s <= cur_line_data_d1;next_line_data_d2_s <= next_line_data_d1;prev_line_data_s <= prev_line_data;cur_line_data_s <= cur_line_data;next_line_data_s <= next_line_data;endif (x_cnt == img_width - 1) beginprev_line_data_d2_s <= prev_line_data_d2;cur_line_data_d2_s <= cur_line_data_d2;next_line_data_d2_s <= next_line_data_d2;prev_line_data_s <= prev_line_data_d1;cur_line_data_s <= cur_line_data_d1;next_line_data_s <= next_line_data_d1;end else beginprev_line_data_d2_s <= prev_line_data_d2;cur_line_data_d2_s <= cur_line_data_d2;next_line_data_d2_s <= next_line_data_d2;prev_line_data_s <= prev_line_data;cur_line_data_s <= cur_line_data;next_line_data_s <= next_line_data;endendendassign Y0 = prev_line_data_d2_s;assign Y1 = cur_line_data_d2_s;assign Y2 = next_line_data_d2_s;assign Y3 = prev_line_data_d1_s;assign Y4 = cur_line_data_d1_s;assign Y5 = next_line_data_d1_s;assign Y6 = prev_line_data_s;assign Y7 = cur_line_data_s;assign Y8 = next_line_data_s;/grad_dx和grad_dy行数据缓存image_line_buffer #(.W(21)) u_image_grad_line_buffer (.clk             (clk),.reset           (reset),.img_width       (img_width),.img_height      (img_height),.valid_i         (valid_i),.img_data_i      ({grad_dx, grad_dy}),.valid_o         (grad_valid),.prev_line_data_o(),.cur_line_data_o (grad_cur_line_data),.next_line_data_o());/非极大值限制计算//计算grad_dx,grad_dy绝对值always @(posedge clk) beginif (reset) begin{grad_dx_sign, grad_dx_abs} <= 0;{grad_dy_sign, grad_dy_abs} <= 0;end else begingrad_dx_sign <= grad_cur_line_data[21];grad_dx_abs  <= grad_cur_line_data[20:11];grad_dy_sign <= grad_cur_line_data[10];grad_dy_abs  <= grad_cur_line_data[9:0];endend//计算模式always @(posedge clk) beginif (reset) beginmode <= 0;{dividend, divisor} <= 0;end else beginif (grad_dx_abs > grad_dy_abs) beginmode <= (grad_dx_sign ^ grad_dy_sign) ? 0 : 1;dividend <= grad_dy_abs;divisor <= grad_dx_abs;end else beginmode <= (grad_dx_sign ^ grad_dy_sign) ? 2 : 3;dividend <= grad_dx_abs;divisor <= grad_dy_abs;endendend//除法计算div_gen_10x10 u_div_gen_10x10 (.aclk                  (clk),               // input wire aclk.s_axis_divisor_tvalid (valid_s),           // input wire s_axis_divisor_tvalid.s_axis_divisor_tdata  ({6'b0, divisor}),   // input wire [15 : 0] s_axis_divisor_tdata.s_axis_dividend_tvalid(valid_s),           // input wire s_axis_dividend_tvalid.s_axis_dividend_tdata ({6'b0, dividend}),  // input wire [15 : 0] s_axis_dividend_tdata.m_axis_dout_tvalid    (div_valid),         // output wire m_axis_dout_tvalid.m_axis_dout_tdata     (div_data)           // output wire [23 : 0] m_axis_dout_tdata);//同步延时always @(posedge clk) beginif (reset) beginmode_shift <= 0;Y_shift <= 0;end else beginmode_shift <= {mode_shift, mode};Y_shift <= {Y_shift, Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8};endendassign mode_s = mode_shift[2*N-1:2*(N-1)];assign {Y0_s, Y1_s, Y2_s, Y3_s, Y4_s, Y5_s, Y6_s, Y7_s, Y8_s} = Y_shift[72*N-1:72*(N-1)];//计算插值系数、插值数据always @(posedge clk) beginif (reset) begindiv_valid_d1 <= 0;weight <= 0;one_sub_weight <= 0;Y4_s_d1 <= 0;{grad1, grad2, grad3, grad4} <= 0;end else begindiv_valid_d1 <= div_valid;weight <= div_data[7:0];one_sub_weight <= 256 - div_data[7:0];Y4_s_d1 <= Y4_s;case (mode_s)0: begingrad1 <= Y7_s;grad2 <= Y1_s;grad3 <= Y8_s;grad4 <= Y0_s;end1: begingrad1 <= Y7_s;grad2 <= Y1_s;grad3 <= Y6_s;grad4 <= Y2_s;end2: begingrad1 <= Y5_s;grad2 <= Y3_s;grad3 <= Y8_s;grad4 <= Y0_s;end3: begingrad1 <= Y5_s;grad2 <= Y3_s;grad3 <= Y6_s;grad4 <= Y2_s;endendcaseendend//计算极值t1\t2always @(posedge clk) beginif (reset) begindiv_valid_d2 <= 0;Y4_s_d2 <= 0;{grad1_m, grad2_m, grad3_m, grad4_m} <= 0;end else begindiv_valid_d2 <= div_valid_d1;Y4_s_d2 <= Y4_s_d1;grad1_m <= grad1 * weight;grad2_m <= grad2 * weight;grad3_m <= grad3 * one_sub_weight;grad4_m <= grad4 * one_sub_weight;endendassign t1 = grad1_m + grad3_m;assign t2 = grad2_m + grad4_m;//超过极值后,赋值为0always @(posedge clk) beginif (reset) beginvalid_o <= 0;img_data_o <= 0;end else if (div_valid_d2) beginvalid_o <= 1;img_data_o <= ({1'b0, Y4_s_d2} > t1[16:8]) && ({1'b0, Y4_s_d2} > t2[16:8]) ? Y4_s_d2 : 0;end else beginvalid_o <= 0;endendendmodule

 

 

8 双阈值代码

`timescale 1ns / 1ps
//双阈值module double_threshold (input clk,input reset,input [10:0] img_width,input [ 9:0] img_height,input [ 7:0] low_threshold,input [ 7:0] high_threshold,input valid_i,input [7:0] img_data_i,output reg valid_o,output reg [7:0] img_data_o
);//常量声明localparam MODE = 1;  //0表示彩色图像输出,1表示灰度图像输出//变量声明wire valid;wire [7:0] prev_line_data;wire [7:0] cur_line_data;wire [7:0] next_line_data;reg valid_d1;reg [7:0] prev_line_data_d1;reg [7:0] cur_line_data_d1;reg [7:0] next_line_data_d1;reg [7:0] prev_line_data_d2;reg [7:0] cur_line_data_d2;reg [7:0] next_line_data_d2;reg [7:0] x_cnt;reg valid_s;reg [7:0] prev_line_data_d2_s;reg [7:0] cur_line_data_d2_s;reg [7:0] next_line_data_d2_s;reg [7:0] prev_line_data_d1_s;reg [7:0] cur_line_data_d1_s;reg [7:0] next_line_data_d1_s;reg [7:0] prev_line_data_s;reg [7:0] cur_line_data_s;reg [7:0] next_line_data_s;wire [7:0] Y0, Y1, Y2;wire [7:0] Y3, Y4, Y5;wire [7:0] Y6, Y7, Y8;image_line_buffer u_image_line_buffer (.clk             (clk),.reset           (reset),.img_width       (img_width),.img_height      (img_height),.valid_i         (valid_i),.img_data_i      (img_data_i),.valid_o         (valid),.prev_line_data_o(prev_line_data),.cur_line_data_o (cur_line_data),.next_line_data_o(next_line_data));always @(posedge clk) beginif (reset) beginvalid_d1 <= 0;prev_line_data_d1 <= 0;cur_line_data_d1 <= 0;next_line_data_d1 <= 0;prev_line_data_d2 <= 0;cur_line_data_d2 <= 0;next_line_data_d2 <= 0;end else beginvalid_d1 <= valid;prev_line_data_d1 <= prev_line_data;cur_line_data_d1 <= cur_line_data;next_line_data_d1 <= next_line_data;prev_line_data_d2 <= prev_line_data_d1;cur_line_data_d2 <= cur_line_data_d1;next_line_data_d2 <= next_line_data_d1;endend//边界数据处理always @(posedge clk) beginif (reset) beginx_cnt <= 0;end else beginx_cnt <= valid_d1 ? ((x_cnt == img_width - 1) ? 0 : x_cnt + 1) : x_cnt;endendalways @(posedge clk) beginif (reset) beginvalid_s <= 0;prev_line_data_d2_s <= 0;cur_line_data_d2_s <= 0;next_line_data_d2_s <= 0;prev_line_data_d1_s <= 0;cur_line_data_d1_s <= 0;next_line_data_d1_s <= 0;prev_line_data_s <= 0;cur_line_data_s <= 0;next_line_data_s <= 0;end else beginvalid_s <= valid_d1;prev_line_data_d1_s <= prev_line_data_d1;cur_line_data_d1_s <= cur_line_data_d1;next_line_data_d1_s <= next_line_data_d1;if (x_cnt == 0) beginprev_line_data_d2_s <= prev_line_data_d1;cur_line_data_d2_s <= cur_line_data_d1;next_line_data_d2_s <= next_line_data_d1;prev_line_data_s <= prev_line_data;cur_line_data_s <= cur_line_data;next_line_data_s <= next_line_data;endif (x_cnt == img_width - 1) beginprev_line_data_d2_s <= prev_line_data_d2;cur_line_data_d2_s <= cur_line_data_d2;next_line_data_d2_s <= next_line_data_d2;prev_line_data_s <= prev_line_data_d1;cur_line_data_s <= cur_line_data_d1;next_line_data_s <= next_line_data_d1;end else beginprev_line_data_d2_s <= prev_line_data_d2;cur_line_data_d2_s <= cur_line_data_d2;next_line_data_d2_s <= next_line_data_d2;prev_line_data_s <= prev_line_data;cur_line_data_s <= cur_line_data;next_line_data_s <= next_line_data;endendendassign Y0 = prev_line_data_d2_s;assign Y1 = cur_line_data_d2_s;assign Y2 = next_line_data_d2_s;assign Y3 = prev_line_data_d1_s;assign Y4 = cur_line_data_d1_s;assign Y5 = next_line_data_d1_s;assign Y6 = prev_line_data_s;assign Y7 = cur_line_data_s;assign Y8 = next_line_data_s;always @(posedge clk) beginif (reset) beginvalid_o <= 0;img_data_o <= 0;end else if (valid_s) beginvalid_o <= 1;if (Y4 < low_threshold) img_data_o <= 0;else if((Y0 > high_threshold)||(Y1 > high_threshold)||(Y2 > high_threshold)||(Y3 > high_threshold)||(Y4 > high_threshold)||(Y5 > high_threshold)||(Y6 > high_threshold)||(Y7 > high_threshold)||(Y8 > high_threshold))img_data_o <= 255;else img_data_o <= 0;end else beginvalid_o <= 0;endendendmodule

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/576418.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯23年第十四届省赛真题-填充|DFS,贪心

题目链接&#xff1a; 1.填充 - 蓝桥云课 (lanqiao.cn) 蓝桥杯2023年第十四届省赛真题-填充 - C语言网 (dotcpp.com) 说明&#xff1a; dfs就不再多说了&#xff0c;对于每个?都有0和1两个分支&#xff0c;数据范围是&#xff1a; 那么有m个 ?&#xff0c;时间复杂度就是…

C++初阶:2_类与对象(下)

类与对象(下) 一.再谈构造函数 1. 构造函数体赋值 在创建对象时&#xff0c;编译器通过调用构造函数&#xff0c;给对象中各个成员变量一个合适的初始值。 class Date { public:Date(int year, int month, int day){_year year;_month month;_day day;} private:int _ye…

38.网络游戏逆向分析与漏洞攻防-游戏网络通信数据解析-解码器类的优化调试

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 如果看不懂、不知道现在做的什么&#xff0c;那就跟着做完看效果 内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;37.解码器细化类…

“光学行业正被量子颠覆”——行业巨头齐聚,展示量子成果

OFC是全球最大的光网络和通信盛会&#xff0c;代表一系列产品&#xff0c;从光学元件和设备到系统、测试设备、软件和特种光纤&#xff0c;代表整个供应链&#xff0c;并提供业界学习、连接、建立网络和达成交易的首要市场&#xff0c;于2024年3月24日至28日在圣地亚哥会议中心…

excel中批量插入分页符

excel中批量插入分页符&#xff0c;实现按班级打印学生名单。 1、把学生按照学号、班级排序好。 2、选择班级一列&#xff0c;点击数据-分类汇总。汇总方式选择计数&#xff0c;最后三个全部勾选。汇总结果一定要显示在数据的下发&#xff0c;如果显示在上方&#xff0c;后期…

Science Robotics 逼真面部表情的机器人

人类可以产生数千种不同的面部表情来传达无数微妙的情绪状态&#xff0c;这种能力是人类社会互动中最有效和最有效的界面之一。在 2019 年冠状病毒病流行期间&#xff0c;口罩使社交互动变得尴尬&#xff0c;因为它们掩盖了面部表情。同时&#xff0c;当摄像机打开时&#xff0…

成都市酷客焕学新媒体科技有限公司:实现品牌的更大价值!

成都市酷客焕学新媒体科技有限公司专注于短视频营销&#xff0c;深知短视频在社交媒体中的巨大影响力。该公司巧妙地将品牌信息融入富有创意和趣味性的内容中&#xff0c;使观众在轻松愉悦的氛围中接受并传播这些信息。凭借独特的创意和精准的营销策略&#xff0c;成都市酷客焕…

火车头通过关键词采集文章的原理

随着互联网信息的爆炸式增长&#xff0c;网站管理员和内容创作者需要不断更新和发布新的文章&#xff0c;以吸引更多的用户和提升网站的排名。而火车头作为一款智能文章采集工具&#xff0c;在这一过程中发挥着重要作用。本文将探讨火车头如何通过关键词采集文章&#xff0c;以…

SAP BTP云上一个JVM与DB Connection纠缠的案例

前言 最近在CF (Cloud Foundry) 云平台上遇到一个比较经典的案例。因为牵扯到JVM &#xff08;app进程&#xff09;与数据库连接两大块&#xff0c;稍有不慎&#xff0c;很容易引起不快。 在云环境下&#xff0c;有时候相互扯皮的事蛮多。如果是DB的问题&#xff0c;就会找DB…

网络爬虫框架Scrapy的入门使用

Scrapy的入门使用 Scrapy概述引擎&#xff08;Engine&#xff09;调度器&#xff08;Scheduler&#xff09;下载器&#xff08;Downloader&#xff09;SpiderItem Pipeline 基本使用安装scrapy创建项目定义Item数据模型对象创建爬虫(Spider)管道pipeline来保存数据启动爬虫 其他…

cuda python课程中“使用 Numba 的 CUDA Python 的自定义核函数和内存管理“一个大坑

总觉得自己的算法没问题&#xff0c;最终还是测试结果不符。 错误出现在一个很顺眼的位置。 解决方案 在最终测验阶段有一个看起来没问题不需要任何修改的Cell&#xff0c;就是这一句&#xff0c;看起来没什么毛病 d_histogram_out cuda.device_array_like(histogram_out)需…

Java代码混淆技术在应用程序保护中的关键作用与应用

摘要 本文探讨了代码混淆在保护Java代码安全性和知识产权方面的重要意义。通过混淆技术&#xff0c;可以有效防止代码被反编译、逆向工程或恶意篡改&#xff0c;提高代码的安全性。常见的Java代码混淆工具如IPAGuard、Allatori、DashO、Zelix KlassMaster和yGuard等&#xff0…