• OpenCV常见的几种背景消除的方法


    1、肤色侦测法
       肤色提取是基于人机互动方面常见的方法。因为肤色是人体的一大特征,它可以迅速从复杂的背景下分离出自己的特征区域。一下介绍两种常见的肤色提取:

    1)HSV空间的肤色提取
     
        HSV色彩空间是一个圆锥形的模型,具体如右图所示:
     色相(H)是色彩的基本属性,就是平常说的颜色名称,例如红色、黄色等,
    依照右图的标准色轮上的位置,取360度得数值。(也有0~100%的方法确定) 饱和度(S)是色彩的纯度,越高色彩越纯,低则变灰。取值为0~100%。明度(V)也叫亮度,取值0~100。
         根据肤色在HSV三个分量上的值,就可以简单的侦测出一张图像上肤色的部分。一下是肤色侦测函数的源代码:

     1 void skinDetectionHSV(IplImage* pImage,int lower,int upper,IplImage* process)
     2 {
     3     IplImage* pImageHSV = NULL;
     4     IplImage* pImageH = NULL;
     5     IplImage* pImageS = NULL;
     6     IplImage* pImageProcessed = NULL;
     7     IplImage* tmpH = NULL;
     8     IplImage* tmpS = NULL;
     9     static IplImage* pyrImage = NULL;
    10 
    11     CvSize imgSize;
    12     imgSize.height = pImage->height;
    13     imgSize.width = pImage->width ;
    14 
    15     //create you want to use image and give them memory allocation
    16     pImageHSV = cvCreateImage(imgSize,IPL_DEPTH_8U,3);
    17     pImageH = cvCreateImage(imgSize,IPL_DEPTH_8U,1);
    18     pImageS = cvCreateImage(imgSize,IPL_DEPTH_8U,1);
    19     tmpS = cvCreateImage(imgSize,IPL_DEPTH_8U,1);
    20     tmpH = cvCreateImage(imgSize,IPL_DEPTH_8U,1);
    21     pImageProcessed = cvCreateImage(imgSize,IPL_DEPTH_8U,1);
    22     pyrImage = cvCreateImage(cvSize(pImage->width/2,pImage->height/2),IPL_DEPTH_8U,1);
    23 
    24     //convert RGB image to HSV image
    25     cvCvtColor(pImage,pImageHSV,CV_BGR2HSV);
    26 
    27     //Then split HSV to three single channel images
    28     cvCvtPixToPlane(pImageHSV,pImageH,pImageS,NULL,NULL);
    29     //The skin scalar range in H and S,    Do they AND algorithm
    30     cvInRangeS(pImageH,cvScalar(0.0,0.0,0,0),cvScalar(lower,0.0,0,0),tmpH);
    31     cvInRangeS(pImageS,cvScalar(26,0.0,0,0),cvScalar(upper,0.0,0,0),tmpS);
    32     cvAnd(tmpH,tmpS,pImageProcessed,0);
    33     //
    34     //cvPyrDown(pImageProcessed,pyrImage,CV_GAUSSIAN_5x5);
    35     //cvPyrUp(pyrImage,pImageProcessed,CV_GAUSSIAN_5x5);
    36     //Erode and dilate
    37     cvErode(pImageProcessed,pImageProcessed,0,2);
    38     cvDilate(pImageProcessed,pImageProcessed,0,1);
    39 
    40     cvCopy(pImageProcessed,process,0);
    41     //do clean
    42     cvReleaseImage(&pyrImage);
    43     cvReleaseImage(&pImageHSV);
    44     cvReleaseImage(&pImageH);
    45     cvReleaseImage(&pImageS);
    46     cvReleaseImage(&pyrImage);
    47     cvReleaseImage(&tmpH);
    48     cvReleaseImage(&tmpS);
    49     cvReleaseImage(&pImageProcessed);
    50 }

     

    (2)YCrCb空间的肤色提取
       YCrCb也是一种颜色空间,也可以说是YUV的颜色空间。Y是亮度的分量,而肤色侦测是对亮度比较敏感的,由摄像头拍摄的RGB图像转化为YCrCb空间的话可以去除亮度对肤色侦测的影响。下面给出基于YCrCb肤色侦测函数的源代码:

     

     1 void skinDetectionYCrCb(IplImage* imageRGB,int lower,int upper,IplImage* imgProcessed)
     2 {
     3 
     4         assert(imageRGB->nChannels==3);
     5     IplImage* imageYCrCb = NULL;
     6     IplImage* imageCb = NULL;
     7     imageYCrCb = cvCreateImage(cvGetSize(imageRGB),8,3);
     8     imageCb = cvCreateImage(cvGetSize(imageRGB),8,1);
     9 
    10     cvCvtColor(imageRGB,imageYCrCb,CV_BGR2YCrCb);
    11     cvSplit(imageYCrCb,0,0,imageCb,0);//Cb
    12     for (int h=0;h<imageCb->height;h++)
    13         {
    14         for (int w=0;w<imageCb->width;w++)
    15                  {
    16             unsigned char* p =(unsigned char*)(imageCb->imageData+h*imageCb->widthStep+w);
    17             if (*p<=upper&&*p>=lower)
    18                        {
    19                 *p=255;
    20             }
    21                         else
    22                         {
    23                 *p=0;
    24             }
    25         }
    26     }
    27     cvCopy(imageCb,imgProcessed,NULL);
    28 }

     

    2、基于混合高斯模型去除背景法

       高斯模型去除背景法也是背景去除的一种常用的方法,经常会用到视频图像侦测中。这种方法对于动态的视频图像特征侦测比较适合,因为模型中是前景和背景分离开来的。分离前景和背景的基准是判断像素点变化率,会把变化慢的学习为背景,变化快的视为前景。

     

     

      1 //
      2 
      3 #include "stdafx.h"
      4 #include "cv.h"
      5 #include "highgui.h"
      6 #include "cxtypes.h"
      7 #include "cvaux.h"
      8 # include <iostream>
      9 
     10 using namespace std;
     11 
     12 
     13 int _tmain(int argc, _TCHAR* argv[])
     14 {
     15     //IplImage* pFirstFrame = NULL;
     16 IplImage* pFrame = NULL;
     17     IplImage* pFrImg = NULL;
     18     IplImage* pBkImg = NULL;
     19     IplImage* FirstImg = NULL;
     20     static IplImage* pyrImg =NULL;
     21     CvCapture* pCapture = NULL;
     22     int nFrmNum = 0;
     23     int first = 0,next = 0;
     24     int thresh = 0;
     25 
     26     cvNamedWindow("video",0);
     27     //cvNamedWindow("background",0);
     28     cvNamedWindow("foreground",0);
     29     cvResizeWindow("video",400,400);
     30     cvResizeWindow("foreground",400,400);
     31     //cvCreateTrackbar("thresh","foreground",&thresh,255,NULL);
     32     //cvMoveWindow("background",360,0);
     33     //cvMoveWindow("foregtound",0,0);
     34 
     35     if(!(pCapture = cvCaptureFromCAM(1)))
     36     {
     37         printf("Could not initialize camera , please check it !");
     38         return -1;
     39     }
     40 
     41     CvGaussBGModel* bg_model = NULL;
     42 
     43     while(pFrame = cvQueryFrame(pCapture))
     44     {
     45         nFrmNum++;
     46         if(nFrmNum == 1)
     47         {
     48             pBkImg = cvCreateImage(cvGetSize(pFrame),IPL_DEPTH_8U,3);
     49             pFrImg = cvCreateImage(cvGetSize(pFrame),IPL_DEPTH_8U,1);
     50             FirstImg = cvCreateImage(cvGetSize(pFrame),IPL_DEPTH_8U,1);
     51             pyrImg = cvCreateImage(cvSize(pFrame->width/2,pFrame->height/2),IPL_DEPTH_8U,1);
     52             
     53             CvGaussBGStatModelParams params;
     54             params.win_size = 2000;             //Learning rate = 1/win_size;
     55             params.bg_threshold = 0.7;         //Threshold  sum of weights for background test
     56             params.weight_init = 0.05;
     57             params.variance_init = 30;
     58             params.minArea = 15.f;
     59             params.n_gauss = 5;    //= K =Number of gaussian in mixture
     60             params.std_threshold = 2.5;
     61 
     62             //cvCopy(pFrame,pFirstFrame,0);
     63         
     64             bg_model = (CvGaussBGModel*)cvCreateGaussianBGModel(pFrame,¶ms);
     65         }
     66         else
     67         {
     68                 int regioncount = 0;
     69                 int totalNum = pFrImg->width *pFrImg->height ;
     70                 
     71                 cvSmooth(pFrame,pFrame,CV_GAUSSIAN,3,0,0,0);
     72     
     73                 cvUpdateBGStatModel(pFrame,(CvBGStatModel*)bg_model,-0.00001);
     74                 cvCopy(bg_model->foreground ,pFrImg,0);
     75                 cvCopy(bg_model->background ,pBkImg,0);
     76                 //cvShowImage("background",pBkImg);
     77 
     78                 //cvSmooth(pFrImg,pFrImg,CV_GAUSSIAN,3,0,0,0);
     79                 //cvPyrDown(pFrImg,pyrImg,CV_GAUSSIAN_5x5);
     80                 //cvPyrUp(pyrImg,pFrImg,CV_GAUSSIAN_5x5);
     81                 //cvSmooth(pFrImg,pFrImg,CV_GAUSSIAN,3,0,0,0);
     82                 cvErode(pFrImg,pFrImg,0,1);
     83                 cvDilate(pFrImg,pFrImg,0,3);
     84 
     85                 //pBkImg->origin = 1;
     86                 //pFrImg->origin = 1;
     87             
     88             cvShowImage("video",pFrame);
     89             cvShowImage("foreground",pFrImg);
     90             //cvReleaseBGStatModel((CvBGStatModel**)&bg_model);
     91             //bg_model = (CvGaussBGModel*)cvCreateGaussianBGModel(pFrame,0);
     92             /*
     93             //catch target frame
     94             if(nFrmNum>10 &&(double)cvSumImage(pFrImg)>0.3 * totalNum)
     95             {
     96                 
     97                 first = cvSumImage(FirstImg);
     98                 next = cvSumImage(pFrImg);
     99                 printf("Next number is :%d /n",next);
    100                 cvCopy(pFrImg,FirstImg,0);
    101             }
    102             cvShowImage("foreground",pFrImg);
    103             cvCopy(pFrImg,FirstImg,0);
    104             */
    105             if(cvWaitKey(2)== 27)
    106             {
    107                 break;
    108             }
    109         }
    110     }
    111     cvReleaseBGStatModel((CvBGStatModel**)&bg_model);
    112     cvDestroyAllWindows();
    113     cvReleaseImage(&pFrImg);
    114     cvReleaseImage(&FirstImg);
    115     cvReleaseImage(&pFrame);
    116     cvReleaseImage(&pBkImg);
    117     cvReleaseCapture(&pCapture);
    118 
    119     return 0;
    120 }

     

    3、背景相减背景去除方法

       所谓的背景相减,是指把摄像头捕捉的图像第一帧作为背景,以后的每一帧都减去背景帧,这样减去之后剩下的就是多出来的特征物体(要侦测的物体)的部分。但是相减的部分也会对特征物体的灰阶值产生影响,一般是设定相关阈值要进行判断。以下是代码部分:

     

      1 int _tmain(int argc, _TCHAR* argv[])
      2 {
      3     int thresh_low = 30;
      4     
      5     IplImage* pImgFrame = NULL; 
      6     IplImage* pImgProcessed = NULL;
      7     IplImage* pImgBackground = NULL;
      8     IplImage* pyrImage = NULL;
      9 
     10     CvMat* pMatFrame = NULL;
     11     CvMat* pMatProcessed = NULL;
     12     CvMat* pMatBackground = NULL;
     13 
     14     CvCapture* pCapture = NULL;
     15 
     16     cvNamedWindow("video", 0);
     17     cvNamedWindow("background",0);
     18     cvNamedWindow("processed",0);
     19     //Create trackbar
     20     cvCreateTrackbar("Low","processed",&thresh_low,255,NULL);
     21 
     22     cvResizeWindow("video",400,400);
     23     cvResizeWindow("background",400,400);
     24     cvResizeWindow("processed",400,400);
     25 
     26     cvMoveWindow("video", 0, 0);
     27     cvMoveWindow("background", 400, 0);
     28     cvMoveWindow("processed", 800, 0);
     29     
     30     if( !(pCapture = cvCaptureFromCAM(1)))
     31     {
     32         fprintf(stderr, "Can not open camera./n");
     33         return -2;
     34     }
     35 
     36     //first frame
     37     pImgFrame = cvQueryFrame( pCapture );
     38     pImgBackground = cvCreateImage(cvSize(pImgFrame->width, pImgFrame->height),  IPL_DEPTH_8U,1);
     39     pImgProcessed = cvCreateImage(cvSize(pImgFrame->width, pImgFrame->height),  IPL_DEPTH_8U,1);
     40     pyrImage = cvCreateImage(cvSize(pImgFrame->width/2, pImgFrame->height/2),  IPL_DEPTH_8U,1);
     41 
     42     pMatBackground = cvCreateMat(pImgFrame->height, pImgFrame->width, CV_32FC1);
     43     pMatProcessed = cvCreateMat(pImgFrame->height, pImgFrame->width, CV_32FC1);
     44     pMatFrame = cvCreateMat(pImgFrame->height, pImgFrame->width, CV_32FC1);
     45 
     46     cvSmooth(pImgFrame, pImgFrame, CV_GAUSSIAN, 3, 0, 0);
     47     cvCvtColor(pImgFrame, pImgBackground, CV_BGR2GRAY);
     48     cvCvtColor(pImgFrame, pImgProcessed, CV_BGR2GRAY);
     49 
     50     cvConvert(pImgProcessed, pMatFrame);
     51     cvConvert(pImgProcessed, pMatProcessed);
     52     cvConvert(pImgProcessed, pMatBackground);
     53     cvSmooth(pMatBackground, pMatBackground, CV_GAUSSIAN, 3, 0, 0);
     54 
     55     while(pImgFrame = cvQueryFrame( pCapture ))
     56     {
     57         cvShowImage("video", pImgFrame);
     58         cvSmooth(pImgFrame, pImgFrame, CV_GAUSSIAN, 3, 0, 0);
     59 
     60         cvCvtColor(pImgFrame, pImgProcessed, CV_BGR2GRAY);
     61         cvConvert(pImgProcessed, pMatFrame);
     62 
     63         cvSmooth(pMatFrame, pMatFrame, CV_GAUSSIAN, 3, 0, 0);
     64         cvAbsDiff(pMatFrame, pMatBackground, pMatProcessed);
     65         //cvConvert(pMatProcessed,pImgProcessed);
     66         //cvThresholdBidirection(pImgProcessed,thresh_low);
     67         cvThreshold(pMatProcessed, pImgProcessed, 30, 255.0, CV_THRESH_BINARY);
     68         
     69         cvPyrDown(pImgProcessed,pyrImage,CV_GAUSSIAN_5x5);
     70         cvPyrUp(pyrImage,pImgProcessed,CV_GAUSSIAN_5x5);
     71         //Erode and dilate
     72         cvErode(pImgProcessed, pImgProcessed, 0, 1);
     73         cvDilate(pImgProcessed, pImgProcessed, 0, 1);    
     74         
     75         //background update
     76         cvRunningAvg(pMatFrame, pMatBackground, 0.0003, 0);                    
     77         cvConvert(pMatBackground, pImgBackground);
     78         
     79         
     80         cvShowImage("background", pImgBackground);
     81         cvShowImage("processed", pImgProcessed);
     82         
     83         //cvZero(pImgProcessed);
     84         if( cvWaitKey(10) == 27 )
     85         {
     86             break;
     87         }
     88     }
     89 
     90     cvDestroyWindow("video");
     91     cvDestroyWindow("background");
     92     cvDestroyWindow("processed");
     93 
     94     cvReleaseImage(&pImgProcessed);
     95     cvReleaseImage(&pImgBackground);
     96 
     97     cvReleaseMat(&pMatFrame);
     98     cvReleaseMat(&pMatProcessed);
     99     cvReleaseMat(&pMatBackground);
    100 
    101     cvReleaseCapture(&pCapture);
    102 
    103     return 0;
    104 }

     

     

     

     

  • 相关阅读:
    js 安全
    js压缩 uglify(2)
    js压缩 uglify
    抢红包算法 java
    手机调试
    Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom
    字符集编码 定长与变长
    db2 sqlcode
    2015.7.14(大盘结束红色,中色连坐4T)
    2015.7.10(全部涨停!想逢高出货,但是担心周一创新高)
  • 原文地址:https://www.cnblogs.com/leven20061001/p/2703670.html
Copyright © 2020-2023  润新知