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

news2024/9/21 14:49:35

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*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

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即可
  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

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) 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

 

 

 

 

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) 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

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) 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

 

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) 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

 

 

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) 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

 

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

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

相关文章

【漏洞复现】chatgpt pictureproxy.php SSRF漏洞(CVE-2024-27564)

0x01 漏洞概述 ChatGPT pictureproxy.php接口存在服务器端请求伪造 漏洞&#xff08;SSRF&#xff09; &#xff0c;未授权的攻击者可以通过将构建的 URL 注入 url参数来强制应用程序发出任意请求。 0x02 测绘语句 fofa: icon_hash"-1999760920" 0x03 漏洞复现 G…

element-ui 自定义点击图标/文本/按钮触发el-date-picker时间组件,不使用插槽

天梦星服务平台 (tmxkj.top)https://tmxkj.top/#/ 1. 图片预览 2.上代码 2.1html <el-button class"hide_input" size"small"><svg t"1711608996149" class"icon" viewBox"0 0 1024 1024" version"1.1"…

中国象棋AI在线对弈游戏源码

源码介绍 这是一款html5小游戏&#xff0c;主要功能在于js&#xff0c;带一套皮肤、内置ai算法&#xff0c;有能力的可以自行修改。 源码截图 下载地址 链接&#xff1a;https://pan.baidu.com/s/1fYp1HWsd91nJOdX1M8RFtQ?pwdh2iz 提取码&#xff1a;h2iz

最近Sentinel-2下载网站好像有点问题

最近Sentinel-2下载网站好像有点点问题&#xff0c;基本属于打不开的状态&#xff01; 这也难怪&#xff0c;Sentinel提供了全世界最好的免费遥感资源。其受欢迎程度可以想象的到&#xff01;这么多人访问网站&#xff0c;网站压力可以说是巨大的。这可是全世界的并发访问&…

快速上手Spring Cloud五:Spring Cloud与持续集成/持续部署(CI/CD)

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …

力扣 718. 最长重复子数组

题目来源&#xff1a;https://leetcode.cn/problems/maximum-length-of-repeated-subarray/description/ C题解&#xff08;思路来源代码随想录&#xff09;&#xff1a;动态规划 确定dp数组&#xff08;dp table&#xff09;以及下标的含义。dp[i][j] &#xff1a;以下标i - …

22.计算机中的数据存储

文章目录 一、计算机中的数据存储二、十进制1、十进制加法2、十进制减法 三、什么是二进制&#xff1f;二进制的运算过程 四、常见的进制五、计算机为什么要用二进制存储数据&#xff1f;六、进制之间的转换1、任意进制转十进制1&#xff09;二进制101转十进制8421快速转换法 2…

自动发卡平台源码优化版配套免签个人支付宝微信插件

这款免签个人支付宝微信插件&#xff0c;配套的是 自动发卡平台源码优化版&#xff0c;支持个人免签支付 其他系统的不支持&#xff01;

动态规划刷题(算法竞赛、蓝桥杯)--导弹拦截(线性DP)

1、题目链接&#xff1a;[NOIP1999 提高组] 导弹拦截 - 洛谷 #include <bits/stdc.h> using namespace std; const int N2e55; int a[N],x,n; int b[N],len;int main(){while(cin>>x)a[n]x;//求最长不上升子序列 b[0]2e9;//初始化为无穷大for(int i1;i<n;i){if(…

详细分析axios.js:72 Uncaught (in promise) Error: 未知错误 的解决方法(图文)

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 调试接口的时候,打开一个网页,在终端出现如下错误: axios.js:72 Uncaught (in promise) Error: 未知错误at __webpack_exports__.default (axios.js:72:1)截图如下所示: 2. 原理分析 点击浏览器的Bug出错: // 如果…

LLM之RAG实战(三十五)| 使用LangChain的3种query扩展来优化RAG

RAG有时无法从矢量数据库中检索到正确的文档。比如我们问如下问题&#xff1a; 从1980年到1990年&#xff0c;国际象棋的规则是什么&#xff1f; RAG在矢量数据库中进行相似性搜索&#xff0c;来查询与国际象棋规则问题相关的相关文档。然而&#xff0c;在某些情况下&#xff0…

设计模式 —— 设计原则

在软件开发中&#xff0c;为了提高软件系统的可维护性和可复用性&#xff0c;增加软件的可扩展性和灵活性&#xff0c;程序员要尽量根据6条原则来开发程序&#xff0c;从而提高软件开发效率、节约软件开发成本和维护成本。 开闭原则 对扩展开放&#xff0c;对修改关闭。在程序需…

0 决策树基础

目录 1 绪论 2 模型 3 决策树面试总结 1 绪论 决策树算法包括ID3、C4.5以及C5.0等&#xff0c;这些算法容易理解&#xff0c;适用各种数据&#xff0c;在解决各种问题时都有良好表现&#xff0c;尤其是以树模型为核心的各种集成算法&#xff0c;在各个行业和领域都有广泛的…

蓝桥杯基础练习详细解析(四)——Fibonacci费伯纳西数列(题目分析、代码实现、Python)

试题 基础练习 Fibonacci数列 提交此题 评测记录 资源限制 内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 Fibonacci数列的递推公式为&#xff1a;FnFn-1Fn-2&#xff0c;其…

RANSAC算法:从原理到图像拼接的实践

RANSAC算法&#xff1a;从原理到图像拼接的实践 1. RANSAC算法原理和步骤 1.1 RANSAC算法简介 RANSAC (RANdom SAmple Consensus, 随机采样一致) 算法是从一组含有“外点”(outliers)的数据中正确估计数学模型参数的迭代算法。“外点”一般指的的数据中的噪声&#xff0c;比…

阿里云CentOS7安装MySQL8

创建目录 [rootnode1 ~]# mkdir /usr/local/mysql [rootnode1 ~]# cd /usr/local/mysql/ 下载安装包 到MySQL官网查看需要下载的版本&#xff0c;并获取到下载地址 https://downloads.mysql.com/archives/community/下载 [rootnode1 mysql]# wget https://downloads.mysql…

uniapp 微信小程序 canvas 手写板获取书写内容区域并输出

uni.canvasGetImageData 返回一个数组&#xff0c;用来描述 canvas 区域隐含的像素数据&#xff0c;在自定义组件下&#xff0c;第二个参数传入自定义组件实例 this&#xff0c;以操作组件内 组件。 // 获取目标 canvas 的像素信息 pixelData let canvas uni.createSelector…

平台介绍-搭建赛事运营平台(3)

上文介绍了品牌隔离的基本原理&#xff0c;就是通过不同的前端和微服务来实现。但是确实很多功能是类似的&#xff0c;所以从编程角度还是有些管理手段的。 前端部分&#xff1a;前端部分没有什么特别手段&#xff0c;就是两个独立的项目工程&#xff0c;分别维护。相同的部分复…

MoonBit MeetUp回顾——张正、宗喆:编程语言在云原生与区块链领域的技术探索

宗喆和张正分别给我们带了 KCL 相关的最新进展&#xff0c;由蚂蚁集团开发的 Rust 编写的开源 DSL&#xff0c;目标是优化云原生策略配置和用户体验。它通过引入动态配置管理、配置校验和基础设施抽象等核心概念&#xff0c;解决开发者认知负担、配置膨胀和标准化工具缺乏的问题…

Flink系列之:Flink SQL Gateway

Flink系列之&#xff1a;Flink SQL Gateway 一、Flink SQL Gateway二、部署三、启动SQL Gateway四、运行 SQL 查询五、SQL 网关启动选项六、SQL网关配置七、支持的端点 一、Flink SQL Gateway SQL 网关是一项允许多个客户端从远程并发执行 SQL 的服务。它提供了一种简单的方法…