基于FPGA的图像腐蚀膨胀及实现

项目简述

膨胀是将与物体接触的所有背景点合并到该物体中,使边界向外部扩张的过程。可以用来填补物体中的空洞。腐蚀是一种消除边界点,使边界向内部收缩的过程。可以用来消除小且无意义的物体。图像的腐蚀与膨胀在图像处理中是非常常见的操作。本次项目的简述是:PC机通过千兆网发送一幅图片经过膨胀或腐蚀之后转存到DDR3中,然后经过USB3.0发送到上位机显示。

本次实验所用到的软硬件环境如下:
1、VIVADO2019.1软件环境
2、Modelsim10.7c仿真环境
3.米联客MA7035FA(100T)开发板
4、米联客USB3.0上位机软件

腐蚀膨胀原理

根据演示, 背景为白色, 即为 1。 0 为图像。
在这里插入图片描述
在此种情况下, 可采取 9 个元素相与的操作。
在这里插入图片描述
在此种情况下, 可采取 9 个元素相或的操作。

从上面我们可以看出,如果背景与图像的颜色互换,那么只需要将图像膨胀与腐蚀的与或运算相互颠倒即可。注意这种方法只适应于二值图像,膨胀和腐蚀, 都是针对于二值图像而言。

图像腐蚀代码

从前面图像腐蚀的原理部分,我们可以发现图像腐蚀的关键还是构建3*3的矩阵,但是我们前面图像处理的文章已经进行了讲解,所以这里不再进行赘述。因为图像的与或操作在我们8位的图像中难以实施,所以我们将与或操作变成了加操作,具体的可以观看如下代码:

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : [email protected]
// Website      : 
// Module Name  : sobel.v
// Create Time  : 2020-04-08 08:32:02
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module sobel(
    //System Interfaces
    input                   sclk            ,
    input                   rst_n           ,
    //Communication Interfaces
    input           [ 7:0]  rx_data         ,
    input                   pi_flag         ,
    output  reg     [ 7:0]  tx_data         ,
    output  reg             po_flag         
);
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
parameter           COL_NUM     =   1024    ;
parameter           ROW_NUM     =   768     ;
parameter           VALUE       =   80      ;

wire                [ 7:0]  mat_row1        ;
wire                [ 7:0]  mat_row2        ;
wire                [ 7:0]  mat_row3        ;
wire                        mat_flag        ; 
reg                 [ 7:0]  mat_row1_1      ;
reg                 [ 7:0]  mat_row2_1      ;
reg                 [ 7:0]  mat_row3_1      ;
reg                 [ 7:0]  mat_row1_2      ;
reg                 [ 7:0]  mat_row2_2      ;
reg                 [ 7:0]  mat_row3_2      ;
reg                         mat_flag_1      ; 
reg                         mat_flag_2      ; 
reg                         mat_flag_3      ; 
reg                         mat_flag_4      ; 
reg                         mat_flag_5      ; 
reg                         mat_flag_6      ; 
reg                         mat_flag_7      ;
     

reg                         mat_row1_flag   ;
reg                         mat_row2_flag   ;
reg                         mat_row3_flag   ; 
reg                         mat_row1_1_flag ;
reg                         mat_row2_1_flag ;
reg                         mat_row3_1_flag ;
reg                         mat_row1_2_flag ;
reg                         mat_row2_2_flag ;
reg                         mat_row3_2_flag ; 

 
//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/
always @(posedge sclk)
    begin
        mat_row1_1          <=          mat_row1;
        mat_row2_1          <=          mat_row2;
        mat_row3_1          <=          mat_row3;
        mat_row1_2          <=          mat_row1_1;
        mat_row2_2          <=          mat_row2_1;
        mat_row3_2          <=          mat_row3_1;
    end
    
always @(posedge sclk)
    begin
        mat_flag_1          <=          mat_flag;      
        mat_flag_2          <=          mat_flag_1;      
        mat_flag_3          <=          mat_flag_2;      
        mat_flag_4          <=          mat_flag_3;      
        mat_flag_5          <=          mat_flag_4;      
        mat_flag_6          <=          mat_flag_5;      
        mat_flag_7          <=          mat_flag_6;      
    end

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row1_flag       <=          1'b0;
    else if(mat_row1 == 8'd255)
        mat_row1_flag       <=          1'b1;
    else
        mat_row1_flag       <=          1'b0;
          
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row2_flag       <=          1'b0;
    else if(mat_row2 == 8'd255)
        mat_row2_flag       <=          1'b1;
    else
        mat_row2_flag       <=          1'b0;
          
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row3_flag       <=          1'b0;
    else if(mat_row3 == 8'd255)
        mat_row3_flag       <=          1'b1;
    else
        mat_row3_flag       <=          1'b0;
          
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row1_1_flag     <=          1'b0;  
    else if(mat_row1_1 == 8'd255)
        mat_row1_1_flag     <=          1'b1;
    else
        mat_row1_1_flag     <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row2_1_flag     <=          1'b0;  
    else if(mat_row2_1 == 8'd255)
        mat_row2_1_flag     <=          1'b1;
    else
        mat_row2_1_flag     <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row3_1_flag     <=          1'b0;  
    else if(mat_row3_1 == 8'd255)
        mat_row3_1_flag     <=          1'b1;
    else
        mat_row3_1_flag     <=          1'b0;
          
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row1_2_flag     <=          1'b0;  
    else if(mat_row1_2 == 8'd255)
        mat_row1_2_flag     <=          1'b1;
    else
        mat_row1_2_flag     <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row2_2_flag     <=          1'b0;  
    else if(mat_row2_2 == 8'd255)
        mat_row2_2_flag     <=          1'b1;
    else
        mat_row2_2_flag     <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row3_2_flag     <=          1'b0;  
    else if(mat_row2_2 == 8'd255)
        mat_row3_2_flag     <=          1'b1;
    else
        mat_row3_2_flag     <=          1'b0;
           
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        tx_data             <=          8'd0; 
    else if(mat_row1_flag + mat_row2_flag + mat_row3_flag + mat_row1_1_flag + mat_row2_1_flag + mat_row3_1_flag + mat_row1_2_flag + mat_row2_2_flag + mat_row3_2_flag >= 'd9)
        tx_data             <=          8'd255;
    else 
        tx_data             <=          8'd0; 

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        po_flag             <=          1'b0;
    else if(mat_flag_2 == 1'b1 && mat_flag_4 == 1'b1) 
        po_flag             <=          1'b1;
    else
        po_flag             <=          1'b0;      
        

mat_3x3 mat_3x3_inst(
    //System Interfaces
    .sclk                   (sclk                   ),
    .rst_n                  (rst_n                  ),
    //Communication Interfaces
    .rx_data                (rx_data                ),
    .pi_flag                (pi_flag                ),
    .mat_row1               (mat_row1               ),
    .mat_row2               (mat_row2               ),
    .mat_row3               (mat_row3               ),
    .mat_flag               (mat_flag               )

);
 

endmodule

相信同学们从上面的代码,再结合原理可以学会图像的腐蚀操作。同样,这里说明一下为了文章的简洁性,我们这里不再给出整个工程的代码,知识给出了中值滤波部分的程序。具体的项目工程代码查看前面的文章***基于FPGA的图像边缘检测***,至于要把这篇论文种的sobel模块换成上面的sobel便可以完成图像的中值滤波,至于这里取名字sobel也只是因为偷懒没改模块名。

图像膨胀代码

图像腐蚀与膨胀的操作几乎一模一样,这里不加赘述。直接给出相应的源码。

`timescale 1ns / 1ps
// *********************************************************************************
// Project Name : OSXXXX
// Author       : zhangningning
// Email        : [email protected]
// Website      : 
// Module Name  : sobel.v
// Create Time  : 2020-04-08 08:32:02
// Editor       : sublime text3, tab size (4)
// CopyRight(c) : All Rights Reserved
//
// *********************************************************************************
// Modification History:
// Date             By              Version                 Change Description
// -----------------------------------------------------------------------
// XXXX       zhangningning          1.0                        Original
//  
// *********************************************************************************

module sobel(
    //System Interfaces
    input                   sclk            ,
    input                   rst_n           ,
    //Communication Interfaces
    input           [ 7:0]  rx_data         ,
    input                   pi_flag         ,
    output  reg     [ 7:0]  tx_data         ,
    output  reg             po_flag         
);
 
//========================================================================================\
//**************Define Parameter and  Internal Signals**********************************
//========================================================================================/
parameter           COL_NUM     =   1024    ;
parameter           ROW_NUM     =   768     ;
parameter           VALUE       =   80      ;

wire                [ 7:0]  mat_row1        ;
wire                [ 7:0]  mat_row2        ;
wire                [ 7:0]  mat_row3        ;
wire                        mat_flag        ; 
reg                 [ 7:0]  mat_row1_1      ;
reg                 [ 7:0]  mat_row2_1      ;
reg                 [ 7:0]  mat_row3_1      ;
reg                 [ 7:0]  mat_row1_2      ;
reg                 [ 7:0]  mat_row2_2      ;
reg                 [ 7:0]  mat_row3_2      ;
reg                         mat_flag_1      ; 
reg                         mat_flag_2      ; 
reg                         mat_flag_3      ; 
reg                         mat_flag_4      ; 
reg                         mat_flag_5      ; 
reg                         mat_flag_6      ; 
reg                         mat_flag_7      ;
     

reg                         mat_row1_flag   ;
reg                         mat_row2_flag   ;
reg                         mat_row3_flag   ; 
reg                         mat_row1_1_flag ;
reg                         mat_row2_1_flag ;
reg                         mat_row3_1_flag ;
reg                         mat_row1_2_flag ;
reg                         mat_row2_2_flag ;
reg                         mat_row3_2_flag ; 

 
//========================================================================================\
//**************     Main      Code        **********************************
//========================================================================================/
always @(posedge sclk)
    begin
        mat_row1_1          <=          mat_row1;
        mat_row2_1          <=          mat_row2;
        mat_row3_1          <=          mat_row3;
        mat_row1_2          <=          mat_row1_1;
        mat_row2_2          <=          mat_row2_1;
        mat_row3_2          <=          mat_row3_1;
    end
    
always @(posedge sclk)
    begin
        mat_flag_1          <=          mat_flag;      
        mat_flag_2          <=          mat_flag_1;      
        mat_flag_3          <=          mat_flag_2;      
        mat_flag_4          <=          mat_flag_3;      
        mat_flag_5          <=          mat_flag_4;      
        mat_flag_6          <=          mat_flag_5;      
        mat_flag_7          <=          mat_flag_6;      
    end

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row1_flag       <=          1'b0;
    else if(mat_row1 == 8'd255)
        mat_row1_flag       <=          1'b1;
    else
        mat_row1_flag       <=          1'b0;
          
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row2_flag       <=          1'b0;
    else if(mat_row2 == 8'd255)
        mat_row2_flag       <=          1'b1;
    else
        mat_row2_flag       <=          1'b0;
          
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row3_flag       <=          1'b0;
    else if(mat_row3 == 8'd255)
        mat_row3_flag       <=          1'b1;
    else
        mat_row3_flag       <=          1'b0;
          
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row1_1_flag     <=          1'b0;  
    else if(mat_row1_1 == 8'd255)
        mat_row1_1_flag     <=          1'b1;
    else
        mat_row1_1_flag     <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row2_1_flag     <=          1'b0;  
    else if(mat_row2_1 == 8'd255)
        mat_row2_1_flag     <=          1'b1;
    else
        mat_row2_1_flag     <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row3_1_flag     <=          1'b0;  
    else if(mat_row3_1 == 8'd255)
        mat_row3_1_flag     <=          1'b1;
    else
        mat_row3_1_flag     <=          1'b0;
          
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row1_2_flag     <=          1'b0;  
    else if(mat_row1_2 == 8'd255)
        mat_row1_2_flag     <=          1'b1;
    else
        mat_row1_2_flag     <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row2_2_flag     <=          1'b0;  
    else if(mat_row2_2 == 8'd255)
        mat_row2_2_flag     <=          1'b1;
    else
        mat_row2_2_flag     <=          1'b0;

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        mat_row3_2_flag     <=          1'b0;  
    else if(mat_row2_2 == 8'd255)
        mat_row3_2_flag     <=          1'b1;
    else
        mat_row3_2_flag     <=          1'b0;
           
always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        tx_data             <=          8'd0; 
    else if(mat_row1_flag + mat_row2_flag + mat_row3_flag + mat_row1_1_flag + mat_row2_1_flag + mat_row3_1_flag + mat_row1_2_flag + mat_row2_2_flag + mat_row3_2_flag >= 'd1)
        tx_data             <=          8'd255;
    else 
        tx_data             <=          8'd0; 

always @(posedge sclk or negedge rst_n)
    if(rst_n == 1'b0)
        po_flag             <=          1'b0;
    else if(mat_flag_2 == 1'b1 && mat_flag_4 == 1'b1) 
        po_flag             <=          1'b1;
    else
        po_flag             <=          1'b0;      
        

mat_3x3 mat_3x3_inst(
    //System Interfaces
    .sclk                   (sclk                   ),
    .rst_n                  (rst_n                  ),
    //Communication Interfaces
    .rx_data                (rx_data                ),
    .pi_flag                (pi_flag                ),
    .mat_row1               (mat_row1               ),
    .mat_row2               (mat_row2               ),
    .mat_row3               (mat_row3               ),
    .mat_flag               (mat_flag               )

);
 

endmodule

对比两种操作的代码,可以发现,我们只是将标志累加和从9换成了1。

下板现象

原图:
在这里插入图片描述
FPGA腐蚀之后的图像:
在这里插入图片描述
FPGA膨胀之后的图像:
在这里插入图片描述
从上面直观的观察可以发现我们处理的正确性。

总结

创作不易,认为文章有帮助的同学们可以关注、点赞、转发支持。(txt文件、图片文件在群中)对文章有什么看法或者需要更近一步交流的同学,可以加入下面的群:
在这里插入图片描述

发布了55 篇原创文章 · 获赞 38 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/zhangningning1996/article/details/105426878
今日推荐