0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

淺述Sobel算子在HLS上的實現(xiàn)教程

FPGA之家 ? 來源:FPGA科技室 ? 作者:FPGA科技室 ? 2021-07-23 14:53 ? 次閱讀

Sobel 原理介紹

索貝爾算子(Sobel operator)主要用作邊緣檢測,在技術(shù)上,它是一離散性差分算子,用來運算圖像亮度函數(shù)的灰度之近似值。在圖像的任何一點使用此算子,將會產(chǎn)生對應(yīng)的灰度矢量或是其法矢量Sobel 卷積因子為:

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

該算子包含兩組 3x3 的矩陣,分別為橫向及縱向,將之與圖像作平面卷積,即可分別得出橫向及縱向的亮度差分近似值。如果以 A 代表原始圖像,Gx 及 Gy 分別代表經(jīng)橫向及縱向邊緣檢測的圖像灰度值,其公式如下:

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)點的灰度值;

圖像的每一個像素的橫向及縱向灰度值通過以下公式結(jié)合,來計算該點灰度的大?。?/p>

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

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

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

Sobel 算子根據(jù)像素點上下、左右鄰點灰度加權(quán)差,在邊緣處達到極值這一現(xiàn)象檢測邊緣。對噪聲具有平滑作用,提供較為精確的邊緣方向信息,邊緣定位精度不夠高。當對精度要求不是很高時,是一種較為常用的邊緣檢測方法。

Sobel 算子在 HLS 上的實現(xiàn)

工程創(chuàng)建

Step1:打開 Vivado HLS 開發(fā)工具,單擊 Creat New Project 創(chuàng)建一個新工程,設(shè)置好工程路徑和工程名,一直點擊 Next 按照默認設(shè)置

Step2:出現(xiàn)如下圖所示界面,時鐘周期 Clock Period 按照默認 10ns,Uncertaintly 和 Solution Name 均按照默認設(shè)置,點擊紅色箭頭部分選擇芯片類型,然后點擊 OK。

點擊 Finish,出現(xiàn)如下界面

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

Step4:右單擊 Source 選項,選擇 New File,創(chuàng)建一個名為 Top.cpp 的文件。(一定要加cpp后綴)

Step5:打開剛剛新建的cpp文件,進入編輯狀態(tài),輸入以下代碼

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 的庫函數(shù),并添加如下程序:

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 “l(fā)ena.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)

{

//獲取圖像數(shù)據(jù)

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);

//釋放內(nèi)存

cvReleaseImage(&src);

cvReleaseImage(&dst);

}

Step8:用同樣的方法,再在 Test Bench 中創(chuàng)建一個 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.。指定一個頂層函數(shù),選定 hls_sobel 為頂層函數(shù),

單擊 開始綜合

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

在協(xié)議類型里面我們可以看到我們主要使用了三種協(xié)議,分別是 axis、ap_stable 和 ap_ctrl_hs 三種,這些協(xié)議的詳細解釋我們均可以在官方手冊 ug902 中找到,其中 ap_ctrl_hs 的時序操作如下圖所示,說簡單點就是復(fù)位完成等待 ap_start 信號開始進行操作

綜合完畢,我們對代碼進行仿真測試,單擊 開始仿真

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

仿真結(jié)果如下,與通過 OPENCV 實現(xiàn)的 Sobel 檢測結(jié)果基本一致。

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

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • sobel
    +關(guān)注

    關(guān)注

    0

    文章

    12

    瀏覽量

    7871

原文標題:Sobel 算子在 HLS 上的實現(xiàn)

文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    優(yōu)化 FPGA HLS 設(shè)計

    減少錯誤并更容易調(diào)試。然而,經(jīng)常出現(xiàn)的問題是性能權(quán)衡。高度復(fù)雜的 FPGA 設(shè)計中實現(xiàn)高性能需要手動優(yōu)化 RTL 代碼,而這對于HLS開發(fā)環(huán)境生成的 RTL 代碼來說是不可能的。然而,存在一些解決方案
    發(fā)表于 08-16 19:56

    摩爾線程攜手智源研究院完成基于Triton的大模型算子庫適配

    里,即成功完成了近60個算子的功能驗證,精度符合交付標準,并實現(xiàn)對Bert-large模型的全面支持。FlagGems算子摩爾線程MUSA架構(gòu)
    的頭像 發(fā)表于 08-02 11:06 ?531次閱讀

    一種HLS中插入HDL代碼的方式

    很多人都比較反感用C/C++開發(fā)(HLS)FPGA,大家第一拒絕的理由就是耗費資源太多。但是HLS也有自己的優(yōu)點,除了快速構(gòu)建算法外,還有一個就是接口的生成,尤其對于AXI類接口,按照標準語法就可以很方便地生成相關(guān)接口。
    的頭像 發(fā)表于 07-16 18:01 ?504次閱讀
    一種<b class='flag-5'>在</b><b class='flag-5'>HLS</b>中插入HDL代碼的方式

    基于FPGA的實時邊緣檢測系統(tǒng)設(shè)計,Sobel圖像邊緣檢測,F(xiàn)PGA圖像處理

    60 為閾值得到圖8(a)和(b)。 通過對比可以看出,使用 FPGA 進行Sobel邊緣檢測能夠實現(xiàn)與 MATLAB 相近的檢測效果,驗證了算法的可行性。相對于 MATLAB,F(xiàn)PGA檢測同樣
    發(fā)表于 05-24 07:45

    AMD-Xilinx的Vitis-HLS編譯指示小結(jié)

    流水線指令 pragma HLS pipeline 通過流水線提高性能是計算機架構(gòu)設(shè)計的8個偉大思想之一,不管是硬件設(shè)計還是軟件設(shè)計,流水線設(shè)計(pipeline)都能夠用更多的資源來實現(xiàn)高速
    發(fā)表于 12-31 21:20

    OpenCV邊緣檢測算子Laplace、LoG詳解

    一階導(dǎo)數(shù)算子(例如 Sobel 算子)通過對圖像求導(dǎo)來確定圖像的邊緣,數(shù)值絕對值較高的點對應(yīng)了圖像的邊緣。如果繼續(xù)求二階導(dǎo),原先數(shù)值絕對值較高的點對應(yīng)了過零點。因此,也可以通過找到二階導(dǎo)數(shù)的過零點來檢測邊緣。
    的頭像 發(fā)表于 12-21 16:34 ?1600次閱讀
    OpenCV邊緣檢測<b class='flag-5'>算子</b>Laplace、LoG詳解

    一文電路系統(tǒng)中的諧振(

    物理學(xué)中,有一套專門的理論和方法用于振動系統(tǒng)的研究。其中,最基本的振動模型是簡諧振動。顧名思義,“簡”即“簡單,基本”,在這里,我們考慮帶彈簧的一維機械系統(tǒng),“諧振”即“共振”,不同的領(lǐng)域有不同的叫法,“動”表示運動狀態(tài)。
    的頭像 發(fā)表于 12-05 16:35 ?2283次閱讀
    一文<b class='flag-5'>淺</b><b class='flag-5'>述</b>電路系統(tǒng)中的諧振(<b class='flag-5'>上</b>)

    如何用HLS實現(xiàn)UART呢?

    UART 是一種舊的串行通信機制,但仍在很多平臺中使用。它在 HDL 語言中的實現(xiàn)并不棘手,可以被視為本科生的作業(yè)。在這里,我將通過這個例子來展示 HLS實現(xiàn)它是多么容易和有趣。
    的頭像 發(fā)表于 11-20 09:50 ?539次閱讀
    如何用<b class='flag-5'>HLS</b><b class='flag-5'>實現(xiàn)</b>UART呢?

    如何用HLS實現(xiàn)UART

    UART 是一種舊的串行通信機制,但仍在很多平臺中使用。它在 HDL 語言中的實現(xiàn)并不棘手,可以被視為本科生的作業(yè)。在這里,我將通過這個例子來展示 HLS實現(xiàn)它是多么容易和有趣。
    的頭像 發(fā)表于 11-20 09:48 ?446次閱讀
    如何用<b class='flag-5'>HLS</b><b class='flag-5'>實現(xiàn)</b>UART

    HLS中組合電路對設(shè)計的影響

    該項目通過一個示例演示了 HLS 中組合電路對設(shè)計的影響。
    的頭像 發(fā)表于 11-03 09:04 ?630次閱讀
    <b class='flag-5'>HLS</b>中組合電路對設(shè)計的影響

    opencv寫好的算子,比如找邊 找圓 模版匹配

    opencv寫好的算子,比如找邊 找圓 模版匹配
    的頭像 發(fā)表于 10-16 09:54 ?394次閱讀

    什么是DASH和HLS流?

    直播無疑已成為網(wǎng)絡(luò)媒體消費的重要組成部分。無論我們是觀看本地新聞網(wǎng)絡(luò)的直播,還是YouTube直播與內(nèi)容創(chuàng)作者互動,它們都使用以下網(wǎng)絡(luò)協(xié)議之一進行工作: MPEG- DASH(MPEG -動態(tài)
    的頭像 發(fā)表于 10-09 17:16 ?1027次閱讀
    什么是DASH和<b class='flag-5'>HLS</b>流?

    迅為RK3568開發(fā)板Scharr濾波器算子邊緣檢測

    。Scharr 算子Sobel 算子的不同點是平滑部分,其中心元素占的權(quán)重更重,相當于使用較小標準差的高斯函數(shù),也就是更瘦高的模板。 Scharr
    發(fā)表于 10-09 11:03

    使用LabVIEW人工智能視覺工具包快速實現(xiàn)傳統(tǒng)Opencv算子的調(diào)用源碼

    電子發(fā)燒友網(wǎng)站提供《使用LabVIEW人工智能視覺工具包快速實現(xiàn)傳統(tǒng)Opencv算子的調(diào)用源碼.rar》資料免費下載
    發(fā)表于 09-28 17:38 ?13次下載

    HLS中RTL無法導(dǎo)出IP核是為什么?

    請教一下,我HLS里面要將以下程序生成IP核,C Synthesis已經(jīng)做好了,但是export RTL的時候一直在運行 int sum_single(int A int B
    發(fā)表于 09-28 06:03