当前位置:   article > 正文

FPGA 图像边缘检测(Canny算子)_基于fpga的canny算法的边缘检测

基于fpga的canny算法的边缘检测

1 顶层代码

  1. `timescale 1ns / 1ps
  2. //边缘检测二阶微分算子:canny算子
  3. module image_canny_edge_detect (
  4. input clk,
  5. input reset, //复位高电平有效
  6. input [10:0] img_width,
  7. input [ 9:0] img_height,
  8. input [ 7:0] low_threshold,
  9. input [ 7:0] high_threshold,
  10. input valid_i,
  11. input [15:0] rgb_565_i, // 输入的16位RGB图像数据
  12. output valid_o,
  13. output [15:0] rgb_565_o // 输出的16位RGB图像数据
  14. );
  15. //变量声明
  16. wire valid_gray;
  17. wire [7:0] img_data_gray;
  18. wire valid_gf;
  19. wire [7:0] img_data_gf;
  20. wire valid_sbl;
  21. wire [7:0] grad_mag;
  22. wire [10:0] grad_dx;
  23. wire [10:0] grad_dy;
  24. wire valid_nms;
  25. wire [7:0] img_data_nms;
  26. wire valid_db;
  27. wire [7:0] img_data_db;
  28. wire [23:0] img_data_i, img_data_o;
  29. 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};
  30. assign rgb_565_o = {{img_data_o[23:19], img_data_o[15:10], img_data_o[7:3]}};
  31. //彩色图像灰度化
  32. image_rgb2gray u_image_rgb2gray (
  33. .clk (clk),
  34. .reset (reset),
  35. .valid_i (valid_i),
  36. .img_data_i(img_data_i),
  37. .valid_o (valid_gray),
  38. .img_data_o(img_data_gray)
  39. );
  40. ///高斯滤波
  41. image_gaussian_filter u_image_gaussian_filter (
  42. .clk (clk),
  43. .reset (reset),
  44. .img_width (img_width),
  45. .img_height(img_height),
  46. .valid_i (valid_gray),
  47. .img_data_i(img_data_gray),
  48. .valid_o (valid_gf),
  49. .img_data_o(img_data_gf)
  50. );
  51. ///Sobel算子
  52. image_sobel_edge u_image_sobel_edge (
  53. .clk (clk),
  54. .reset (reset),
  55. .img_width (img_width),
  56. .img_height(img_height),
  57. .valid_i (valid_gf),
  58. .img_data_i(img_data_gf),
  59. .valid_o (valid_sbl),
  60. .grad_mag (grad_mag),
  61. .grad_dx (grad_dx),
  62. .grad_dy (grad_dy)
  63. );
  64. ///非极大值计算
  65. non_maximum_suppression u_non_maximum_suppression (
  66. .clk (clk),
  67. .reset (reset),
  68. .img_width (img_width),
  69. .img_height(img_height),
  70. .valid_i (valid_sbl),
  71. .grad_mag (grad_mag),
  72. .grad_dx (grad_dx),
  73. .grad_dy (grad_dy),
  74. .valid_o (valid_nms),
  75. .img_data_o(img_data_nms)
  76. );
  77. 双阈值
  78. //根据输入的低阈值和高阈值来判断,如果这个像素点大于高阈值,则赋值为255;如果低于低阈值,则赋值为0;
  79. double_threshold u_double_threshold (
  80. .clk (clk),
  81. .reset (reset),
  82. .img_width (img_width),
  83. .img_height (img_height),
  84. .low_threshold (low_threshold),
  85. .high_threshold(high_threshold),
  86. .valid_i (valid_nms),
  87. .img_data_i (img_data_nms),
  88. .valid_o (valid_db),
  89. .img_data_o (img_data_db)
  90. );
  91. assign valid_o = valid_db;
  92. assign img_data_o = {3{img_data_db}};
  93. endmodule

2 彩色图变灰度图代码

  1. `timescale 1ns / 1ps
  2. //彩色图像灰度化
  3. module image_rgb2gray (
  4. input clk,
  5. input reset,
  6. input valid_i,
  7. input [23:0] img_data_i,
  8. output valid_o,
  9. output [7:0] img_data_o
  10. );
  11. //常量
  12. parameter MODE = 0; //0表示加权平均法,1表示平均法
  13. //Y=0.299*R十0.587*G+0.114*B
  14. parameter C0 = 9'd306; //0.299*1024;
  15. parameter C1 = 10'd601; //0.587*1024;
  16. parameter C2 = 7'd117; //0.114*1024;
  17. //参数声明
  18. wire [7:0] R, G, B;
  19. assign {R, G, B} = img_data_i;
  20. generate
  21. if (MODE) begin
  22. reg valid_d1;
  23. reg [9:0] RGB_avr;
  24. reg valid_d2;
  25. reg [16:0] RGB_avr_m;
  26. reg valid_d3;
  27. reg [7:0] RGB_new;
  28. //平均法
  29. //1/3 * 512 = 171
  30. always @(posedge clk) begin
  31. if (reset) begin
  32. valid_d1 <= 'b0;
  33. RGB_avr <= 'b0;
  34. end else begin
  35. valid_d1 <= valid_i;
  36. RGB_avr <= R + G + B;
  37. end
  38. end
  39. //最大值不可能超过255*3*171 = 17'd130815
  40. always @(posedge clk) begin
  41. RGB_avr_m <= RGB_avr * 8'd171;
  42. end
  43. always @(posedge clk) begin
  44. if (reset) begin
  45. valid_d2 <= 'b0;
  46. end else begin
  47. valid_d2 <= valid_d1;
  48. end
  49. end
  50. //最大值不可能超过255
  51. always @(posedge clk) begin
  52. if (reset) begin
  53. valid_d3 <= 'b0;
  54. RGB_new <= 'b0;
  55. end else begin
  56. valid_d3 <= valid_d2;
  57. RGB_new <= RGB_avr_m[16:9];
  58. end
  59. end
  60. assign valid_o = valid_d3;
  61. assign img_data_o = {3{RGB_new}};
  62. end else begin
  63. //加权平均法
  64. reg valid_d1;
  65. reg [16:0] Y_R_m;
  66. reg [17:0] Y_G_m;
  67. reg [14:0] Y_B_m;
  68. reg valid_d2;
  69. reg [17:0] Y_s;//最大值,当RGB都等于255时,(C0 + C1 + C2)*255 = 1024*255;不会出现负数
  70. reg valid_d3;
  71. reg [7:0] Y;
  72. always @(posedge clk) begin
  73. Y_R_m <= R * C0;
  74. Y_G_m <= G * C1;
  75. Y_B_m <= B * C2;
  76. end
  77. always @(posedge clk) begin
  78. if (reset) begin
  79. valid_d1 <= 0;
  80. end else begin
  81. valid_d1 <= valid_i;
  82. end
  83. end
  84. always @(posedge clk) begin
  85. if (reset) begin
  86. Y_s <= 0;
  87. valid_d2 <= 0;
  88. end else begin
  89. if (valid_d1) begin
  90. Y_s <= Y_R_m + Y_G_m + Y_B_m;
  91. end
  92. valid_d2 <= valid_d1;
  93. end
  94. end
  95. always @(posedge clk) begin
  96. if (reset) begin
  97. Y <= 0;
  98. valid_d3 <= 0;
  99. end else begin
  100. if (valid_d2) begin
  101. Y <= Y_s[17:10];
  102. end
  103. valid_d3 <= valid_d2;
  104. end
  105. end
  106. assign valid_o = valid_d3;
  107. assign img_data_o = Y;
  108. end
  109. endgenerate
  110. endmodule

3 3行缓存代码

  1. `timescale 1ns / 1ps
  2. //FIFO实现3行图像缓存
  3. module image_line_buffer #(
  4. parameter W = 8
  5. ) (
  6. input wire clk,
  7. input wire reset,
  8. input wire [10:0] img_width,
  9. input wire [ 9:0] img_height,
  10. input wire valid_i,
  11. input wire [W-1:0] img_data_i,
  12. output reg valid_o,
  13. output reg [W-1:0] prev_line_data_o,
  14. output reg [W-1:0] cur_line_data_o,
  15. output reg [W-1:0] next_line_data_o
  16. );
  17. //常量声明
  18. localparam N = 3; //窗口大小
  19. //变量声明
  20. genvar i;
  21. integer j;
  22. wire [0:0] valid[0:N-1];
  23. wire [W-1:0] data[0:N-1];
  24. reg [10:0] out_data_cnt;
  25. reg [9:0] out_line_cnt;
  26. reg ch_valid;
  27. reg [W-1:0] ch_data[0:N-1];
  28. assign valid[0] = valid_i;
  29. assign data[0] = img_data_i;
  30. //行缓存模块, 只需要缓存N-1个fifo即可
  31. generate
  32. for (i = 1; i < N; i = i + 1) begin : lb
  33. line_buffer #(
  34. .W(W)
  35. ) u_line_buffer (
  36. .clk (clk),
  37. .reset (reset),
  38. .img_width(img_width),
  39. .valid_i (valid[i-1]),
  40. .data_i (data[i-1]),
  41. .valid_o (valid[i]),
  42. .data_o (data[i])
  43. );
  44. end
  45. endgenerate
  46. //模式1,按照上一行、当前行、下一行输出
  47. //特殊情况,可根据需求设定,是复制还是给0
  48. //1个行缓存,是整个画面的第1行时, 上一行数据不存在,复制第1个行缓存或者直接为0输出
  49. //1个行缓存,是整个画面的最后1行时,下一行数据不存在,复制第1个行缓存输出
  50. always @(posedge clk) begin
  51. if (reset) begin
  52. for (j = 0; j < 3; j = j + 1) ch_data[j] <= 0;
  53. end else if (valid[N-2]) begin
  54. ch_data[1] <= data[1];
  55. if (out_line_cnt == 0) begin
  56. ch_data[2] <= 0;
  57. ch_data[0] <= data[0];
  58. end else if (out_line_cnt == img_height - 1) begin
  59. ch_data[2] <= data[2];
  60. ch_data[0] <= 0;
  61. end else begin
  62. ch_data[2] <= data[2];
  63. ch_data[0] <= data[0];
  64. end
  65. end
  66. end
  67. always @(posedge clk) begin
  68. if (reset) begin
  69. ch_valid <= 0;
  70. out_data_cnt <= 0;
  71. out_line_cnt <= 0;
  72. end else begin
  73. ch_valid <= valid[N-2];
  74. out_data_cnt <= valid[N-2] ? ((out_data_cnt == img_width - 1) ? 0 : out_data_cnt + 1) : out_data_cnt;
  75. 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;
  76. end
  77. end
  78. //单路输出
  79. always @(posedge clk) begin
  80. if (reset) begin
  81. valid_o <= 0;
  82. prev_line_data_o <= 0;
  83. cur_line_data_o <= 0;
  84. next_line_data_o <= 0;
  85. end else begin
  86. valid_o <= ch_valid;
  87. prev_line_data_o <= ch_data[2];
  88. cur_line_data_o <= ch_data[1];
  89. next_line_data_o <= ch_data[0];
  90. end
  91. end
  92. endmodule

4 1行缓存代码

  1. `timescale 1ns / 1ps
  2. //FIFO实现1行图像缓存
  3. module line_buffer #(
  4. parameter W = 8
  5. ) (
  6. input wire clk,
  7. input wire reset,
  8. input wire [10:0] img_width,
  9. input wire valid_i,
  10. input wire [W-1:0] data_i,
  11. output wire valid_o,
  12. output wire [W-1:0] data_o
  13. );
  14. //变量声明
  15. reg [10:0] wr_data_cnt;
  16. wire rd_en;
  17. wire [11:0] fifo_data_count_w;
  18. //写入数据计数
  19. always @(posedge clk or posedge reset) begin
  20. if (reset) begin
  21. wr_data_cnt <= 0;
  22. end else begin
  23. wr_data_cnt <= valid_i && (wr_data_cnt < img_width) ? (wr_data_cnt + 1'b1) : wr_data_cnt;
  24. end
  25. end
  26. //assign rd_en = valid_i&&(wr_data_cnt == img_width) ? 1'b1 : 1'b0;
  27. //等价于
  28. assign rd_en = valid_i && (fifo_data_count_w == img_width) ? 1'b1 : 1'b0;
  29. assign valid_o = rd_en;
  30. generate
  31. if (W == 8) begin
  32. fifo_line_buffer_w8 u_fifo_line_buffer_w8 (
  33. .clk (clk), // input wire clk
  34. .srst (reset), // input wire srst
  35. .din (data_i), // input wire [7 : 0] din
  36. .wr_en (valid_i), // input wire wr_en
  37. .rd_en (rd_en), // input wire rd_en
  38. .dout (data_o), // output wire [7 : 0] dout
  39. .full (), // output wire full
  40. .empty (), // output wire empty
  41. .data_count(fifo_data_count_w) // output wire [11 : 0] data_count
  42. );
  43. end else begin
  44. fifo_line_buffer u_fifo_line_buffer (
  45. .clk (clk), // input wire clk
  46. .srst (reset), // input wire srst
  47. .din (data_i), // input wire [22 : 0] din
  48. .wr_en (valid_i), // input wire wr_en
  49. .rd_en (rd_en), // input wire rd_en
  50. .dout (data_o), // output wire [22 : 0] dout
  51. .full (), // output wire full
  52. .empty (), // output wire empty
  53. .data_count(fifo_data_count_w) // output wire [11 : 0] data_count
  54. );
  55. end
  56. endgenerate
  57. endmodule

 

 

 

 

5 高斯滤波代码

  1. `timescale 1ns / 1ps
  2. // 高斯滤波
  3. module image_gaussian_filter (
  4. input wire clk,
  5. input wire reset,
  6. input wire [10:0] img_width,
  7. input wire [ 9:0] img_height,
  8. input wire valid_i,
  9. input wire [7:0] img_data_i,
  10. output reg valid_o,
  11. output reg [7:0] img_data_o
  12. );
  13. //常量声明
  14. localparam MODE = 1; //0表示彩色图像输出,1表示灰度图像输出
  15. //变量声明
  16. wire valid;
  17. wire [7:0] prev_line_data;
  18. wire [7:0] cur_line_data;
  19. wire [7:0] next_line_data;
  20. reg valid_d1;
  21. reg [7:0] prev_line_data_d1;
  22. reg [7:0] cur_line_data_d1;
  23. reg [7:0] next_line_data_d1;
  24. reg [7:0] prev_line_data_d2;
  25. reg [7:0] cur_line_data_d2;
  26. reg [7:0] next_line_data_d2;
  27. reg [7:0] x_cnt;
  28. reg valid_s;
  29. reg [7:0] prev_line_data_d2_s;
  30. reg [7:0] cur_line_data_d2_s;
  31. reg [7:0] next_line_data_d2_s;
  32. reg [7:0] prev_line_data_d1_s;
  33. reg [7:0] cur_line_data_d1_s;
  34. reg [7:0] next_line_data_d1_s;
  35. reg [7:0] prev_line_data_s;
  36. reg [7:0] cur_line_data_s;
  37. reg [7:0] next_line_data_s;
  38. wire [7:0] Y0, Y1, Y2;
  39. wire [7:0] Y3, Y4, Y5;
  40. wire [7:0] Y6, Y7, Y8;
  41. reg valid_s_d1;
  42. reg [9:0] Y_sum0;
  43. reg [10:0] Y_sum1;
  44. reg [9:0] Y_sum2;
  45. reg valid_s_d2;
  46. reg [14:0] Y_sum;
  47. wire [15:0] RGB_sum;
  48. wire [7:0] gray;
  49. image_line_buffer u_image_line_buffer (
  50. .clk (clk),
  51. .reset (reset),
  52. .img_width (img_width),
  53. .img_height (img_height),
  54. .valid_i (valid_i),
  55. .img_data_i (img_data_i),
  56. .valid_o (valid),
  57. .prev_line_data_o(prev_line_data),
  58. .cur_line_data_o (cur_line_data),
  59. .next_line_data_o(next_line_data)
  60. );
  61. always @(posedge clk) begin
  62. if (reset) begin
  63. valid_d1 <= 0;
  64. prev_line_data_d1 <= 0;
  65. cur_line_data_d1 <= 0;
  66. next_line_data_d1 <= 0;
  67. prev_line_data_d2 <= 0;
  68. cur_line_data_d2 <= 0;
  69. next_line_data_d2 <= 0;
  70. end else begin
  71. valid_d1 <= valid;
  72. prev_line_data_d1 <= prev_line_data;
  73. cur_line_data_d1 <= cur_line_data;
  74. next_line_data_d1 <= next_line_data;
  75. prev_line_data_d2 <= prev_line_data_d1;
  76. cur_line_data_d2 <= cur_line_data_d1;
  77. next_line_data_d2 <= next_line_data_d1;
  78. end
  79. end
  80. //边界数据处理
  81. always @(posedge clk) begin
  82. if (reset) begin
  83. x_cnt <= 0;
  84. end else begin
  85. x_cnt <= valid_d1 ? ((x_cnt == img_width - 1) ? 0 : x_cnt + 1) : x_cnt;
  86. end
  87. end
  88. always @(posedge clk) begin
  89. if (reset) begin
  90. valid_s <= 0;
  91. prev_line_data_d2_s <= 0;
  92. cur_line_data_d2_s <= 0;
  93. next_line_data_d2_s <= 0;
  94. prev_line_data_d1_s <= 0;
  95. cur_line_data_d1_s <= 0;
  96. next_line_data_d1_s <= 0;
  97. prev_line_data_s <= 0;
  98. cur_line_data_s <= 0;
  99. next_line_data_s <= 0;
  100. end else begin
  101. valid_s <= valid_d1;
  102. prev_line_data_d1_s <= prev_line_data_d1;
  103. cur_line_data_d1_s <= cur_line_data_d1;
  104. next_line_data_d1_s <= next_line_data_d1;
  105. if (x_cnt == 0) begin
  106. prev_line_data_d2_s <= prev_line_data_d1;
  107. cur_line_data_d2_s <= cur_line_data_d1;
  108. next_line_data_d2_s <= next_line_data_d1;
  109. prev_line_data_s <= prev_line_data;
  110. cur_line_data_s <= cur_line_data;
  111. next_line_data_s <= next_line_data;
  112. end
  113. if (x_cnt == img_width - 1) begin
  114. prev_line_data_d2_s <= prev_line_data_d2;
  115. cur_line_data_d2_s <= cur_line_data_d2;
  116. next_line_data_d2_s <= next_line_data_d2;
  117. prev_line_data_s <= prev_line_data_d1;
  118. cur_line_data_s <= cur_line_data_d1;
  119. next_line_data_s <= next_line_data_d1;
  120. end else begin
  121. prev_line_data_d2_s <= prev_line_data_d2;
  122. cur_line_data_d2_s <= cur_line_data_d2;
  123. next_line_data_d2_s <= next_line_data_d2;
  124. prev_line_data_s <= prev_line_data;
  125. cur_line_data_s <= cur_line_data;
  126. next_line_data_s <= next_line_data;
  127. end
  128. end
  129. end
  130. assign Y0 = prev_line_data_d2_s;
  131. assign Y1 = cur_line_data_d2_s;
  132. assign Y2 = next_line_data_d2_s;
  133. assign Y3 = prev_line_data_d1_s;
  134. assign Y4 = cur_line_data_d1_s;
  135. assign Y5 = next_line_data_d1_s;
  136. assign Y6 = prev_line_data_s;
  137. assign Y7 = cur_line_data_s;
  138. assign Y8 = next_line_data_s;
  139. //高斯滤波模版
  140. /************
  141. [1. 2. 1.]
  142. [2. 4. 2.]
  143. [1. 2. 1.]
  144. *************/
  145. always @(posedge clk) begin
  146. if (reset) begin
  147. valid_s_d1 <= 0;
  148. {Y_sum0, Y_sum1, Y_sum2} <= 0;
  149. end else if (valid_s) begin
  150. valid_s_d1 <= 1;
  151. Y_sum0 <= Y0 + {Y1, 1'b0} + Y2;
  152. Y_sum1 <= {Y3, 1'b0} + {Y4, 2'b0} + {Y5, 1'b0};
  153. Y_sum2 <= Y6 + {Y7, 1'b0} + Y8;
  154. end else valid_s_d1 <= 0;
  155. end
  156. //彩色图像 直接求和
  157. //灰度图像 1/3,扩大4bit,即16/3约等于5 = 4 + 1
  158. always @(posedge clk) begin
  159. if (reset) begin
  160. valid_s_d2 <= 0;
  161. Y_sum <= 0;
  162. end else if (valid_s_d1) begin
  163. valid_s_d2 <= 1;
  164. Y_sum <= Y_sum0 + Y_sum1 + Y_sum2;
  165. end else valid_s_d2 <= 0;
  166. end
  167. always @(posedge clk) begin
  168. if (reset) begin
  169. valid_o <= 0;
  170. img_data_o <= 0;
  171. end else if (valid_s_d2) begin
  172. valid_o <= 1;
  173. img_data_o <= Y_sum[11:4];
  174. end else begin
  175. valid_o <= 0;
  176. end
  177. end
  178. endmodule

6 sobel边缘检测代码

  1. `timescale 1ns / 1ps
  2. //边缘检测一阶微分算子:Sobel算子
  3. module image_sobel_edge (
  4. input wire clk,
  5. input wire reset,
  6. input wire [10:0] img_width,
  7. input wire [ 9:0] img_height,
  8. input wire valid_i,
  9. input wire [7:0] img_data_i,
  10. output reg valid_o,
  11. output reg [7:0] grad_mag,
  12. output reg [10:0] grad_dx,
  13. output reg [10:0] grad_dy
  14. );
  15. //常量声明
  16. localparam N = 16;
  17. //变量声明
  18. wire valid;
  19. wire [7:0] prev_line_data;
  20. wire [7:0] cur_line_data;
  21. wire [7:0] next_line_data;
  22. reg valid_d1;
  23. reg [7:0] prev_line_data_d1;
  24. reg [7:0] cur_line_data_d1;
  25. reg [7:0] next_line_data_d1;
  26. reg [7:0] prev_line_data_d2;
  27. reg [7:0] cur_line_data_d2;
  28. reg [7:0] next_line_data_d2;
  29. reg [10:0] x_cnt;
  30. reg valid_s;
  31. reg [7:0] prev_line_data_d2_s;
  32. reg [7:0] cur_line_data_d2_s;
  33. reg [7:0] next_line_data_d2_s;
  34. reg [7:0] prev_line_data_d1_s;
  35. reg [7:0] cur_line_data_d1_s;
  36. reg [7:0] next_line_data_d1_s;
  37. reg [7:0] prev_line_data_s;
  38. reg [7:0] cur_line_data_s;
  39. reg [7:0] next_line_data_s;
  40. wire [7:0] Y0;
  41. wire [7:0] Y1;
  42. wire [7:0] Y2;
  43. wire [7:0] Y3;
  44. wire [7:0] Y4;
  45. wire [7:0] Y5;
  46. wire [7:0] Y6;
  47. wire [7:0] Y7;
  48. wire [7:0] Y8;
  49. reg valid_s_d1;
  50. wire [9:0] Gx_Y0_a;
  51. wire [9:0] Gx_Y1_a;
  52. wire [9:0] Gy_Y0_a;
  53. wire [9:0] Gy_Y1_a;
  54. reg Gx_Y_sign;
  55. reg [9:0] Gx_Y;
  56. reg Gy_Y_sign;
  57. reg [9:0] Gy_Y;
  58. reg valid_s_d2;
  59. reg Gx_Y_sign_d1;
  60. reg [19:0] Gx_Y_square;
  61. reg Gy_Y_sign_d1;
  62. reg [19:0] Gy_Y_square;
  63. wire [20:0] Gx_Gy_sum;
  64. reg [N-1:0] Gx_Y_sign_shift;
  65. reg [10*N-1:0] Gx_Y_shift;
  66. reg [N-1:0] Gy_Y_sign_shift;
  67. reg [10*N-1:0] Gy_Y_shift;
  68. wire valid_sqr;
  69. wire [10:0] data_sqr;
  70. image_line_buffer u_image_line_buffer (
  71. .clk (clk),
  72. .reset (reset),
  73. .img_width (img_width),
  74. .img_height (img_height),
  75. .valid_i (valid_i),
  76. .img_data_i (img_data_i),
  77. .valid_o (valid),
  78. .prev_line_data_o(prev_line_data),
  79. .cur_line_data_o (cur_line_data),
  80. .next_line_data_o(next_line_data)
  81. );
  82. always @(posedge clk) begin
  83. if (reset) begin
  84. valid_d1 <= 0;
  85. prev_line_data_d1 <= 0;
  86. cur_line_data_d1 <= 0;
  87. next_line_data_d1 <= 0;
  88. prev_line_data_d2 <= 0;
  89. cur_line_data_d2 <= 0;
  90. next_line_data_d2 <= 0;
  91. end else begin
  92. valid_d1 <= valid;
  93. prev_line_data_d1 <= prev_line_data;
  94. cur_line_data_d1 <= cur_line_data;
  95. next_line_data_d1 <= next_line_data;
  96. prev_line_data_d2 <= prev_line_data_d1;
  97. cur_line_data_d2 <= cur_line_data_d1;
  98. next_line_data_d2 <= next_line_data_d1;
  99. end
  100. end
  101. //边界数据处理
  102. always @(posedge clk) begin
  103. if (reset) begin
  104. x_cnt <= 0;
  105. end else begin
  106. x_cnt <= valid_d1 ? ((x_cnt == img_width - 1) ? 0 : x_cnt + 1) : x_cnt;
  107. end
  108. end
  109. always @(posedge clk) begin
  110. if (reset) begin
  111. valid_s <= 0;
  112. prev_line_data_d2_s <= 0;
  113. cur_line_data_d2_s <= 0;
  114. next_line_data_d2_s <= 0;
  115. prev_line_data_d1_s <= 0;
  116. cur_line_data_d1_s <= 0;
  117. next_line_data_d1_s <= 0;
  118. prev_line_data_s <= 0;
  119. cur_line_data_s <= 0;
  120. next_line_data_s <= 0;
  121. end else begin
  122. valid_s <= valid_d1;
  123. prev_line_data_d1_s <= prev_line_data_d1;
  124. cur_line_data_d1_s <= cur_line_data_d1;
  125. next_line_data_d1_s <= next_line_data_d1;
  126. if (x_cnt == 0) begin
  127. prev_line_data_d2_s <= prev_line_data_d1;
  128. cur_line_data_d2_s <= cur_line_data_d1;
  129. next_line_data_d2_s <= next_line_data_d1;
  130. prev_line_data_s <= prev_line_data;
  131. cur_line_data_s <= cur_line_data;
  132. next_line_data_s <= next_line_data;
  133. end
  134. if (x_cnt == img_width - 1) begin
  135. prev_line_data_d2_s <= prev_line_data_d2;
  136. cur_line_data_d2_s <= cur_line_data_d2;
  137. next_line_data_d2_s <= next_line_data_d2;
  138. prev_line_data_s <= prev_line_data_d1;
  139. cur_line_data_s <= cur_line_data_d1;
  140. next_line_data_s <= next_line_data_d1;
  141. end else begin
  142. prev_line_data_d2_s <= prev_line_data_d2;
  143. cur_line_data_d2_s <= cur_line_data_d2;
  144. next_line_data_d2_s <= next_line_data_d2;
  145. prev_line_data_s <= prev_line_data;
  146. cur_line_data_s <= cur_line_data;
  147. next_line_data_s <= next_line_data;
  148. end
  149. end
  150. end
  151. assign Y0 = prev_line_data_d2_s;
  152. assign Y1 = cur_line_data_d2_s;
  153. assign Y2 = next_line_data_d2_s;
  154. assign Y3 = prev_line_data_d1_s;
  155. assign Y4 = cur_line_data_d1_s;
  156. assign Y5 = next_line_data_d1_s;
  157. assign Y6 = prev_line_data_s;
  158. assign Y7 = cur_line_data_s;
  159. assign Y8 = next_line_data_s;
  160. /Sobey算子
  161. /************
  162. [-1. 0. 1]
  163. [-2. 0. 2]
  164. Gx= [-1. 0. 1]
  165. [ 1. 2. 1]
  166. [ 0. 0. 0]
  167. Gy= [-1. -2. -1]
  168. *************/
  169. assign Gx_Y0_a = Y0 + {Y3, 1'b0} + Y6;
  170. assign Gx_Y1_a = Y2 + {Y5, 1'b0} + Y8;
  171. assign Gy_Y0_a = Y0 + {Y1, 1'b0} + Y2;
  172. assign Gy_Y1_a = Y6 + {Y7, 1'b0} + Y8;
  173. always @(posedge clk) begin
  174. if (reset) begin
  175. valid_s_d1 <= 0;
  176. {Gx_Y, Gy_Y} <= 0;
  177. {Gx_Y_sign, Gy_Y_sign} <= 0;
  178. end else if (valid_s) begin
  179. valid_s_d1 <= 1;
  180. Gx_Y <= (Gx_Y0_a > Gx_Y1_a) ? Gx_Y0_a - Gx_Y1_a : Gx_Y1_a - Gx_Y0_a;
  181. Gx_Y_sign <= (Gx_Y0_a > Gx_Y1_a) ? 1 : 0;
  182. Gy_Y <= (Gy_Y0_a > Gy_Y1_a) ? Gy_Y0_a - Gy_Y1_a : Gy_Y1_a - Gy_Y0_a;
  183. Gy_Y_sign <= (Gy_Y0_a > Gy_Y1_a) ? 1 : 0;
  184. end else valid_s_d1 <= 0;
  185. end
  186. //求平方
  187. always @(posedge clk) begin
  188. if (reset) begin
  189. valid_s_d2 <= 0;
  190. Gx_Y_square <= 0;
  191. Gy_Y_square <= 0;
  192. end else begin
  193. valid_s_d2 <= valid_s_d1;
  194. Gx_Y_square <= Gx_Y * Gx_Y;
  195. Gy_Y_square <= Gy_Y * Gy_Y;
  196. end
  197. end
  198. assign Gx_Gy_sum = Gx_Y_square + Gy_Y_square;
  199. //平方根
  200. cordic_square_root u_cordic_square_root (
  201. .aclk (clk), // input wire aclk
  202. .s_axis_cartesian_tvalid(valid_s_d2), // input wire s_axis_cartesian_tvalid
  203. .s_axis_cartesian_tdata (Gx_Gy_sum), // input wire [23 : 0] s_axis_cartesian_tdata
  204. .m_axis_dout_tvalid (valid_sqr), // output wire m_axis_dout_tvalid
  205. .m_axis_dout_tdata (data_sqr) // output wire [15 : 0] m_axis_dout_tdata
  206. );
  207. always @(posedge clk) begin
  208. if (reset) begin
  209. Gx_Y_sign_shift <= 0;
  210. Gx_Y_shift <= 0;
  211. Gy_Y_sign_shift <= 0;
  212. Gy_Y_shift <= 0;
  213. end else begin
  214. Gx_Y_sign_shift <= {Gx_Y_sign_shift, Gx_Y_sign};
  215. Gx_Y_shift <= {Gx_Y_shift, Gx_Y};
  216. Gy_Y_sign_shift <= {Gy_Y_sign_shift, Gy_Y_sign};
  217. Gy_Y_shift <= {Gy_Y_shift, Gy_Y};
  218. end
  219. end
  220. always @(posedge clk) begin
  221. if (reset) begin
  222. valid_o <= 0;
  223. grad_mag <= 0;
  224. grad_dx <= 0;
  225. grad_dy <= 0;
  226. end else if (valid_sqr) begin
  227. valid_o <= 1;
  228. grad_mag <= data_sqr;
  229. grad_dx <= {Gx_Y_sign_shift[N-1], Gx_Y_shift[N*10-1:(N-1)*10]};
  230. grad_dy <= {Gy_Y_sign_shift[N-1], Gy_Y_shift[N*10-1:(N-1)*10]};
  231. end else begin
  232. valid_o <= 0;
  233. end
  234. end
  235. endmodule

7 非极大值抑制代码

  1. `timescale 1ns / 1ps
  2. // 非极大值抑制
  3. module non_maximum_suppression (
  4. input clk,
  5. input reset,
  6. input wire [10:0] img_width,
  7. input wire [ 9:0] img_height,
  8. input valid_i,
  9. input [7:0] grad_mag,
  10. input [10:0] grad_dx,
  11. input [10:0] grad_dy,
  12. output reg valid_o,
  13. output reg [7:0] img_data_o
  14. );
  15. //常量
  16. localparam N = 24;
  17. //参数声明
  18. wire valid;
  19. wire [7:0] prev_line_data;
  20. wire [7:0] cur_line_data;
  21. wire [7:0] next_line_data;
  22. reg valid_d1;
  23. reg [7:0] prev_line_data_d1;
  24. reg [7:0] cur_line_data_d1;
  25. reg [7:0] next_line_data_d1;
  26. reg [7:0] prev_line_data_d2;
  27. reg [7:0] cur_line_data_d2;
  28. reg [7:0] next_line_data_d2;
  29. reg [10:0] x_cnt;
  30. reg valid_s;
  31. reg [7:0] prev_line_data_d2_s;
  32. reg [7:0] cur_line_data_d2_s;
  33. reg [7:0] next_line_data_d2_s;
  34. reg [7:0] prev_line_data_d1_s;
  35. reg [7:0] cur_line_data_d1_s;
  36. reg [7:0] next_line_data_d1_s;
  37. reg [7:0] prev_line_data_s;
  38. reg [7:0] cur_line_data_s;
  39. reg [7:0] next_line_data_s;
  40. wire [7:0] Y0, Y1, Y2;
  41. wire [7:0] Y3, Y4, Y5;
  42. wire [7:0] Y6, Y7, Y8;
  43. wire grad_valid;
  44. wire [21:0] grad_cur_line_data;
  45. reg valid_s_d1;
  46. reg grad_dx_sign;
  47. reg [9:0] grad_dx_abs;
  48. reg grad_dy_sign;
  49. reg [9:0] grad_dy_abs;
  50. reg [1:0] mode;
  51. reg [9:0] dividend, divisor;
  52. wire div_valid;
  53. wire [23:0] div_data;
  54. reg [2*N-1:0] mode_shift;
  55. wire mode_s;
  56. reg [72*N-1:0] Y_shift;
  57. wire [7:0] Y0_s, Y1_s, Y2_s;
  58. wire [7:0] Y3_s, Y4_s, Y5_s;
  59. wire [7:0] Y6_s, Y7_s, Y8_s;
  60. reg div_valid_d1;
  61. reg [7:0] grad1, grad2, grad3, grad4;
  62. reg [7:0] weight;
  63. reg [8:0] one_sub_weight;
  64. reg [7:0] Y4_s_d1;
  65. reg div_valid_d2;
  66. reg [15:0] grad1_m, grad2_m;
  67. reg [16:0] grad3_m, grad4_m;
  68. reg [7:0] Y4_s_d2;
  69. wire [16:0] t1, t2;
  70. /行视频数据缓存
  71. image_line_buffer u_image_line_buffer (
  72. .clk (clk),
  73. .reset (reset),
  74. .img_width (img_width),
  75. .img_height (img_height),
  76. .valid_i (valid_i),
  77. .img_data_i (grad_mag),
  78. .valid_o (valid),
  79. .prev_line_data_o(prev_line_data),
  80. .cur_line_data_o (cur_line_data),
  81. .next_line_data_o(next_line_data)
  82. );
  83. always @(posedge clk) begin
  84. if (reset) begin
  85. valid_d1 <= 0;
  86. prev_line_data_d1 <= 0;
  87. cur_line_data_d1 <= 0;
  88. next_line_data_d1 <= 0;
  89. prev_line_data_d2 <= 0;
  90. cur_line_data_d2 <= 0;
  91. next_line_data_d2 <= 0;
  92. end else begin
  93. valid_d1 <= valid;
  94. prev_line_data_d1 <= prev_line_data;
  95. cur_line_data_d1 <= cur_line_data;
  96. next_line_data_d1 <= next_line_data;
  97. prev_line_data_d2 <= prev_line_data_d1;
  98. cur_line_data_d2 <= cur_line_data_d1;
  99. next_line_data_d2 <= next_line_data_d1;
  100. end
  101. end
  102. //边界数据处理
  103. always @(posedge clk) begin
  104. if (reset) begin
  105. x_cnt <= 0;
  106. end else begin
  107. x_cnt <= valid_d1 ? ((x_cnt == img_width - 1) ? 0 : x_cnt + 1) : x_cnt;
  108. end
  109. end
  110. always @(posedge clk) begin
  111. if (reset) begin
  112. valid_s <= 0;
  113. prev_line_data_d2_s <= 0;
  114. cur_line_data_d2_s <= 0;
  115. next_line_data_d2_s <= 0;
  116. prev_line_data_d1_s <= 0;
  117. cur_line_data_d1_s <= 0;
  118. next_line_data_d1_s <= 0;
  119. prev_line_data_s <= 0;
  120. cur_line_data_s <= 0;
  121. next_line_data_s <= 0;
  122. end else begin
  123. valid_s <= valid_d1;
  124. prev_line_data_d1_s <= prev_line_data_d1;
  125. cur_line_data_d1_s <= cur_line_data_d1;
  126. next_line_data_d1_s <= next_line_data_d1;
  127. if (x_cnt == 0) begin
  128. prev_line_data_d2_s <= prev_line_data_d1;
  129. cur_line_data_d2_s <= cur_line_data_d1;
  130. next_line_data_d2_s <= next_line_data_d1;
  131. prev_line_data_s <= prev_line_data;
  132. cur_line_data_s <= cur_line_data;
  133. next_line_data_s <= next_line_data;
  134. end
  135. if (x_cnt == img_width - 1) begin
  136. prev_line_data_d2_s <= prev_line_data_d2;
  137. cur_line_data_d2_s <= cur_line_data_d2;
  138. next_line_data_d2_s <= next_line_data_d2;
  139. prev_line_data_s <= prev_line_data_d1;
  140. cur_line_data_s <= cur_line_data_d1;
  141. next_line_data_s <= next_line_data_d1;
  142. end else begin
  143. prev_line_data_d2_s <= prev_line_data_d2;
  144. cur_line_data_d2_s <= cur_line_data_d2;
  145. next_line_data_d2_s <= next_line_data_d2;
  146. prev_line_data_s <= prev_line_data;
  147. cur_line_data_s <= cur_line_data;
  148. next_line_data_s <= next_line_data;
  149. end
  150. end
  151. end
  152. assign Y0 = prev_line_data_d2_s;
  153. assign Y1 = cur_line_data_d2_s;
  154. assign Y2 = next_line_data_d2_s;
  155. assign Y3 = prev_line_data_d1_s;
  156. assign Y4 = cur_line_data_d1_s;
  157. assign Y5 = next_line_data_d1_s;
  158. assign Y6 = prev_line_data_s;
  159. assign Y7 = cur_line_data_s;
  160. assign Y8 = next_line_data_s;
  161. /grad_dx和grad_dy行数据缓存
  162. image_line_buffer #(
  163. .W(21)
  164. ) u_image_grad_line_buffer (
  165. .clk (clk),
  166. .reset (reset),
  167. .img_width (img_width),
  168. .img_height (img_height),
  169. .valid_i (valid_i),
  170. .img_data_i ({grad_dx, grad_dy}),
  171. .valid_o (grad_valid),
  172. .prev_line_data_o(),
  173. .cur_line_data_o (grad_cur_line_data),
  174. .next_line_data_o()
  175. );
  176. /非极大值限制计算
  177. //计算grad_dx,grad_dy绝对值
  178. always @(posedge clk) begin
  179. if (reset) begin
  180. {grad_dx_sign, grad_dx_abs} <= 0;
  181. {grad_dy_sign, grad_dy_abs} <= 0;
  182. end else begin
  183. grad_dx_sign <= grad_cur_line_data[21];
  184. grad_dx_abs <= grad_cur_line_data[20:11];
  185. grad_dy_sign <= grad_cur_line_data[10];
  186. grad_dy_abs <= grad_cur_line_data[9:0];
  187. end
  188. end
  189. //计算模式
  190. always @(posedge clk) begin
  191. if (reset) begin
  192. mode <= 0;
  193. {dividend, divisor} <= 0;
  194. end else begin
  195. if (grad_dx_abs > grad_dy_abs) begin
  196. mode <= (grad_dx_sign ^ grad_dy_sign) ? 0 : 1;
  197. dividend <= grad_dy_abs;
  198. divisor <= grad_dx_abs;
  199. end else begin
  200. mode <= (grad_dx_sign ^ grad_dy_sign) ? 2 : 3;
  201. dividend <= grad_dx_abs;
  202. divisor <= grad_dy_abs;
  203. end
  204. end
  205. end
  206. //除法计算
  207. div_gen_10x10 u_div_gen_10x10 (
  208. .aclk (clk), // input wire aclk
  209. .s_axis_divisor_tvalid (valid_s), // input wire s_axis_divisor_tvalid
  210. .s_axis_divisor_tdata ({6'b0, divisor}), // input wire [15 : 0] s_axis_divisor_tdata
  211. .s_axis_dividend_tvalid(valid_s), // input wire s_axis_dividend_tvalid
  212. .s_axis_dividend_tdata ({6'b0, dividend}), // input wire [15 : 0] s_axis_dividend_tdata
  213. .m_axis_dout_tvalid (div_valid), // output wire m_axis_dout_tvalid
  214. .m_axis_dout_tdata (div_data) // output wire [23 : 0] m_axis_dout_tdata
  215. );
  216. //同步延时
  217. always @(posedge clk) begin
  218. if (reset) begin
  219. mode_shift <= 0;
  220. Y_shift <= 0;
  221. end else begin
  222. mode_shift <= {mode_shift, mode};
  223. Y_shift <= {Y_shift, Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8};
  224. end
  225. end
  226. assign mode_s = mode_shift[2*N-1:2*(N-1)];
  227. 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)];
  228. //计算插值系数、插值数据
  229. always @(posedge clk) begin
  230. if (reset) begin
  231. div_valid_d1 <= 0;
  232. weight <= 0;
  233. one_sub_weight <= 0;
  234. Y4_s_d1 <= 0;
  235. {grad1, grad2, grad3, grad4} <= 0;
  236. end else begin
  237. div_valid_d1 <= div_valid;
  238. weight <= div_data[7:0];
  239. one_sub_weight <= 256 - div_data[7:0];
  240. Y4_s_d1 <= Y4_s;
  241. case (mode_s)
  242. 0: begin
  243. grad1 <= Y7_s;
  244. grad2 <= Y1_s;
  245. grad3 <= Y8_s;
  246. grad4 <= Y0_s;
  247. end
  248. 1: begin
  249. grad1 <= Y7_s;
  250. grad2 <= Y1_s;
  251. grad3 <= Y6_s;
  252. grad4 <= Y2_s;
  253. end
  254. 2: begin
  255. grad1 <= Y5_s;
  256. grad2 <= Y3_s;
  257. grad3 <= Y8_s;
  258. grad4 <= Y0_s;
  259. end
  260. 3: begin
  261. grad1 <= Y5_s;
  262. grad2 <= Y3_s;
  263. grad3 <= Y6_s;
  264. grad4 <= Y2_s;
  265. end
  266. endcase
  267. end
  268. end
  269. //计算极值t1\t2
  270. always @(posedge clk) begin
  271. if (reset) begin
  272. div_valid_d2 <= 0;
  273. Y4_s_d2 <= 0;
  274. {grad1_m, grad2_m, grad3_m, grad4_m} <= 0;
  275. end else begin
  276. div_valid_d2 <= div_valid_d1;
  277. Y4_s_d2 <= Y4_s_d1;
  278. grad1_m <= grad1 * weight;
  279. grad2_m <= grad2 * weight;
  280. grad3_m <= grad3 * one_sub_weight;
  281. grad4_m <= grad4 * one_sub_weight;
  282. end
  283. end
  284. assign t1 = grad1_m + grad3_m;
  285. assign t2 = grad2_m + grad4_m;
  286. //超过极值后,赋值为0
  287. always @(posedge clk) begin
  288. if (reset) begin
  289. valid_o <= 0;
  290. img_data_o <= 0;
  291. end else if (div_valid_d2) begin
  292. valid_o <= 1;
  293. img_data_o <= ({1'b0, Y4_s_d2} > t1[16:8]) && ({1'b0, Y4_s_d2} > t2[16:8]) ? Y4_s_d2 : 0;
  294. end else begin
  295. valid_o <= 0;
  296. end
  297. end
  298. endmodule

 

8 双阈值代码

  1. `timescale 1ns / 1ps
  2. //双阈值
  3. module double_threshold (
  4. input clk,
  5. input reset,
  6. input [10:0] img_width,
  7. input [ 9:0] img_height,
  8. input [ 7:0] low_threshold,
  9. input [ 7:0] high_threshold,
  10. input valid_i,
  11. input [7:0] img_data_i,
  12. output reg valid_o,
  13. output reg [7:0] img_data_o
  14. );
  15. //常量声明
  16. localparam MODE = 1; //0表示彩色图像输出,1表示灰度图像输出
  17. //变量声明
  18. wire valid;
  19. wire [7:0] prev_line_data;
  20. wire [7:0] cur_line_data;
  21. wire [7:0] next_line_data;
  22. reg valid_d1;
  23. reg [7:0] prev_line_data_d1;
  24. reg [7:0] cur_line_data_d1;
  25. reg [7:0] next_line_data_d1;
  26. reg [7:0] prev_line_data_d2;
  27. reg [7:0] cur_line_data_d2;
  28. reg [7:0] next_line_data_d2;
  29. reg [7:0] x_cnt;
  30. reg valid_s;
  31. reg [7:0] prev_line_data_d2_s;
  32. reg [7:0] cur_line_data_d2_s;
  33. reg [7:0] next_line_data_d2_s;
  34. reg [7:0] prev_line_data_d1_s;
  35. reg [7:0] cur_line_data_d1_s;
  36. reg [7:0] next_line_data_d1_s;
  37. reg [7:0] prev_line_data_s;
  38. reg [7:0] cur_line_data_s;
  39. reg [7:0] next_line_data_s;
  40. wire [7:0] Y0, Y1, Y2;
  41. wire [7:0] Y3, Y4, Y5;
  42. wire [7:0] Y6, Y7, Y8;
  43. image_line_buffer u_image_line_buffer (
  44. .clk (clk),
  45. .reset (reset),
  46. .img_width (img_width),
  47. .img_height (img_height),
  48. .valid_i (valid_i),
  49. .img_data_i (img_data_i),
  50. .valid_o (valid),
  51. .prev_line_data_o(prev_line_data),
  52. .cur_line_data_o (cur_line_data),
  53. .next_line_data_o(next_line_data)
  54. );
  55. always @(posedge clk) begin
  56. if (reset) begin
  57. valid_d1 <= 0;
  58. prev_line_data_d1 <= 0;
  59. cur_line_data_d1 <= 0;
  60. next_line_data_d1 <= 0;
  61. prev_line_data_d2 <= 0;
  62. cur_line_data_d2 <= 0;
  63. next_line_data_d2 <= 0;
  64. end else begin
  65. valid_d1 <= valid;
  66. prev_line_data_d1 <= prev_line_data;
  67. cur_line_data_d1 <= cur_line_data;
  68. next_line_data_d1 <= next_line_data;
  69. prev_line_data_d2 <= prev_line_data_d1;
  70. cur_line_data_d2 <= cur_line_data_d1;
  71. next_line_data_d2 <= next_line_data_d1;
  72. end
  73. end
  74. //边界数据处理
  75. always @(posedge clk) begin
  76. if (reset) begin
  77. x_cnt <= 0;
  78. end else begin
  79. x_cnt <= valid_d1 ? ((x_cnt == img_width - 1) ? 0 : x_cnt + 1) : x_cnt;
  80. end
  81. end
  82. always @(posedge clk) begin
  83. if (reset) begin
  84. valid_s <= 0;
  85. prev_line_data_d2_s <= 0;
  86. cur_line_data_d2_s <= 0;
  87. next_line_data_d2_s <= 0;
  88. prev_line_data_d1_s <= 0;
  89. cur_line_data_d1_s <= 0;
  90. next_line_data_d1_s <= 0;
  91. prev_line_data_s <= 0;
  92. cur_line_data_s <= 0;
  93. next_line_data_s <= 0;
  94. end else begin
  95. valid_s <= valid_d1;
  96. prev_line_data_d1_s <= prev_line_data_d1;
  97. cur_line_data_d1_s <= cur_line_data_d1;
  98. next_line_data_d1_s <= next_line_data_d1;
  99. if (x_cnt == 0) begin
  100. prev_line_data_d2_s <= prev_line_data_d1;
  101. cur_line_data_d2_s <= cur_line_data_d1;
  102. next_line_data_d2_s <= next_line_data_d1;
  103. prev_line_data_s <= prev_line_data;
  104. cur_line_data_s <= cur_line_data;
  105. next_line_data_s <= next_line_data;
  106. end
  107. if (x_cnt == img_width - 1) begin
  108. prev_line_data_d2_s <= prev_line_data_d2;
  109. cur_line_data_d2_s <= cur_line_data_d2;
  110. next_line_data_d2_s <= next_line_data_d2;
  111. prev_line_data_s <= prev_line_data_d1;
  112. cur_line_data_s <= cur_line_data_d1;
  113. next_line_data_s <= next_line_data_d1;
  114. end else begin
  115. prev_line_data_d2_s <= prev_line_data_d2;
  116. cur_line_data_d2_s <= cur_line_data_d2;
  117. next_line_data_d2_s <= next_line_data_d2;
  118. prev_line_data_s <= prev_line_data;
  119. cur_line_data_s <= cur_line_data;
  120. next_line_data_s <= next_line_data;
  121. end
  122. end
  123. end
  124. assign Y0 = prev_line_data_d2_s;
  125. assign Y1 = cur_line_data_d2_s;
  126. assign Y2 = next_line_data_d2_s;
  127. assign Y3 = prev_line_data_d1_s;
  128. assign Y4 = cur_line_data_d1_s;
  129. assign Y5 = next_line_data_d1_s;
  130. assign Y6 = prev_line_data_s;
  131. assign Y7 = cur_line_data_s;
  132. assign Y8 = next_line_data_s;
  133. always @(posedge clk) begin
  134. if (reset) begin
  135. valid_o <= 0;
  136. img_data_o <= 0;
  137. end else if (valid_s) begin
  138. valid_o <= 1;
  139. if (Y4 < low_threshold) img_data_o <= 0;
  140. else if((Y0 > high_threshold)||(Y1 > high_threshold)||(Y2 > high_threshold)||
  141. (Y3 > high_threshold)||(Y4 > high_threshold)||(Y5 > high_threshold)||
  142. (Y6 > high_threshold)||(Y7 > high_threshold)||(Y8 > high_threshold))
  143. img_data_o <= 255;
  144. else img_data_o <= 0;
  145. end else begin
  146. valid_o <= 0;
  147. end
  148. end
  149. endmodule

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/797702
推荐阅读
相关标签
  

闽ICP备14008679号