• HLS学习之图像的二值化处理


    HLS中相关数据类型的介绍:【传送门


    由于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 
    #include 
    
    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类型
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    头文件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
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    有这两个文件其实已经可以进行综合了,综合前记得修改设置顶层函数,否则编译器不知道入口函数是哪一个,修改的方法:

    Project -> Project Settings -> Synthesis -> 在Top Function那里选择hlsMain,点击OK进行确定
    
    • 1

    测试文件的内容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;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    点击仿真之后当前的目录下的\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 
    
    • 1

    最后想吐槽一下: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

    	--晓凡   202292日于南宁书  
    
    • 1
  • 相关阅读:
    SpringCloud - Spring Cloud Alibaba 之 Gateway 集成Sentinel (十一)
    android 获取SD卡路径
    计算机毕业设计 基于SpringBoot家政服务平台的设计与实现 Java实战项目 附源码+文档+视频讲解
    OFDM Tutorial Series-1: 线性分组码
    [算法日志]图论刷题 沉岛思想的运用
    计算机毕业设计之java+javaweb的超市库存管理系统
    职业技能鉴定服务中心前端静态页面(官网+证书查询)
    华为云Stack的学习(四)
    【Python黑科技】cv2库实现证件照抠图替换背景(注释比代码多)
    win10离线安装.net3.5失败的解决方案
  • 原文地址:https://blog.csdn.net/xzs520xzs/article/details/126659820