基于FPGA的二值图像的腐蚀算法的实现

基于FPGA的二值图像的腐蚀算法的实现

九层之台,起于累土

1 背景知识

腐蚀和膨胀是形态学处理的基础,许多形态学算法都是以这两种操作作为基础的。

 

基于FPGA的二值图像的腐蚀算法的实现_第1张图片

                   1 使用腐蚀去除图像中的部件

1 a一幅大小为486x486的连线模板二值图像,图1b~d分别使用11x11,15X1545X45的模板进行腐蚀。我们从这个例子看到,腐蚀缩小或细化了二值图像中的物体。事实上,我们可以将腐蚀看成是形态学滤波操作,这种操作将小于模板的图像细节从图像中滤除。

2 腐蚀算法

使用白色腐蚀:    

基于FPGA的二值图像的腐蚀算法的实现_第2张图片

2 腐蚀演示

在二值图像的腐蚀算法过程中我们使用二值图像3x3图像矩阵,由图2可知,当九个格子中不全为‘0’或者‘1’时,经过腐蚀算法后九个格子的值最终都会变成‘1’;如果九个全是‘1’或者‘0’时,那么最终的结果九个全是‘1’或者‘0’。

3 FPGA腐蚀算法实现

 

基于FPGA的二值图像的腐蚀算法的实现_第3张图片

3 二值图像腐蚀FPGA模块架构

3中我们使用串口传图,传入的是二值图像。

FPGA源码:

/*

Module name:  binary_image_etch.v

Description:  binary image etch

*/

`timescale 1ns/1ps

 

module binary_image_etch(

       input             clk,  //pixel clk

 input             rst_n,

 input             hs_in,

 input             vs_in,

 input [15:0]      data_in,

 input             data_in_en,

 

 output            hs_out,

 output            vs_out,

 output  reg [15:0]    data_out,

 output            data_out_en

 );

 

wire [15:0] line0;

wire [15:0] line1;

wire [15:0] line2;

 

reg [15:0] line0_data0;

reg [15:0] line0_data1;

reg [15:0] line0_data2;

 

reg [15:0] line1_data0;

reg [15:0] line1_data1;

reg [15:0] line1_data2;

 

reg [15:0] line2_data0;

reg [15:0] line2_data1;

reg [15:0] line2_data2;

 

reg        data_out_en0;

reg        data_out_en1;

reg        data_out_en2;

reg        hs_r0;

reg        hs_r1;

reg        hs_r2;

 

reg        vs_r0;

reg        vs_r1;

reg        vs_r2;

wire[18:0]  result_data;

 

line3x3 line3x3_inst(

        .clken(data_in_en),

     .clock(clk),

     .shiftin(data_in),

     .shiftout(),

     .taps0x(line0),

     .taps1x(line1),

     .taps2x(line2)

  );

//----------------------------------------------------------------------

// Form an image matrix of three multiplied by three

//----------------------------------------------------------------------

always @(posedge clk or negedge rst_n) begin

  if(!rst_n) begin

    line0_data0 <= 16'b0;

 line0_data1 <= 16'b0;

 line0_data2 <= 16'b0;

 

 line1_data0 <= 16'b0;

 line1_data1 <= 16'b0;

 line1_data2 <= 16'b0;

 

 line2_data0 <= 16'b0;

 line2_data1 <= 16'b0;

 line2_data2 <= 16'b0;

 

 data_out_en0 <= 1'b0;

 data_out_en1 <= 1'b0;

 data_out_en2 <= 1'b0;

 

 hs_r0 <= 1'b0;

 hs_r1 <= 1'b0;

 hs_r2 <= 1'b0;

 

 vs_r0 <= 1'b0;

 vs_r1 <= 1'b0;

 vs_r2 <= 1'b0;

  end

  else if(data_in_en) begin

    line0_data0 <= line0;

 line0_data1 <= line0_data0;

 line0_data2 <= line0_data1;

 

 line1_data0 <= line1;

 line1_data1 <= line1_data0;

 line1_data2 <= line1_data1;

 

 line2_data0 <= line2;

 line2_data1 <= line2_data0;

 line2_data2 <= line2_data1;

 

 data_out_en0 <= data_in_en;

 data_out_en1 <= data_out_en0;

 data_out_en2 <= data_out_en1;

   

    hs_r0 <= hs_in;

 hs_r1 <= hs_r0;

 hs_r2 <= hs_r1;

 

 vs_r0 <= vs_in;

 vs_r1 <= vs_r0;

 vs_r2 <= vs_r1;

  end

end

 

//-----------------------------------------------------------------

// line0_data0   line0_data1   line0_data2

// line1_data0   line1_data1   line1_data2

// line2_data0   line2_data1   line2_data2

//----------------------------------------------------------------

/*

always @(posedge clk or negedge rst_n) begin

  if(!rst_n)

    data_out <= 16'h0000;

  else if(data_out_en1)

    if(line0_data0 ^ line0_data1 ^ line0_data2 ^ line1_data0 ^ line1_data1 ^ line1_data2 ^ line2_data0 ^ line2_data1 ^ line2_data2)

      data_out <= line1_data1;

    else

   data_out <= 16'hffff;  // 

end

*/

 

always @(posedge clk or negedge rst_n) begin

  if(!rst_n)

    data_out <= 16'h0000;

  else if(data_out_en1)

    if((line0_data0 == 16'h0000) && (line0_data1 == 16'h0000) && (line0_data2 == 16'h0000) && (line1_data0 == 16'h0000) && (line1_data1 == 16'h0000) && (line1_data2 == 16'h0000) && (line2_data0 == 16'h0000) && (line2_data1 == 16'h0000) && (line2_data2 == 16'h0000))

      data_out <= line1_data1;

    else if((line0_data0 == 16'hffff) && (line0_data1 == 16'hffff) && (line0_data2 == 16'hffff) && (line1_data0 == 16'hffff) && (line1_data1 == 16'hffff) && (line1_data2 == 16'hffff) && (line2_data0 == 16'hffff) && (line2_data1 == 16'hffff) && (line2_data2 == 16'hffff))

      data_out <= line1_data1;

    else

      data_out <= 16'hffff; 

end

 

endmodule  

IP设置

基于FPGA的二值图像的腐蚀算法的实现_第4张图片

 

图4 line3x3 IP

  如图4所示,shift register(RAM-based)ip主要为了形成三行像素缓存。

4.3TFT显示屏的行缓存大小为4805TFT显示屏的行缓存大小为800

4实验结果

基于FPGA的二值图像的腐蚀算法的实现_第5张图片

 

图5 实验原图

基于FPGA的二值图像的腐蚀算法的实现_第6张图片

 

图6 原图显示

 

基于FPGA的二值图像的腐蚀算法的实现_第7张图片

 

图7 腐蚀后的结果

结果分析:

    图6和图7进行对比,图6中最细的图案在图7中已经消失,比较粗的线条也相对变细,实验成功。如果大家想进行更大力度的腐蚀可以使用更大的模板。

   最后欢迎大家关注我的微信公众号FPGA开源工作室和QQ资料群

基于FPGA的二值图像的腐蚀算法的实现_第8张图片基于FPGA的二值图像的腐蚀算法的实现_第9张图片

 

 

 

 

 

你可能感兴趣的:(基于FPGA的二值图像的腐蚀算法的实现)