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