0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Sobel算子原理介绍与实现方法

FPGA之家 来源:FPGA科技室 作者:FPGA科技室 2022-07-21 17:27 次阅读

Sobel 原理介绍

索贝尔算子(Sobel operator)主要用作边缘检测,在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰度之近似值。在图像的任何一点使用此算子,将会产生对应的灰度矢量或是其法矢量Sobel 卷积因子为:

ed34c6c8-04a1-11ed-ba43-dac502259ad0.png

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

ed476f3a-04a1-11ed-ba43-dac502259ad0.png

具体计算如下:

Gx = (-1)*f(x-1, y-1) + 0*f(x,y-1) + 1*f(x+1,y-1)

+(-2)*f(x-1,y) + 0*f(x,y)+2*f(x+1,y)

+(-1)*f(x-1,y+1) + 0*f(x,y+1) + 1*f(x+1,y+1)

= [f(x+1,y-1)+2*f(x+1,y)+f(x+1,y+1)]-[f(x-1,y-1)+2*f(x-1,y)+f(x-1,y+1)]

Gy =1* f(x-1, y-1) + 2*f(x,y-1)+ 1*f(x+1,y-1)

+0*f(x-1,y) 0*f(x,y) + 0*f(x+1,y)

+(-1)*f(x-1,y+1) + (-2)*f(x,y+1) + (-1)*f(x+1, y+1)

= [f(x-1,y-1)+2f(x,y-1)+f(x+1,y-1)]-[f(x-1, y+1) + 2*f(x,y+1)+f(x+1,y+1)]

其中 f(a,b), 表示图像(a,b)点的灰度值;

图像的每一个像素的横向及纵向灰度值通过以下公式结合,来计算该点灰度的大小:

ed64d85e-04a1-11ed-ba43-dac502259ad0.png

通常,为了提高效率 使用不开平方的近似值

ed72c252-04a1-11ed-ba43-dac502259ad0.png

Sobel 算子根据像素点上下、左右邻点灰度加权差,在边缘处达到极值这一现象检测边缘。对噪声具有平滑作用,提供较为精确的边缘方向信息,边缘定位精度不够高。当对精度要求不是很高时,是一种较为常用的边缘检测方法。

Sobel 算子在 HLS 上的实现

工程创建

Step1:打开Vivado HLS开发工具,单击Creat New Project创建一个新工程,设置好工程路径和工程名,一直点击 Next 按照默认设置

ed8913e0-04a1-11ed-ba43-dac502259ad0.png

Step2:出现如下图所示界面,时钟周期Clock Period按照默认10nsUncertaintlySolution Name均按照默认设置,点击红色箭头部分选择芯片类型,然后点击 OK。

ed9a241e-04a1-11ed-ba43-dac502259ad0.png

edad5fe8-04a1-11ed-ba43-dac502259ad0.png

edc20aec-04a1-11ed-ba43-dac502259ad0.png

点击Finish,出现如下界面

eddfd31a-04a1-11ed-ba43-dac502259ad0.png

Step4:右单击Source选项,选择New File,创建一个名为Top.cpp的文件。(一定要加cpp后缀)

Step5:打开刚刚新建的cpp文件,进入编辑状态,输入以下代码

ede74794-04a1-11ed-ba43-dac502259ad0.png

Top.cpp代码

#include "top.h"
void hls_sobel(AXI_STREAM& INPUT_STREAM, AXI_STREAM&
OUTPUT_STREAM, int rows, int cols)
{
//Create AXI streaming interfaces for the core
#pragma HLS INTERFACE axis port=INPUT_STREAM
#pragma HLS INTERFACE axis port=OUTPUT_STREAM
#pragma HLS RESOURCE core=AXI_SLAVE variable=rows metadata="- bus_bundle CONTROL_BUS"
#pragma HLS RESOURCE core=AXI_SLAVE variable=cols metadata="-bus_bundle CONTROL_BUS"
#pragma HLS RESOURCE core=AXI_SLAVE variable=return metadata="-bus_bundle CONTROL_BUS"
#pragma HLS INTERFACE ap_stable port=rows
#pragma HLS INTERFACE ap_stable port=cols
RGB_IMAGE img_0(rows, cols);
RGB_IMAGE img_1(rows, cols);
RGB_IMAGE img_2(rows, cols);
RGB_IMAGE img_3(rows, cols);
RGB_IMAGE img_4(rows, cols);
RGB_IMAGE img_5(rows, cols);
RGB_PIXEL pix(50, 50, 50);
#pragma HLS dataflow
hls::AXIvideo2Mat(INPUT_STREAM, img_0);
hls::Sobel<1,0,3>(img_0, img_1);
hls::SubS(img_1, pix, img_2);
hls::Scale(img_2, img_3, 2, 0);
hls::Erode(img_3, img_4);
hls::Dilate(img_4, img_5);
hls::Mat2AXIvideo(img_5, OUTPUT_STREAM)
}

Step6:再在Source中添加一个名为Top.h的库函数,并添加如下程序:

edfb2232-04a1-11ed-ba43-dac502259ad0.png

Top.h代码

#ifndefTOP_H
#defineTOP_H
#include "hls_video.h"
// maximum image size
#define MAX_WIDTH 512
#define MAX_HEIGHT 512
// I/O Image Settings
#define INPUT_IMAGE "lena.jpg"
#define OUTPUT_IMAGE "result.jpg"
#define OUTPUT_IMAGE_GOLDEN "result_golden.jpg"
// typedef video library core structures
typedef hls::stream> AXI_STREAM;
typedef hls::Scalar<3, unsigned char> RGB_PIXEL;
typedef hls::MatRGB_IMAGE;
// top level function for HW synthesis
void hls_sobel(AXI_STREAM& src_axi, AXI_STREAM& dst_axi, int rows, int cols);
#endif

Step7:在Test Bench中,用同样的方法添加一个名为Test.cpp的测试程序。添加如下代码

ee09b36a-04a1-11ed-ba43-dac502259ad0.png

Test.cpp代码

#include "top.h"
#include "opencv_top.h"
using namespace std;
using namespace cv;
int main (int argc, char** argv)
{
//获取图像数据
IplImage* src = cvLoadImage(INPUT_IMAGE);
IplImage* dst = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);

//使用HLS库进行处理
AXI_STREAM src_axi, dst_axi;
IplImage2AXIvideo(src, src_axi);
hls_sobel(src_axi, dst_axi, src->height, src->width);
AXIvideo2IplImage(dst_axi, dst);
cvSaveImage(OUTPUT_IMAGE,dst);
cvShowImage("hls_dst", dst);
//使用OPENCV库进行处理
opencv_image_filter(src, dst);
cvShowImage("cv_dst", dst);
cvSaveImage(OUTPUT_IMAGE_GOLDEN,dst);
waitKey(0);
//释放内存
cvReleaseImage(&src);
cvReleaseImage(&dst);
}

Step8:用同样的方法,再在Test Bench中创建一个opencv_top.cppopencv_top.h文件,添加如下程序:

ee22ec86-04a1-11ed-ba43-dac502259ad0.png

Opencv_top.cpp代码

#include "opencv_top.h"
#include "top.h"
void opencv_image_filter(IplImage* src, IplImage* dst)
{
IplImage* tmp = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
cvCopy(src, tmp);
cv::Mat)tmp, (cv::Mat)dst, -1, 1, 0);
cvSubS(dst, cvScalar(50,50,50), tmp);
cvScale(tmp, dst, 2, 0);
cvErode(dst, tmp);
cvDilate(tmp, dst);
cvReleaseImage(&tmp);
}
void sw_image_filter(IplImage* src, IplImage* dst)
{
AXI_STREAM src_axi, dst_axi;
IplImage2AXIvideo(src, src_axi);
hls_sobel(src_axi, dst_axi, src->height, src->width);
AXIvideo2IplImage(dst_axi, dst);
}

opencv_top.h代码

#ifndefOPENCV_TOP_H___ #define ___OPENCV_TOP_H
#include "hls_opencv.h"
void opencv_image_filter(IplImage* src, IplImage* dst);
void sw_image_filter(IplImage* src, IplImage* dst);
#endif

Step7:在Test Bench中添加一张名为lena.jpg的测试图片

ee2d0f86-04a1-11ed-ba43-dac502259ad0.png

接下来对工程进行编译和仿真

Step1:单击Project-Project settings或直接单击快捷按钮。

ee3fd6e8-04a1-11ed-ba43-dac502259ad0.png

Step2选择Synthesis选项,然后点击Browse..指定一个顶层函数,选定hls_sobel为顶层函数,

ee4c0062-04a1-11ed-ba43-dac502259ad0.png

单击开始综合

ee604dd8-04a1-11ed-ba43-dac502259ad0.png

ee6dd868-04a1-11ed-ba43-dac502259ad0.png

eea38d78-04a1-11ed-ba43-dac502259ad0.png

eeabb6a6-04a1-11ed-ba43-dac502259ad0.jpg

在协议类型里面我们可以看到我们主要使用了三种协议,分别是axisap_stableap_ctrl_hs三种,这些协议的详细解释我们均可以在官方手册ug902中找到,其中ap_ctrl_hs的时序操作如下图所示,说简单点就是复位完成等待ap_start信号开始进行操作

综合完毕,我们对代码进行仿真测试,单击开始仿真

eec59d00-04a1-11ed-ba43-dac502259ad0.png

仿真结果如下,与通过OPENCV实现的Sobel检测结果基本一致。

eecf51b0-04a1-11ed-ba43-dac502259ad0.png

审核编辑:汤梓红


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 算子
    +关注

    关注

    0

    文章

    16

    浏览量

    7253
  • HLS
    HLS
    +关注

    关注

    1

    文章

    129

    浏览量

    24097
  • sobel
    +关注

    关注

    0

    文章

    12

    浏览量

    7904

原文标题:Sobel 算子在 HLS 上的实现

文章出处:【微信号:zhuyandz,微信公众号:FPGA之家】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    基于 DSP5509 进行数字图像处理中 Sobel 算子边缘检测的硬件连接电路图

    以下是基于 DSP5509 进行数字图像处理中 Sobel 算子边缘检测的硬件设计方案: 一、总体架构 图像采集:使用合适的图像传感器,如 CMOS 传感器,通过相应的接口(如 SPI、I2C 等
    发表于 09-25 15:25

    基于FPGA的Sobel边缘检测的实现

    我们在此基础上修改,从而实现,基于FPGA的动态图片的Sobel边缘检测、中值滤波、Canny算子边缘检测、腐蚀和膨胀等。那么这篇文章我们将来实现基于FPGA的
    发表于 08-29 15:41

    Labview图像处理——边缘检测

    边缘的灰度值过度较为明显,梯度算子可以得到较好的边缘检测结果。边缘提取其实也是一种滤波,不同的算子有不同的提取效果。比较常用的方法有三种,Sobel
    发表于 12-01 12:16

    labview视觉自动对焦

    的清晰度?可以通过以下算法定义并计算:Tenengrad梯度方法利用Sobel算子分别计算水平和垂直方向的梯度,同一场景下梯度值越高,图像越清晰。以下是具体实现,这里衡量的指标是经过
    发表于 05-09 17:26

    边缘检测的几种微分算子

    一、边缘检测边缘检测的几种微分算子:一阶微分算子:Roberts、Sobel、Prewitt二阶微分算子:Laplacian、Log/Marr非微分
    发表于 07-26 08:29

    EdgeBoard中神经网络算子在FPGA中的实现方法是什么?

    FPGA加速的关键因素是什么?EdgeBoard中神经网络算子在FPGA中的实现方法是什么?
    发表于 09-28 06:37

    迅为iTOP-RK3568开发板Sobel 算子边缘检测

    (索贝尔)算子是计算机视觉领域的一种重要处理方法。主要用于获得数字图像的一阶梯度,常见的应用和物理意义是边缘检测。 索贝尔算子把图像中每个像素的上下左右四领域的灰度值加权差,在边缘处达到极值从而检测边缘
    发表于 09-18 10:27

    拉普拉斯算子的FPGA实现方法

    拉普拉斯算子的FPGA实现方法  引 言   在图像处理系统中常需要对图像进行预处理。由于图像处理的数据量大,对于实时性要求高的系统,采用软件实现通常
    发表于 02-11 11:01 1527次阅读
    拉普拉斯<b class='flag-5'>算子</b>的FPGA<b class='flag-5'>实现</b><b class='flag-5'>方法</b>

    LOG算子在FPGA中的实现

    介绍了一种高斯拉普拉斯LOG算子在FPGA中的实现方案!并通过对一幅BMP图像的处理!论证了在FPGA中实现的LOG算子的图像增强效果
    发表于 05-16 17:12 50次下载
    LOG<b class='flag-5'>算子</b>在FPGA中的<b class='flag-5'>实现</b>

    Vivado HLS在Zedboard中的Sobel滤波算法实现步骤教程

    索贝尔算子Sobel operator)主要用作边缘检测,在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰度之近似值。在图像的任何一点使用此算子,将会产生对应的灰度矢量或是其
    的头像 发表于 07-14 06:05 3773次阅读
    Vivado HLS在Zedboard中的<b class='flag-5'>Sobel</b>滤波算法<b class='flag-5'>实现</b>步骤教程

    基于CORDIC的高速Sobel算法实现

    为提高图像边缘检测的处理速度,提出一种基于CORDIC的高速Sobel算法实现
    的头像 发表于 10-05 09:54 3561次阅读
    基于CORDIC的高速<b class='flag-5'>Sobel</b>算法<b class='flag-5'>实现</b>

    Laplacian算子的FPGA实现方法

    拉普拉斯算子是一种重要的图像增强算子,它是一种各向同性滤波器,即滤波器的响应与滤波器作用图像的突变方向无关,而且实现简单,被广泛用于图像锐化和高频增强等算法中。在此,提出一种使用QuartusⅡ开发环境的Megafunction
    的头像 发表于 06-16 17:47 3263次阅读
    Laplacian<b class='flag-5'>算子</b>的FPGA<b class='flag-5'>实现</b><b class='flag-5'>方法</b>

    浅述Sobel算子在HLS上的实现教程

    Sobel 原理介绍 索贝尔算子Sobel operator)主要用作边缘检测,在技术上,它是一离散性差分算子,用来运算图像亮度函数的灰度
    的头像 发表于 07-23 14:53 2296次阅读
    浅述<b class='flag-5'>Sobel</b><b class='flag-5'>算子</b>在HLS上的<b class='flag-5'>实现</b>教程

    SpinalHDL里如何实现Sobel边缘检测

    书接上文,趁着今天休假,采用SpinalHDL做一个小的demo,看看在SpinalHDL里如何优雅的实现Sobel边缘检测。
    的头像 发表于 08-26 08:59 1281次阅读

    图像锐化的Sobel、Laplacian算子基础知识介绍

    Sobel 算子是一种用于边缘检测的离散微分算子,它结合了高斯平滑和微分求导
    的头像 发表于 09-13 09:52 1362次阅读
    图像锐化的<b class='flag-5'>Sobel</b>、Laplacian<b class='flag-5'>算子</b>基础知识<b class='flag-5'>介绍</b>