基於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文件、圖片文件在羣中)對文章有什麼看法或者需要更近一步交流的同學,可以加入下面的羣:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章