zoukankan      html  css  js  c++  java
  • 基础学习笔记之opencv(17):皮肤检测类CvAdaptiveSkinDetector的使用

     

      前言
      皮肤检测是利用皮肤的颜色信息的阈值来进行检测的,不过这些阈值一般不是使用rgb空间,而是用HSV或者YCrCb等空间。皮肤检测是使用统计的方法统计出大量人的皮肤信息,然后就可以得到色彩空间某一分量的阈值了,利用该阈值就可以初步对皮肤进行分割。当然了,OpenCV中也自带了皮肤检测算子,包含在类CvAdaptiveSkinDetector中。本节内容就是来试试OpenCV自带的皮肤检测算法的性能。

      开发环境:OpenCV2.4.3+QtCreator2.5.1

     

      实验基础

      OpenCV自带是算法的参考文献有网友说是An adaptive real-time skin detector based on Hue thresholding: A comparison on two motion tracking methods,见参考资料1。稍微看了下该论文的算法流程和CvAdaptiveSkinDetector类的源码,该源码的实现差不多就是按照这篇文章进行的,主要是把皮肤阈值分割和运动检测相结合。该算法的流程图如下所示:

      

      可以看出该皮肤检测算法是在HSV空间进行的,HSV空间模型图如下所示:

      

      其中H表示的是色相,即不同颜色最具有区别性的地方,见模型中的那个圆弧;S代表的是饱和度,也就是含白光的纯度,见模型中的那条半径,S越大表示越饱和,即表示对应色相越纯;V表示亮度,见模型中那条竖直的线,V越大表示对应点越亮。 

      下面来看看CvAdaptiveSkinDetector类中的2个比较重要的函数:

      CvAdaptiveSkinDetector(int samplingDivider = 1, int morphingMethod = MORPHING_METHOD_NONE);

      该函数为类的构造函数,其中参数1表示的是样本采样的间隔,默认情况下为1,即表示不进行降采样;参数2为图形学操作方式,即对用皮肤检测后的图像进行图形学操作。其取值有3种可能,如果为MORPHING_METHOD_ERODE,则表示只进行一次腐蚀操作;如果为MORPHING_METHOD_ERODE_ERODE,则表示连续进行2次腐蚀操作;如果为MORPHING_METHOD_ERODE_DILATE,则表示先进行一次腐蚀操作,后进行一次膨胀操作。 

      virtual void process(IplImage *inputBGRImage, IplImage *outputHueMask);

      该函数为皮肤检测的核心函数,参数1为需要进行皮肤检测的输入图像;参数2为输出皮肤的掩膜图像,如果其值为1,代表该像素为皮肤,否则当其为0时,代表为非皮肤。另外需要注意的是,这个函数只有opencv的c版本的,因为CvAdaptiveSkinDetector这个类放在opencv源码里的contrib目录里,即表示比较新的但不成熟的算法,所以暂时没有提供c++版本的opencv。因此参数1和参数2的图像数据类型都是IplImage,如果要使用Mat,就得先进行一个小小的转换,具体参考代码部分。

     

     

      C/c++知识点总结:

      看了CvAdaptiveSkinDetector类的源码,发现在类的设计中,其内部还可以设计一个类,比如CvAdaptiveSkinDetector中嵌入了一个直方图的类。

     

     

      实验结果

      下面的图是需要进行肤色检测的图(主要是检测出手部):

      

     

      其检测完后的效果图如下:

      

      由此可见,其检测效果一般般,因为很多背景都被考虑进来了。

     

      实验代码及注释:

      main.cpp:

    #include <opencv2/core/core.hpp>
    #include <opencv2/highgui/highgui.hpp>
    #include <opencv2/contrib/contrib.hpp>
    #include <opencv2/imgproc/imgproc.hpp>
    #include <iostream>
    
    using namespace std;
    using namespace cv;
    
    Mat input_image;
    Mat output_mask;
    Mat output_image;
    IplImage *src_image;
    IplImage *dst_image;
    void main()
    {
        VideoCapture cam(0);
        if(!cam.isOpened())
            return;
    
        namedWindow("input image");
        namedWindow("output mask");
        namedWindow("output image");
    
        CvAdaptiveSkinDetector skin_detector(1, CvAdaptiveSkinDetector::MORPHING_METHOD_NONE);
        while(true) {
            cam >> input_image;
            src_image = &input_image.operator IplImage();
            if(dst_image == NULL)
                dst_image = cvCreateImage(cvSize(src_image->width, src_image->height), IPL_DEPTH_8U, 1);    //一定要先分配一个内存
            skin_detector.process(src_image, dst_image);
            output_mask = 255*Mat(dst_image);
            input_image.copyTo(output_image, output_mask);
    
            imshow("input image", input_image);
            imshow("output mask", output_mask);
            imshow("output image", output_image);
            output_image.setTo(0);
            if(27 == waitKey(30))
                return;
        }
        return;
    }

     

      实验总结:

      皮肤检测本身就受背景,光照,肤色等方面的影响,所以要使效果好还是比较难的,OpenCV带的该算法效果也非常一般。

     

      参考资料:

         基于opencv的皮肤检测

         An adaptive real-time skin detector based on Hue thresholding: A comparison on two motion tracking methods

     

     

     

  • 相关阅读:
    linux 更换golang版本
    ubuntu 搭建NFS
    golang 异步并发http轮询(爬虫)
    Mysql 事务锁等待时间超时
    排序算法之鸡尾酒排序
    Sql Server一个表向另一个表添加多条数据,关联时查询出一条数据
    Easyui datagrid 开始时间不能大于结束时间
    用python爬了上千万条招聘信息后,最终分析出python要学这些才能就业...
    用python把B站小姐姐跳舞视频爬下来,并打包成可以直接运行的exe文件
    女朋友股票亏惨了,我一怒之下用Python爬取了证券最新数据...
  • 原文地址:https://www.cnblogs.com/tornadomeet/p/2778740.html
Copyright © 2011-2022 走看看