FPGA中值滤波实现并Modelsim仿真,与MATLAB中值滤波进行对比

文章目录

  • 一、中值滤波算法
  • 二、FPGA实现中值滤波
    • 2.1 3*3窗口的生成
    • 2.2 排序模块
    • 2.3中值滤波模块
    • 2.4 整体RTL图
  • 三、modeslim仿真
  • 四、matlab中值滤波
  • 五、效果对比

一、中值滤波算法

1、中值滤波算法作用

可以去除孤点噪声(适用于消除椒盐噪声(黑白噪声)),而且还可以保持图像的边缘特性,不会使图像产生显著的模糊。


2、算法原理
中值滤波算法简单来说就是:通过对33窗口中的数据进行排序,最终获得中值。
FPGA中值滤波实现并Modelsim仿真,与MATLAB中值滤波进行对比_第1张图片
对于待处理的像素,我们选择一个3
3的窗口模板,该窗口内的像素为待处理像素的邻近像素,对窗口内的像素分别按行列排序,最终计算出中值,用该中值代替原像素值,实现中值滤波。

二、FPGA实现中值滤波

2.1 3*3窗口的生成

参考该博主的文章,这里不再赘述。

module filter_3x3(
    input clk,
    input rst_n,
    
    input  gray_de,
	 
    input [7:0] iData,

    output  filter_de, //生成窗口花费2clk,de信号延迟两拍
	 
    output reg [7:0] oData_11, oData_12, oData_13,
    output reg [7:0] oData_21, oData_22, oData_23,
    output reg [7:0] oData_31, oData_32, oData_33
);
endmodule

2.2 排序模块

FPGA中无排序IP核,因此编写如下模块,每次排序直接例化调用即可。
sort模块:

module sort(

    input                clk,
    input                rst_n,
	       
    input [7:0]          data1, 
    input [7:0]	       data2, 
    input [7:0]	       data3, 
	 
    output reg [7:0]     max, 
    output reg [7:0] 	 mid, 
    output reg [7:0] 	 min 
);

//最大值
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n) 
            max <= 0; 
		  else begin
            if(data1 >= data2 && data1 >= data3)
                max <= data1;
            else if(data2 >= data1 && data2 >= data3)
                max <= data2;
            else
                max <= data3;
        end
    end
	 
//中间值	 
always @(posedge clk or negedge rst_n) begin
        if(!rst_n)
            mid <= 0;
				
		  else begin
            if((data1 >= data2 && data1 <= data3) || (data1 >= data3 && data1 <= data2))
                mid <= data1;
            else if((data2 >= data1 && data2 <= data3) || (data2 >= data3 && data2 <= data1))
                mid <= data2;
            else
                mid <= data3;
        end
    end
	 
//最小值	 
always @(posedge clk, negedge rst_n) begin
        if(!rst_n)
            min <= 0;
				
		  else begin

            if(data1 <= data2 && data1 <= data3)
                min <= data1;
            else if(data2 <= data1 && data2 <= data3)
                min <= data2;
            else
                min <= data3;
        end
    end	 
	 
endmodule

2.3中值滤波模块

流水线技术处理
FPGA中值滤波实现并Modelsim仿真,与MATLAB中值滤波进行对比_第2张图片

module median_filter(
    input            clk,
    input            rst_n,
	 
    input   wire		iValid					,

    input   [7:0]     filter_11,filter_12,filter_13, //生成的3*3窗口数据
    input   [7:0]     filter_21,filter_22,filter_23,
    input   [7:0]     filter_31,filter_32,filter_33,

    output  			 median_de    ,//de同步信号
	 
    output   [7:0]    median_data  // 最终中值

);

reg [3:0]           de_shift1 ;  

//第一行
wire  [7:0]          max_data1 ;  
wire  [7:0]          mid_data1 ; 
wire  [7:0]          min_data1 ;
//第二行
wire  [7:0]          max_data2 ;
wire  [7:0]          mid_data2 ;
wire  [7:0]          min_data2 ;
//第三行
wire  [7:0]          max_data3 ;
wire  [7:0]          mid_data3 ;
wire  [7:0]          min_data3 ;
//max-min,mid-mid,min-max
wire  [7:0]          max_min_data  ;
wire  [7:0]          mid_mid_data  ; 
wire  [7:0]          min_max_data  ;



//---------------------------------------------------
//                   中值滤波
//             按行排序,共三行,例化三个模块
//               得到每行的最大、中间最小值
//---------------------------------------------------
//第一行
sort u1
(
    .clk              (clk                    ),
    .rst_n            (rst_n                  ),
    .data1            (matrix_11              ), 
    .data2            (matrix_12              ), 
    .data3            (matrix_13              ),
    .max              (max_data1              ),
    .mid              (mid_data1              ),
    .min              (min_data1              )
);
//第二行
sort u2
(
    .clk              (clk                    ),
    .rst_n            (rst_n                  ),
    .data1            (matrix_21              ), 
    .data2            (matrix_22              ), 
    .data3            (matrix_23              ),
    .max              (max_data2              ),
    .mid              (mid_data2              ),
    .min              (min_data2              )
);

//第三行
sort u3
(
    .clk              (clk                    ),
    .rst_n            (rst_n                  ),
    .data1            (matrix_31              ), 
    .data2            (matrix_32              ), 
    .data3            (matrix_33              ),
    .max              (max_data3              ),
    .mid              (mid_data3              ),
    .min              (min_data3              )
);

//---------------------------------------------------
//                每一行排完后
//                取出第一列中的最小值
//                第二列的中间值
//                第三列的最大值
//---------------------------------------------------

//max-min
sort u4
(
    .clk                    (clk                    ),
    .rst_n                  (rst_n                  ),
    .data1                  (max_data1              ), 
    .data2                  (max_data2              ), 
    .data3                  (max_data3              ),
    .max               (                       ),
    .mid               (                       ),
    .min               (max_min_data           )
);

//mid-mid
sort u5
(
    .clk                    (clk                    ),
    .rst_n                  (rst_n                  ),
    .data1                  (mid_data1              ),
    .data2                  (mid_data2              ),
    .data3                  (mid_data3              ),
    .max               (                       ),
    .mid               (mid_mid_data           ),
    .min               (                       )
);

//min-max
sort u6
(
    .clk                    (clk                    ),
    .rst_n                  (rst_n                  ),
    .data1                  (min_data1              ),
    .data2                  (min_data2              ),
    .data3                  (min_data3              ),
    .max               (min_max_data           ),
    .mid               (                       ),
    .min               (                       )
);

//---------------------------------------------------
//            得到最终中值mid_data 
//---------------------------------------------------

sort u7
(
    .clk              (clk                    ),
    .rst_n            (rst_n                  ),
    .data1            (max_min_data           ), 
    .data2            (mid_mid_data           ), 
    .data3            (min_max_data           ),
	
    .max              (                       ),
    .mid              (median_data            ),
    .min              (                       )
);

// 打拍做同步.3*3窗口花费1clk,中值滤波花费3clk

    always @(posedge clk or  negedge rst_n) begin
        if(!rst_n)begin
            de_shift1   <=  4'b000;
				
				end
        else begin
            de_shift1 <= {de_shift1[2:0], iValid};
				end
    end

    assign median_de   = de_shift1[3];
  endmodule

RTL如下:
FPGA中值滤波实现并Modelsim仿真,与MATLAB中值滤波进行对比_第3张图片

2.4 整体RTL图

和均值滤波相同,3*3窗口 + 滤波算法
FPGA中值滤波实现并Modelsim仿真,与MATLAB中值滤波进行对比_第4张图片

三、modeslim仿真

以此时为例,对中值滤波进行验证。

FPGA中值滤波实现并Modelsim仿真,与MATLAB中值滤波进行对比_第5张图片
中值滤波花费3clk,因此三个clk后输出计算值为30,与计算出来的对比正确。

FPGA中值滤波实现并Modelsim仿真,与MATLAB中值滤波进行对比_第6张图片

四、matlab中值滤波

clc;
clear all;
close all;

RGB = imread('flower.bmp');          
imgn = imnoise(RGB,'salt & pepper',0.05); %加入椒盐噪声
gray = im2double(rgb2gray(imgn));         %灰度化

[ROW,COL, DIM] = size(gray); 
%--------------------------------------------------------------------------
%                        Mean Filter 均值滤波
%--------------------------------------------------------------------------
Mean_Img = zeros(ROW,COL);
for r = 2:1:ROW-1
    for c = 2:1:COL-1
        Mean_Img(r,c) = (gray(r-1, c-1) + gray(r-1, c) + gray(r-1, c+1) + gray(r, c-1) + gray(r, c) + gray(r, c+1) + gray(r+1, c-1) + gray(r+1, c) + gray(r+1, c+1)) / 9;
    end
end
%--------------------------------------------------------------------------
%                        Median Filter 中值滤波
%--------------------------------------------------------------------------
Median_Img = zeros(ROW,COL);
for r = 2:ROW-1
    for c = 2:COL-1
        median3x3 =[gray(r-1,c-1)    gray(r-1,c) gray(r-1,c+1)
                    gray(r,c-1)      gray(r,c)      gray(r,c+1)
                    gray(r+1,c-1)      gray(r+1,c) gray(r+1,c+1)];
        sort1 = sort(median3x3, 2, 'descend');
        sort2 = sort([sort1(1), sort1(4), sort1(7)], 'descend');
        sort3 = sort([sort1(2), sort1(5), sort1(8)], 'descend');
        sort4 = sort([sort1(3), sort1(6), sort1(9)], 'descend');
        mid_num = sort([sort2(3), sort3(2), sort4(1)], 'descend');
        Median_Img(r,c) = mid_num(2);
    end
end
%--------------------------------------------------------------------------
%                          图像显示
%--------------------------------------------------------------------------
subplot(2,2,1); imshow(imgn);       title('椒盐噪声');
subplot(2,2,2); imshow(gray);       title('含椒盐噪声的灰度图');
subplot(2,2,3); imshow(Mean_Img);   title('均值滤波');
subplot(2,2,4); imshow(Median_Img); title('中值滤波');
%--------------------------------------------------------------------------
%                          图像保存
%--------------------------------------------------------------------------
imwrite (gray,'含椒盐噪声的灰度图.bmp');
imwrite (Median_Img,'中值滤波.bmp');

运行结果:
FPGA中值滤波实现并Modelsim仿真,与MATLAB中值滤波进行对比_第7张图片

由运行结果可知:中值滤波对椒盐噪声更有效,一次中值滤波后还存在少量椒盐噪声,可再次滤波,达到更好效果。均值滤波对椒盐噪声基本无作用。

五、效果对比

原图:
FPGA中值滤波实现并Modelsim仿真,与MATLAB中值滤波进行对比_第8张图片

FPGA实现中值滤波:
FPGA中值滤波实现并Modelsim仿真,与MATLAB中值滤波进行对比_第9张图片

matlab实现中值滤波:
FPGA中值滤波实现并Modelsim仿真,与MATLAB中值滤波进行对比_第10张图片

可看到实现了椒盐噪声的去噪。

完整工程

你可能感兴趣的:(FPGA图像处理及仿真测试,fpga开发,matlab,开发语言)