ZYNQ图像处理(6)——均值滤波和中值滤波

这篇具有很好参考价值的文章主要介绍了ZYNQ图像处理(6)——均值滤波和中值滤波。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、均值和中值滤波基本原理

首先要做的是最简单的均值滤波算法。均值滤波是典型的线性滤波算法,它是指在图像上对目标像素给一个模板,该模板包括了其周围的临近像素(以目标象素为中心的周围 8 个像素,构成一个滤波模板,即去掉目标像素本身),再用模板中的全体像素的平均值来代替原来像素值。中值滤波算法可以形象的用上述表格来描述,即对于每个 33 的阵列而言,中间像素的值,等于边缘 8 个像素的平均值。
ZYNQ图像处理(6)——均值滤波和中值滤波
无论是直接获取的灰度图像,还是由彩色图像转换得到的灰度图像,里面都有噪声的存在,噪声对图像质量有很大的影响。进行中值滤波不仅可以去除孤点噪声,而且可以保持图像的边缘特性,不会使图像产生显著的模糊,比较适合于实验中的人脸图像。中值滤波算法与均值滤波非常的相似,但滤波的效果却有很大的差别,区别如下:(1) 均值滤波相当于低通滤波,有将图像模糊化的趋势,对椒盐噪声基本无能力。(2) 中值滤波的有点事可以很好的过滤椒盐噪声,缺点是容易造成图像的不连续。中值滤波的算法非常简单,只要求得 3
3 像素阵列的中间值即可,这样就有效的移植了最大值与最小值,图像会变得均匀,对椒盐噪声有很好的滤除效果!
《基于FPGA的实时中值滤波器的硬件实现》这篇文章中介绍了一种适合FPGA实现的快速寻找中值的算法,算法过程是这样的:首先计算每一行的最大值、中值以及最小值;之后计算第一列最大值中的最小值,第二列中间值中的中间值,第三列最小值中的最大值;最后再次计算这三个值的中间值就可以得到中值了。
ZYNQ图像处理(6)——均值滤波和中值滤波

二、3×3图像矩阵的提取

可以发现,无论是均值滤波还是中值滤波,一个必要的步骤就是得到3×3的图像矩阵。这个图像矩阵在matlab中很容易得到,因为matlab读取的是整一张的图片。但是在FPGA中对图像的实时处理,则需要先缓存两到三行的数据,然后从这3行数据中获得3×3图像矩阵。
查阅了一些资料,发现在VIVADO中实现3×3矩阵有以下几种方法。(1)第一种是利用vivado的IP核:ram based shift register,这个ip核在缓存数据量小的时候可以用。但是数据量很大,为几百个以上的时候,缓存数量就不准了,不知道是不是bug,因此不推荐使用。(2)第二种是利用RAM(3)第三种是利用fifo实现,利用fifo实现野火教程很详细。我这边是利用了两个ram实现数据的缓存和3×3矩阵的提取,接下来介绍实现过程。

2.1、例化ram ip核

首先自然是先需要例化一个ram的IP核,这个ram的配置信息如下如所示,是一个双端口的ram,宽度8位,深度1024位,优先写操作。详细的可以看配置的图。
ZYNQ图像处理(6)——均值滤波和中值滤波
ZYNQ图像处理(6)——均值滤波和中值滤波
ZYNQ图像处理(6)——均值滤波和中值滤波

2.2、基于ram的移位寄存器

基于ram 的移位寄存器代码如下图所示。输入端口有时钟信号、时钟使能信号、行同步信号、数据输入信号。输出端口有前一行数据、前前一行的数据。具体实现是这样的,当行同步和时钟使能到来时,地址开始累加了,当行同步结束,地址清零。之后对时钟信号、地址信号、数据信号都延迟三拍。最后两个ram分别存储了前一行和前前一行的图像。
比较关键的一点是,ram是先开始读,延迟几个时钟后才开始写,因为刚开始是读不到数据的,只有下一个行同步信号来的时候,前一行数据才会被读出来,这里比较绕。

module line_shift_RAM_8bit1(
	input clock,

	input          clken,
	input          per_frame_href,
	
	input   [7:0]  shiftin,  //当前行的数据
	output  [7:0]  taps0x,   //前一行的数据
	output  [7:0]  taps1x    //前前一行的数据
);

//reg define
reg  [2:0]  clken_dly;
reg  [9:0]  ram_rd_addr;
reg  [9:0]  ram_rd_addr_d0;
reg  [9:0]  ram_rd_addr_d1;
reg  [9:0]  ram_rd_addr_d2;
reg  [7:0]  shiftin_d0;
reg  [7:0]  shiftin_d1;
reg  [7:0]  shiftin_d2;
reg  [7:0]  taps0x_d0;

//在数据到来时,RAM的读地址累加
always@(posedge clock)begin
	if(per_frame_href)
		if(clken)
			ram_rd_addr <= ram_rd_addr + 1 ;
		else
			ram_rd_addr <= ram_rd_addr ;
	else
		ram_rd_addr <= 0 ;
end

//对时钟延迟3拍
always@(posedge clock) begin
	clken_dly <= { clken_dly[1:0] , clken };
end

//将RAM地址延迟3拍
always@(posedge clock ) begin
	ram_rd_addr_d0 <= ram_rd_addr;
	ram_rd_addr_d1 <= ram_rd_addr_d0;
	ram_rd_addr_d2 <= ram_rd_addr_d1;
end

//输入数据延迟3拍送入RAM
always@(posedge clock)begin
	shiftin_d0 <= shiftin;
	shiftin_d1 <= shiftin_d0;
	shiftin_d2 <= shiftin_d1;
end

//用于存储前一行图像的RAM
blk_mem_gen_0  u_ram_1024x8_0(
  .clka   (clock),
  .wea    (clken_dly[2]),
  .addra  (ram_rd_addr_d2),     //在延迟的第三个时钟周期,当前行的数据写入RAM0
  .dina   (shiftin_d2),
  
  .clkb   (clock),
  .addrb  (ram_rd_addr),    
  .doutb  (taps0x)              //延迟一个时钟周期,输出RAM0中前一行图像的数据
);

//寄存前一行图像的数据
always@(posedge clock)begin
	taps0x_d0  <= taps0x;
end

//用于存储前前一行图像的RAM
blk_mem_gen_0  u_ram_1024x8_1(
	.clka   (clock),
	.wea    (clken_dly[1]),
	.addra  (ram_rd_addr_d1),
	.dina   (taps0x_d0),       //在延迟的第二个时钟周期,将前一行图像的数据写入RAM1

	.clkb   (clock),
	.addrb  (ram_rd_addr),
	.doutb  (taps1x)           //延迟一个时钟周期,输出RAM1中前前一行图像的数据
);

endmodule

我这边结合仿真说一下,当clken[2]信号为高时,开始往里边写信号,可以看到第一次是把十六进制51写到了地址0中,但是可以发现读地址是已经到了3了,所以读速度是比写速度快了三个时钟周期,因为下一个行同步来时才可以得到上一行数据。
ZYNQ图像处理(6)——均值滤波和中值滤波
可以看到,下面这张图就是下一个行同步时间内,下一行数据从taps0x中读了出来。taps1x也是同样的道理,这边不在叙述。
ZYNQ图像处理(6)——均值滤波和中值滤波

2.3、3×3图像矩阵提取

3×3图像矩阵提取的代码如下图所示,代码本身比较简单,就是将输入信号缓存,然后提取出矩阵。这里需要注意信号的同步,得到3×3矩阵信号要比进来的信号慢了两个时钟周期。所以需要延迟两拍。

module  VIP_matrix_generate
(
	input				clk,  		
	input				rst_n,				

	input				per_frame_vsync,
	input				per_frame_href,
	input				per_frame_clken,
	input        [7:0]  per_img_Y,

	output				matrix_frame_vsync,
	output				matrix_frame_href,
	output				matrix_frame_clken,
	output	reg  [7:0]  matrix_p11, 
	output	reg  [7:0]  matrix_p12,
	output	reg  [7:0]  matrix_p13,
	output	reg	 [7:0]  matrix_p21, 
	output	reg  [7:0]  matrix_p22, 
	output	reg  [7:0]  matrix_p23,
	output	reg	 [7:0]  matrix_p31, 
	output	reg  [7:0]  matrix_p32, 
	output	reg  [7:0]  matrix_p33
);

//wire define
wire  [7:0]  row1_data;
wire  [7:0]  row2_data;
wire	     read_frame_href ;
wire	     read_frame_clken;

//reg define
reg  [7:0]  row3_data;
reg  [1:0]  per_frame_vsync_r;
reg  [1:0]  per_frame_href_r;
reg  [1:0]  per_frame_clken_r;

assign	read_frame_href    = per_frame_href_r[0] ;
assign	read_frame_clken   = per_frame_clken_r[0];
assign	matrix_frame_vsync = per_frame_vsync_r[1];
assign	matrix_frame_href  = per_frame_href_r[1] ;
assign	matrix_frame_clken = per_frame_clken_r[1];

//present signal
always@(posedge clk or negedge rst_n) begin
	if(!rst_n)
		row3_data <= 0;
	else begin		
		if(per_frame_clken)
			row3_data <= per_img_Y ;
		else
			row3_data <= row3_data ;
	end
end


line_shift_RAM_8bit1 u_line_shift_RAM_8bit1(
    .clock          ( clk               ),
    .clken          ( per_frame_clken   ),
    .per_frame_href ( per_frame_href    ),
    .shiftin        ( per_img_Y         ),
    .taps0x         ( row2_data         ),
    .taps1x         ( row1_data         )
);


//delay 2 tclk
always@(posedge clk or negedge rst_n) begin
	if(!rst_n) begin		
		per_frame_vsync_r <= 0;
		per_frame_href_r  <= 0;
		per_frame_clken_r <= 0;
	end
	else begin		
		per_frame_vsync_r <= { per_frame_vsync_r[0], per_frame_vsync };
		per_frame_href_r  <= { per_frame_href_r[0],  per_frame_href  };
		per_frame_clken_r <= { per_frame_clken_r[0], per_frame_clken };
	end
end

//generate the 3X3 matrix 
always@(posedge clk or negedge rst_n) begin
	if(!rst_n) begin		
		{matrix_p11, matrix_p12, matrix_p13} <= 24'h0;
		{matrix_p21, matrix_p22, matrix_p23} <= 24'h0;
		{matrix_p31, matrix_p32, matrix_p33} <= 24'h0;
	end
	else if(read_frame_href) begin
		if(read_frame_clken) begin			
			{matrix_p11, matrix_p12, matrix_p13} <= {matrix_p12, matrix_p13, row1_data};
			{matrix_p21, matrix_p22, matrix_p23} <= {matrix_p22, matrix_p23, row2_data};
			{matrix_p31, matrix_p32, matrix_p33} <= {matrix_p32, matrix_p33, row3_data};
		end
		else begin			
			{matrix_p11, matrix_p12, matrix_p13} <= {matrix_p11, matrix_p12, matrix_p13};
			{matrix_p21, matrix_p22, matrix_p23} <= {matrix_p21, matrix_p22, matrix_p23};
			{matrix_p31, matrix_p32, matrix_p33} <= {matrix_p31, matrix_p32, matrix_p33};
		end	
	end
	else begin		
		{matrix_p11, matrix_p12, matrix_p13} <= 24'h0;
		{matrix_p21, matrix_p22, matrix_p23} <= 24'h0;
		{matrix_p31, matrix_p32, matrix_p33} <= 24'h0;
	end
end

endmodule

仿真的结果如下面三张图所示,当pei_img_Y数据来到的时候,延迟两个时钟周期进入到row3_data中,之后在延迟一个周期数据送到p31、p32以及p33中。row2_data和row1_data的得到也是同样的原理。
ZYNQ图像处理(6)——均值滤波和中值滤波
ZYNQ图像处理(6)——均值滤波和中值滤波
ZYNQ图像处理(6)——均值滤波和中值滤波

三、均值滤波的实现

前面已经清楚描述了均值滤波的实现过程,主要就是将图像像素点周围8个像素的值加起来然后除以8就可以了,下面式均值滤波的实现代码。

module mean_filter(
    input clk,
    input rst_n,

    input [23:0] pre_data,
    input per_vsync,
    input per_href,
    input per_clken,
    
    output [23:0] post_data,
    output post_vsync,
    output post_href,
    output post_clken
);

//-----------------------------
//generate 3×3 picture matrix
//-----------------------------
wire matrix_frame_clken;
wire matrix_frame_href;
wire matrix_frame_vsync;
wire [7:0] matrix_p11;
wire [7:0] matrix_p12;
wire [7:0] matrix_p13;
wire [7:0] matrix_p21;
wire [7:0] matrix_p22;
wire [7:0] matrix_p23;
wire [7:0] matrix_p31;
wire [7:0] matrix_p32;
wire [7:0] matrix_p33;

VIP_matrix_generate u_VIP_matrix_generate(
    .clk                ( clk                ),
    .rst_n              ( rst_n              ),
    .per_frame_vsync    ( per_vsync   	 	 ),
    .per_frame_href     ( per_href           ),
    .per_frame_clken    ( per_clken      	 ),
    .per_img_Y          ( pre_data[7:0]      ),
    .matrix_frame_vsync ( matrix_frame_vsync ),
    .matrix_frame_href  ( matrix_frame_href  ),
    .matrix_frame_clken ( matrix_frame_clken ),
    .matrix_p11         ( matrix_p11         ),
    .matrix_p12         ( matrix_p12         ),
    .matrix_p13         ( matrix_p13         ),
    .matrix_p21         ( matrix_p21         ),
    .matrix_p22         ( matrix_p22         ),
    .matrix_p23         ( matrix_p23         ),
    .matrix_p31         ( matrix_p31         ),
    .matrix_p32         ( matrix_p32         ),
    .matrix_p33         ( matrix_p33         )
);

//-----------------------------
//mean filter function
//-----------------------------
reg [11:0] add_p1;
reg [11:0] add_p2;
reg [11:0] add_p3;
reg [11:0] add_all;
//step1:add every href
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)begin
        add_p1<=12'd0;
        add_p2<=12'd0;
        add_p3<=12'd0;
    end
    else begin
      add_p1<=matrix_p11+matrix_p12+matrix_p13;
      add_p2<=matrix_p21+matrix_p23;
      add_p3<=matrix_p31+matrix_p32+matrix_p33;
    end
end
//step2:add all the data
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)begin
        add_all<=12'd0;
    end
    else begin
        add_all<=add_p1+add_p2+add_p3;
    end
end
//step3:shift to get mean filter data
assign post_data={3{add_all[10:3]}};

//-----------------------------
//clk signal synchronization
//-----------------------------
reg [1:0] post_clken_dy;
reg [1:0] post_href_dy;
reg [1:0] post_vsync_dy;
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)begin
        post_clken_dy<=2'd0;
        post_href_dy<=2'd0;
        post_vsync_dy<=2'd0;
    end
    else begin
        post_clken_dy<={post_clken_dy[0],matrix_frame_clken};
        post_href_dy<={post_href_dy[0],matrix_frame_href};
        post_vsync_dy<={post_vsync_dy[0],matrix_frame_vsync};
    end
end
assign post_clken=post_clken_dy[1];
assign post_href=post_href_dy[1];
assign post_vsync=post_vsync_dy[1];

endmodule 

然后下面两张图分别是我用vivado仿真的加了椒盐噪声之后的图片以及均值滤波之后的图片。可以发现,均值滤波片让图片变得模糊了,而且椒盐噪声也没有有效滤除。这边的vivado仿真图像处理是用verilog去模拟了摄像头的产生时序,实现过程是参考了b站up主大磊FPGA。
ZYNQ图像处理(6)——均值滤波和中值滤波
ZYNQ图像处理(6)——均值滤波和中值滤波

四、中值滤波的实现

中值滤波的实现和均值滤波相似,也是需要先提取3×3的图像矩阵,然后提取9个值中的中值,提取的方法在上面也讲到了。
首先下面是对三个输出信号进行排序的代码,分别排序并且输出最大值,中间值以及最小值。

module sort_three(
    input clk,
    input rst_n,
    input [7:0] data1,
    input [7:0] data2,
    input [7:0] data3,
    
    output reg [7:0] max_data,
    output reg [7:0] mid_data,
    output reg [7:0] min_data

);

//find max,mid and min data 
//one clk to finish
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)begin
      max_data<=8'd0;
      mid_data<=8'd0;
      min_data<=8'd0;
    end
    else if (data1>=data2 && data2>=data3)begin
        max_data<=data1;
        mid_data<=data2;
        min_data<=data3;
    end
    else if (data1>=data3 && data3>=data2)begin
        max_data<=data1;
        mid_data<=data3;
        min_data<=data2;
    end
    else if (data2>=data1 && data1>=data3)begin
        max_data<=data2;
        mid_data<=data1;
        min_data<=data3;
    end
    else if (data2>=data3 && data3>=data1)begin
        max_data<=data2;
        mid_data<=data3;
        min_data<=data1;
    end
    else if (data3>=data1 && data1>=data2)begin
        max_data<=data3;
        mid_data<=data1;
        min_data<=data2;
    end
    else if (data3>=data2 && data2>=data1)begin
        max_data<=data3;
        mid_data<=data2;
        min_data<=data1;
    end
end

endmodule 

之后是中值滤波的代码,这部分实现的原理就是上文说到的提取中值的过程。

module median_filter(
    input clk,
    input rst_n,

    input [23:0] per_data,
    input per_vsync,
    input per_href,
    input per_clken,
    
    output [23:0] post_data,
    output post_vsync,
    output post_href,
    output post_clken
);

//-----------------------------
//generate 3×3 picture matrix
//-----------------------------
wire matrix_frame_clken;
wire matrix_frame_href;
wire matrix_frame_vsync;
reg [2:0] post_clken_dy;
reg [2:0] post_href_dy;
reg [2:0] post_vsync_dy;
wire [7:0] matrix_p11;
wire [7:0] matrix_p12;
wire [7:0] matrix_p13;
wire [7:0] matrix_p21;
wire [7:0] matrix_p22;
wire [7:0] matrix_p23;
wire [7:0] matrix_p31;
wire [7:0] matrix_p32;
wire [7:0] matrix_p33;

VIP_matrix_generate u_VIP_matrix_generate(
    .clk                ( clk                ),
    .rst_n              ( rst_n              ),
    .per_frame_vsync    ( per_vsync   	 	 ),
    .per_frame_href     ( per_href           ),
    .per_frame_clken    ( per_clken      	 ),
    .per_img_Y          ( per_data[7:0]      ),
    .matrix_frame_vsync ( matrix_frame_vsync ),
    .matrix_frame_href  ( matrix_frame_href  ),
    .matrix_frame_clken ( matrix_frame_clken ),
    .matrix_p11         ( matrix_p11         ),
    .matrix_p12         ( matrix_p12         ),
    .matrix_p13         ( matrix_p13         ),
    .matrix_p21         ( matrix_p21         ),
    .matrix_p22         ( matrix_p22         ),
    .matrix_p23         ( matrix_p23         ),
    .matrix_p31         ( matrix_p31         ),
    .matrix_p32         ( matrix_p32         ),
    .matrix_p33         ( matrix_p33         )
);

//---------------------------------------------------
//              midian filter function
//---------------------------------------------------
//[a11 a12 a13]             [max1 med1 min1]
//[a21 a22 a23]      to     [max2 med2 min2]
//[a31 a32 a33]             [max3 med3 min3]  
//                                 to
//                 [min_of_max med_of_med max_of_min]
//                                to
//                               [med]    
wire [7:0] max_data_1;
wire [7:0] mid_data_1;
wire [7:0] min_data_1;
wire [7:0] max_data_2;
wire [7:0] mid_data_2;
wire [7:0] min_data_2;
wire [7:0] max_data_3;
wire [7:0] mid_data_3;
wire [7:0] min_data_3;
wire [7:0] max_data_4;
wire [7:0] mid_data_4;
wire [7:0] min_data_4;
wire [7:0] max_data_5;
wire [7:0] mid_data_5;
wire [7:0] min_data_5;
wire [7:0] max_data_6;
wire [7:0] mid_data_6;
wire [7:0] min_data_6;
wire [7:0] max_data_7;
wire [7:0] mid_data_7;
wire [7:0] min_data_7;

//step1:every line find max,mid and min data
sort_three u_sort_three_1(
    .clk      ( clk              ),
    .rst_n    ( rst_n            ),
    .data1    ( matrix_p11       ),
    .data2    ( matrix_p12       ),
    .data3    ( matrix_p13       ),
    .max_data ( max_data_1       ),
    .mid_data ( mid_data_1       ),
    .min_data ( min_data_1       )
);
sort_three u_sort_three_2(
    .clk      ( clk              ),
    .rst_n    ( rst_n            ),
    .data1    ( matrix_p21       ),
    .data2    ( matrix_p22       ),
    .data3    ( matrix_p23       ),
    .max_data ( max_data_2       ),
    .mid_data ( mid_data_2       ),
    .min_data ( min_data_2       )
);
sort_three u_sort_three_3(
    .clk      ( clk              ),
    .rst_n    ( rst_n            ),
    .data1    ( matrix_p31       ),
    .data2    ( matrix_p32       ),
    .data3    ( matrix_p33       ),
    .max_data ( max_data_3       ),
    .mid_data ( mid_data_3       ),
    .min_data ( min_data_3       )
);
//step2:every line find min_of_max,med_of_med,max_of_min
sort_three u_sort_three_4(
    .clk      ( clk              ),
    .rst_n    ( rst_n            ),
    .data1    ( max_data_1       ),
    .data2    ( max_data_2       ),
    .data3    ( max_data_3       ),
    .max_data ( max_data_4       ),
    .mid_data ( mid_data_4       ),
    .min_data ( min_data_4       )
);
sort_three u_sort_three_5(
    .clk      ( clk              ),
    .rst_n    ( rst_n            ),
    .data1    ( mid_data_1       ),
    .data2    ( mid_data_2       ),
    .data3    ( mid_data_3       ),
    .max_data ( max_data_5       ),
    .mid_data ( mid_data_5       ),
    .min_data ( min_data_5       )
);
sort_three u_sort_three_6(
    .clk      ( clk              ),
    .rst_n    ( rst_n            ),
    .data1    ( min_data_1       ),
    .data2    ( min_data_2       ),
    .data3    ( min_data_3       ),
    .max_data ( max_data_6       ),
    .mid_data ( mid_data_6       ),
    .min_data ( min_data_6       )
);
//step3:find median value
sort_three u_sort_three_7(
    .clk      ( clk              ),
    .rst_n    ( rst_n            ),
    .data1    ( min_data_4       ),
    .data2    ( mid_data_5       ),
    .data3    ( max_data_6       ),
    .max_data ( max_data_7       ),
    .mid_data ( mid_data_7       ),
    .min_data ( min_data_7       )
);
assign post_data={3{mid_data_7}};

//-----------------------------
//   signal synchronization
//-----------------------------
assign post_clken=post_clken_dy[2];
assign post_href=post_href_dy[2];
assign post_vsync=post_vsync_dy[2];
always @(posedge clk or negedge rst_n) begin
    if(~rst_n)begin
        post_clken_dy<=3'd0;
        post_href_dy<=3'd0;
        post_vsync_dy<=3'd0;
    end
    else begin
        post_clken_dy<={post_clken_dy[1:0],matrix_frame_clken};
        post_href_dy<={post_href_dy[1:0],matrix_frame_href};
        post_vsync_dy<={post_vsync_dy[1:0],matrix_frame_vsync};
    end
end

endmodule

接下来是中值滤波的仿真结果,我打个比方,比如下面69这个数值是输出的中值。获得中值需要消耗三个时钟周期,因此矩阵数据比中值要快三个时钟周期,所以和这个中值对应的矩阵数据是:36、36、36、d7、bc、36、ff、f5、69。对应中值就是69,这边显示696969是把8位数据拼接成了24位的。
ZYNQ图像处理(6)——均值滤波和中值滤波
最后给出的这三张图片一次是加了椒盐噪声的RGB图片,均值滤波后的图片以及中值滤波后的图片。可以明显看到,中值滤波对椒盐噪声的滤除作用明显。
ZYNQ图像处理(6)——均值滤波和中值滤波
ZYNQ图像处理(6)——均值滤波和中值滤波
ZYNQ图像处理(6)——均值滤波和中值滤波

五、总结

均值滤波和中值滤波是图像处理的基本操作,主要核心都是提取3×3的图像矩阵。因为现在的摄像头含噪声很少,所有没有放到FPGA开发板中进行测试,只是对其进行了matlab和vivado的仿真。后面做完这部分基础的图像处理后我整理下代码并供大家参考。文章来源地址https://www.toymoban.com/news/detail-472595.html

到了这里,关于ZYNQ图像处理(6)——均值滤波和中值滤波的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Opencv-C++笔记 (13) : opencv-图像卷积一(均值、中值、高斯、双边滤波)与 边缘处理

    头文件 quick_opencv.h:声明类与公共函数 主函数调用 src:输入图像 。 dst:输出图像 。 ksize:内核大小 ,一般用 Size(w,h),w 为宽度,h 为深度。 anchor:被平滑的点,表示取 内核中心 ,默认值 Point(-1,-1)。 boderType:推断图像外部像素的某种边界模式。默认值 BORDER_DEFAULT 目的:

    2024年02月16日
    浏览(154)
  • 【C++】【图像处理】均值滤波 and 高斯滤波 and 中值滤波 and Sobel算子边缘提取(低通滤波)算法解析(以.raw格式的图像为基础进行图像处理、gray levels:256)

     中值滤波: 中值滤波中的MidValueFind函数的实现就是冒泡排序,最后去中间值返回:  Soble算子边缘提取:     总结: 1、均值、高斯滤波和Sobel算子边缘提取的核心,创建卷积核并确定各个点上的权重,然后将边缘灰度级归零(是否边缘归零按业务需求决定),提取非边缘像

    2024年02月05日
    浏览(58)
  • 【C++】【图像处理】均值滤波 and 高斯滤波 and 中值滤波 (低通滤波器)and Sobel算子边缘提取算法解析(以.raw格式的图像为基础进行图像处理、gray levels:256)

     中值滤波: 中值滤波中的MidValueFind函数的实现就是冒泡排序,最后去中间值返回:  Soble算子边缘提取:     总结: 1、均值、高斯滤波和Sobel算子边缘提取的核心,创建卷积核并确定各个点上的权重,然后将边缘灰度级归零(是否边缘归零按业务需求决定),提取非边缘像

    2024年02月05日
    浏览(56)
  • 算法 | 数字图像处理之「中值滤波」

    中值滤波就是用一个奇数点的移动窗口(要求奇数主要是为了保证整个模板有唯一中心元素),将窗口中心点的值用窗口内各点的中值代替。假设窗口内有5点,其值为80、90、200、110和120,那么此窗口内各点的中值即为110。 设有一个一维序列 (f_1,f_2,...,f_n) ,取窗口长度(点

    2023年04月13日
    浏览(36)
  • FPGA图像处理_中值滤波实现(含源码)

    非线性滤波器在通常情况下没有特定的转移函数。一类比较重要的非线性滤波就是统计排序滤波器,统计排序滤波器即对窗口内的像素值进行排序并通过多路选择器选择使用排序后的值,例如中值滤波、最大/最小值滤波等。排序滤波器或者其组合,可以在很多图像处理的场合

    2023年04月15日
    浏览(39)
  • 图像处理:均值滤波算法

    目录 前言 概念介绍 基本原理 Opencv实现均值滤波 Python手写实现均值滤波 参考文章 在此之前,我曾在此篇中推导过图像处理:推导五种滤波算法(均值、中值、高斯、双边、引导)。这在此基础上,我想更深入地研究和推导这些算法,以便为将来处理图像的项目打下基础。

    2023年04月23日
    浏览(79)
  • 数字图像处理(七)均值滤波

    题目:使用均值滤波器对图像进行滤波。 采用国际标准测试图像Lena。 3*3的均值滤波器定义如下: c++代码: 结果展示: 均值滤波器的特点: 计算均值会将图像中的边缘信息和特征信息模糊掉,丢失很多特征,使得景物的清晰度降低,画面变得模糊。对于高斯噪声,当滤波器

    2024年02月11日
    浏览(91)
  • Matlab图像处理-均值滤波

    均值滤波 均值滤波所使用的运算是卷积。均值滤波用邻域内像素的平均值来代替中心像素的值,相当于低通滤波,有将图像模糊化的趋势,对椒盐噪声基本无能为力。 在 MATLAB 中,可使用 imfilter 函数 来实现线性空间滤波,该函数的语法如下 : J = imfilter ( I,w,filtering_mode,bound

    2024年02月06日
    浏览(44)
  • 【图像处理OpenCV(C++版)】——5.4 图像平滑之中值平滑(滤波)

    前言 : 😊😊😊 欢迎来到本博客 😊😊😊 🌟🌟🌟 本专栏主要结合OpenCV和C++来实现一些基本的图像处理算法并详细解释各参数含义,适用于平时学习、工作快速查询等,随时更新。 😊😊😊 具体食用方式:可以点击本专栏【OpenCV快速查找(更新中)】–搜索你要查询的算子

    2024年02月10日
    浏览(54)
  • FPGA图像处理仿真实验——均值滤波(FIFO)

            之前的博客中用shift ram做的均值滤波,那篇文章里讲了原理,在这里不进行重复。考虑到shift ram的深度有限,在处理高分辨率图片时可能会收到限制,所以这次采用FIFO来进行均值滤波。FIFO可以看成是一个先进先出的堆栈,有两个独立的读使能信号和写使能信号,

    2024年02月13日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包