目录
1.软件版本
2.像素排序模块原理
3.像素排序模块Verilog实现
3.1 像素排序模块FPGA实现思路
3.2 verilog程序实现
4.像素排序模块的仿真测试
欢迎订阅FPGA/MATLAB/Simulink系列教程
《★教程1:matlab入门100例》
《★教程2:fpga入门100例》
《★教程3:simulink入门60例》
《★教程4:FPGA/MATLAB/Simulink联合开发入门与进阶X例》
《★专题3:人工智能基础应用研究》
1.软件版本
vivado2022.2
2.像素排序模块原理
我们以3*3窗口为例,首先需要提取图像中3*3窗口的像素值,在FPGA中,获得图像3.*3的像素矩阵。对于相邻的两个像素,只要通过延迟模块,进行延迟,就可以在一个时间得到3个像素,而对于不同行之间的像素值,则需要延迟256个周期来得到,其实现结构如下:
通过这个结构,可以同时获得三行,三列中的九个像素值。 此时,我们就获得了九个像素值,然后将这九个像素值进行排序,最后提取中间值作为输出,如下示意图所示:
3.像素排序模块Verilog实现
3.1 像素排序模块FPGA实现思路
我们根据上面介绍的排序原理,将FPGA的中值滤波器的实现过程,通过如下的流程来实现,首先,假设提取的3×3窗口矩阵:
p11,p12,p13
p21,p22,p23
p31,p32,p33
然后进行多级排序:
第一级排序:对3×3窗口的每一行像素分别排序,输出每行的最大值、中值、最小值;
对p11,p12,p13(第一行)排序,输出p1_max/p1_mid/p1_min;
对p21,p22,p23(第二行)排序,输出p2_max/p2_mid/p2_min;
对p31,p32,p33(第三行)排序,输出p3_max/p3_mid/p3_min;
第二级排序:
对3个最大值p1_max/p2_max/p3_max排序,提取最小值p123_min;
对3个中值p1_mid/p2_mid/p3_mid排序,仅提取中值p123_mid;
对3个最小值p1_min/p2_min/p3_min排序,仅提取最大值p123_max;
第三级排序:
对3个中值p123_min/p123_mid/p123_max排序,仅提取中值Pmid;
3.2 verilog程序实现
这里,我们首先对上述模块各个子排序模块进行实现,其程序如下:
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2025/12/15 20:15:53 // Design Name: // Module Name: Fmed0 // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module Fmed0( input i_clk,// 时钟 input i_rst, // 复位 input [7:0] i_pix1, i_pix2, i_pix3, // 三个像素 i_pix1、i_pix2 和 i_pix3 output reg [7:0] o_pixmax, o_pixmid, o_pixmin// 输出o_pixmax、o_pixmid 和 o_pixmin ); always @(posedge i_clk, posedge i_rst) begin if(i_rst) begin o_pixmax <= 0; o_pixmid <= 0; o_pixmin <= 0; end else begin // 最大值 if(i_pix1 >= i_pix2 && i_pix1 >= i_pix3) o_pixmax <= i_pix1; else if(i_pix2 >= i_pix1 && i_pix2 >= i_pix3) o_pixmax <= i_pix2; else o_pixmax <= i_pix3; // 中间值 if((i_pix1 >= i_pix2 && i_pix1 <= i_pix3) || (i_pix1 >= i_pix3 && i_pix1 <= i_pix2)) o_pixmid <= i_pix1; else if((i_pix2 >= i_pix1 && i_pix2 <= i_pix3) || (i_pix2 >= i_pix3 && i_pix2 <= i_pix1)) o_pixmid <= i_pix2; else o_pixmid <= i_pix3; //最小值 if(i_pix1 <= i_pix2 && i_pix1 <= i_pix3) o_pixmin <= i_pix1; else if(i_pix2 <= i_pix1 && i_pix2 <= i_pix3) o_pixmin <= i_pix2; else o_pixmin <= i_pix3; end end endmodule4.像素排序模块的仿真测试
我们编写如下的testbench文件:
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2025/12/15 20:23:11 // Design Name: // Module Name: test_Fmed0 // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module test_Fmed0(); reg i_clk; reg i_rst; reg [7:0] x1,x2,x3; wire [7:0] o_pixmax; wire [7:0] o_pixmid; wire [7:0] o_pixmin; Fmed0 Fmed0_u( .i_clk (i_clk), .i_rst (i_rst), .i_pix1 (x1), .i_pix2 (x2), .i_pix3 (x3), .o_pixmax (o_pixmax), .o_pixmid (o_pixmid), .o_pixmin (o_pixmin) ); initial begin i_clk=1; i_rst=1; x1=0; x2=0; x3=0; #1000; i_rst=0; x1=127; x2=64; x3=231; #100 x1=0; x2=0; x3=0; end always #5 i_clk=~i_clk; endmodule仿真结果如下图所示:
从测试结果看,最大值输出为231,中间值输出为127,最小值为64。