FPGA图像处理-sobel边缘检测

简介

串口传图进FPGA,对图片进行灰度化后进行sobel边缘检测,再通过vga显示。
开发板:DE2
开发工具:Quartus 13.0

sobel算子原理

以下内容来自crazybingo:
该算子包含两组3x3的矩阵,分别为横向及纵向,将之与图像作平面
卷积,即可分别得出横向及纵向的亮度差分近似值。如果以 A 代表原始
图像,Gx 及 Gy 分别代表经横向及纵向边缘检测的图像灰度值,其公式
如下:
在这里插入图片描述
图像的每一个像素的横向及纵向灰度值通过以下公式结合,来计算
该点灰度的大小:
在这里插入图片描述
如果梯度 G 大于某一阀值 则认为该点(x,y)为边缘点。

sobel边缘检测模块简介

module Sobel_Edge_Detect(
    input clk,
    input rst_n,
    
    // sobel边缘检测的阈值
    input [7:0] Sobel_Threshold,

    input iValid,
    input [7:0] iData,

    output oValid,
    output reg [7:0] oData
);

输入和输出依旧是valid+data形式,不过比之前的图像处理模块多了个sobel边缘阈值输入,当然,不要这个输入,用固定的阈值也行。

流水线方式实现sobel边缘检测

分析上述公式,总体上分为三步,我们首先要算出Gx和Gy,然后求平方和开根号,最后根据阈值决定是不是边缘点。可以分为5级流水线:

  • 第一级 计算Gx模板的左列和、右列和,计算Gy模板的上行和、下行和
  • 第二级 计算Gx和Gy
  • 第三级 计算Gx和Gy的平方和
  • 第四级 对平方和开根号
  • 第五级 根据阈值决定边缘点

获取3x3卷积模板

第一步自然是先获取3x3卷积模板,在之前的博客中有介绍过,这一步消耗2时钟周期。

filter_3x3 inst_filter_3x3(
    .clk      (clk),
    .rst_n    (rst_n),
    .iValid   (iValid),
    .iData    (iData),
    .oValid   (filter_oValid),
    .oData_11 (filter_11), .oData_12 (filter_12), .oData_13 (filter_13),
    .oData_21 (filter_21), .oData_22 (filter_22), .oData_23 (filter_23),
    .oData_31 (filter_31), .oData_32 (filter_32), .oData_33 (filter_33)
);

第一级流水线

计算Gx模板的左列和、右列和,计算Gy模板的上行和、下行和

always @(posedge clk, negedge rst_n) begin
    if(!rst_n) begin
        Gx_col_1 <= 0;
        Gx_col_3 <= 0;
        Gy_row_1 <= 0;
        Gy_row_3 <= 0;
    end else begin
        // Gx模板的左列和与右列和
        Gx_col_1 <= filter_11 + (filter_21 << 1) + filter_31;
        Gx_col_3 <= filter_13 + (filter_23 << 1) + filter_33;
        // Gy模板的上行和与下行和
        Gy_row_1 <= filter_11 + (filter_12 << 1) + filter_13;
        Gy_row_3 <= filter_31 + (filter_32 << 1) + filter_33;
    end
end

第二级流水线

计算Gx和Gy

always @(posedge clk, negedge rst_n) begin
    if(!rst_n) begin
        Gx <= 0;
        Gy <= 0;
    end else begin
        Gx <= (Gx_col_1 >= Gx_col_3) ? (Gx_col_1 - Gx_col_3) : (Gx_col_3 - Gx_col_1);
        Gy <= (Gy_row_1 >= Gy_row_3) ? (Gy_row_1 - Gy_row_3) : (Gy_row_3 - Gy_row_3);
    end
end

第三级流水线

计算Gx和Gy的平方和

always @(posedge clk, negedge rst_n) begin
    if(!rst_n)
        G_square <= 0;
    else
        G_square <= Gx * Gx + Gy * Gy;
end

第四级流水线

对平方和开根号,这一步直接用Quartus中的ip核,设置其时钟周期消耗为1

ALT_SQRT inst_ALT_SQRT(
    .clk(clk), 
    .radical(G_square), 
    .q(G_sqrt), 
    .remainder()
);

第五级流水线

根据阈值决定边缘点,这里选择白色背景,黑色边缘。

always @(posedge clk, negedge rst_n) begin
    if(!rst_n)
        oData <= 8'd255;
    else if(G_sqrt > Sobel_Threshold)
        oData <= 0;
    else
        oData <= 8'd255;
end

由于3x3模板消耗了2时钟周期,sobel边缘检测消耗了5时钟周期,所以总共消耗7时钟周期,oValid需要比iValid延后7个时钟周期。

效果演示

阈值输入为80,发送的图片为:
在这里插入图片描述
VGA显示为:
在这里插入图片描述

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值