基礎學習筆記之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

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM