本博文採用Xilinx HLS 2014.4工具。实现一个肤色检測的模块。当中,本文重点是构建HLS图像处理函数。

新建HLSproject的步骤,本博文不再详述。

本project新建之后,仅仅加入了五个文件,例如以下图所看到的。当中,top.cpp中的主函数终于会综合生成HLS硬件图像处理模块。test.cpp是測试文件,调用測试图片。測试top.cpp的图像处理函数功能。

top.cpp的源代码例如以下:

  1. #include "top.h"
  2. #include "imgprocess.h"
  3. #include <string.h>
  4.  
  5. void ImgProcess_Top(AXI_STREAM& input, AXI_STREAM& output,int rows, int cols,
  6. int y_lower,int y_upper,int cb_lower,int cb_upper,int cr_lower,int cr_upper)
  7. {
  8. #pragma HLS RESOURCE variable=input core=AXIS metadata="-bus_bundle INPUT_STREAM"
  9. #pragma HLS RESOURCE variable=output core=AXIS metadata="-bus_bundle OUTPUT_STREAM"
  10. #pragma HLS RESOURCE core=AXI_SLAVE variable=rows metadata="-bus_bundle CONTROL_BUS"
  11. #pragma HLS RESOURCE core=AXI_SLAVE variable=cols metadata="-bus_bundle CONTROL_BUS"
  12. #pragma HLS RESOURCE core=AXI_SLAVE variable=y_lower metadata="-bus_bundle CONTROL_BUS"
  13. #pragma HLS RESOURCE core=AXI_SLAVE variable=y_upper metadata="-bus_bundle CONTROL_BUS"
  14. #pragma HLS RESOURCE core=AXI_SLAVE variable=cb_lower metadata="-bus_bundle CONTROL_BUS"
  15. #pragma HLS RESOURCE core=AXI_SLAVE variable=cb_upper metadata="-bus_bundle CONTROL_BUS"
  16. #pragma HLS RESOURCE core=AXI_SLAVE variable=cr_lower metadata="-bus_bundle CONTROL_BUS"
  17. #pragma HLS RESOURCE core=AXI_SLAVE variable=cr_upper metadata="-bus_bundle CONTROL_BUS"
  18. #pragma HLS RESOURCE core=AXI_SLAVE variable=return metadata="-bus_bundle CONTROL_BUS"
  19.  
  20. #pragma HLS INTERFACE ap_stable port=rows
  21. #pragma HLS INTERFACE ap_stable port=cols
  22. #pragma HLS INTERFACE ap_stable port=y_lower
  23. #pragma HLS INTERFACE ap_stable port=y_upper
  24. #pragma HLS INTERFACE ap_stable port=cb_lower
  25. #pragma HLS INTERFACE ap_stable port=cb_upper
  26. #pragma HLS INTERFACE ap_stable port=cr_lower
  27. #pragma HLS INTERFACE ap_stable port=cr_upper
  28. RGB_IMAGE src_mat(rows,cols);
  29. RGB_IMAGE dst_mat(rows,cols);
  30. #pragma HLS dataflow
  31. hls::AXIvideo2Mat(input, src_mat);
  32. SkinColorDetect(src_mat,dst_mat, y_lower, y_upper, cb_lower, cb_upper, cr_lower, cr_upper);
  33. hls::Mat2AXIvideo(dst_mat, output);
  34. }

当中。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源代码例如以下:

  1. #ifndef ___IMAGEPROCESS__
  2. #define ___IMAGEPROCESS__
  3. #include "top.h"
  4.  
  5. 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)
  6. {
  7. #pragma HLS PIPELINE
  8. u8 y, cr, cb;
  9. y = (76 * R.to_int() + 150 * G.to_int() + 29 * B.to_int()) >> 8;
  10. cb = 128 + ((128*B.to_int() -43*R.to_int() - 85*G.to_int())>>8);
  11. cr = 128 + ((128*R.to_int() -107*G.to_int() - 21 * B.to_int())>>8);
  12.  
  13. if (y > y_lower && y < y_upper && cb > cb_lower && cb < cb_upper
  14. && cr > cr_lower && cr < cr_upper)
  15. return 1;
  16. else
  17. return 0;
  18. }
  19.  
  20. namespace hls {
  21. template<int SRC_T, int DST_T,int ROW, int COL>
  22. void ImgProcess(Mat<ROW, COL, SRC_T> &_src, Mat<ROW, COL, DST_T> &_dst,
  23. int y_lower,int y_upper,int cb_lower,int cb_upper,int cr_lower,int cr_upper)
  24. {
  25. loop_height: for(HLS_SIZE_T i= 0;i< ROW;i++)
  26. {
  27. #pragma HLS LOOP_TRIPCOUNT max=ROW
  28. loop_width: for (HLS_SIZE_T j= 0;j< COL;j++)
  29. {
  30. #pragma HLS LOOP_FLATTEN OFF
  31. #pragma HLS LOOP_TRIPCOUNT max=COL
  32. #pragma HLS DEPENDENCE array inter false
  33. #pragma HLS PIPELINE
  34. u8 r, g, b;
  35. u1 skin_region;
  36.  
  37. HLS_TNAME(SRC_T) temp0=0;
  38. HLS_TNAME(SRC_T) temp1=0;
  39. HLS_TNAME(SRC_T) temp2=0;
  40. /***********stream input *********/
  41. _src.data_stream[0]>>temp0;
  42. _src.data_stream[1]>>temp1;
  43. _src.data_stream[2]>>temp2;
  44.  
  45. b = temp0;
  46. g = temp1;
  47. r = temp2;
  48. /********detect skin region*******/
  49. skin_region = rgb2ycbcr(b, g, r,y_lower,y_upper,cb_lower,cb_upper,cr_lower,cr_upper);
  50. HLS_TNAME(DST_T) temp_dst0=0;
  51. HLS_TNAME(DST_T) temp_dst1=0;
  52. HLS_TNAME(DST_T) temp_dst2=0;
  53.  
  54. temp_dst0= (skin_region == 1)? b : (u8)0;
  55. temp_dst1= (skin_region == 1)?
  56.  
  57. g : (u8)0;
  58. temp_dst2= (skin_region == 1)?
  59.  
  60. r : (u8)0;
  61.  
  62. /***********stream output ********/
  63. _dst.data_stream[0]<<temp_dst0;
  64. _dst.data_stream[1]<<temp_dst1;
  65. _dst.data_stream[2]<<temp_dst2;
  66.  
  67. }
  68. }
  69. }
  70.  
  71. template<int SRC_T, int DST_T,int ROW, int COL>
  72. void SkinColorDetect(Mat<ROW, COL, SRC_T> &_src,Mat<ROW, COL, DST_T> &_dst,
  73. int y_lower,int y_upper,int cb_lower,int cb_upper,int cr_lower,int cr_upper)
  74. {
  75. #pragma HLS INLINE
  76. ImgProcess(_src, _dst, y_lower, y_upper, cb_lower, cb_upper, cr_lower, cr_upper);
  77. }
  78.  
  79. }
  80.  
  81. #endif

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

保存后,综合。

综合完成,打开分析工具:

点击红框里的内容:

能够看到imgprocess.h中,ImgProcess这个函数的运行状态:

然后点击ImgProcess_Top_rgb2ycbcr,能够看到例如以下图:

我们发现,仅仅需一个时钟周期就可以运行完成。这是由于rgb2ycbcr这个函数採用了流水线的优化指令:#pragma HLS PIPELINE。

综合之后,就能够測试了。

test.cpp内容例如以下:

  1. #include "top.h"
  2. #include "hls_opencv.h"
  3. #include"iostream"
  4. #include<time.h>
  5. using namespace std;
  6. using namespace cv;
  7.  
  8. int main (int argc, char** argv) {
  9.  
  10. Mat src = imread("test.jpg");
  11. AXI_STREAM src_axi, dst_axi;
  12. Mat dst(Size(640,480),CV_8UC3);
  13.  
  14. resize(src,src,Size(640,480));
  15. //mat to axi video
  16. cvMat2AXIvideo(src, src_axi);
  17. //test function
  18. ImgProcess_Top(src_axi, dst_axi, 480, 640,0,255,80,135,131,185);
  19. //axi video to mat
  20. AXIvideo2cvMat(dst_axi, dst);
  21.  
  22. imshow("src",src);
  23. imshow("dst_hls",dst);
  24.  
  25. waitKey(0);
  26.  
  27. return 0;
  28. }

測试的图像例如以下:

执行測试程序后。输出图像例如以下:

通过測试后,点击hls界面工具栏的export RTLbutton,打包生成ip。最后的IP例如以下所看到的:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTFpZMjcyOTQyNTE4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

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

  1. 图像处理之Canny边缘检測

    图像处理之Canny 边缘检測 一:历史 Canny边缘检測算法是1986年有John F. Canny开发出来一种基于图像梯度计算的边缘 检測算法,同一时候Canny本人对计算图像边缘提取学科的发展 ...

  2. 爱国者布局智能硬件,空探系列PM2.5检測仪“嗅霾狗”大曝光

        随着6月1日史上最严禁烟令的正式实施,国内包含北京.上海.成都等大中型城市已经在公共场所全面禁烟.众所周知,实施禁烟令的根本在于促进空气的净化,实现环境的改善,要达到这个目的,光有禁烟令是远远 ...

  3. Python图像处理(8):边缘检測

    快乐虾 http://blog.csdn.net/lights_joy/ 欢迎转载,但请保留作者信息 此前已经得到了单个区域植株图像,接下来似乎应该尝试对这些区域进行分类识别.通过外形和叶脉进行植物种 ...

  4. OpenCV图像处理篇之边缘检測算子

    3种边缘检測算子 灰度或结构等信息的突变位置是图像的边缘,图像的边缘有幅度和方向属性.沿边缘方向像素变化缓慢,垂直边缘方向像素变化剧烈.因此,边缘上的变化能通过梯度计算出来. 一阶导数的梯度算子 对于 ...

  5. 【OpenCV新手教程之十二】OpenCV边缘检測:Canny算子,Sobel算子,Laplace算子,Scharr滤波器合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/25560901 作者:毛星云(浅墨) ...

  6. Matlab图像处理系列2———空间域平滑滤波器

    注:本系列来自于图像处理课程实验,用Matlab实现最主要的图像处理算法 本文章是Matlab图像处理系列的第二篇文章.介绍了空间域图像处理最主要的概念----模版和滤波器,给出了均值滤波起和中值滤波 ...

  7. 【OpenCV新手教程之十七】OpenCV重映射 &amp; SURF特征点检測合辑

    本系列文章由@浅墨_毛星云 出品.转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/30974513 作者:毛星云(浅墨)  ...

  8. 目标检測的图像特征提取之(一)HOG特征

    1.HOG特征: 方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检測的特征描写叙述子.它通过计算和统计图像局部区 ...

  9. AIX下RAC搭建 Oracle10G(一)检測系统环境

    AIX下RAC搭建系列 环境 节点 节点1 节点2 小机型号 IBM P-series 630 IBM P-series 630 主机名 AIX203 AIX204 交换机 SAN光纤交换机 存储 S ...

随机推荐

  1. 李洪强漫谈iOS开发[C语言-054]-函数

    // //  main.c //  02 翻译数字的优化 // //  Created by vic fan on 2017/6/4. //  Copyright © 2017年 李洪强. All r ...

  2. Spark使用总结与分享【转】

    背景 使用spark开发已有几个月.相比于python/hive,scala/spark学习门槛较高.尤其记得刚开时,举步维艰,进展十分缓慢.不过谢天谢地,这段苦涩(bi)的日子过去了.忆苦思甜,为了 ...

  3. java 多线程8 : synchronized锁机制 之 方法锁

    脏读 一个常见的概念.在多线程中,难免会出现在多个线程中对同一个对象的实例变量或者全局静态变量进行并发访问的情况,如果不做正确的同步处理,那么产生的后果就是"脏读",也就是取到的数 ...

  4. iOS网络NSURLConnection使用详解

    一.整体介绍 NSURLConnection是苹果提供的原生网络访问类,但是苹果很快会将其废弃,且由NSURLSession(iOS7以后)来替代.目前使用最广泛的第三方网络框架AFNetworkin ...

  5. iOS开发之Xcode常见错误

    一."file/file.h" file not found 如果遇到这种类型的问题报错,可以分为三部来解决,由简到复杂一步一步来,直到解决问题位置.1. 点击Xcode -> ...

  6. 友盟分享和cocos2dx符合重复duplicate symbol 解决方案

    最近使用友盟分享的sdk,没想到libWechatSDK.a居然和cocos2dx的符合冲突,提示base64.o重复了. 于是到网上找了一下解决方案,基本上去除微信的base64.o即可了. 用ar ...

  7. 启动haoop并运行wordcount

    启动hadoop,这里hadoop的版本是2.7.4 进入Hadoop的安装目录的bin目录下,采用-format命令格式化文件系统. hadoop namenode -format hadoop d ...

  8. zip文件内存中解压读取

    // 构造zip输入流 ZipInputStream zip = new ZipInputStream(fis,Charset.forName("gbk")); byte[] tm ...

  9. MongoDB自动删除过期数据--TTL索引

      前序: 由于公司业务需求,对于3个月前的过期数据需要进行删除动作,以释放空间和方便维护 本来想的是使用crontab写个脚本定时执行,但是看到Mongo本身就有自动删除过期数据的功能,所以还是用一 ...

  10. 将BAT文件注册为服务的方法

    一.什么是instsrv.exe和srvany.exe instsrv.exe.exe和srvany.exe是Microsoft Windows Resource Kits工具集中 的两个实用工具,这 ...