设为首页 加入收藏

TOP

基于 FPGA 的图像边缘检测(二)
2017-10-10 12:21:17 】 浏览:8054
Tags:基于 FPGA 图像 边缘 检测
;5   -- >  p21 p22 p23

6  7  8   -- >  p31 p32 p33

核心代码如下:

reg [5:0]p_11,p_12,p_13;  // 3 * 3 卷积核中的像素点
reg [5:0]p_21,p_22,p_23;
reg [5:0]p_31,p_32,p_33;
reg [8:0]mean_value_add1,mean_value_add2,mean_value_add3;//每一行之和


always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        {p_11,p_12,p_13} <= {5'b0,5'b0,5'b0}   ;
        {p_21,p_22,p_23} <= {15'b0,15'b0,15'b0};
        {p_31,p_32,p_33} <= {15'b0,15'b0,15'b0};
    end
    else  begin
     if(per_href_ff0==1&&flag_do==1)begin
        {p_11,p_12,p_13}<={p_12,p_13,row_1};
        {p_21,p_22,p_23}<={p_22,p_23,row_2};
        {p_31,p_32,p_33}<={p_32,p_33,row_3};
     end
     else begin
         {p_11,p_12,p_13}<={5'b0,5'b0,5'b0};
         {p_21,p_22,p_23}<={5'b0,5'b0,5'b0}
         {p_31,p_32,p_33}<={5'b0,5'b0,5'b0}
     end
   end
end



always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        mean_value_add1<=0;
        mean_value_add2<=0;
        mean_value_add3<=0;
    end
    else if(per_href_ff1)begin
        mean_value_add1<=p_11+p_12+p_13;
        mean_value_add2<=p_21+   0   +p_23;
        mean_value_add3<=p_31+p_32+p_33;
    end
end

wire [8:0]mean_value;//8位数之和
wire [5:0]fin_y_data; //平均数,除以8,相当于左移三位。

assign mean_value=mean_value_add1+mean_value_add2+mean_value_add3;
assign fin_y_data=mean_value[8:3]; 

 


 

sobel 边缘检测 

边缘检测的原理

该算子包含两组 3x3 的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。A代表原始图像的 3*3 像素阵列,Gx及Gy分别代表经横向及纵向边缘检测的图像,其公式如下:

图像的每一个像素的横向及纵向梯度近似值可用以下的公式结合,来计算梯度的大小。

 

如果梯度G大于某一阀值则认为该点(x,y)为边缘点。

-------------------------------------------------------------------------------------------------------------------

用的是 边缘检测算法。

难点:(1)掌握了 3*3 像素阵列,Gx 与 Gy 就很好计算了 (注意问题:为了避免计算过程中出现负值,所以将正负值分开单独计算,具体见代码)

        (2)G的计算需要开平方,如何进行开平方运算

Quartus 提供了开平方 ip 核,因此我们直接调用就好了 。

代码:

reg [8:0] p_x_data ,p_y_data ;  // x 和 y 的正值之和
reg [8:0] n_x_data ,n_y_data ; // x 和 y 的负值之和
reg [8:0] gx_data  ,gy_data  ; //最终结果

always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
       p_x_data <=0;
       n_x_data <=0;
       gx_data   <=0;
    end
    else if(per_href_ff1==1) begin 
        p_x_data <= p_13 + (p_23<<1) + p_33 ;
        n_x_data <= p_11 + (p_12<<1 )+ p_13 ;
        gx_data   <= (p_x_data >=n_x_data)? p_x_data - n_x_data : n_x_data - p_x_data ; 
    end
    else begin
         p_x_data<=0;
         n_x_data<=0;
         gx_data <=0;
    end  
end

always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
       p_y_data <=0;
       n_y_data <=0;
       gy_data   <=0;
    end
    else if(per_href_ff1==1) begin
        p_y_data <= p_11 + (p_12<<1) + p_13 ;
        n_y_data <= p_31 + (p_32<<1) + p_33 ;
        gy_data   <= (p_y_data >=n_y_data)? p_y_data - n_y_data : n_y_data - p_y_data ; 
    end
    else begin
        p_y_data <=0;
        n_y_data <=0;
        gy_data   <=0;
   end
end

//求平方和,调用ip核开平方
reg [16:0] gxy; // Gx 与 Gy 的平方和
always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)begin
        gxy<=0;
    end
    else begin
        gxy<= gy_data* gy_data + gx_data* gx_data ;
    end
end

wire [8:0] squart_out ; 
altsquart  u1_altsquart (     //例化开平方的ip核
    .radical (gxy),
    .q       (squart_out),  //输出的结果
    .remainder()
                       );

//与阈值进行比较
reg [15:0] post_y_data_r;
always  @(posedge clk or negedge rst_n)begin
    if(rst_n==1'b0)be
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇verilog 实现中值滤波 下一篇SDRAM 学习(三)之command

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目