sobel边缘检测

一:sobel边缘检测的基本原理

在图像中,边缘是指临界的意思,一幅图像的临界表现为图像上亮度显著变化的地方。实现边缘检测有很多种不同的方法,其中sobel算子方法较好。sobel是一个梯度的计算,如下图所示,是x和y方向的3x3窗口的卷积

其实左图是计算在x方向的算子,Gx是图像数据与其进行卷积后的结果,也是个3x3的矩阵,然后窗口一直在滑动,实际的计算公式是下图

实际为了进一步简化计算,把算子进行简化,调整为如下图

二:程序设计

在网上看了许多别人的代码,感觉sobel的计算公式代码都不一样,这使我疑惑了好久,后来发现是为了方便编写代码,大家都把公式进行了简化,所以代码看起来不太一样,但实际上效果都是差不多的。本实验做了一个三行的图像缓存,这样可以轻松实现3x3的窗口,然后按照简化公式,采用绝对值的方式计算sobel。

always@(posedge pclk)
begin
    x1 <= {2'b00,p11} + {2'b00,p31} + {1'b0,p21,1'b0};
    x3 <= {2'b00,p13} + {2'b00,p33} + {1'b0,p23,1'b0};
    
    y1 <= {2'b00,p11} + {2'b00,p13} + {1'b0,p12,1'b0};
    y3 <= {2'b00,p31} + {2'b00,p33} + {1'b0,p32,1'b0};
end

always@(posedge pclk)
begin
    abs_x <= (x1 > x3) ? x1 - x3 : x3 - x1;
    abs_y <= (y1 > y3) ? y1 - y3 : y3 - y1;
    abs_g <= abs_x + abs_y;
end

计算完成后,要进行简单的二值化处理,将sobel值与阈值对比,产生黑白的二值化图像

always@(posedge pclk)
begin
    data_out <= (abs_g > threshold) ? 8'h00 : 8'hff;
end

完整代码如下

module sobel (
    input                       rst,
    input                       pclk,
    input[7:0]                  threshold,
    input                       ycbcr_hs,
    input                       ycbcr_vs,
    input                       ycbcr_de,
    input[7:0]                  data_in,
    output reg[7:0]             data_out,
    output                      sobel_hs,
    output                      sobel_vs,
    output                      sobel_de
    
);
reg  [7:0]  p11,p12,p13;
reg  [7:0]  p21,p22,p23;
reg  [7:0]  p31,p32,p33;
wire [7:0]  p1,p2,p3;
reg  [9:0]  x1,x3;
reg  [9:0]  y1,y3;
reg  [9:0]  abs_x,abs_y;
reg  [10:0] abs_g;

reg [8:0] hs_buf ;
reg [8:0] vs_buf ;
reg [8:0] de_buf ;

linebuffer_Wapper#
(
    .no_of_lines(3),
    .samples_per_line(1024),
    .data_width(8)
)
 linebuffer_Wapper_m0(
    .ce         (1'b1   ),
    .wr_clk     (pclk   ),
    .wr_en      (ycbcr_de   ),
    .wr_rst     (rst   ),
    .data_in    (data_in),
    .rd_en      (ycbcr_de   ),
    .rd_clk     (pclk   ),
    .rd_rst     (rst   ),
    .data_out   ({p3,p2,p1}  )
   );
always@(posedge pclk)
begin
    p11 <= p1;
    p21 <= p2;
    p31 <= p3;
    
    p12 <= p11;
    p22 <= p21;
    p32 <= p31;
    
    p13 <= p12;
    p23 <= p22;
    p33 <= p32;
end

always@(posedge pclk)
begin
    x1 <= {2'b00,p11} + {2'b00,p31} + {1'b0,p21,1'b0};
    x3 <= {2'b00,p13} + {2'b00,p33} + {1'b0,p23,1'b0};
    
    y1 <= {2'b00,p11} + {2'b00,p13} + {1'b0,p12,1'b0};
    y3 <= {2'b00,p31} + {2'b00,p33} + {1'b0,p32,1'b0};
end

always@(posedge pclk)
begin
    abs_x <= (x1 > x3) ? x1 - x3 : x3 - x1;
    abs_y <= (y1 > y3) ? y1 - y3 : y3 - y1;
    abs_g <= abs_x + abs_y;
end

always@(posedge pclk)
begin
    data_out <= (abs_g > threshold) ? 8'h00 : 8'hff;
end
//hs vs de delay 9 clock
always@(posedge pclk or posedge rst)
begin
  if (rst)
  begin
    hs_buf <= 9'd0 ;
    vs_buf <= 9'd0 ;
    de_buf <= 9'd0 ;
  end
  else
  begin
    hs_buf <= {hs_buf[7:0], ycbcr_hs} ;
     vs_buf <= {vs_buf[7:0], ycbcr_vs} ;
     de_buf <= {de_buf[7:0], ycbcr_de} ;
  end
end

assign sobel_hs = hs_buf[8] ;
assign sobel_vs = vs_buf[8] ;
assign sobel_de = de_buf[8] ;
     
endmodule

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值