3. 图像二值化阈值处理的FPGA实现

任务与实现范围

本模块对 8 位灰度视频流做实时二值化:像素值 ≥ 阈值输出 255,否则输出 0。阈值由外部输入 thresh 提供,可通过按键或串口在运行时修改。模块采用流水线寄存器输出,保证每拍一个像素的吞吐,适配视频时序。

核心代码(Verilog)

module binarize #(
    parameter WIDTH = 8
)(
    input  wire             clk,
    input  wire             rst_n,
    input  wire             de,        // 数据有效
    input  wire [WIDTH-1:0] gray,      // 灰度输入
    input  wire [WIDTH-1:0] thresh,    // 可配置阈值
    output reg              de_out,
    output reg  [WIDTH-1:0] bin_out    // 0 或 255
);

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            de_out  <= 1'b0;
            bin_out <= {WIDTH{1'b0}};
        end else begin
            de_out  <= de;
            bin_out <= (gray >= thresh) ? {WIDTH{1'b1}} : {WIDTH{1'b0}};
        end
    end

endmodule

阈值动态调整(按键/串口接入)

阈值寄存器在视频时钟域外更新,写入后下一帧生效。下面给出按键步进与串口单字节写入两种最小接入方式,二者共用同一阈值寄存器。

module thresh_ctrl (
    input  wire        clk,
    input  wire        rst_n,
    input  wire        key_inc,     // 按键:阈值 +8
    input  wire        key_dec,     // 按键:阈值 -8
    input  wire        uart_valid,  // 串口收到 1 字节
    input  wire [7:0]  uart_data,   // 串口数据即新阈值
    output reg  [7:0]  thresh
);
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n)
            thresh <= 8'd128;                 // 默认阈值
        else if (uart_valid)
            thresh <= uart_data;              // 串口直接设定
        else if (key_inc)
            thresh <= (thresh > 8'd247) ? 8'd255 : thresh + 8'd8;
        else if (key_dec)
            thresh <= (thresh < 8'd8)   ? 8'd0   : thresh - 8'd8;
    end
endmodule

顶层连接与运行

// 视频像素时钟域
binarize u_bin (
    .clk(clk_pix), .rst_n(rst_n),
    .de(de_in), .gray(gray_in),
    .thresh(thresh),
    .de_out(de_out), .bin_out(bin_out)
);

// 阈值控制(可用同一 clk_pix 或系统时钟,跨域时加同步)
thresh_ctrl u_thr (
    .clk(clk_pix), .rst_n(rst_n),
    .key_inc(key_inc), .key_dec(key_dec),
    .uart_valid(uart_valid), .uart_data(uart_data),
    .thresh(thresh)
);

运行方式:将 bin_out 与 de_out 接入 VGA/HDMI 显示通路,灰度源接摄像头或测试图。按键每按一次阈值变化 8;串口发送单字节(如 0x40=64)即设为该值。综合工具用 Vivado/Quartus 均可,无特殊 IP。

验证方法与通过条件

  • 仿真:给 gray 依次输入 0、100、200,thresh=128,检查 bin_out 应为 0、0、255,且 de_out 比 de 延迟 1 拍。
  • 上板:显示画面应呈黑白两色;按 key_inc 白色区域增大,按 key_dec 白色区域减小;串口写入新阈值后画面立即按新阈值分割。
  • 通过条件:输出仅含 0/255,阈值改变时分割边界随之移动,且无像素丢失(de_out 与 de 计数一致)。

数据流示意

灰度输入 gray 比较器 gray ≥ thresh ? bin_out 0/255 thresh 寄存器 按键/串口

按键或串口更新阈值寄存器,比较器每拍将灰度与阈值比较,输出二值像素,实现实时分割。