FPGA图像处理(六)------ 图像腐蚀and图像膨胀

发布于:2025-05-14 ⋅ 阅读:(11) ⋅ 点赞:(0)

默认迭代次数为1,只进行一次腐蚀、膨胀

一、图像腐蚀

1.相关定义 

2.图像腐蚀效果图

 

3.fpga实现 

彩色图像灰度化,灰度图像二值化,图像缓存生成滤波模块(3*3),图像腐蚀算法

`timescale 1ns / 1ps
//
// Description: 图像腐蚀 (前景色是黑色(0),背景色是白色(1)  腐蚀黑色)
//
module image_erode(
   input wire           clk             ,
   input wire           reset           ,
   
   input wire [10:0]    img_width       ,
   input wire [9:0]     img_height      ,
   
   input wire           valid_i         ,
   input wire [23:0]    last_line_data  ,
   input wire [23:0]    cur_line_data   ,
   input wire [23:0]    next_line_data  ,
   
   output reg           valid_o         ,
   output reg [23:0]    img_data_o
);
    //常量声明
    parameter N = 3; //窗口大小
    //结构系数模版为{1,1,1,
    //              1,1,1,
    //              1,1,1}
 
    //变量声明
    reg         valid_d1;
    reg [23:0]  last_line_data_d1, last_line_data_d2;
    reg [23:0]  cur_line_data_d1 , cur_line_data_d2 ;
    reg [23:0]  next_line_data_d1, next_line_data_d2;

    //中心点位置,为cur_line_data_d1
    always@(posedge clk or posedge reset) begin
        if(reset) begin
            valid_d1 <= 0;
            {last_line_data_d1, last_line_data_d2} <= 0;
            {cur_line_data_d1 , cur_line_data_d2 } <= 0;
            {next_line_data_d1, next_line_data_d2} <= 0;
        end else begin
            valid_d1 <= valid_i;
            last_line_data_d1 <= last_line_data;
            last_line_data_d2 <= last_line_data_d1;
            cur_line_data_d1  <= cur_line_data;
            cur_line_data_d2  <= cur_line_data_d1;
            next_line_data_d1 <= next_line_data;
            next_line_data_d2 <= next_line_data_d1;
        end
    end

    //模板窗口范围内判断,前景色是黑色,背景色是白色,腐蚀处理就是前景色黑色减少
    //简单理解也就是,3*3窗口中所有像素值都是0时,才能将当前像素值为0输出

    always@(posedge clk or posedge reset) begin
        if(reset) begin
            valid_o <= 0;
            img_data_o <= 0;
        end 
        else if(valid_d1) begin
            if({last_line_data_d2, last_line_data_d1, last_line_data,
                cur_line_data_d2 , cur_line_data_d1 , cur_line_data ,
                next_line_data_d2, next_line_data_d1, next_line_data} == {27{8'd0}}) begin

                img_data_o <= cur_line_data_d1;
                    
            end 
            else begin
                img_data_o <= {3{8'd255}};   
            end
            valid_o <= 1'b1;
        end 
        else begin
            valid_o <= 0;
            img_data_o <= 0;
        end
    end
      
endmodule

明显可以看书汉字部分,经过腐蚀运算之后,白色字体变宽了(要是清晰显示文字,应该腐蚀白色,效果可能更好一点) 


二、图像膨胀

1.相关定义

 2.图像膨胀与图像腐蚀的联系

 3.FPGA实现

`timescale 1ns / 1ps
//
// Description: 图像膨胀 (前景色是黑色,背景色是白色  只要覆盖区域有前景色则膨胀黑色)
//
module image_dilate(
   input  wire          clk             ,
   input  wire          reset           ,
    
   input  wire [10:0]   img_width       ,
   input  wire [9:0]    img_height      ,
    
   input  wire          valid_i         ,
   input  wire [23:0]   last_line_data  ,
   input  wire [23:0]   cur_line_data   ,
   input  wire [23:0]   next_line_data  , 
   
   output reg           valid_o         ,
   output reg [23:0]    img_data_o      
);
    //常量声明
    parameter N = 3; //窗口大小
    //结构系数模版为{1,1,1,1,1,1,1,1,1}

    //变量声明
    reg valid_d1;
    reg [23:0] last_line_data_d1, last_line_data_d2;
    reg [23:0] cur_line_data_d1 , cur_line_data_d2 ;
    reg [23:0] next_line_data_d1, next_line_data_d2;

    //中心点位置,为cur_line_data_d1
    always@(posedge clk or posedge reset) begin
        if(reset) begin
            valid_d1 <= 0;
            {last_line_data_d1, last_line_data_d2} <= 0;
            {cur_line_data_d1 , cur_line_data_d2 } <= 0;
            {next_line_data_d1, next_line_data_d2} <= 0;
        end else begin
            valid_d1 <= valid_i;
            last_line_data_d1 <= last_line_data;
            last_line_data_d2 <= last_line_data_d1;
            cur_line_data_d1  <= cur_line_data;
            cur_line_data_d2  <= cur_line_data_d1;
            next_line_data_d1 <= next_line_data;
            next_line_data_d2 <= next_line_data;
        end
    end

    //模板窗口范围内判断,前景色是黑色,背景色是白色,膨胀处理就是前景色黑色扩张
    //简单理解也就是,3*3窗口中所有像素值都是255(白)时,才能将当前像素值为255输出
    always@(posedge clk or posedge reset) begin
        if(reset) begin
            valid_o <= 0;
            img_data_o <= 0;
        end else if(valid_d1) begin
            if({last_line_data_d2, last_line_data_d1, last_line_data,
                cur_line_data_d2 , cur_line_data_d1 , cur_line_data ,
                next_line_data_d2, next_line_data_d1, next_line_data} == {27{8'd255}}) begin

                img_data_o <= cur_line_data_d1;
                    
            end else begin
                img_data_o <= 0;   
            end
            valid_o <= 1'b1;
        end else begin
            valid_o <= 0;
            img_data_o <= 0;
        end
    end

endmodule

 三、图像处理的开运算,闭运算和梯度运算

1.相关定义 

2.fpga实现 

开运算:

闭运算 :

梯度运算:

module image_process_top(
   input wire clk,
   input wire reset,
   
   input wire [10:0] img_width,
   input wire [9:0] img_height,
   
   input wire valid_i,
   input wire [23:0] img_data_i,
   
   output wire valid_o,
   output wire [23:0] img_data_o
    );

    //参数定义
    wire rgb2gray_valid;
    wire [23:0] rgb2gray_data;

    wire binary_valid;
    wire [23:0] binary_data;

    wire line_valid;
    wire [23:0] last_line_data, cur_line_data, next_line_data;
    
    wire erode_valid;
    wire [23:0] erode_data;
    
    wire dilate_valid;
    wire [23:0] dilate_data;
    
    wire line1_valid;
    wire [23:0] last_line1_data, cur_line1_data, next_line1_data;
    
    //灰度化处理
    image_rgb2gray u_image_rgb2gray(
    .clk        ( clk        ),
    .reset      ( reset      ),
    .valid_i    ( valid_i    ),
    .img_data_i ( img_data_i ),
    .valid_o    ( rgb2gray_valid    ),
    .img_data_o  ( rgb2gray_data  )
    );


    //二值化处理
     image_binary u_image_binary(
    .clk        ( clk        ),
    .reset      ( reset      ),
    .valid_i    ( rgb2gray_valid    ),
    .img_data_i ( rgb2gray_data ),
    .valid_o    ( binary_valid    ),
    .img_data_o  ( binary_data  )
    );

    //开运算
/*
    //3行缓存
    image_line_buffer u_image_line_buffer(
    .clk            ( clk            ),
    .reset          ( reset          ),
    .img_width      ( img_width      ),
    .img_height     ( img_height     ),
    .valid_i        ( binary_valid ),
    .img_data_i     ( binary_data ),
    .valid_o        ( line_valid        ),
    .last_line_data ( last_line_data ),
    .cur_line_data  ( cur_line_data  ),
    .next_line_data  ( next_line_data  )
    );


    //图像腐蚀
    image_erode u_image_erode(
    .clk            ( clk            ),
    .reset          ( reset          ),
    .img_width      ( img_width      ),
    .img_height     ( img_height     ),
    .valid_i        ( line_valid        ),
    .last_line_data ( last_line_data ),
    .cur_line_data  ( cur_line_data  ),
    .next_line_data ( next_line_data ),
    .valid_o        ( erode_valid    ),
    .img_data_o     ( erode_data     )
    );

    //3行缓存
    image_line_buffer u_image_line_buffer1(
    .clk            ( clk            ),
    .reset          ( reset          ),
    .img_width      ( img_width      ),
    .img_height     ( img_height     ),
    .valid_i        ( erode_valid ),
    .img_data_i     ( erode_data ),
    .valid_o        ( line1_valid        ),
    .last_line_data ( last_line1_data ),
    .cur_line_data  ( cur_line1_data  ),
    .next_line_data  ( next_line1_data  )
    );

    //图像膨胀
    image_dilate u_image_dilate(
    .clk            ( clk            ),
    .reset          ( reset          ),
    .img_width      ( img_width      ),
    .img_height     ( img_height     ),
    .valid_i        ( line1_valid        ),
    .last_line_data ( last_line1_data ),
    .cur_line_data  ( cur_line1_data  ),
    .next_line_data ( next_line1_data ),
    .valid_o        ( valid_o        ),
    .img_data_o     ( img_data_o     )
    );
*/

    //闭运算
/*
    //3行缓存
    image_line_buffer u_image_line_buffer(
    .clk            ( clk            ),
    .reset          ( reset          ),
    .img_width      ( img_width      ),
    .img_height     ( img_height     ),
    .valid_i        ( binary_valid ),
    .img_data_i     ( binary_data ),
    .valid_o        ( line_valid        ),
    .last_line_data ( last_line_data ),
    .cur_line_data  ( cur_line_data  ),
    .next_line_data  ( next_line_data  )
    );


    //图像膨胀
    image_dilate u_image_dilate(
    .clk            ( clk            ),
    .reset          ( reset          ),
    .img_width      ( img_width      ),
    .img_height     ( img_height     ),
    .valid_i        ( line_valid        ),
    .last_line_data ( last_line_data ),
    .cur_line_data  ( cur_line_data  ),
    .next_line_data ( next_line_data ),
    .valid_o        ( dilate_valid    ),
    .img_data_o     ( dilate_data     )
    );

    //3行缓存
    image_line_buffer u_image_line_buffer1(
    .clk            ( clk            ),
    .reset          ( reset          ),
    .img_width      ( img_width      ),
    .img_height     ( img_height     ),
    .valid_i        ( dilate_valid ),
    .img_data_i     ( dilate_data ),
    .valid_o        ( line1_valid        ),
    .last_line_data ( last_line1_data ),
    .cur_line_data  ( cur_line1_data  ),
    .next_line_data  ( next_line1_data  )
    );

    //图像腐蚀
    image_erode u_image_erode(
    .clk            ( clk            ),
    .reset          ( reset          ),
    .img_width      ( img_width      ),
    .img_height     ( img_height     ),
    .valid_i        ( line1_valid        ),
    .last_line_data ( last_line1_data ),
    .cur_line_data  ( cur_line1_data  ),
    .next_line_data ( next_line1_data ),
    .valid_o        ( valid_o        ),
    .img_data_o     ( img_data_o     )
    );
*/

    //梯度运算

    //3行缓存
    image_line_buffer u_image_line_buffer(
    .clk            ( clk            ),
    .reset          ( reset          ),
    .img_width      ( img_width      ),
    .img_height     ( img_height     ),
    .valid_i        ( binary_valid ),
    .img_data_i     ( binary_data ),
    .valid_o        ( line_valid        ),
    .last_line_data ( last_line_data ),
    .cur_line_data  ( cur_line_data  ),
    .next_line_data  ( next_line_data  )
    );


    //图像膨胀
    image_dilate u_image_dilate(
    .clk            ( clk            ),
    .reset          ( reset          ),
    .img_width      ( img_width      ),
    .img_height     ( img_height     ),
    .valid_i        ( line_valid        ),
    .last_line_data ( last_line_data ),
    .cur_line_data  ( cur_line_data  ),
    .next_line_data ( next_line_data ),
    .valid_o        ( dilate_valid    ),
    .img_data_o     ( dilate_data     )
    );

    //图像腐蚀
    image_erode u_image_erode(
    .clk            ( clk            ),
    .reset          ( reset          ),
    .img_width      ( img_width      ),
    .img_height     ( img_height     ),
    .valid_i        ( line_valid        ),
    .last_line_data ( last_line_data ),
    .cur_line_data  ( cur_line_data  ),
    .next_line_data ( next_line_data ),
    .valid_o        ( erode_valid    ),
    .img_data_o     ( erode_data     )
    );

    assign valid_o = dilate_valid;
    assign img_data_o = (dilate_data == 0)&&(erode_data == {3{8'd255}}) ? 0 : {3{8'd255}};

endmodule


网站公告

今日签到

点亮在社区的每一天
去签到