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

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

3天内不再提示

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

FPGA之家 来源:FPGA科技室 作者:FPGA科技室 2021-07-23 14:53 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

Sobel 原理介绍

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

31c07d38-e10c-11eb-9e57-12bb97331649.png

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

31c8e838-e10c-11eb-9e57-12bb97331649.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)点的灰度值;

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

31d47bf8-e10c-11eb-9e57-12bb97331649.png

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

31de8f8a-e10c-11eb-9e57-12bb97331649.png

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

Sobel 算子在 HLS 上的实现

工程创建

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

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

点击 Finish,出现如下界面

32508d6a-e10c-11eb-9e57-12bb97331649.png

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

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

325a9c06-e10c-11eb-9e57-12bb97331649.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 的库函数,并添加如下程序:

32656f00-e10c-11eb-9e57-12bb97331649.png

Top.h代码

#ifndef TOP_H

#define TOP_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《ap_axiu《32,1,1,1 style=“font-size: inherit;color: inherit;line-height: inherit;”》》 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《/ap_axiu《32,1,1,1》

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

326e7546-e10c-11eb-9e57-12bb97331649.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.cpp 和 opencv_top.h 文件,添加如下程序:

3278679a-e10c-11eb-9e57-12bb97331649.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代码

#ifndef OPENCV_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的测试图片

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

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

329dac1c-e10c-11eb-9e57-12bb97331649.png

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

单击 开始综合

32b39afe-e10c-11eb-9e57-12bb97331649.png

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

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

33ed078e-e10c-11eb-9e57-12bb97331649.png

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

33f6f532-e10c-11eb-9e57-12bb97331649.png

编辑:jq

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

    关注

    0

    文章

    12

    浏览量

    8168

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

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

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    如何利用Verilog HDLFPGA实现SRAM的读写测试

    本篇将详细介绍如何利用Verilog HDLFPGA实现SRAM的读写测试。SRAM是一种非易失性存储器,具有高速读取和写入的特点。FPGA中
    的头像 发表于 10-22 17:21 3947次阅读
    如何利用Verilog HDL<b class='flag-5'>在</b>FPGA<b class='flag-5'>上</b><b class='flag-5'>实现</b>SRAM的读写测试

    深入解析面向不同市场的多样化Arm计算子系统

    如果你曾基于 Arm 技术开发过产品,很大机会已经感受到了 Arm 计算子系统 (Arm Compute Subsystems, Arm CSS) 所带来的强劲性能。
    的头像 发表于 09-06 14:09 790次阅读
    深入解析面向不同市场的多样化Arm计<b class='flag-5'>算子</b>系统

    基于FPGA的压缩算法加速实现

    本设计中,计划实现对文件的压缩及解压,同时优化压缩中所涉及的信号处理和计算密集型功能,实现对其的加速处理。本设计的最终目标是证明充分并行化的硬件体系结构 FPGA
    的头像 发表于 07-10 11:09 2072次阅读
    基于FPGA的压缩算法加速<b class='flag-5'>实现</b>

    如何在Unified IDE中创建视觉库HLS组件

    最近我们分享了开发者分享|AMD Vitis HLS 系列 1 - AMD Vivado IP 流程(Vitis 传统 IDE)和开发者分享|AMD Vitis HLS 系列 2:AMD
    的头像 发表于 07-02 10:55 1118次阅读
    如何在Unified IDE中创建视觉库<b class='flag-5'>HLS</b>组件

    使用AMD Vitis Unified IDE创建HLS组件

    这篇文章开发者分享|AMD Vitis HLS 系列 1 - AMD Vivado IP 流程(Vitis 传统 IDE) 的基础撰写,但使用的是 AMD Vitis Unified IDE,而不是之前传统版本的 Vitis
    的头像 发表于 06-20 10:06 1909次阅读
    使用AMD Vitis Unified IDE创建<b class='flag-5'>HLS</b>组件

    如何使用AMD Vitis HLS创建HLS IP

    本文逐步演示了如何使用 AMD Vitis HLS 来创建一个 HLS IP,通过 AXI4 接口从存储器读取数据、执行简单的数学运算,然后将数据写回存储器。接着会在 AMD Vivado Design Suite 设计中使用此 HLS
    的头像 发表于 06-13 09:50 1271次阅读
    如何使用AMD Vitis <b class='flag-5'>HLS</b>创建<b class='flag-5'>HLS</b> IP

    Vivado HLS设计流程

    为了尽快把新产品推向市场,数字系统的设计者需要考虑如何加速设计开发的周期。设计加速主要可以从“设计的重用”和“抽象层级的提升”这两个方面来考虑。Xilinx 推出的 Vivado HLS 工具可以
    的头像 发表于 04-16 10:43 1345次阅读
    Vivado <b class='flag-5'>HLS</b>设计流程

    芯片制造中的沟道隔离工艺技术

    沟道隔离(STI)是芯片制造中的关键工艺技术,用于半导体器件中形成电学隔离区域,防止相邻晶体管之间的电流干扰。本文简单介绍沟道隔离技术的作用、材料和步骤。
    的头像 发表于 03-03 10:00 3033次阅读
    芯片制造中的<b class='flag-5'>浅</b>沟道隔离工艺技术

    FPGA的图像处理算法集成与优化

    本文详细介绍了多种图像处理技术,包括RG/GB单通道提取、亮度和对比度调整、图像反转、均值滤波、高斯滤波、图像锐化、中值滤波、阈值分割、边缘检测(Sobel算子)、图像膨胀与腐蚀、开运算与闭运算
    的头像 发表于 02-14 13:46 1147次阅读
    FPGA<b class='flag-5'>上</b>的图像处理算法集成与优化

    使用HLS流程设计和验证图像信号处理设备

    STMicroelectronics成像部门负责向消费者、工业、安全和汽车市场提供创新的成像技术和产品。该团队精心制定了一套通过模板实现的High-Level Synthesis(HLS)高层次综合流程,使得上述产品能够迅速上市。对于汽车市场,该流程符合ISO 26262
    的头像 发表于 01-08 14:39 1138次阅读
    使用<b class='flag-5'>HLS</b>流程设计和验证图像信号处理设备

    EE-284:ADSP-21160 SHARC处理器实现覆盖

    电子发烧友网站提供《EE-284:ADSP-21160 SHARC处理器实现覆盖.pdf》资料免费下载
    发表于 01-06 16:14 0次下载
    EE-284:<b class='flag-5'>在</b>ADSP-21160 SHARC处理器<b class='flag-5'>上</b><b class='flag-5'>实现</b>覆盖

    EE-295:SHARC处理器实现延迟块

    电子发烧友网站提供《EE-295:SHARC处理器实现延迟块.pdf》资料免费下载
    发表于 01-06 14:34 0次下载
    EE-295:<b class='flag-5'>在</b>SHARC处理器<b class='flag-5'>上</b><b class='flag-5'>实现</b>延迟块

    深居出AutoCAD二次开发

    深居出AutoCAD二次开发,net版
    发表于 01-06 14:12 12次下载

    MATLA B助力数字与模拟芯片设计:高效实现HLS、UCIe和UVM

      本文将分享 MathWorks 参与 中国集成电路设计业高峰论坛暨展览会 ICCAD-Expo 的展台展示以及发表主题演讲《MATLAB 加速数字和模拟芯片设计--高效实现 HLS、UCIe
    的头像 发表于 12-20 11:11 1254次阅读
    MATLA B助力数字与模拟芯片设计:高效<b class='flag-5'>实现</b><b class='flag-5'>HLS</b>、UCIe和UVM

    助力AIoT应用:米尔FPGA开发板实现Tiny YOLO V4

    受限的设备运行,尤其低功耗、实时检测的边缘计算设备中表现出色。相比传统 GPU,FPGA 能在小面积和低功耗下实现类似的推理性能,非常契合 AIoT 应用。像米尔 ZU3EG 这样的 FPGA
    发表于 12-06 17:18