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

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

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

Sobel算子原理介紹與實現(xiàn)方法

FPGA之家 ? 來源:FPGA科技室 ? 作者:FPGA科技室 ? 2022-07-21 17:27 ? 次閱讀

Sobel 原理介紹

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

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

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

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

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

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

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

ed72c252-04a1-11ed-ba43-dac502259ad0.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è)置

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

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

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

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

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

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

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

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

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

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

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)
{
//獲取圖像數(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.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..指定一個頂層函數(shù),選定hls_sobel為頂層函數(shù),

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

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

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

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

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

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

審核編輯:湯梓紅


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

    關(guān)注

    0

    文章

    16

    瀏覽量

    7250
  • HLS
    HLS
    +關(guān)注

    關(guān)注

    1

    文章

    128

    瀏覽量

    23993
  • sobel
    +關(guān)注

    關(guān)注

    0

    文章

    12

    瀏覽量

    7890

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

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

收藏 人收藏

    評論

    相關(guān)推薦

    基于 DSP5509 進行數(shù)字圖像處理中 Sobel 算子邊緣檢測的硬件連接電路圖

    以下是基于 DSP5509 進行數(shù)字圖像處理中 Sobel 算子邊緣檢測的硬件設(shè)計方案: 一、總體架構(gòu) 圖像采集:使用合適的圖像傳感器,如 CMOS 傳感器,通過相應(yīng)的接口(如 SPI、I2C 等
    發(fā)表于 09-25 15:25

    基于FPGA的Sobel邊緣檢測的實現(xiàn)

    我們在此基礎(chǔ)上修改,從而實現(xiàn),基于FPGA的動態(tài)圖片的Sobel邊緣檢測、中值濾波、Canny算子邊緣檢測、腐蝕和膨脹等。那么這篇文章我們將來實現(xiàn)基于FPGA的
    發(fā)表于 08-29 15:41

    Labview圖像處理——邊緣檢測

    邊緣的灰度值過度較為明顯,梯度算子可以得到較好的邊緣檢測結(jié)果。邊緣提取其實也是一種濾波,不同的算子有不同的提取效果。比較常用的方法有三種,Sobel
    發(fā)表于 12-01 12:16

    labview視覺自動對焦

    的清晰度?可以通過以下算法定義并計算:Tenengrad梯度方法利用Sobel算子分別計算水平和垂直方向的梯度,同一場景下梯度值越高,圖像越清晰。以下是具體實現(xiàn),這里衡量的指標是經(jīng)過
    發(fā)表于 05-09 17:26

    邊緣檢測的幾種微分算子

    一、邊緣檢測邊緣檢測的幾種微分算子:一階微分算子:Roberts、Sobel、Prewitt二階微分算子:Laplacian、Log/Marr非微分
    發(fā)表于 07-26 08:29

    EdgeBoard中神經(jīng)網(wǎng)絡(luò)算子在FPGA中的實現(xiàn)方法是什么?

    FPGA加速的關(guān)鍵因素是什么?EdgeBoard中神經(jīng)網(wǎng)絡(luò)算子在FPGA中的實現(xiàn)方法是什么?
    發(fā)表于 09-28 06:37

    迅為iTOP-RK3568開發(fā)板Sobel 算子邊緣檢測

    (索貝爾)算子是計算機視覺領(lǐng)域的一種重要處理方法。主要用于獲得數(shù)字圖像的一階梯度,常見的應(yīng)用和物理意義是邊緣檢測。 索貝爾算子把圖像中每個像素的上下左右四領(lǐng)域的灰度值加權(quán)差,在邊緣處達到極值從而檢測邊緣
    發(fā)表于 09-18 10:27

    拉普拉斯算子的FPGA實現(xiàn)方法

    拉普拉斯算子的FPGA實現(xiàn)方法  引 言   在圖像處理系統(tǒng)中常需要對圖像進行預(yù)處理。由于圖像處理的數(shù)據(jù)量大,對于實時性要求高的系統(tǒng),采用軟件實現(xiàn)通常
    發(fā)表于 02-11 11:01 ?1507次閱讀
    拉普拉斯<b class='flag-5'>算子</b>的FPGA<b class='flag-5'>實現(xiàn)</b><b class='flag-5'>方法</b>

    LOG算子在FPGA中的實現(xiàn)

    介紹了一種高斯拉普拉斯LOG算子在FPGA中的實現(xiàn)方案!并通過對一幅BMP圖像的處理!論證了在FPGA中實現(xiàn)的LOG算子的圖像增強效果
    發(fā)表于 05-16 17:12 ?50次下載
    LOG<b class='flag-5'>算子</b>在FPGA中的<b class='flag-5'>實現(xiàn)</b>

    Vivado HLS在Zedboard中的Sobel濾波算法實現(xiàn)步驟教程

    索貝爾算子Sobel operator)主要用作邊緣檢測,在技術(shù)上,它是一離散性差分算子,用來運算圖像亮度函數(shù)的灰度之近似值。在圖像的任何一點使用此算子,將會產(chǎn)生對應(yīng)的灰度矢量或是其
    的頭像 發(fā)表于 07-14 06:05 ?3734次閱讀
    Vivado HLS在Zedboard中的<b class='flag-5'>Sobel</b>濾波算法<b class='flag-5'>實現(xiàn)</b>步驟教程

    基于CORDIC的高速Sobel算法實現(xiàn)

    為提高圖像邊緣檢測的處理速度,提出一種基于CORDIC的高速Sobel算法實現(xiàn)。
    的頭像 發(fā)表于 10-05 09:54 ?3525次閱讀
    基于CORDIC的高速<b class='flag-5'>Sobel</b>算法<b class='flag-5'>實現(xiàn)</b>

    Laplacian算子的FPGA實現(xiàn)方法

    拉普拉斯算子是一種重要的圖像增強算子,它是一種各向同性濾波器,即濾波器的響應(yīng)與濾波器作用圖像的突變方向無關(guān),而且實現(xiàn)簡單,被廣泛用于圖像銳化和高頻增強等算法中。在此,提出一種使用QuartusⅡ開發(fā)環(huán)境的Megafunction
    的頭像 發(fā)表于 06-16 17:47 ?3205次閱讀
    Laplacian<b class='flag-5'>算子</b>的FPGA<b class='flag-5'>實現(xiàn)</b><b class='flag-5'>方法</b>

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

    Sobel 原理介紹 索貝爾算子Sobel operator)主要用作邊緣檢測,在技術(shù)上,它是一離散性差分算子,用來運算圖像亮度函數(shù)的灰度
    的頭像 發(fā)表于 07-23 14:53 ?2208次閱讀
    淺述<b class='flag-5'>Sobel</b><b class='flag-5'>算子</b>在HLS上的<b class='flag-5'>實現(xiàn)</b>教程

    SpinalHDL里如何實現(xiàn)Sobel邊緣檢測

    書接上文,趁著今天休假,采用SpinalHDL做一個小的demo,看看在SpinalHDL里如何優(yōu)雅的實現(xiàn)Sobel邊緣檢測。
    的頭像 發(fā)表于 08-26 08:59 ?1246次閱讀

    圖像銳化的Sobel、Laplacian算子基礎(chǔ)知識介紹

    Sobel 算子是一種用于邊緣檢測的離散微分算子,它結(jié)合了高斯平滑和微分求導(dǎo)
    的頭像 發(fā)表于 09-13 09:52 ?1226次閱讀
    圖像銳化的<b class='flag-5'>Sobel</b>、Laplacian<b class='flag-5'>算子</b>基礎(chǔ)知識<b class='flag-5'>介紹</b>