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.mzph.cn/news/778482.shtml

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

相关文章

【案例·增】一条insert语句批量插入多条记录

问题描述&#xff1a; 往MySQL中的数据库表中批量插入多条记录&#xff0c;可以使用 SQL 中的 ((), ()…)来处理 案例&#xff1a; INSERT INTO items(name,city,price,number,picture) VALUES(耐克运动鞋,广州,500,1000,003.jpg),(耐克运动鞋2,广州2,500,1000,002.jpg);规则…

基于java+springboot+vue实现的宠物领养救助平台(文末源码+Lw+ppt)23-363

摘 要 宠物领养救助平台采用B/S架构&#xff0c;数据库是MySQL。网站的搭建与开发采用了先进的java进行编写&#xff0c;使用了springboot框架。该系统从两个对象&#xff1a;由管理员和用户来对系统进行设计构建。主要功能包括&#xff1a;个人信息修改&#xff0c;对用户、…

【Redis】redis主从复制

概述 常见的Redis高可用的方案包括持久化、主从复制&#xff08;及读写分离&#xff09;、哨兵和集群。其中持久化侧重解决的是Redis数据的单机备份问题&#xff08;从内存到硬盘的备份&#xff09;&#xff1b;而主从复制则侧重解决数据的多机热备。此外&#xff0c;主从复制…

提高三维模型数据的立体裁剪技术

提高三维模型数据的立体裁剪技术 立体裁剪是三维模型处理中的重要步骤&#xff0c;可以用于去除模型中不需要的部分&#xff0c;提高模型的质量和准确性。本文将介绍几种常见的立体裁剪技术&#xff0c;包括边界裁剪、体素裁剪和几何裁剪&#xff0c;并分析它们的优缺点和适用场…

新朋友+1!拓数派 PieCloudDB Database 与 OpenCloudOS、TencentOS Server 完成产品兼容互认证

近日&#xff0c;拓数派旗下产品云原生虚拟数仓 PieCloudDB Database 与开源操作系统 OpenCloudOS 以及腾讯云旗下操作系统 TencentOS Server 完成了产品兼容性互认证。测试期间&#xff0c;双方产品运行稳定&#xff0c;兼容性良好&#xff0c;功能正常。 随着“数据要素x”三…

交互式RDP服务启停及修改端口的bat脚本

1、执行效果 2、脚本代码 echo off chcp 65001REM 检查是否有管理员权限 net session >nul 2>&1 if %errorlevel% neq 0 (echo 请右键【以管理员身份运行】此脚本。pauseexit /b )REM 提示是否开启或关闭RDP服务 set /p enable_disable是否开启或关闭RDP远程桌面服务…

生成的短链接/二维码,如何更改跳转网址?C1N 短网址一键解决

在当今的营销推广领域&#xff0c;短链接的运用已不可或缺。它能直接将网页、产品或服务呈现在潜在客户或用户面前&#xff0c;提升知名度与曝光率。 然而&#xff0c;使用短链接时也会遭遇一些问题&#xff0c;最常见的便是推广链接已发出&#xff0c;却发现有误或需修改&…

CC工具箱使用指南:【经度转3度带和6度带】

一、简介 在规划工作中&#xff0c;经常会遇到不清楚规划用地所在的3度带或6度带带号的情况。 其实只要知道所在地的经度即可计算出带号&#xff0c;具体计算方法百度可知&#xff1a; 三度带和六度带1.高斯投影6度带&#xff1a;自0子午线起每隔经差6自西向东分带&#xff…

神策数据参与制定首份 SDK 网络安全国家标准

国家市场监督管理总局、国家标准化管理委员会发布中华人民共和国国家标准公告&#xff08;2023 年第 13 号&#xff09;&#xff0c;全国信息安全标准化技术委员会归口的 3 项国家标准正式发布。其中&#xff0c;首份 SDK 国家标准《信息安全技术 移动互联网应用程序&#xff0…

2014年认证杯SPSSPRO杯数学建模B题(第二阶段)位图的处理算法全过程文档及程序

2014年认证杯SPSSPRO杯数学建模 B题 位图的处理算法 原题再现&#xff1a; 图形&#xff08;或图像&#xff09;在计算机里主要有两种存储和表示方法。矢量图是使用点、直线或多边形等基于数学方程的几何对象来描述图形&#xff0c;位图则使用像素来描述图像。一般来说&#…

某某消消乐增加步数漏洞分析

一、漏洞简介 1&#xff09; 漏洞所属游戏名及基本介绍&#xff1a;某某消消乐&#xff0c;三消游戏&#xff0c;类似爱消除。 2&#xff09; 漏洞对应游戏版本及平台&#xff1a;某某消消乐Android 1.22.22。 3&#xff09; 漏洞功能&#xff1a;增加游戏步数。 4&#xf…

【MATLAB源码-第22期】基于matlab的手动实现的(未调用内置函数)CRC循环码编码译码仿真。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 循环码是线性分组码的一种&#xff0c;所以它具有线性分组码的一般特性&#xff0c;此外还具有循环性。循环码的编码和解码设备都不太复杂&#xff0c;且检(纠)错能力强。它不但可以检测随机的错误&#xff0c;还可以检错突发…

RPA使用Native Messaging协议实现浏览器自动化

RPA 即机器人流程自动化&#xff0c;是一种利用软件机器人或人工智能来自动化业务流程中规则性、重复性任务的技术。RPA 技术可以模拟和执行人类在计算机上的交互操作&#xff0c;从而实现自动化处理数据、处理交易、触发通知等任务。帮助企业或个人实现业务流程的自动化和优化…

【绝对有用】“利用ChatGPT赋能学术写作:技巧、方法与创新策略“

为了帮助读者利用ChatGPT进行学术写作&#xff0c;我以一种引人入胜的信息图表形式&#xff0c;概括了以下步骤和技巧&#xff1a; 使用英文提问&#xff1a;用英文提出问题&#xff0c;可以获得更准确的回答。生成大纲&#xff1a;通过创建文章大纲&#xff0c;为写作提供清晰…

leetcode热题100.柱状图中最大的矩形

Problem: 84. 柱状图中最大的矩形 文章目录 题目思路复杂度Code 题目 给定 n 个非负整数&#xff0c;用来表示柱状图中各个柱子的高度。每个柱子彼此相邻&#xff0c;且宽度为 1 。 求在该柱状图中&#xff0c;能够勾勒出来的矩形的最大面积。 示例 1: 输入&#xff1a;hei…

按需自动加载 Element Plus 实测

按需加载是一种优化策略&#xff0c;可以提高前端应用程序的性能、用户体验和可维护性。在使用 Element UI 或其他大型 UI 组件库时&#xff0c;通过按需加载可以最大程度地发挥其优势&#xff0c;确保应用程序的性能和可扩展性得到有效的管理&#xff1b;其优势有&#xff1a;…

MySQL安装环境配置,工具(超详细讲解)

一、什么是MySQL MySQL与SQL server一样都是关系型数据库管理系统&#xff0c;起初它是由瑞典的MySQL AB公司开发的&#xff0c;该公司于2008年被Sun公司收购。之后&#xff0c;Sun公司在2009年被Oracle公司收购。现在MySQL是Oracle公司的重要产品之一。 1、MySQL版本 针对不…

python实战之基础篇(二)

一. 定义函数 二. 调用函数 1. 使用位置参数调用函数 2. 使用关键字参数调用函数 三. 参数的默认值 四. 可变参数 1. 基于元组的可变参数 2. 基于字典的可变参数 五. 函数中变量的作用域 global 可以将局部变量提升为全局变量 六. 过滤函数filter() 七. 映射函数map() 八. la…

Elasticsearch 和 Kibana 8.13:简化 kNN 和改进查询并行化

作者&#xff1a;Gilad Gal, Tyler Perkins, Srikanth Manvi, Aris Papadopoulos, Trevor Blackford 在 8.13 版本中&#xff0c;Elastic 引入了向量搜索的重大增强&#xff0c;并将 Cohere 嵌入集成到其统一 inference API 中。这些更新简化了将大型语言模型&#xff08;LLM&a…

【阿里近100人+花27.1万造的】中文医学数据集 ChineseBLUE 分析

中文医学数据集 ChineseBLUE 分析 基本介绍数据集分类构造成本 论文&#xff1a;https://arxiv.org/pdf/2106.08087v5.pdf 链接&#xff1a;https://github.com/alibaba-research/ChineseBLUE 基本介绍 需要注意的是&#xff0c;中文生物医学文本在语言上与英文不同&#xf…