赞
踩
由于vivado hls中的mat类型,实际上为stream类型,只可以顺序存取,不可以随机存取,因此无法随便怼同一个数据进行复用。VIVADO HLS图像处理的一般步骤是将IplImage图像(Intel Image Processing Library,缩写Ipl)类型转化为AXI STREAM图像类型,再将AXI STREAM图像类型转化为HLS Video视频库可处理的MAT类型,输出部分逆转化成IplImage图像类型输出即可。其中AXI STREAM图像类型转化为MAT类型,MAT类型转化为AXI STREAM图像类型是可被综合的。
这个例子是HLS实现图像的二值化。
参照博客【传送门】完成的这个例程。
这个代码移植需要注意的地方:
源文件内容,命名为pixelBinary.cpp
,新建工程后将其添加到Source目录下(在这个文件中右键有添加文件的选项):
#include "pixelBinary.h" #include <stdio.h> #include <iostream> using namespace std; void hls::pixelBinary(GRAY_IMAGE &src, GRAY_IMAGE &dst) { uchar pixelValue; GRAY_PIXEL src_data; GRAY_PIXEL dst_data; LOOP_ROW: for(int idxRow = 0; idxRow < IMG_HEIGHT; idxRow++) { LOOP_COL: for(int idxCol = 0; idxCol < IMG_WIDTH; idxCol++) { #pragma HLS PIPELINE II=1 src >> src_data; pixelValue = src_data.val[0]; dst_data.val[0] = pixelValue > 128 ? 0 : 255;//二值化的关键语句,像素的值大于128时,赋值为0(黑色),小于时赋值为255(白色) dst << dst_data; } } } void hlsMain(AXI_STREAM& src_axi, AXI_STREAM& dst_axi) { #pragma HLS INTERFACE axis port=src_axi bundle=INPUT_STREAM #pragma HLS INTERFACE axis port=dst_axi bundle=OUTPUT_STREAM GRAY_IMAGE img_src; GRAY_IMAGE img_dst; #pragma HLS dataflow hls::AXIvideo2Mat(src_axi,img_src);//axi stream类型转化为HLS能处理的mat数据类型 hls::pixelBinary(img_src,img_dst);//调用自定义函数处理图片 hls::Mat2AXIvideo(img_dst,dst_axi);//输出结果图片需要将数据从mat类型转换为axi stream类型 }
头文件pixelBinary.h
的内容,添加到Source目录下:
#ifndef _PIXELBINARY_H_ #define _PIXELBINARY_H_ #include "hls_video.h" #include "hls_math.h" #include "ap_int.h" #include "ap_fixed.h" // maximum image size #define IMG_WIDTH 1280//图片的宽 #define IMG_HEIGHT 1706//图片的高,不同的图片记得修改这两个参数 // I/O Image Settings #define INPUT_IMAGE "input_image.png" #define OUTPUT_IMAGE "output_image.png" // typedef video library core structures typedef unsigned char uchar; typedef hls::stream<ap_axiu<8,1,1,1> > AXI_STREAM; typedef hls::Mat<IMG_HEIGHT, IMG_WIDTH, HLS_8UC1> GRAY_IMAGE; typedef hls::Scalar<1, uchar> GRAY_PIXEL; // typedef HLS namespace namespace hls { void pixelBinary(GRAY_IMAGE &src, GRAY_IMAGE &dst); } //top level function for HW synthesis void hlsMain(AXI_STREAM& src_axi, AXI_STREAM& dst_axi); #endif
有这两个文件其实已经可以进行综合了,综合前记得修改设置顶层函数,否则编译器不知道入口函数是哪一个,修改的方法:
Project -> Project Settings -> Synthesis -> 在Top Function那里选择hlsMain,点击OK进行确定
测试文件的内容tb.cpp,将其添加到工程的Test Bench中:
#include "iostream" #include "hls_opencv.h" #include "pixelBinary.h" using namespace std; using namespace cv; int main() { //获取图像数据 CV_LOAD_IMAGE_GRAYSCALE IplImage* src = cvLoadImage(INPUT_IMAGE,CV_LOAD_IMAGE_GRAYSCALE);//IplImage为结构体,将其指向结构体,结构体的内容可以进去看 //获取仿真图片并直接转为灰度图像 IplImage* dst = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);//获取原始图像的大小 AXI_STREAM src_axi, dst_axi; IplImage2AXIvideo(src, src_axi); hlsMain(src_axi, dst_axi); AXIvideo2IplImage(dst_axi, dst); cvSaveImage(OUTPUT_IMAGE,dst); //释放内存 cvReleaseImage(&src); cvReleaseImage(&dst); return 0; }
点击仿真之后当前的目录下的\solution1\csim\build文件夹中后生成的输出图片output_image.png。
WARNING: Hls::stream 'hls::stream<ap_axiu<8, 1, 1, 1> >.2' is read while empty, which may result in RTL
最后想吐槽一下:HLS这个软件对写代码不太友好,反应有点迟钝,错误的代码修改过来之后还是显示错误,这个软件是采用java语言写的,是不是因为这个原因所以反应有点迟钝呢?目前这个问题没有想到好的方法解决。有没有什么好用的编辑器代替呢。最后的最后愿所有的程序员写的代码少些bug,一次通过。
参考:
【1】https://blog.csdn.net/weixin_50988214/article/details/116534049?ops_request_misc=&request_id=&biz_id=102&utm_term=hls::AXIvideo2Mat&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-7-116534049.142v44pc_rank_34_1&spm=1018.2226.3001.4187
【2】https://blog.csdn.net/qq_51474038/article/details/123472267
--晓凡 2022年9月2日于南宁书
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。