HLS图像处理系列——肤色检测

2023-11-18

本博文采用Xilinx HLS 2014.4工具,实现一个肤色检测的模块。其中,本文重点是构建HLS图像处理函数。新建HLS工程的步骤,本博文不再详述。

本工程新建之后,只添加了五个文件,如下图所示。其中,top.cpp中的主函数最终会综合生成HLS硬件图像处理模块。test.cpp是测试文件,调用测试图片,测试top.cpp的图像处理函数功能。


top.cpp的源码如下:

#include "top.h"
#include "imgprocess.h"
#include <string.h>

void ImgProcess_Top(AXI_STREAM& input, AXI_STREAM& output,int rows, int cols,
		int y_lower,int y_upper,int cb_lower,int cb_upper,int cr_lower,int cr_upper)
{
	#pragma HLS RESOURCE variable=input core=AXIS metadata="-bus_bundle INPUT_STREAM"
	#pragma HLS RESOURCE variable=output core=AXIS metadata="-bus_bundle OUTPUT_STREAM"
	#pragma HLS RESOURCE core=AXI_SLAVE variable=rows metadata="-bus_bundle CONTROL_BUS"
	#pragma HLS RESOURCE core=AXI_SLAVE variable=cols metadata="-bus_bundle CONTROL_BUS"
	#pragma HLS RESOURCE core=AXI_SLAVE variable=y_lower metadata="-bus_bundle CONTROL_BUS"
	#pragma HLS RESOURCE core=AXI_SLAVE variable=y_upper metadata="-bus_bundle CONTROL_BUS"
	#pragma HLS RESOURCE core=AXI_SLAVE variable=cb_lower metadata="-bus_bundle CONTROL_BUS"
	#pragma HLS RESOURCE core=AXI_SLAVE variable=cb_upper metadata="-bus_bundle CONTROL_BUS"
	#pragma HLS RESOURCE core=AXI_SLAVE variable=cr_lower metadata="-bus_bundle CONTROL_BUS"
	#pragma HLS RESOURCE core=AXI_SLAVE variable=cr_upper metadata="-bus_bundle CONTROL_BUS"
	#pragma HLS RESOURCE core=AXI_SLAVE variable=return metadata="-bus_bundle CONTROL_BUS"

	#pragma HLS INTERFACE ap_stable port=rows
	#pragma HLS INTERFACE ap_stable port=cols
	#pragma HLS INTERFACE ap_stable port=y_lower
	#pragma HLS INTERFACE ap_stable port=y_upper
	#pragma HLS INTERFACE ap_stable port=cb_lower
	#pragma HLS INTERFACE ap_stable port=cb_upper
	#pragma HLS INTERFACE ap_stable port=cr_lower
	#pragma HLS INTERFACE ap_stable port=cr_upper
	RGB_IMAGE  src_mat(rows,cols);
	RGB_IMAGE  dst_mat(rows,cols);
	#pragma HLS dataflow
	hls::AXIvideo2Mat(input, src_mat);
	SkinColorDetect(src_mat,dst_mat, y_lower, y_upper, cb_lower, cb_upper, cr_lower, cr_upper);
	hls::Mat2AXIvideo(dst_mat, output);
}
其中,ImgProcess_Top这个函数最后生成一个IP核,可以放在图像通路中使用。函数的接口如下:

input:视频流输入,axi-stream接口;

output:视频流输出,axi-stream接口;

rows,cols:可配置参数,图像的行数、列数。通过AXI-Lite接口,由PS配置。

y_lower,y_upper,cb_lower,cb_upper,cr_lower,cr_upper:可配置参数,肤色检测的一些阈值。通过AXI-Lite接口,由PS配置。

上述代码中,比较重要的一条优化指令为:#pragma HLS dataflow。它使得任务之间为流水线方式,也就是hls::AXIvideo2Mat(input, src_mat);SkinColorDetect(src_mat,dst_mat, y_lower, y_upper, cb_lower, cb_upper, cr_lower, cr_upper);hls::Mat2AXIvideo(dst_mat, output);这三个函数之间为流水线方式执行。

肤色检测的核心函数为SkinColorDetect(src_mat,dst_mat, y_lower, y_upper, cb_lower, cb_upper, cr_lower, cr_upper);它包含在imgprocess.h源码如下:

#ifndef ___IMAGEPROCESS__
#define ___IMAGEPROCESS__
#include "top.h"

u1 rgb2ycbcr(u8 B, u8 G, u8 R, int y_lower, int y_upper, int cb_lower, int cb_upper, int cr_lower, int cr_upper)
{
#pragma HLS PIPELINE
	u8 y, cr, cb;
	y = (76 * R.to_int() + 150 * G.to_int() + 29 * B.to_int()) >> 8;
	cb = 128 + ((128*B.to_int() -43*R.to_int() - 85*G.to_int())>>8);
	cr = 128 + ((128*R.to_int() -107*G.to_int() - 21 * B.to_int())>>8);

	if (y > y_lower && y < y_upper && cb > cb_lower && cb < cb_upper
			&& cr > cr_lower && cr < cr_upper)
		 return 1;
	else
		 return 0;
}

namespace hls {
template<int SRC_T, int DST_T,int ROW, int COL>
void ImgProcess(Mat<ROW, COL, SRC_T> &_src, Mat<ROW, COL, DST_T>	&_dst,
		int y_lower,int y_upper,int cb_lower,int cb_upper,int cr_lower,int cr_upper)
{
	loop_height: for(HLS_SIZE_T i= 0;i< ROW;i++)
	{
	#pragma HLS LOOP_TRIPCOUNT max=ROW
		loop_width: for (HLS_SIZE_T j= 0;j< COL;j++)
		{
		#pragma HLS LOOP_FLATTEN OFF
		#pragma HLS LOOP_TRIPCOUNT max=COL
		#pragma HLS DEPENDENCE array inter false
		#pragma HLS PIPELINE
			u8 r, g, b;
			u1 skin_region;

			HLS_TNAME(SRC_T) temp0=0;
			HLS_TNAME(SRC_T) temp1=0;
			HLS_TNAME(SRC_T) temp2=0;
			/***********stream input *********/
			_src.data_stream[0]>>temp0;
			_src.data_stream[1]>>temp1;
			_src.data_stream[2]>>temp2;

			b = temp0;
			g = temp1;
			r = temp2;
			/********detect skin region*******/
			skin_region = rgb2ycbcr(b, g, r,y_lower,y_upper,cb_lower,cb_upper,cr_lower,cr_upper);
			HLS_TNAME(DST_T) temp_dst0=0;
			HLS_TNAME(DST_T) temp_dst1=0;
			HLS_TNAME(DST_T) temp_dst2=0;

			temp_dst0= (skin_region == 1)? b : (u8)0;
			temp_dst1= (skin_region == 1)? g : (u8)0;
			temp_dst2= (skin_region == 1)? r : (u8)0;

			/***********stream output ********/
			_dst.data_stream[0]<<temp_dst0;
			_dst.data_stream[1]<<temp_dst1;
			_dst.data_stream[2]<<temp_dst2;

		}
	}
}



template<int SRC_T, int DST_T,int ROW, int COL>
void SkinColorDetect(Mat<ROW, COL, SRC_T> &_src,Mat<ROW, COL, DST_T> &_dst,
		int y_lower,int y_upper,int cb_lower,int cb_upper,int cr_lower,int cr_upper)
{
#pragma HLS INLINE
	ImgProcess(_src, _dst, y_lower, y_upper, cb_lower, cb_upper, cr_lower, cr_upper);
}

}



#endif


核心函数是rgb2ycbcr这个函数。关于肤色检测有多种方式,本文的肤色检测方法是将rgb转换为ycbcr,然后设置阈值。

保存后,综合。综合完毕,打开分析工具:


点击红框里的内容:


可以看到imgprocess.h中,ImgProcess这个函数的执行状态:


然后点击ImgProcess_Top_rgb2ycbcr,可以看到如下图:


我们发现,只需一个时钟周期即可执行完毕。这是因为rgb2ycbcr这个函数采用了流水线的优化指令:#pragma HLS PIPELINE。

综合之后,就可以测试了。test.cpp内容如下:

#include "top.h"
#include "hls_opencv.h"
#include"iostream"
#include<time.h>
using namespace std;
using namespace cv;


int main (int argc, char** argv) {



    Mat src = imread("test.jpg");
	AXI_STREAM  src_axi, dst_axi;
	Mat dst(Size(640,480),CV_8UC3);

	resize(src,src,Size(640,480));
	//mat to axi video
	cvMat2AXIvideo(src, src_axi);
	//test function
	ImgProcess_Top(src_axi, dst_axi, 480, 640,0,255,80,135,131,185);
	//axi video to mat
	AXIvideo2cvMat(dst_axi, dst);

	imshow("src",src);
	imshow("dst_hls",dst);

	waitKey(0);

	return 0;
}
测试的图像如下:

运行测试程序后,输出图像如下:

通过测试后,点击hls界面工具栏的export RTL按钮,打包生成ip。最后的IP如下所示:



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HLS图像处理系列——肤色检测 的相关文章

  • SDC时序约束 - create_clock

    在写 sdc约束文件时 要做的第一件事情就是使用create clock对进入FPGA的时钟进行约束 其语法格式如下 create clock add name
  • 【Linux】在Xilinx平台上实现UVC Gadget(2)- 解决dwc3驱动bug

    Linux 在Xilinx平台上实现UVC Gadget 2 解决dwc3驱动bug 一 bug描述 二 具体修改方法 1 找到内核源码位置并复制到其他目录 2 Petalinux里面设置使用自定义内核源码 1 选第2个Linux Comp
  • 【常见 error】Vivado 综合出现中断、失败、“PID not specified”

    目录 发现问题 解决历程 总结 发现问题 在对工程进行综合时 出现综合过程中出现中止或者完全不启动综合 类似下图 明明点击综合启动了几分钟 但是 elapsed 一直显示为 0 表示完全没用启动综合 在 TCL Console 栏中出现了
  • 深入讲解set_multicycle_path多周期约束---实战篇

    设计一个FIFO并且在VIVADO中进行时序约束和时序分析 1 demo背景 设计一个异步的FIFO 2 FIFO时钟的周期约束 create clock period 2 500 name fifo wr clk waveform 0 1
  • FPGA图像处理系列——乒乓球追踪设计实例

    注 本博文将讲解一个FPGA设计图像处理系统实例 此实例的功能为高速追踪乒乓球 读者可以参考本博文的算法思路 工程框架 但博主并不提供工程 当前 实用的图像处理系统都要求高速处理 目前广泛采用软件进行处理 但软件处理存在速度 成本的问题 近
  • vivado创建IP时出现IP_Flow 19-3153] Bus Interface ‘user_clk‘: ASSOCIATED_BUSIF bus parameter is missing解决

    我新建IP时 里面添加了一个自己的输入时钟 系统默认给添加到了时钟和复位信号里面了 如下图箭头指示 然后提示 解决办法 其实就是按照其提示给这个信号添加bus parameter ASSOCIATED BUSIF 右键单击上图红色箭头指示的
  • 【Vivado使用误区与进阶】XDC约束技巧——时钟篇

    Xilinx 的新一代设计套件Vivado中引入了全新的约束文件XDC 在很多规则和技巧上都跟上一代产品ISE中支持的UCF大不相同 给使用者带来许多额外挑战 Xilinx工具专家告诉你 其实用好XDC很容易 只需掌握几点核心技巧 并且时刻
  • Xilinx ISE、MicroBlaze系列教程

    本文是Xilinx MicroBlaze系列教程的第0篇文章 这个系列文章是我个人最近两年使用Xilinx MicroBlaze软核的经验和笔记 以Xilinx ISE 14 7和Spartan 6 Vivado 2018 3和Artix
  • Vivado中ILA(集成逻辑分析仪)的使用

    Vivado中ILA 集成逻辑分析仪 的使用 一 写在前面 二 ILA Integrated Logic Analyzer 的使用 2 1 ILA查找 2 2 ILA配置 2 2 1 General Options 2 2 2 Probe
  • 教程:在ZYBO板卡实现PL-PS交互

    目的 学会vivado PL PS协同开发流程 平台 ZYBO开发板 zynq 7010 clg400芯片 工具 Vivado 2014 4 功能 实现PL PS协同通信 PS通过AXI总线读取PL部分的GPIO状态 对应zybo的四个开关
  • 赛灵思FPGA编程入门指南

    中英双语字幕精校版 赛灵思FPGA编程入门之新手指南第1集 什么是FPGA 现场可编程门阵列 FPGA概念 什么是FPGA 现场可编程门阵列 FPGA概念 本系列视频旨在为FPGA新人逐步讲解教程和基本概念 提供FPGA编程入门指导 帮助您
  • Android如何离线播放加密(HLS)m3u8视频——实现HLS缓存

    HTTP Live Streaming HLS 是苹果公司 Apple Inc 实现的基于HTTP的流媒体传输协议 可实现流媒体的直播和点播 主要应用在iOS系统 为iOS设备 如iPhone iPad 提供音视频直播和点播方案 它的工作原
  • HLS 流传输库hls::stream

    流传输数据是一种数据传输形式 其中数据样本从第一个样本开始按顺序发送 流传输不需要地址管理 Vivado HLS 提供了 C 模板类 hls stream lt gt 用于对流传输数据结构进行建模 使用 hls stream lt gt 类
  • xilinx mipi ip

    占位
  • 如何利用FPGA生成SPWM调制信号

    如何利用FPGA生成SPWM调制信号 实验目标 稍微说一下原理 SPWM即正弦波宽度脉冲调制 冲量等效原理 双极性的的SPWM信号 具体步骤 1 用matlab生成三角波和正弦波的coe文件 2 调用ROM的ip读取coe文件 3 调用pl
  • HLS图像处理系列——肤色检测

    本博文采用Xilinx HLS 2014 4工具 实现一个肤色检测的模块 其中 本文重点是构建HLS图像处理函数 新建HLS工程的步骤 本博文不再详述 本工程新建之后 只添加了五个文件 如下图所示 其中 top cpp中的主函数最终会综合生
  • 【FPGA】Xilinx vivado IP核许可申请——以MIPI CSI-2为例

    1 先进入xilinx官网 复制这个链接直接进入ip申请的地址 http www xilinx com getlicense 打开链接后需要登录 没账户的那就需要注册 点击红色方框内的蓝色字体即可注册 2 注册完成后 可以选择相应的IP核进
  • Verilog 奇怪的仿真结果综合后

    我面临一个奇怪的问题 该代码适用于简单的 ALU 仅将感兴趣的代码粘贴到此处 always posedge clk or posedge rst begin if rst 1 begin mul valid shr 3 b000 end e
  • 触发器在两个信号的边沿触发

    我需要一个对两个不同信号的边缘做出反应的触发器 像这样的东西 if rising edge sig1 then bit lt 0 elsif rising edge sig2 then bit lt 1 end if 这样的触发器是否存在或
  • 将库添加到 Vivado 2014.4

    我对 Vivado 和 VHDL 还很陌生 我想要一些关于基本问题的指导 我猜我可以创建自己的库并在我的项目中使用它们 就像使用默认库和基本库一样 eg library IEEE use IEEE std logic 1164 ALL us

随机推荐