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 }

 

 

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM