首页>>科技 >>内容

卜算子 咏梅毛译文,Sobel算子原理介绍与实现方法

发布时间:2023-10-09 20:08:11编辑:温柔的背包来源:

很多朋友对卜算子 咏梅毛译文,Sobel算子原理介绍与实现方法不是很了解,每日小编刚好整理了这方面的知识,今天就来带大家一探究竟。

卜算子 咏梅毛译文,Sobel算子原理介绍与实现方法

索贝尔原理简介

Sobel算子主要用于边缘检测。从技术上讲,它是一个离散差分算子,用于计算图像亮度函数灰度的近似值。在图像中的任意点使用该算子都会产生相应的灰度向量或其法向量Sobel卷积因子:

该算子包含两组3x3矩阵,一组用于水平方向,另一组用于垂直方向。通过与图像进行平面卷积,可以分别得到水平和垂直亮度差的近似值。如果A代表原始图像,Gx和Gy分别代表图像经过水平和垂直边缘检测后的灰度值,它们的公式如下:

具体计算如下:

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

图像中每个像素的水平和垂直灰度值通过以下公式组合,计算出该点的灰度大小:

通常,出于效率原因,使用非平方根近似值

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

Sobel算子在HLS上的实现

项目创建

Step1:打开Vivado HLS开发工具,点击Create New Project新建一个项目,设置项目路径和项目名称,一直点击Next按照默认设置即可。

Step2:出现下图所示界面。时钟周期默认为10ns,不确定性和解决方案名称均默认设置。单击红色箭头选择芯片类型,然后单击“确定”。

点击Finish,会出现如下界面。

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

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

top.cpp代码#include 'top.h'void hls_sobel(AXI_STREAM INPUT_STREAM, AXI_STREAMOUTPUT_STREAM, int rows, int cols){//为核心创建AXI流接口#pragma HLS INTERFACE axis port=INPUT_STREAM#pragma HLS INTERFACE axis port=OUTPUT_STREAM#pragma HLS RESOURCE core=AXI_SLAVE 变量=行元数据='-bus_bundle CONTROL_BUS'#pragma HLS RESOURCE core=AXI_SLAVE 变量=cols 元数据='-bus_bundle CONTROL_BUS'#pragma HLS RESOURCE core=AXI_SLAVE 变量=返回元数据='-bus_bundle CONTROL_BUS'#pragma HLS INTERFACE ap_stable port=rows#pragma HLS INTERFACE ap_stable port=colsRGB_IMAGE img_0(行、列);RGB_IMAGE img_1(行、列);RGB_IMAGE img_2(行、列);RGB_IMAGE img_3(行、列);RGB_IMAGE img_4(行、列);RGB_IMAGE img_5(行、列);RGB_PIXEL pix(50, 50, 50);#pragma HLS dataflowhls:AXIvideo2Mat(INPUT_STREAM, img_0);hls:Sobel1,0,3(img_0, img_1) );hls:SubS(img_1, pix, img_2);hls:缩放(img_2, img_3, 2, 0);hls:侵蚀(img_3, img_4);hls:扩张(img_4, img_5);hls:Mat2AXIvideo(img_5, OUTPUT_STREAM)}

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

Top.h代码#ifndefTOP_H#defineTOP_H#include 'hls_video.h'//最大图像尺寸#define MAX_WIDTH 512#define MAX_HEIGHT 512//I/O图像设置#define INPUT_IMAGE 'lena.jpg'#define OUTPUT_IMAGE 'result.jpg '#define OUTPUT_IMAGE_GOLDEN 'result_golden.jpg'//typedef 视频库核心结构typedef hls:streamap_axiu32,1,1,1 style='font-size:继承;颜色:继承;line-height:继承;' AXI_STREAM;typedef hls :Scalar3, unsigned char RGB_PIXEL;typedef hls:MatRGB_IMAGE;//硬件合成的顶级函数void hls_sobel(AXI_STREAM src_axi, AXI_STREAM dst_axi, int rows, int cols);#endif/ap_axiu32,1,1, 1

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

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-深度, 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文件,并添加以下程序:

opencv_top.cpp代码#include 'opencv_top.h'#include 'top.h'void opencv_image_filter(IplImage* src, IplImage* dst){IplImage* tmp=cvCreateImage(cvGetSize(src), src-深度, 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_a xi ) ;hls_sobel(src_axi, dst_axi, src-高度, src-宽度);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

步骤7:将名为lena.jpg的测试图像添加到Test Bench

接下来,编译并模拟该项目。

Step1:点击项目-项目设置或直接点击快捷按钮。

步骤2:选择Synthesis选项,然后单击Browse.指定顶级函数并选择hls_sobel作为顶级函数。

点击开始合成

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

综合完成后,我们对代码进行仿真测试,点击开始仿真。

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

审稿人:唐子宏

以上知识分享希望能够帮助到大家!