一、项目简介
本工程基于 Vivado HLS 2019.2 实现硬件加速图像算法:输入 AXI4-Stream 格式 RGB 图像流,完成 RGB 转灰度、灰度转回标准 RGB 三通道流输出,适配 FPGA 图像采集 / 显示链路,全程使用 HLS 原生hls::Mat与 AXI 视频流接口,可直接封装为 IP 接入 Vivado 工程。
功能流程
AXI 视频流 → HLS Mat 缓存 → RGB2GRAY 灰度转换 → GRAY2RGB 补齐三通道 → 输出 AXI 视频流
二、工程文件结构
plaintext
myrgb2gray/
├── myrgb2gray.h // 类型定义、函数声明(顶层头文件)
├── myrgb2gray.cpp // HLS硬件顶层处理函数
└── test_myrgb2gray.cpp// C仿真Testbench,基于OpenCV2完成图像读写激励
三、核心代码分段解析
1. 头文件 myrgb2gray.h:接口与图像类型封装
cpp
运行
#ifndef _MYRGB2GRAY_H_
#define _MYRGB2GRAY_H_
#include "hls_video.h"
// 定义32bit AXI-Stream视频流,适配图像像素传输
typedef hls::stream<ap_axiu<32,1,1,1>> AXI_STREAM;
// 最大支持1080P RGB三通道图像
typedef hls::Mat<1080,1920,HLS_8UC3> RGB_IMAGE;
// 单通道8bit灰度图
typedef hls::Mat<1080,1920,HLS_8UC1> GRAY_IMAGE;
// 顶层硬件函数声明
void myrgb2gray(AXI_STREAM &src,AXI_STREAM &dst,int rows,int cols);
#endif
关键点:
ap_axiu<32,1,1,1>:标准 AXI 视频轴,32bit 像素位宽,适配 RGB888 打包;hls::Mat<HEIGHT,WIDTH,DEPTH>:HLS 专用片上图像缓存,综合时生成 BRAM/FIFO;- 预设 1080P 分辨率,可根据需求修改行列参数适配 4K/720P。
2. 顶层硬件函数 myrgb2gray.cpp(可综合硬件逻辑)
cpp
运行
#include "myrgb2gray.h"
void myrgb2gray(AXI_STREAM &src,AXI_STREAM &dst,int rows ,int cols){
RGB_IMAGE img_0(rows,cols);
GRAY_IMAGE img_1(rows,cols);
RGB_IMAGE img_2(rows,cols);
// AXI流转HLS Mat
hls::AXIvideo2Mat(src,img_0);
// RGB转单通道灰度图
hls::CvtColor<HLS_RGB2GRAY>(img_0,img_1);
// 单通道灰度转回三通道RGB(R=G=B,兼容显示外设)
hls::CvtColor<HLS_GRAY2RGB>(img_1,img_2);
// Mat数据转回AXI-Stream输出
hls::Mat2AXIvideo(img_2,dst);
}
硬件特性:
- 全程使用 HLS 内置
hls::CvtColor,工具自动综合为流水线运算电路,无浮点; - 两次色彩转换保证输出依旧是 3 通道 AXI 流,直接对接 HDMI / 显示器 IP;
- 函数参数
rows/cols动态适配任意小于 1080P 分辨率输入。
3. Testbench 测试文件 test_myrgb2gray.cpp(C 仿真激励)
cpp
运行
#include "myrgb2gray.h"
#include "hls_opencv.h"
#include <stdio.h>
// 图片绝对路径,使用VMware共享目录拷贝的bmp图片(兼容HLS内置OpenCV2)
#define INPUT_IMAGE "/home/xuhaitao/FPGA_project/HLS_learing/myrgb2gray/test.bmp"
#define OUTPUT_IMAGE "/home/xuhaitao/FPGA_project/HLS_learing/myrgb2gray/result.bmp"
int main(int argc, char ** argv){
printf("[1/6] 开始加载图片: %s\n", INPUT_IMAGE);
IplImage *src = cvLoadImage(INPUT_IMAGE);
// 空指针校验,防止图片路径错误导致段错误SIGSEGV
if (src == NULL) {
printf("错误:无法加载输入图片,请检查文件路径、文件名和格式!\n");
return -1;
}
printf("[2/6] 图片加载成功,尺寸: %d x %d, 通道数: %d\n", src->width, src->height, src->nChannels);
// 校验图片分辨率不超过1080P缓存上限
if (src->width > 1920 || src->height > 1080) {
printf("错误:图片尺寸超过Mat最大限制(1920x1080)!\n");
cvReleaseImage(&src);
return -1;
}
IplImage *dst = cvCreateImage(cvGetSize(src), src->depth, src->nChannels);
AXI_STREAM axi_src, axi_dst;
printf("[3/6] 原图转换为AXI流\n");
IplImage2AXIvideo(src, axi_src);
printf("[4/6] 调用HLS灰度转换顶层函数\n");
myrgb2gray(axi_src, axi_dst, src->height, src->width);
printf("[5/6] AXI流转回OpenCV图像\n");
AXIvideo2IplImage(axi_dst, dst);
printf("[6/6] 保存灰度输出图片: %s\n", OUTPUT_IMAGE);
cvSaveImage(OUTPUT_IMAGE, dst);
// 释放OpenCV内存,避免内存泄漏
cvReleaseImage(&src);
cvReleaseImage(&dst);
printf("===== C仿真执行完成 =====\n");
return 0;
}
仿真设计要点:
- 采用绝对路径 + BMP 格式:规避 Linux 中文路径、JPG 解码兼容问题,解决 SIGSEGV 段错误;
- 多层安全校验:图片空指针判断、分辨率上限判断,精准定位崩溃位置;
IplImage2AXIvideo/AXIvideo2IplImage:HLS 提供的 OpenCV 与 AXI 流互转 API,快速搭建仿真激励。
四、踩坑问题与解决方案(博客重点避坑章节)
坑 1:#include "../src/myrgb2gray.h" 头文件找不到
原因:工程无 src 文件夹,相对路径不匹配。 解决:直接使用#include "myrgb2gray.h",同目录文件直接引用。
坑 2:INPUT_IMAGE/OUTPUT_IMAGE未定义编译报错
原因:缺少图片路径宏定义。 解决:在 Testbench 头部添加绝对路径宏,使用 BMP 格式图片。
坑 3:C 仿真 SIGSEGV 段错误(程序崩溃)
诱因 1:图片路径错误,cvLoadImage返回空指针; 诱因 2:图片分辨率超过hls::Mat预设最大 1080P; 诱因 3:路径包含中文 / 空格,OpenCV 读取失败。 解决:
- VMware 共享目录复制图片到 Ubuntu 本地工程文件夹,重命名为纯英文;
- 增加空指针、分辨率判断打印,定位崩溃环节;
- 统一使用 BMP 位图,兼容 Vivado HLS2019.2 内置 OpenCV2。
坑 4:日志报 Virtex-7 库找不到 Warning
说明:仅器件库提示,不影响 C 仿真、综合,可直接忽略。
五、完整开发流程
- 工程搭建:新建 Vivado HLS 工程,添加头文件、顶层 C 代码、Testbench;
- 路径配置:VMware 共享目录拷贝测试图片到 Ubuntu 工程目录,统一使用绝对路径;
- C 仿真验证(CSIM):运行 C 仿真,控制台无报错,生成灰度输出图片肉眼验证功能;
- 逻辑综合 Synthesis:将 C 代码编译为 FPGA 可执行 RTL 电路,查看资源、时序;
- C/RTL 协同仿真 Co-Sim:对比 C 模型与硬件 RTL 输出,保证硬件功能和软件一致;
- 导出 AXI IP:封装图像处理模块,导入 Vivado 搭建完整图像采集显示系统。
六、项目拓展方向
- 修改
hls::Mat行列参数,适配 4K/720P 等不同分辨率; - 在
CvtColor后新增对比度、高斯模糊等图像算子,流水线并行加速; - 增加 AXI-Lite 寄存器接口,动态配置图像宽高、灰度阈值;
- 对接 OV5640/HDMI IP,搭建完整 FPGA 实时图像采集链路。
七、博客结尾总结
本工程完整演示 Vivado HLS 基于 AXI-Stream 的硬件图像加速开发全流程,覆盖类型定义、可综合硬件代码、OpenCV 仿真激励、仿真排错全环节,代码可直接复用。解决了新手最容易遇到的头文件路径、图片读取段错误、OpenCV 兼容三大典型问题,输出模块为标准 AXI 视频流 IP,可无缝接入 Xilinx FPGA 图像工程,适合入门 HLS 图像处理开发学习。