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

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

具體計(jì)算如下:
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)點(diǎn)的灰度值;
圖像的每一個(gè)像素的橫向及縱向灰度值通過(guò)以下公式結(jié)合,來(lái)計(jì)算該點(diǎn)灰度的大小:

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

Sobel 算子根據(jù)像素點(diǎn)上下、左右鄰點(diǎn)灰度加權(quán)差,在邊緣處達(dá)到極值這一現(xiàn)象檢測(cè)邊緣。對(duì)噪聲具有平滑作用,提供較為精確的邊緣方向信息,邊緣定位精度不夠高。當(dāng)對(duì)精度要求不是很高時(shí),是一種較為常用的邊緣檢測(cè)方法。
Sobel 算子在 HLS 上的實(shí)現(xiàn)
工程創(chuàng)建
Step1:打開 Vivado HLS 開發(fā)工具,單擊 Creat New Project 創(chuàng)建一個(gè)新工程,設(shè)置好工程路徑和工程名,一直點(diǎn)擊 Next 按照默認(rèn)設(shè)置
Step2:出現(xiàn)如下圖所示界面,時(shí)鐘周期 Clock Period 按照默認(rèn) 10ns,Uncertaintly 和 Solution Name 均按照默認(rèn)設(shè)置,點(diǎn)擊紅色箭頭部分選擇芯片類型,然后點(diǎn)擊 OK。
點(diǎn)擊 Finish,出現(xiàn)如下界面

Step4:右單擊 Source 選項(xiàng),選擇 New File,創(chuàng)建一個(gè)名為 Top.cpp 的文件。(一定要加cpp后綴)
Step5:打開剛剛新建的cpp文件,進(jìn)入編輯狀態(tài),輸入以下代碼

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 中添加一個(gè)名為 Top.h 的庫(kù)函數(shù),并添加如下程序:

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 中,用同樣的方法添加一個(gè)名為 Test.cpp 的測(cè)試程序。添加如下代碼:

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庫(kù)進(jìn)行處理
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庫(kù)進(jìn)行處理
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)建一個(gè) opencv_top.cpp 和 opencv_top.h 文件,添加如下程序:

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的測(cè)試圖片
接下來(lái)對(duì)工程進(jìn)行編譯和仿真。
Step1:?jiǎn)螕?Project-Project settings 或直接單擊快捷按鈕。

Step2:選擇 Synthesis 選項(xiàng),然后點(diǎn)擊 Browse.。指定一個(gè)頂層函數(shù),選定 hls_sobel 為頂層函數(shù),
單擊 開始綜合

在協(xié)議類型里面我們可以看到我們主要使用了三種協(xié)議,分別是 axis、ap_stable 和 ap_ctrl_hs 三種,這些協(xié)議的詳細(xì)解釋我們均可以在官方手冊(cè) ug902 中找到,其中 ap_ctrl_hs 的時(shí)序操作如下圖所示,說(shuō)簡(jiǎn)單點(diǎn)就是復(fù)位完成等待 ap_start 信號(hào)開始進(jìn)行操作
綜合完畢,我們對(duì)代碼進(jìn)行仿真測(cè)試,單擊 開始仿真

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

編輯:jq
-
sobel
+關(guān)注
關(guān)注
0文章
12瀏覽量
8210
原文標(biāo)題:Sobel 算子在 HLS 上的實(shí)現(xiàn)
文章出處:【微信號(hào):zhuyandz,微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
一文掌握瑞芯微RK系列NPU算子支持全景:覆蓋6大平臺(tái),新增硬件加速算子,嵌入式AI開發(fā)不踩坑
HLS設(shè)計(jì)中的BRAM使用優(yōu)勢(shì)
通過(guò)vivado HLS設(shè)計(jì)一個(gè)FIR低通濾波器
如何在TensorFlow Lite Micro中添加自定義操作符(2)
詳解JPEG解碼在MCU上的實(shí)現(xiàn)挑戰(zhàn)
蜂鳥處理器+OV5640攝像頭模塊開發(fā)
如何利用Verilog HDL在FPGA上實(shí)現(xiàn)SRAM的讀寫測(cè)試
深入解析面向不同市場(chǎng)的多樣化Arm計(jì)算子系統(tǒng)
使用Verilog在FPGA上實(shí)現(xiàn)FOC電機(jī)控制系統(tǒng)
基于淺切多道的晶圓切割 TTV 均勻性控制與應(yīng)力釋放技術(shù)
基于FPGA的壓縮算法加速實(shí)現(xiàn)
如何在Unified IDE中創(chuàng)建視覺(jué)庫(kù)HLS組件
使用AMD Vitis Unified IDE創(chuàng)建HLS組件
如何使用AMD Vitis HLS創(chuàng)建HLS IP
Vivado HLS設(shè)計(jì)流程
淺述Sobel算子在HLS上的實(shí)現(xiàn)教程
評(píng)論