zoukankan      html  css  js  c++  java
  • OpenCV背景去除的几种方法

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

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

    [c-sharp] view plaincopy
    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肤色侦测函数的源代码:

    [c-sharp] view plaincopy
    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、基于混合高斯模型去除背景法

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

    [c-sharp] view plaincopy
    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、背景相减背景去除方法

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


     

    [c-sharp] view plaincopy
    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. }  
  • 相关阅读:
    vue 仿IOS 滚轮选择器
    一道题目学ES6 API,合并对象id相同的两个数组对象
    Express中间件原理详解
    webpack原理与实战
    LS522 体积小低电压低成本的13.56MHz非接触式读写卡芯片,集成了在13.56MHz下所有类型的被动非接触式通信方式和协议,支持ISO14443A/B的多层应用( PIN对PIN MFRC522 )
    SP213EEA-L/TR +5V高性能RS232收发器
    多速率SDI集成接收器 SDI解码芯片 GS2971A-IBE3
    低电容3.3V TVS管 R CLAMP3304N.TCT
    高ESD耐压/TVS二极管 UCLAMP2804L.TCT
    高性能正电压稳压管SC4215HSETRT
  • 原文地址:https://www.cnblogs.com/mfryf/p/2424024.html
Copyright © 2011-2022 走看看