赞
踩
- `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
- `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*B
- parameter 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;
- generate
- if (MODE) begin
- reg 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 = 171
- always @(posedge clk) begin
- if (reset) begin
- valid_d1 <= 'b0;
- RGB_avr <= 'b0;
- end else begin
- valid_d1 <= valid_i;
- RGB_avr <= R + G + B;
- end
- end
- //最大值不可能超过255*3*171 = 17'd130815
- always @(posedge clk) begin
- RGB_avr_m <= RGB_avr * 8'd171;
- end
- always @(posedge clk) begin
- if (reset) begin
- valid_d2 <= 'b0;
- end else begin
- valid_d2 <= valid_d1;
- end
- end
-
- //最大值不可能超过255
- always @(posedge clk) begin
- if (reset) begin
- valid_d3 <= 'b0;
- RGB_new <= 'b0;
- end else begin
- valid_d3 <= valid_d2;
- RGB_new <= RGB_avr_m[16:9];
- end
- end
-
- assign 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) begin
- Y_R_m <= R * C0;
- Y_G_m <= G * C1;
- Y_B_m <= B * C2;
- end
-
- always @(posedge clk) begin
- if (reset) begin
- valid_d1 <= 0;
- end else begin
- valid_d1 <= valid_i;
- end
- end
-
- always @(posedge clk) begin
- if (reset) begin
- Y_s <= 0;
- valid_d2 <= 0;
- end else begin
- if (valid_d1) begin
- Y_s <= Y_R_m + Y_G_m + Y_B_m;
- end
- valid_d2 <= valid_d1;
- end
- end
-
- always @(posedge clk) begin
- if (reset) begin
- Y <= 0;
- valid_d3 <= 0;
- end else begin
- if (valid_d2) begin
- Y <= Y_s[17:10];
- end
- valid_d3 <= valid_d2;
- end
- end
-
- assign valid_o = valid_d3;
- assign img_data_o = Y;
-
- end
- endgenerate
-
-
- endmodule
- `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即可
- generate
- for (i = 1; i < N; i = i + 1) begin : lb
-
- line_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])
- );
- end
- endgenerate
-
- //模式1,按照上一行、当前行、下一行输出
- //特殊情况,可根据需求设定,是复制还是给0
- //第1个行缓存,是整个画面的第1行时, 上一行数据不存在,复制第1个行缓存或者直接为0输出
- //第1个行缓存,是整个画面的最后1行时,下一行数据不存在,复制第1个行缓存输出
- always @(posedge clk) begin
- if (reset) begin
- for (j = 0; j < 3; j = j + 1) ch_data[j] <= 0;
- end else if (valid[N-2]) begin
- ch_data[1] <= data[1];
- if (out_line_cnt == 0) begin
- ch_data[2] <= 0;
- ch_data[0] <= data[0];
- end else if (out_line_cnt == img_height - 1) begin
- ch_data[2] <= data[2];
- ch_data[0] <= 0;
- end else begin
- ch_data[2] <= data[2];
- ch_data[0] <= data[0];
- end
- end
- end
-
-
- always @(posedge clk) begin
- if (reset) begin
- ch_valid <= 0;
- out_data_cnt <= 0;
- out_line_cnt <= 0;
- end else begin
- ch_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;
- end
- end
-
- //单路输出
- always @(posedge clk) begin
- if (reset) begin
- valid_o <= 0;
- prev_line_data_o <= 0;
- cur_line_data_o <= 0;
- next_line_data_o <= 0;
- end else begin
- valid_o <= ch_valid;
- prev_line_data_o <= ch_data[2];
- cur_line_data_o <= ch_data[1];
- next_line_data_o <= ch_data[0];
- end
- end
-
-
- endmodule
- `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) begin
- if (reset) begin
- wr_data_cnt <= 0;
- end else begin
- wr_data_cnt <= valid_i && (wr_data_cnt < img_width) ? (wr_data_cnt + 1'b1) : wr_data_cnt;
- end
- end
- //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;
- generate
- if (W == 8) begin
- fifo_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 begin
- fifo_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
- );
- end
- endgenerate
- endmodule
- `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) begin
- if (reset) begin
- valid_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 begin
- valid_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;
- end
- end
-
- //边界数据处理
- always @(posedge clk) begin
- if (reset) begin
- x_cnt <= 0;
- end else begin
- x_cnt <= valid_d1 ? ((x_cnt == img_width - 1) ? 0 : x_cnt + 1) : x_cnt;
- end
- end
-
- always @(posedge clk) begin
- if (reset) begin
- valid_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 begin
- valid_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) begin
- prev_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;
- end
- if (x_cnt == img_width - 1) begin
- prev_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 begin
- prev_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;
- end
- end
- end
-
- assign 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) begin
- if (reset) begin
- valid_s_d1 <= 0;
- {Y_sum0, Y_sum1, Y_sum2} <= 0;
- end else if (valid_s) begin
- valid_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 + 1
- always @(posedge clk) begin
- if (reset) begin
- valid_s_d2 <= 0;
- Y_sum <= 0;
- end else if (valid_s_d1) begin
- valid_s_d2 <= 1;
- Y_sum <= Y_sum0 + Y_sum1 + Y_sum2;
- end else valid_s_d2 <= 0;
- end
- always @(posedge clk) begin
- if (reset) begin
- valid_o <= 0;
- img_data_o <= 0;
- end else if (valid_s_d2) begin
- valid_o <= 1;
- img_data_o <= Y_sum[11:4];
- end else begin
- valid_o <= 0;
- end
- end
- endmodule
- `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) begin
- if (reset) begin
- valid_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 begin
- valid_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;
- end
- end
-
- //边界数据处理
- always @(posedge clk) begin
- if (reset) begin
- x_cnt <= 0;
- end else begin
- x_cnt <= valid_d1 ? ((x_cnt == img_width - 1) ? 0 : x_cnt + 1) : x_cnt;
- end
- end
-
- always @(posedge clk) begin
- if (reset) begin
- valid_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 begin
- valid_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) begin
- prev_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;
- end
- if (x_cnt == img_width - 1) begin
- prev_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 begin
- prev_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;
- end
- end
- end
-
- assign 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) begin
- if (reset) begin
- valid_s_d1 <= 0;
- {Gx_Y, Gy_Y} <= 0;
- {Gx_Y_sign, Gy_Y_sign} <= 0;
- end else if (valid_s) begin
- valid_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) begin
- if (reset) begin
- valid_s_d2 <= 0;
- Gx_Y_square <= 0;
- Gy_Y_square <= 0;
- end else begin
- valid_s_d2 <= valid_s_d1;
- Gx_Y_square <= Gx_Y * Gx_Y;
- Gy_Y_square <= Gy_Y * Gy_Y;
- end
- end
- assign 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) begin
- if (reset) begin
- Gx_Y_sign_shift <= 0;
- Gx_Y_shift <= 0;
- Gy_Y_sign_shift <= 0;
- Gy_Y_shift <= 0;
- end else begin
- Gx_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};
- end
- end
-
- always @(posedge clk) begin
- if (reset) begin
- valid_o <= 0;
- grad_mag <= 0;
- grad_dx <= 0;
- grad_dy <= 0;
- end else if (valid_sqr) begin
- valid_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 begin
- valid_o <= 0;
- end
- end
-
- endmodule
- `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) begin
- if (reset) begin
- valid_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 begin
- valid_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;
- end
- end
-
- //边界数据处理
- always @(posedge clk) begin
- if (reset) begin
- x_cnt <= 0;
- end else begin
- x_cnt <= valid_d1 ? ((x_cnt == img_width - 1) ? 0 : x_cnt + 1) : x_cnt;
- end
- end
-
- always @(posedge clk) begin
- if (reset) begin
- valid_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 begin
- valid_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) begin
- prev_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;
- end
- if (x_cnt == img_width - 1) begin
- prev_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 begin
- prev_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;
- end
- end
- end
-
- assign 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) begin
- if (reset) begin
- {grad_dx_sign, grad_dx_abs} <= 0;
- {grad_dy_sign, grad_dy_abs} <= 0;
- end else begin
- grad_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];
- end
- end
-
- //计算模式
- always @(posedge clk) begin
- if (reset) begin
- mode <= 0;
- {dividend, divisor} <= 0;
- end else begin
- if (grad_dx_abs > grad_dy_abs) begin
- mode <= (grad_dx_sign ^ grad_dy_sign) ? 0 : 1;
- dividend <= grad_dy_abs;
- divisor <= grad_dx_abs;
- end else begin
- mode <= (grad_dx_sign ^ grad_dy_sign) ? 2 : 3;
- dividend <= grad_dx_abs;
- divisor <= grad_dy_abs;
- end
- end
- end
-
- //除法计算
- 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) begin
- if (reset) begin
- mode_shift <= 0;
- Y_shift <= 0;
- end else begin
- mode_shift <= {mode_shift, mode};
- Y_shift <= {Y_shift, Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8};
- end
- end
-
- assign 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) begin
- if (reset) begin
- div_valid_d1 <= 0;
- weight <= 0;
- one_sub_weight <= 0;
- Y4_s_d1 <= 0;
- {grad1, grad2, grad3, grad4} <= 0;
- end else begin
- div_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: begin
- grad1 <= Y7_s;
- grad2 <= Y1_s;
- grad3 <= Y8_s;
- grad4 <= Y0_s;
- end
- 1: begin
- grad1 <= Y7_s;
- grad2 <= Y1_s;
- grad3 <= Y6_s;
- grad4 <= Y2_s;
- end
- 2: begin
- grad1 <= Y5_s;
- grad2 <= Y3_s;
- grad3 <= Y8_s;
- grad4 <= Y0_s;
- end
- 3: begin
- grad1 <= Y5_s;
- grad2 <= Y3_s;
- grad3 <= Y6_s;
- grad4 <= Y2_s;
- end
- endcase
- end
- end
-
- //计算极值t1\t2
- always @(posedge clk) begin
- if (reset) begin
- div_valid_d2 <= 0;
- Y4_s_d2 <= 0;
- {grad1_m, grad2_m, grad3_m, grad4_m} <= 0;
- end else begin
- div_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;
- end
- end
-
- assign t1 = grad1_m + grad3_m;
- assign t2 = grad2_m + grad4_m;
-
- //超过极值后,赋值为0
- always @(posedge clk) begin
- if (reset) begin
- valid_o <= 0;
- img_data_o <= 0;
- end else if (div_valid_d2) begin
- valid_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 begin
- valid_o <= 0;
- end
- end
-
- endmodule
- `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) begin
- if (reset) begin
- valid_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 begin
- valid_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;
- end
- end
-
- //边界数据处理
- always @(posedge clk) begin
- if (reset) begin
- x_cnt <= 0;
- end else begin
- x_cnt <= valid_d1 ? ((x_cnt == img_width - 1) ? 0 : x_cnt + 1) : x_cnt;
- end
- end
-
- always @(posedge clk) begin
- if (reset) begin
- valid_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 begin
- valid_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) begin
- prev_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;
- end
- if (x_cnt == img_width - 1) begin
- prev_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 begin
- prev_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;
- end
- end
- end
-
- assign 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) begin
- if (reset) begin
- valid_o <= 0;
- img_data_o <= 0;
- end else if (valid_s) begin
- valid_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 begin
- valid_o <= 0;
- end
- end
-
- endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。