PotatoPie 4.0 实验教程(30) —— FPGA实现摄像头图像中值滤波-Anlogic-安路社区-FPGA CPLD-ChipDebug

PotatoPie 4.0 实验教程(30) —— FPGA实现摄像头图像中值滤波

手机扫码

20240416075513933-1713225291635

链接直达

https://item.taobao.com/item.htm?ft=t&id=776516984361

中值滤波是什么?

图像的中值滤波是一种非线性图像滤波方法,它用于去除图像中的椒盐噪声或其他类型的噪声。中值滤波的原理是用每个像素周围的邻域中的中值来替代该像素的值。与均值滤波不同,中值滤波不会受到极端值的影响,因此在处理存在椒盐噪声的图像时通常效果更好。

中值滤波的步骤如下:

  1. 定义邻域大小: 对于图像中的每个像素,定义一个固定大小的邻域,通常是一个正方形或矩形区域。

  2. 获取邻域像素值: 对于每个像素,获取其邻域内的像素值。

  3. 排序邻域像素值: 将邻域内的像素值按照大小进行排序,通常是从小到大或从大到小。

  4. 计算中值: 根据邻域内像素值的排序结果,找到中间位置的像素值,即中位数。

  5. 应用中值: 将中位数作为该像素的新值,用于替代原始图像中的像素值。

  6. 重复步骤: 对图像中的每个像素都重复执行上述步骤,直到整个图像都被处理过。

中值滤波的关键特点是它不受异常值的影响,因为它使用邻域内像素值的中间值来替代当前像素值,从而有效地去除噪声并保留图像的细节信息。

中值滤波的算法实现

python实现图像中值滤波的源码

这段 Python 代码实现了图像处理中的几个常见操作:

  1. 从文件系统中读取名为 “Lena.jpg” 的图像文件,并将其转换为灰度图像。
  2. 实现了中值滤波函数 median_filter,用于对灰度图像进行中值滤波处理。中值滤波是一种非线性滤波器,用于去除图像中的噪声,通过用像素点周围区域的中值替换当前像素值。
  3. 实现了添加椒盐噪声的函数 add_salt_pepper_noise。椒盐噪声是一种常见的图像噪声,随机将像素点的灰度值设置为黑色或白色,模拟图像传感器中的随机错误。
  4. 使用中值滤波函数处理原始灰度图像、添加椒盐噪声后的图像以及高斯噪声后的图像,并显示处理前后的结果。

整体来说,这段代码演示了如何使用 Python 和 OpenCV 库对图像进行中值滤波处理以及添加椒盐噪声,并展示了处理前后的图像效果。

20240419095710518-image

MATLAB实现图像中值滤波的源码

这段 MATLAB 代码实现了图像的中值滤波,包括对原始灰度图像、添加椒盐噪声后的图像以及添加高斯噪声后的图像进行中值滤波处理,并显示处理前后的图像。

  1. 首先,代码读取了名为 ‘Lena.jpg’ 的图像文件,并将其转换为灰度图像。
  2. 然后,对灰度图像进行了中值滤波处理,使用的窗口大小为3×3,即对每个像素及其周围8个像素进行排序,并将中间值作为该像素的值。
  3. 接着,代码生成了添加了椒盐噪声的图像,并对其进行了相同的中值滤波处理。
  4. 最后,代码生成了添加了高斯噪声的图像,并同样进行了中值滤波处理。

在处理后,原始灰度图像、添加椒盐噪声后的图像和添加高斯噪声后的图像分别与其对应的中值滤波处理结果一起显示在一个图像窗口中,以便比较处理前后的效果。

20240419094613349-image

FPGA工程分析

工程层次图

20240419132648176-image

demo18相比,只是多了一个img_med_fltr的模块,也就是下面这一段代码,在从SDRAM读出来之后,经它处理后再输出hdmi_tx模块。

img_med_fltr u_img_med_fltr
(
    .i_clk(clk_pixel),
    .i_rst_n(sys_rst_n),
    .i_hs(VGA_HS),
    .i_vs(VGA_VS),
    .i_de(VGA_DE),
    .i_r(VGA_RGB[23:16]),
    .i_g(VGA_RGB[15:8] ),
    .i_b(VGA_RGB[7:0]  ),          
    .o_hs(img_med_hs),
    .o_vs(img_med_vs),
    .o_de(img_med_de),   
    .o_r(img_med_data[23:16]),
    .o_g(img_med_data[15:8] ),
    .o_b(img_med_data[7:0]  )
);

img_med_fltr模块源代码分析

跟前面几篇教程一样,我们都需要先用行缓存将像素转化为同时输出3行3列来,后面的讲解都以R通道为例,因为其它三个通道的行为是一样的:

// R通道行缓存
img_buf u_r_buf
(
	.i_clk		(i_clk			),
	.i_rst_n	(i_rst_n		),
	.i_de		(i_de			),
	.i_data		(i_r			),
	.o_de		(				),
	.o_p11		(r_p_11			),
	.o_p12		(r_p_12			),
	.o_p13		(r_p_13			),	
	.o_p21		(r_p_21			),
	.o_p22		(r_p_22			),
	.o_p23		(r_p_23			),		
	.o_p31		(r_p_31			),
	.o_p32		(r_p_32			),
	.o_p33		(r_p_33			)
);

然后对像素进行排序,分成三步:

1.先按行找出同一行中的最大值,最小值,中值,即:

2.从找出这三行的三个最大值中找出最大值里的最小值,同时从三行的最小值里找出最大值,还有从三行的最值里找出最中值,即:

3.从第2步的值里找出最终的中值reg [7:0] r_med;

具体怎么比较,verilog代码里写得比较清楚。

管脚约束

PotatoPie 4.0 实验教程(18) —— FPGA实现OV5640摄像头采集以SDRAM作为显存进行HDMI输出显示相同,不作赘述。

时序约束

PotatoPie 4.0 实验教程(18) —— FPGA实现OV5640摄像头采集以SDRAM作为显存进行HDMI输出显示相同,不作赘述。

实验效果

20240419134015747-ae16d7aa7cf72d9e03dfcddc1ada9c5

请登录后发表评论

    没有回复内容