本帖最后由 RZJM 于 2016-3-11 20:50 编辑
本篇文章在上篇文章【ZYNQ-7000开发之十四】的基础上,利用OpenCV HLS的函数,hls::Sobel,编写边缘检测算法,仿真测试,创建IP,最后在vivado里测试Sobel IP,此外本篇文章的实验还要基于 【ZYNQ-7000开发之十】TGP+VDMA+HDMI搭建视频通路,把做好的HLS Sobel IP添加到此工程,进行测试,当然这个不是必须的,大家可以使用测试自己的方法 关于HLS详细内容请参考官方文献ug902-vivado-high-level-synthesis
本文主要参考文献:
how_to_accelerate_opencv_applications_using_vivado_hls
xapp890-zynq-sobel-vivado-hls 本文所使用的开发板是Miz702(兼容zedboard)
PC 开发环境版本:Vivado 2015.2 Xilinx SDK 2015.2
需要准备HDMI显示器和串口线一条 sobel算子原理简介计算机视觉领域的一种重要处理方法。主要用于获得数字图像的一阶梯度,常见的应用和物理意义是边缘检测。在技术上,它是一个离散的一阶差分算子,用来计算图像亮度函数的一阶梯度之近似值。在图像的任何一点使用此算子,将会产生该点对应的梯度矢量或是其法矢量。
Sobel 算子有两个,一个是检测水平边缘的 ;另一个是检测垂直边缘的 。所以该算子包含两组3x3的矩阵,分别为横向及纵向,将之与图像作平面卷积,即可分别得出横向及纵向的亮度差分近似值。公式如下:
Sobel测试效果的图像(摘自wikipedia,本文使用TPG产生的动态视频进行测试的,效果没那么明显)
建立HLS工程建好之后,在新建头文件 top.h源码
- #ifndef _TOP_H_
- #define _TOP_H_
- #include"hls_video.h" //这里调用可以综合的视频库
- // maximum image size
- #define MAX_WIDTH 1920
- #define MAX_HEIGHT 1080
- // I/O Image Settings
- #define INPUT_IMAGE "test_1080p.jpg"
- #define OUTPUT_IMAGE "result_1080p.jpg"
- #define OUTPUT_IMAGE_GOLDEN "result_1080p_golden.jpg"
- // typedef video library core structures
- typedef hls::stream<ap_axiu<24,1,1,1> > AXI_STREAM_IN;
- typedef hls::stream<ap_axiu<24,1,1,1> > AXI_STREAM_OUT;
- typedef hls::Mat<MAX_HEIGHT, MAX_WIDTH, HLS_8UC3> RGB_IMAGE;
- // top level function for HW synthesis
- void hls_sobel(AXI_STREAM_IN& src_axi, AXI_STREAM_OUT& dst_axi, int rows, int cols);
-
- #endif
复制代码
hls_sobel.cpp源码
- #include "top.h"
- void hls_sobel(AXI_STREAM_IN& input, AXI_STREAM_OUT& output, int rows, int cols) {
- #pragma HLS RESOURCE variable=input core=AXI4Stream metadata="-bus_bundle INPUT_STREAM"
- #pragma HLS RESOURCE variable=output core=AXI4Stream metadata="-bus_bundle OUTPUT_STREAM"
- #pragma HLS INTERFACE ap_none port=cols
- #pragma HLS INTERFACE ap_none port=rows
- //AP_CONTROL_BUS_AXI(CONTROL_BUS);
- //set_directive_interface -mode ap_ctrl_none hls_sobel
- #pragma HLS interface ap_ctrl_none port=return
-
- RGB_IMAGE img_0(rows, cols);
- RGB_IMAGE img_1(rows, cols);
- #pragma HLS DATAFLOW // must use data flow to stream the data
- hls::AXIvideo2Mat(input, img_0); //read video stream by frames
- hls::Sobel<1,0,3>(img_0, img_1);//use Hls Sobel
- hls::Mat2AXIvideo(img_1, output); //write the frames to video stream
复制代码
C综合点击Solution -> Run C Synthesis -> Active Solution test.cpp源码
- #include "top.h"
- #include "opencv/cv.h"
- #include "opencv/cxcore.h"
- #include "opencv/highgui.h"
- #include "hls_opencv.h"
- int main (int argc, char** argv) {
- IplImage* src = cvLoadImage(INPUT_IMAGE);
- IplImage* dst = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
- AXI_STREAM_IN src_axi;
- AXI_STREAM_OUT dst_axi;
- IplImage2AXIvideo(src, src_axi); //将图像转为视频流结构
- hls_sobel(src_axi, dst_axi, src->height, src->width);
- AXIvideo2IplImage(dst_axi, dst);
- cvSaveImage(OUTPUT_IMAGE, dst);
- cvReleaseImage(&src);
- cvReleaseImage(&dst);
- }
复制代码
运行test.cpp C仿真测试点击Project -> Run C simulation,弹出的对话框按照如图所示设置
在弹出的Debug界面,点击resume(左上角有个快捷按钮),
到相应的路径下查找测试输出的图片(我的是XXX\sobel\solution1\csim\build) 测试结果点击
原图像:
进行Sobel 滤波的图像:
生成IP点击 Solution -> export -> Solution
按照如下配置
完成后,会在(xxx\sobel\solution1\impl\ip)路径下产生IP Core 在vivado调用HLS打开以前做好的HDMI工程( 【ZYNQ-7000开发之十】TGP+VDMA+HDMI搭建视频通路) 连接方式,如图
TPG配置方式:
上板测试结果……视频截图(动态的),不是很漂亮啊,中间一条黑色的不知道怎么回事,原图就不传了,编译一次时间太久了
大家可以加入摄像头试下,测试效果
原书图(手机直接拍摄的):
测试效果(目前bit数有点低):
|