[X]关闭

【ZYNQ-7000开发之十五】Vivado HLS和OpenCV_下

文档创建者:RZJM
浏览次数:8236
最后更新:2016-12-12
本帖最后由 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源码
  1. #ifndef _TOP_H_
  2. #define _TOP_H_
  3. #include"hls_video.h" //这里调用可以综合的视频库
  4. // maximum image size
  5. #define MAX_WIDTH 1920
  6. #define MAX_HEIGHT 1080
  7. // I/O Image Settings
  8. #define INPUT_IMAGE "test_1080p.jpg"
  9. #define OUTPUT_IMAGE "result_1080p.jpg"
  10. #define OUTPUT_IMAGE_GOLDEN "result_1080p_golden.jpg"
  11. // typedef video library core structures
  12. typedef hls::stream<ap_axiu<24,1,1,1> > AXI_STREAM_IN;
  13. typedef hls::stream<ap_axiu<24,1,1,1> > AXI_STREAM_OUT;
  14. typedef hls::Mat<MAX_HEIGHT, MAX_WIDTH, HLS_8UC3> RGB_IMAGE;
  15. // top level function for HW synthesis
  16. void hls_sobel(AXI_STREAM_IN& src_axi, AXI_STREAM_OUT& dst_axi, int rows, int cols);
  17. #endif
复制代码
hls_sobel.cpp源码
  1. #include "top.h"
  2. void hls_sobel(AXI_STREAM_IN& input, AXI_STREAM_OUT& output, int rows, int cols) {
  3. #pragma HLS RESOURCE variable=input core=AXI4Stream metadata="-bus_bundle INPUT_STREAM"
  4. #pragma HLS RESOURCE variable=output core=AXI4Stream metadata="-bus_bundle OUTPUT_STREAM"
  5. #pragma HLS INTERFACE ap_none port=cols
  6. #pragma HLS INTERFACE ap_none port=rows
  7. //AP_CONTROL_BUS_AXI(CONTROL_BUS);
  8. //set_directive_interface -mode ap_ctrl_none hls_sobel
  9. #pragma HLS interface ap_ctrl_none port=return
  10. RGB_IMAGE img_0(rows, cols);
  11. RGB_IMAGE img_1(rows, cols);
  12. #pragma HLS DATAFLOW // must use data flow to stream the data
  13. hls::AXIvideo2Mat(input, img_0); //read video stream by frames
  14. hls::Sobel<1,0,3>(img_0, img_1);//use Hls Sobel
  15. hls::Mat2AXIvideo(img_1, output); //write the frames to video stream
复制代码
C综合

点击Solution -> Run C Synthesis -> Active Solution

test.cpp源码
  1. #include "top.h"
  2. #include "opencv/cv.h"
  3. #include "opencv/cxcore.h"
  4. #include "opencv/highgui.h"
  5. #include "hls_opencv.h"
  6. int main (int argc, char** argv) {
  7.     IplImage* src = cvLoadImage(INPUT_IMAGE);
  8.     IplImage* dst = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
  9.     AXI_STREAM_IN src_axi;
  10.     AXI_STREAM_OUT dst_axi;
  11.     IplImage2AXIvideo(src, src_axi); //将图像转为视频流结构
  12.     hls_sobel(src_axi, dst_axi, src->height, src->width);
  13.     AXIvideo2IplImage(dst_axi, dst);
  14.     cvSaveImage(OUTPUT_IMAGE, dst);
  15.     cvReleaseImage(&src);
  16.     cvReleaseImage(&dst);
  17. }
复制代码
运行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数有点低):



发表评论已发布 2

uisrc

发表于 2016-3-20 13:25:27 | 显示全部楼层

越努力越幸运!加油!
回复

使用道具 举报

xieshengguang

发表于 2016-12-12 17:21:02 | 显示全部楼层


完整的工程有吗?我的工程配置移植有问题
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则