PotatoPie 4.0 实验教程(35) —— FPGA实现摄像头图像二值化膨胀效果-Anlogic-安路论坛-FPGA CPLD-ChipDebug

PotatoPie 4.0 实验教程(35) —— FPGA实现摄像头图像二值化膨胀效果

手机扫码

20240416075513933-1713225291635

链接直达

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

什么是图像二值化膨胀,有什么作用?

图像二值化膨胀是图像处理中的一种基本操作,它用于扩展和增强二值图像中的白色区域。具体而言,二值化膨胀操作会将图像中的白色区域进行扩张,使得白色区域的面积增大,边缘变得更加平滑,同时减小了黑色区域的面积。

二值化膨胀的主要作用包括:

  1. 连接分离的白色区域:当二值图像中存在一些白色区域之间有一定的间隔时,通过膨胀操作可以将它们连接起来,形成更大的连通区域。

  2. 填充小孔和缝隙:在二值图像中可能存在一些小的黑色孔洞或者白色缝隙,通过膨胀操作可以将这些孔洞或缝隙填充掉,使得图像的连通性更强。

  3. 平滑边缘:二值化膨胀可以使得白色区域的边缘变得更加平滑,去除一些锯齿状的边缘,从而使得图像更加美观。

  4. 扩展目标区域:在目标检测和分割等任务中,膨胀操作可以扩展目标区域的大小,从而更好地识别和分割目标。

总的来说,二值化膨胀可以帮助改善二值图像的质量,增强目标区域的连通性和稳定性,为后续的图像处理和分析提供更好的基础。

图像二值化膨胀算法步骤

图像二值化膨胀是通过一系列的像素运算来实现的。下面是其基本的算法步骤:

  1. 遍历图像中的每个像素: 从图像的左上角开始,逐行逐列地遍历每个像素。

  2. 定义结构元素: 定义一个结构元素(也称为膨胀核),它是一个指定形状和大小的像素矩阵,通常是一个正方形或圆形。

  3. 将结构元素与图像进行对应位置的匹配: 将结构元素的中心与当前像素位置对齐,然后将结构元素覆盖在图像的局部区域上。

  4. 判断膨胀操作: 如果结构元素覆盖区域内存在至少一个白色像素(像素值为255),则将当前像素的值设置为白色(像素值为255);否则将当前像素的值设置为黑色(像素值为0)。

  5. 重复步骤2-4直到遍历完整个图像: 对图像中的每个像素都执行上述步骤,直到遍历完整个图像。

  6. 输出结果图像: 完成遍历后,得到的图像就是经过膨胀处理后的二值化图像,其中白色区域的面积可能增大,黑色区域的面积可能减小。

通过以上步骤,图像二值化膨胀操作可以扩张和增强二值图像中的白色区域,达到连接、填充和平滑等效果。

与前面的二值化腐蚀相反,我们用3*3的模版滑动,只要这9个像素中有一个像素为255,那就把这9个全部涂为255。

python代码实现图像二值化膨胀源码

这段代码实现了图像的二值化和膨胀处理,并使用 Python 编程语言和 OpenCV 库来实现。具体功能说明如下:

  1. 导入必要的库:导入了 NumPy 用于数组操作,OpenCV 用于图像处理,os 用于路径操作,matplotlib.pyplot 用于图像显示。

  2. 读取图像:从指定路径读取图像,并获取其尺寸。

  3. 将图像转换为灰度图像:使用 OpenCV 的 cvtColor 函数将彩色图像转换为灰度图像。

  4. 图像二值化:将灰度图像转换为二值图像,根据阈值(92)将像素值大于阈值的设置为255,小于等于阈值的设置为0。

  5. 图像膨胀处理:使用按位或操作对二值图像进行膨胀处理,将图像中的白色区域扩张,使其变得更加连通。

  6. 显示图像:使用 matplotlib.pyplot 的 subplot 函数将原始灰度图像、二值化图像和膨胀处理后的图像显示在子图中,并设置标题为中文并使用微软雅黑字体。

对函数的说明如下:

  • cv2.imread(): 读取图像文件。
  • cv2.cvtColor(): 将图像从一个颜色空间转换为另一个颜色空间。
  • plt.imshow(): 显示图像。
  • plt.title(): 设置图像标题。
  • plt.subplot(): 创建子图。
  • plt.show(): 显示图像。

从下图可以看到图像白色的部分增加了:

20240420160947868-image

matlab代码实现图像二值化膨胀源码

这段 MATLAB 代码实现了图像的二值化和膨胀处理,并使用 subplot 函数将原始灰度图像、二值化图像以及经过不同次数膨胀处理后的图像显示在同一窗口中。

功能说明:

  1. 首先,代码读取了名为 “Lena.jpg” 的图像文件,并将其转换为灰度图像。

  2. 然后,通过阈值将灰度图像进行二值化处理,将灰度值大于 92 的像素置为白色(255),其余置为黑色(0)。

  3. 接着,对二值化后的图像进行膨胀处理,分别进行了三次膨胀处理,每次处理都是将图像中的黑色像素点与其周围的8个像素点进行按位或运算,并将结果赋值给当前像素点。这样可以使得黑色区域扩张,增加图像中白色区域的连通性。

  4. 最后,使用 subplot 函数将原始灰度图像、二值化图像以及经过不同次数膨胀处理后的图像显示在同一窗口中,并设置了标题的字体为微软雅黑,方便阅读和展示。

函数功能说明:

  • imread:用于读取图像文件。
  • rgb2gray:将彩色图像转换为灰度图像。
  • subplot:用于在同一窗口中显示多个子图像。
  • imshow:用于显示图像。
  • title:用于设置图像的标题,并设置了标题的字体为微软雅黑。
  • for 循环:用于遍历图像的每个像素,并进行二值化和膨胀处理。

从下图可以看到图像白色的部分增加了:

20240420160312915-image

FPGA工程解析

工程层次图

20240420162127620-image

demo18相比,只是多了一个img_dlat_fltr的模块,同时这个例程中使能了video_tgp_24b模块目的是为了不使用摄像头数据而使用video_tgp_24b生成的条纹数,这样效果更明显,也就是下面这两段代码,在从SDRAM读出来之后,经img_dlat_fltr处理后再输出hdmi_tx模块。

video_tgp_24b    
#(
    .H_DISP             (12'd1280),
    .V_DISP             (12'd720)
)
u_video_tgp_24b
(
    .clk                (pattern_clk),        
    .rst_n              (sys_rst_n),     
    
    .vaild          (sdram_init_done),
    .DIVIDE_PARAM       (8'd128),
    .data           (pattern_data),    
    .we             (pattern_we)
);
img_dlat_fltr u_img_dlat_fltr_1
(
    .i_clk          (clk_pixel             ),//input   wire        
    .i_rst_n        (sys_rst_n            ),//input   wire        
    .i_hs         (VGA_HS           ),//input   wire        
    .i_vs         (VGA_VS           ),//input   wire        
    .i_en           (VGA_DE           ),//input   wire        
    .i_bin       (v_bin              ),//input   wire [7:0]  
    .o_hs           (dlat_1_hs         ),//output  wire        
    .o_vs           (dlat_1_vs         ),//output  wire        
    .o_en           (dlat_1_de         ),//output  wire        
    .o_bin       (dlat_1_bin     ) //output  wire [7:0]  
);

共计例化了img_dlat_fltr6次,每处理一次会显示一个画面并延迟一会。

video_tgp_24b模块代码解析

相比之前教程中的video_tgp_24b模块,将图像的测试固定在了img_state <= 2'd1; 这一状态。即图像始终输出为data <= ((lcd_ypos[4]==1'b1) ^ (lcd_xpos[4]==1'b1)) ? {24{1'b0}} : {24{1'b1}}; ,显示为黑白条纹。

img_dilation_fltr模块代码解析

首先例化图像缓冲模块,用于将图像从一个时钟一个像素转为一个时钟输出三行三列9个像素,由于图像是二值图,我们只需随意例化一个通道的buf就可以,我们这里例化R通道。

同前面的腐蚀代码相比,膨胀就是把&运算改为|运算,因为只要9个像素中有一个不为0,那么所有像素就都为255。

erosion_or <= r_p11  |
		               r_p12 |
		               r_p13 |
		               r_p21 |
		               r_p22 |
		               r_p23 |
		               r_p31 |
		               r_p32 |
		               r_p33;

管脚约束

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

时序约束

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

实验结果:

这个程序会进行6次膨胀,每次膨胀之后会停顿1秒,可以看到图中的白条纹越来越小,黑条纹越来越细,就是白条纹被膨胀了。

20240409200523703-d72c17ab0277878e8bf559658b4e7fb

请登录后发表评论

    没有回复内容