软件版本:VIVADO2017.4 操作系统:WIN10 64bit 硬件平台:适用米联客 ZYNQ系列开发板 米联客(MSXBO)论坛:www.osrc.cn答疑解惑专栏开通,欢迎大家给我提问!! 4.1 概述 本章节通过设计一个肤色检测的算法对前面几章的内容进行了巩固和验证,通过一组仿真验证了整个算法的有效性。虽然基于颜色空间转换加阈值进行肤色检测的结果有误差,但我们完全可以对算法进行优化,减小误差,本章重点介绍的是如何设计算法,因此对算法的优化就不再介绍,感兴趣的可以尝试优化一下算法。 4.2 肤色检测原理及应用 肤色作为人的体表显著特征之一,尽管人的肤色因为人种的不同有差异,呈现出不同的颜色,但是在排除了亮度和视觉环境等对肤色的影响后,皮肤的色调基本一致,这就为利用颜色信息来做肤色分割提供了理论的依据。 在肤色识别中,常用的颜色空间为YCbCr颜色空间。在YCbCr颜色空间中,Y代表亮度,Cb和Cr分别代表蓝色分量和红色分量,两者合称为色彩分量。YCbCr颜色空间具有将色度与亮度分离的特点,在YCbCr色彩空间中,肤色的聚类特性比较好,而且是两维独立分布,能够比较好地限制肤色的分布区域,并且受人种的影响不大。对比RGB颜色空间和YCbCr颜色空间,当光强发生变化时,RGB颜色空间中(R,G,B)会同时发生变化,而YCbCr颜色空间中受光强相对独立,色彩分量受光强度影响不大,因此YCbCr颜色空间更适合用于肤色识别。 由于肤色在YCbCr空间受亮度信息的影响较小,本算法直接考虑YCbCr空间的CbCr分量,映射为两维独立分布的CbCr空间。在CbCr空间下,肤色类聚性好,利用人工阈值法将肤色与非肤色区域分开,形成二值图像。 RGB转YCbCr的公式为: Y = 0.257*R+0.564*G+0.098*B+16 Cb= -0.148*R-0.291*G+0.439*B+128 Cr = 0.439*R-0.368*G-0.071*B+128 对肤色进行判定的条件常使用如下判定条件: Cb > 77 && Cb < 127 Cr > 133 && Cr < 173 4.3 检测算法实现4.3.1 工程创建Step1:打开HLS,按照之前介绍的方法,创建一个新的工程,命名为Skin_Dection。 Step2:右单击Source选项,选择New File,创建一个名为Top.cpp的文件。 Step3:在打开的编辑区中,把下面的程序拷贝进去: #include "top.h" #include <string.h> void hls::hls_skin_dection(RGB_IMAGE& src, RGB_IMAGE& dst,int rows, int cols, int y_lower,int y_upper,int cb_lower,int cb_upper,int cr_lower,int cr_upper) { LOOp_ROWS:for(int row = 0; row < rows ; row++) { LOOp_COLS:for(int col = 0; col < cols; col++) { //变量定义 RGB_PIXEL src_data; RGB_PIXEL pix; RGB_PIXEL dst_data; bool skin_region; if(row < rows && col < cols) { src >> src_data; } //获取RGB通道数据 uchar B = src_data.val[0]; uchar G = src_data.val[1]; uchar R = src_data.val[2]; //RGB-->YCbCr颜色空间转换 uchar y = (76 * R + 150 * G + 29 * B) >> 8; uchar cb = ((128*B -43*R - 85*G)>>8) + 128 ; uchar cr = ((128*R -107*G - 21 * B)>>8)+ 128 ; //肤色区域判定 if (y > y_lower && y < y_upper && cb > cb_lower && cb < cb_upper && cr > cr_lower && cr < cr_upper) skin_region = 1; else skin_region = 0; uchar temp0= (skin_region == 1)? (uchar)255: B; uchar temp1= (skin_region == 1)? (uchar)255: G; uchar temp2= (skin_region == 1)? (uchar)255: R; dst_data.val[0] = temp0; dst_data.val[1] = temp1; dst_data.val[2] = temp2; dst << dst_data; } } } 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) { RGB_IMAGE img_0(rows, cols); RGB_IMAGE img_1(rows, cols); #pragma HLS dataflow hls::AXIvideo2Mat(input,img_0); hls::hls_skin_dection(img_0,img_1,rows,cols,y_lower,y_upper,cb_lower,cb_upper,cr_lower,cr_upper); hls::Mat2AXIvideo(img_1, output); } |
同样的方法创建一个名为Top.h的文件。 #ifndef _TOP_H_ #define _TOP_H_ #include "hls_video.h" // maximum image size #define MAX_WIDTH 1920 #define MAX_HEIGHT 1080 typedef unsigned char uchar; // I/O Image Settings #define INPUT_IMAGE "test_1080p.bmp" #define OUTPUT_IMAGE "result_1080p.bmp" #define OUTPUT_IMAGE_GOLDEN "result_1080p_golden.bmp" // typedef video library core structures typedef hls::stream<ap_axiu<24,1,1,1> > AXI_STREAM; typedef hls::Mat<MAX_HEIGHT, MAX_WIDTH, HLS_8UC3> RGB_IMAGE; typedef hls::Scalar<3, unsigned char> RGB_PIXEL; //声明hls命名空间 namespace hls { void hls_skin_dection(RGB_IMAGE& src, RGB_IMAGE& dst,int rows, int cols, int y_lower,int y_upper,int cb_lower,int cb_upper,int cr_lower,int cr_upper); } 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); #endif |
Step4:在Test Bench中,用同样的方法添加一个名为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) { //IplImage* src = cvLoadImage(INPUT_IMAGE); IplImage* src = cvLoadImage("test.jpg"); //IplImage* src = cvLoadImage("test_img1.jpg"); IplImage* dst = cvCreateImage(cvGetSize(src), src->depth, src->nChannels); AXI_STREAM src_axi, dst_axi; IplImage2AXIvideo(src, src_axi); ImgProcess_Top(src_axi, dst_axi, src->height, src->width,0,255,75,125,131,185); AXIvideo2IplImage(dst_axi, dst); cvShowImage("src",src); cvShowImage("dst_hls",dst); waitKey(0); return 0; } |
Step5:在Test Bench中添加一张名为test.jpg的测试图片,图片可以在我们提供的源程序中的Image文件夹中找到。完整的工程如下图所示: 4.3.2 代码综合 了解了肤色检测的原理以后我们进行算法实现可以发现,算法的关键就是进行RGB到YCbCr颜色空间的转换,其关键算法如下,大家可以发现其实算法只需要几十行就可以很容易的实现检测算法,不过需要大家注意的是因为我们使用C++进行开发,那么为了程序的通用性以及方便团队合作开发,建议大家使用namespace命名空间,这样可以很好的解决重名问题,而且可以增加程序的可读性。 接下来,我们对项目进行代码综合。 Step1:单击Project—project settings命令。 Step2:在弹出的窗口中选择综合选项,然后在顶层函数设置区中单击右边的Browse…按钮。 Step3:选择ImgProcess_Top为顶层函数,然后单击两次OK,完成工程的设置。 Step4:单击综合快捷按钮Active Solution开始代码综合。 等待一段时间后,在未经代码优化及约束的条件下生成的综合报告如图:
-
米联客FMC-SFP模块支持4路SFP光纤接口,最大支持10Gbps速率。可以安装到具有HPC的FMC接口开发板上使用。控
14760
-
FMC-3G SDI子卡测试1.1概述使用FMC-3GSDI子卡来实现 FPGA 通过 GTH 高速收发器从同轴电缆接收 3G-SDI 信号
15400
-
-
双十一欢乐购!米联客天猫商城和京东商城狂欢15日!2022.10.28-2022.11.11店铺推出满减优惠券!领券下单享
12910
-
1产品概述FEP-CARD-DAQ9248是一款14bits双通道65MSPS ADC采集模块,该方案采用了ADI的AD9248芯片,扩展接口
55660
-
1产品概述FEP-DAQ976X是一款14bits双通道125MSPS DAC数模转换模块,该方案采用了ADI的AD9767芯片,扩展接口
34940
-
本文在 AXI_DMA_LOOP 环路测试架构的基础上,在 DATA FIFO 端加入 FPGA 代码,对 FIFO 写,实现将 PL 端数
86253
-
在前文中我们学习了AXI总线协议,而且通过VIVADO自定义了AXI-LITE总线协议的IP CORE,并且实现了寄存器的读
49601
-
FDMA是米联客的基于AXI4总线协议定制的一个DMA控制器。有了这个IP我们可以统一实现用FPGA代码直接读写PL的D
79303
-
在前文的实验中我们详细介绍了FDMA的使用方法,以及使用了AXI-BRAM演示了FDMA的使用,现在我们已经掌握了FD
89288
-
米联客FMC-SFP模块支持4路SFP光纤接口,最大支持10Gbps速率。可以安装到具有HPC的FMC接口开发板上使用。控
14760
-
FMC-3G SDI子卡测试1.1概述使用FMC-3GSDI子卡来实现 FPGA 通过 GTH 高速收发器从同轴电缆接收 3G-SDI 信号
15400
-
-
双十一欢乐购!米联客天猫商城和京东商城狂欢15日!2022.10.28-2022.11.11店铺推出满减优惠券!领券下单享
12870
-
1产品概述FEP-CARD-DAQ9248是一款14bits双通道65MSPS ADC采集模块,该方案采用了ADI的AD9248芯片,扩展接口
55650
-
1产品概述FEP-DAQ976X是一款14bits双通道125MSPS DAC数模转换模块,该方案采用了ADI的AD9767芯片,扩展接口
34930
-
本文在 AXI_DMA_LOOP 环路测试架构的基础上,在 DATA FIFO 端加入 FPGA 代码,对 FIFO 写,实现将 PL 端数
86253
-
在前文中我们学习了AXI总线协议,而且通过VIVADO自定义了AXI-LITE总线协议的IP CORE,并且实现了寄存器的读
49581
-
FDMA是米联客的基于AXI4总线协议定制的一个DMA控制器。有了这个IP我们可以统一实现用FPGA代码直接读写PL的D
79283
-
在前文的实验中我们详细介绍了FDMA的使用方法,以及使用了AXI-BRAM演示了FDMA的使用,现在我们已经掌握了FD
89288
-
米联客FMC-SFP模块支持4路SFP光纤接口,最大支持10Gbps速率。可以安装到具有HPC的FMC接口开发板上使用。控
14760
-
FMC-3G SDI子卡测试1.1概述使用FMC-3GSDI子卡来实现 FPGA 通过 GTH 高速收发器从同轴电缆接收 3G-SDI 信号
15390
-
-
双十一欢乐购!米联客天猫商城和京东商城狂欢15日!2022.10.28-2022.11.11店铺推出满减优惠券!领券下单享
12830
-
1产品概述FEP-CARD-DAQ9248是一款14bits双通道65MSPS ADC采集模块,该方案采用了ADI的AD9248芯片,扩展接口
55640
-
1产品概述FEP-DAQ976X是一款14bits双通道125MSPS DAC数模转换模块,该方案采用了ADI的AD9767芯片,扩展接口
34910
-
本文在 AXI_DMA_LOOP 环路测试架构的基础上,在 DATA FIFO 端加入 FPGA 代码,对 FIFO 写,实现将 PL 端数
86243
-
在前文中我们学习了AXI总线协议,而且通过VIVADO自定义了AXI-LITE总线协议的IP CORE,并且实现了寄存器的读
49521
-
FDMA是米联客的基于AXI4总线协议定制的一个DMA控制器。有了这个IP我们可以统一实现用FPGA代码直接读写PL的D
79273
-
在前文的实验中我们详细介绍了FDMA的使用方法,以及使用了AXI-BRAM演示了FDMA的使用,现在我们已经掌握了FD
89218
-
1.1 FPGA技术背景笔者也是在偶然的机缘下接触到FPGA的,当初只有感性的认识就是FPGA速
1018520
-
淘宝购买链接:https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-18659455309
1288915
-
在前面的课程种,我们已经提供了FDMA和XDMA配合使用,应用于PCIE传图的方案。但是前面
14319615
-
8B/10B编码是1983年由IBM公司的Al Widmer和PeterFranaszek所提出的数据传输编码标准,
676410
-
淘宝购买连接:https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-18659455309
89038
-
1概述在米联客老版本的MIA701开发板(2017版本)中,米联开源了1套原创的UDP IP协议栈。
115398
-
1、电源改动版本使用电压输入电压范围201712275V4.7-5.2V201909185V2.0-16V新版本采用
58258
-
前面我们完成了一个PCIE中断采集图像的方案,但是很多应用中我们需要采集分析ADC的数
93768
-
本章讲解使用PL端以太网口实现UDP通信。开发板中实现千兆网 UDP 传输的基本逻辑框架如
126958
-
在前文的实验中我们详细介绍了FDMA的使用方法,以及使用了AXI-BRAM演示了FDMA的使用,
89238
-
1.1 FPGA技术背景笔者也是在偶然的机缘下接触到FPGA的,当初只有感性的认识就是FPGA速
1018820
-
在前面的课程种,我们已经提供了FDMA和XDMA配合使用,应用于PCIE传图的方案。但是前面
14320115
-
淘宝购买链接:https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-18659455309
1288915
-
8B/10B编码是1983年由IBM公司的Al Widmer和PeterFranaszek所提出的数据传输编码标准,
676610
-
1、电源改动版本使用电压输入电压范围201712275V4.7-5.2V201909185V2.0-16V新版本采用
58258
-
前面我们完成了一个PCIE中断采集图像的方案,但是很多应用中我们需要采集分析ADC的数
93788
-
本章讲解使用PL端以太网口实现UDP通信。开发板中实现千兆网 UDP 传输的基本逻辑框架如
126978
-
在前文的实验中我们详细介绍了FDMA的使用方法,以及使用了AXI-BRAM演示了FDMA的使用,
89288
-
淘宝购买连接:https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-18659455309
89048
-
1概述在米联客老版本的MIA701开发板(2017版本)中,米联开源了1套原创的UDP IP协议栈。
115438
-
1.1 FPGA技术背景笔者也是在偶然的机缘下接触到FPGA的,当初只有感性的认识就是FPGA速
1018820
-
淘宝购买链接:https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-18659455309
1288915
-
在前面的课程种,我们已经提供了FDMA和XDMA配合使用,应用于PCIE传图的方案。但是前面
14320115
-
8B/10B编码是1983年由IBM公司的Al Widmer和PeterFranaszek所提出的数据传输编码标准,
676610
-
淘宝购买连接:https://item.taobao.com/item.htm?spm=a1z10.5-c-s.w4002-18659455309
89058
-
1概述在米联客老版本的MIA701开发板(2017版本)中,米联开源了1套原创的UDP IP协议栈。
115438
-
1、电源改动版本使用电压输入电压范围201712275V4.7-5.2V201909185V2.0-16V新版本采用
58258
-
前面我们完成了一个PCIE中断采集图像的方案,但是很多应用中我们需要采集分析ADC的数
93788
-
本章讲解使用PL端以太网口实现UDP通信。开发板中实现千兆网 UDP 传输的基本逻辑框架如
126978
-
在前文的实验中我们详细介绍了FDMA的使用方法,以及使用了AXI-BRAM演示了FDMA的使用,
89288
-
米联客FMC-SFP模块支持4路SFP光纤接口,最大支持10Gbps速率。可以安装到具有HPC的FMC
14760
-
FMC-3G SDI子卡测试1.1概述使用FMC-3GSDI子卡来实现 FPGA 通过 GTH 高速收发器从同轴
15400
-
双十一欢乐购!米联客天猫商城和京东商城狂欢15日!2022.10.28-2022.11.11店铺推出满
12840
-
1产品概述FEP-CARD-DAQ9248是一款14bits双通道65MSPS ADC采集模块,该方案采用了ADI的
55650
-
1产品概述FEP-DAQ976X是一款14bits双通道125MSPS DAC数模转换模块,该方案采用了ADI的
34920
-
本文在 AXI_DMA_LOOP 环路测试架构的基础上,在 DATA FIFO 端加入 FPGA 代码,对 FIFO
86243
-
在前文中我们学习了AXI总线协议,而且通过VIVADO自定义了AXI-LITE总线协议的IP CORE,
49551
-
FDMA是米联客的基于AXI4总线协议定制的一个DMA控制器。有了这个IP我们可以统一实现用F
79273
-
在前文的实验中我们详细介绍了FDMA的使用方法,以及使用了AXI-BRAM演示了FDMA的使用,
89248
-
基于FDMA可以完成很多数据读写存储类的应用,本文将展示通过FDMA读写AXI-BRAM
本文实
49771
-
米联客FMC-SFP模块支持4路SFP光纤接口,最大支持10Gbps速率。可以安装到具有HPC的FMC
14760
-
FMC-3G SDI子卡测试1.1概述使用FMC-3GSDI子卡来实现 FPGA 通过 GTH 高速收发器从同轴
15400
-
双十一欢乐购!米联客天猫商城和京东商城狂欢15日!2022.10.28-2022.11.11店铺推出满
12910
-
1产品概述FEP-CARD-DAQ9248是一款14bits双通道65MSPS ADC采集模块,该方案采用了ADI的
55660
-
1产品概述FEP-DAQ976X是一款14bits双通道125MSPS DAC数模转换模块,该方案采用了ADI的
34940
-
本文在 AXI_DMA_LOOP 环路测试架构的基础上,在 DATA FIFO 端加入 FPGA 代码,对 FIFO
86253
-
在前文中我们学习了AXI总线协议,而且通过VIVADO自定义了AXI-LITE总线协议的IP CORE,
49601
-
FDMA是米联客的基于AXI4总线协议定制的一个DMA控制器。有了这个IP我们可以统一实现用F
79313
-
在前文的实验中我们详细介绍了FDMA的使用方法,以及使用了AXI-BRAM演示了FDMA的使用,
89288
-
基于FDMA可以完成很多数据读写存储类的应用,本文将展示通过FDMA读写AXI-BRAM
本文实
49781
-
米联客FMC-SFP模块支持4路SFP光纤接口,最大支持10Gbps速率。可以安装到具有HPC的FMC
14760
-
FMC-3G SDI子卡测试1.1概述使用FMC-3GSDI子卡来实现 FPGA 通过 GTH 高速收发器从同轴
15400
-
双十一欢乐购!米联客天猫商城和京东商城狂欢15日!2022.10.28-2022.11.11店铺推出满
12890
-
1产品概述FEP-CARD-DAQ9248是一款14bits双通道65MSPS ADC采集模块,该方案采用了ADI的
55660
-
1产品概述FEP-DAQ976X是一款14bits双通道125MSPS DAC数模转换模块,该方案采用了ADI的
34940
-
本文在 AXI_DMA_LOOP 环路测试架构的基础上,在 DATA FIFO 端加入 FPGA 代码,对 FIFO
86253
-
在前文中我们学习了AXI总线协议,而且通过VIVADO自定义了AXI-LITE总线协议的IP CORE,
49591
-
FDMA是米联客的基于AXI4总线协议定制的一个DMA控制器。有了这个IP我们可以统一实现用F
79303
-
在前文的实验中我们详细介绍了FDMA的使用方法,以及使用了AXI-BRAM演示了FDMA的使用,
89288
-
基于FDMA可以完成很多数据读写存储类的应用,本文将展示通过FDMA读写AXI-BRAM
本文实
49781
|