• opencv去除背景


    1、肤色侦测法
       肤色提取是基于人机互动方面常见的方法。因为肤色是人体的一大特征,它可以迅速从复杂的背景下分离出自己的特征区域。一下介绍两种常见的肤色提取:
    
    (1)HSV空间的肤色提取
         HSV色彩空间是一个圆锥形的模型,具体如右图所示:
     色相(H)是色彩的基本属性,就是平常说的颜色名称,例如红色、黄色等,
    依照右图的标准色轮上的位置,取360度得数值。(也有0~100%的方法确定) 饱和度(S)是色彩的纯度,越高色彩越纯,低则变灰。取值为0~100%。明度(V)也叫亮度,取值0~100。
         根据肤色在HSV三个分量上的值,就可以简单的侦测出一张图像上肤色的部分。一下是肤色侦测函数的源代码:
    [c-sharp] view plaincopy
    
        void skinDetectionHSV(IplImage* pImage,int lower,int upper,IplImage* process)  
        {  
            IplImage* pImageHSV = NULL;  
            IplImage* pImageH = NULL;  
            IplImage* pImageS = NULL;  
            IplImage* pImageProcessed = NULL;  
            IplImage* tmpH = NULL;  
            IplImage* tmpS = NULL;  
            static IplImage* pyrImage = NULL;  
          
            CvSize imgSize;  
            imgSize.height = pImage->height;  
            imgSize.width = pImage->width ;  
          
            //create you want to use image and give them memory allocation  
            pImageHSV = cvCreateImage(imgSize,IPL_DEPTH_8U,3);  
            pImageH = cvCreateImage(imgSize,IPL_DEPTH_8U,1);  
            pImageS = cvCreateImage(imgSize,IPL_DEPTH_8U,1);  
            tmpS = cvCreateImage(imgSize,IPL_DEPTH_8U,1);  
            tmpH = cvCreateImage(imgSize,IPL_DEPTH_8U,1);  
            pImageProcessed = cvCreateImage(imgSize,IPL_DEPTH_8U,1);  
            pyrImage = cvCreateImage(cvSize(pImage->width/2,pImage->height/2),IPL_DEPTH_8U,1);  
          
            //convert RGB image to HSV image  
            cvCvtColor(pImage,pImageHSV,CV_BGR2HSV);  
          
            //Then split HSV to three single channel images  
            cvCvtPixToPlane(pImageHSV,pImageH,pImageS,NULL,NULL);  
            //The skin scalar range in H and S, Do they AND algorithm  
            cvInRangeS(pImageH,cvScalar(0.0,0.0,0,0),cvScalar(lower,0.0,0,0),tmpH);  
            cvInRangeS(pImageS,cvScalar(26,0.0,0,0),cvScalar(upper,0.0,0,0),tmpS);  
            cvAnd(tmpH,tmpS,pImageProcessed,0);  
            //  
            //cvPyrDown(pImageProcessed,pyrImage,CV_GAUSSIAN_5x5);  
            //cvPyrUp(pyrImage,pImageProcessed,CV_GAUSSIAN_5x5);  
            //Erode and dilate  
            cvErode(pImageProcessed,pImageProcessed,0,2);  
            cvDilate(pImageProcessed,pImageProcessed,0,1);  
          
            cvCopy(pImageProcessed,process,0);  
            //do clean  
            cvReleaseImage(&pyrImage);  
            cvReleaseImage(&pImageHSV);  
            cvReleaseImage(&pImageH);  
            cvReleaseImage(&pImageS);  
            cvReleaseImage(&pyrImage);  
            cvReleaseImage(&tmpH);  
            cvReleaseImage(&tmpS);  
            cvReleaseImage(&pImageProcessed);  
        }  
    
     
    
     
    
     (2)YCrCb空间的肤色提取
       YCrCb也是一种颜色空间,也可以说是YUV的颜色空间。Y是亮度的分量,而肤色侦测是对亮度比较敏感的,由摄像头拍摄的RGB图像转化为YCrCb空间的话可以去除亮度对肤色侦测的影响。下面给出基于YCrCb肤色侦测函数的源代码:
    
     
    [c-sharp] view plaincopy
    
        void skinDetectionYCrCb(IplImage* imageRGB,int lower,int upper,IplImage* imgProcessed)  
        {  
          
                assert(imageRGB->nChannels==3);  
            IplImage* imageYCrCb = NULL;  
            IplImage* imageCb = NULL;  
            imageYCrCb = cvCreateImage(cvGetSize(imageRGB),8,3);  
            imageCb = cvCreateImage(cvGetSize(imageRGB),8,1);  
          
            cvCvtColor(imageRGB,imageYCrCb,CV_BGR2YCrCb);  
            cvSplit(imageYCrCb,0,0,imageCb,0);//Cb  
            for (int h=0;hheight;h++)  
                {  
                for (int w=0;wwidth;w++)  
                         {  
                    unsigned char* p =(unsigned char*)(imageCb->imageData+h*imageCb->widthStep+w);  
                    if (*p<=upper&&*p>=lower)  
                               {  
                        *p=255;  
                    }  
                                else  
                                {  
                        *p=0;  
                    }  
                }  
            }  
            cvCopy(imageCb,imgProcessed,NULL);  
        }  
    
     
    
    2、基于混合高斯模型去除背景法
    
       高斯模型去除背景法也是背景去除的一种常用的方法,经常会用到视频图像侦测中。这种方法对于动态的视频图像特征侦测比较适合,因为模型中是前景和背景分离开来的。分离前景和背景的基准是判断像素点变化率,会把变化慢的学习为背景,变化快的视为前景。
    [c-sharp] view plaincopy
    
        //  
         
        #include "stdafx.h"  
        #include "cv.h"  
        #include "highgui.h"  
        #include "cxtypes.h"  
        #include "cvaux.h"  
        # include   
          
        using namespace std;  
          
          
        int _tmain(int argc, _TCHAR* argv[])  
        {  
            //IplImage* pFirstFrame = NULL;  
        IplImage* pFrame = NULL;  
            IplImage* pFrImg = NULL;  
            IplImage* pBkImg = NULL;  
            IplImage* FirstImg = NULL;  
            static IplImage* pyrImg =NULL;  
            CvCapture* pCapture = NULL;  
            int nFrmNum = 0;  
            int first = 0,next = 0;  
            int thresh = 0;  
          
            cvNamedWindow("video",0);  
            //cvNamedWindow("background",0);  
            cvNamedWindow("foreground",0);  
            cvResizeWindow("video",400,400);  
            cvResizeWindow("foreground",400,400);  
            //cvCreateTrackbar("thresh","foreground",&thresh,255,NULL);  
            //cvMoveWindow("background",360,0);  
            //cvMoveWindow("foregtound",0,0);  
          
            if(!(pCapture = cvCaptureFromCAM(1)))  
            {  
                printf("Could not initialize camera , please check it !");  
                return -1;  
            }  
          
            CvGaussBGModel* bg_model = NULL;  
          
            while(pFrame = cvQueryFrame(pCapture))  
            {  
                nFrmNum++;  
                if(nFrmNum == 1)  
                {  
                    pBkImg = cvCreateImage(cvGetSize(pFrame),IPL_DEPTH_8U,3);  
                    pFrImg = cvCreateImage(cvGetSize(pFrame),IPL_DEPTH_8U,1);  
                    FirstImg = cvCreateImage(cvGetSize(pFrame),IPL_DEPTH_8U,1);  
                    pyrImg = cvCreateImage(cvSize(pFrame->width/2,pFrame->height/2),IPL_DEPTH_8U,1);  
                      
                    CvGaussBGStatModelParams params;  
                    params.win_size = 2000;             //Learning rate = 1/win_size;  
                    params.bg_threshold = 0.7;         //Threshold  sum of weights for background test  
                    params.weight_init = 0.05;  
                    params.variance_init = 30;  
                    params.minArea = 15.f;  
                    params.n_gauss = 5; //= K =Number of gaussian in mixture  
                    params.std_threshold = 2.5;  
          
                    //cvCopy(pFrame,pFirstFrame,0);  
                  
                    bg_model = (CvGaussBGModel*)cvCreateGaussianBGModel(pFrame,¶ms);  
                }  
                else  
                {  
                        int regioncount = 0;  
                        int totalNum = pFrImg->width *pFrImg->height ;  
                          
                        cvSmooth(pFrame,pFrame,CV_GAUSSIAN,3,0,0,0);  
              
                        cvUpdateBGStatModel(pFrame,(CvBGStatModel*)bg_model,-0.00001);  
                        cvCopy(bg_model->foreground ,pFrImg,0);  
                        cvCopy(bg_model->background ,pBkImg,0);  
                        //cvShowImage("background",pBkImg);  
          
                        //cvSmooth(pFrImg,pFrImg,CV_GAUSSIAN,3,0,0,0);  
                        //cvPyrDown(pFrImg,pyrImg,CV_GAUSSIAN_5x5);  
                        //cvPyrUp(pyrImg,pFrImg,CV_GAUSSIAN_5x5);  
                        //cvSmooth(pFrImg,pFrImg,CV_GAUSSIAN,3,0,0,0);  
                        cvErode(pFrImg,pFrImg,0,1);  
                        cvDilate(pFrImg,pFrImg,0,3);  
          
                        //pBkImg->origin = 1;  
                        //pFrImg->origin = 1;  
                      
                    cvShowImage("video",pFrame);  
                    cvShowImage("foreground",pFrImg);  
                    //cvReleaseBGStatModel((CvBGStatModel**)&bg_model);  
                    //bg_model = (CvGaussBGModel*)cvCreateGaussianBGModel(pFrame,0);  
                    /* 
                    //catch target frame 
                    if(nFrmNum>10 &&(double)cvSumImage(pFrImg)>0.3 * totalNum) 
                    { 
                         
                        first = cvSumImage(FirstImg); 
                        next = cvSumImage(pFrImg); 
                        printf("Next number is :%d /n",next); 
                        cvCopy(pFrImg,FirstImg,0); 
                    } 
                    cvShowImage("foreground",pFrImg); 
                    cvCopy(pFrImg,FirstImg,0); 
                    */  
                    if(cvWaitKey(2)== 27)  
                    {  
                        break;  
                    }  
                }  
            }  
            cvReleaseBGStatModel((CvBGStatModel**)&bg_model);  
            cvDestroyAllWindows();  
            cvReleaseImage(&pFrImg);  
            cvReleaseImage(&FirstImg);  
            cvReleaseImage(&pFrame);  
            cvReleaseImage(&pBkImg);  
            cvReleaseCapture(&pCapture);  
          
            return 0;  
        }  
    
     
    
     
    
    3、背景相减背景去除方法
    
       所谓的背景相减,是指把摄像头捕捉的图像第一帧作为背景,以后的每一帧都减去背景帧,这样减去之后剩下的就是多出来的特征物体(要侦测的物体)的部分。但是相减的部分也会对特征物体的灰阶值产生影响,一般是设定相关阈值要进行判断。以下是代码部分:
    
    
     
    [c-sharp] view plaincopy
    
        int _tmain(int argc, _TCHAR* argv[])  
        {  
            int thresh_low = 30;  
              
            IplImage* pImgFrame = NULL;   
            IplImage* pImgProcessed = NULL;  
            IplImage* pImgBackground = NULL;  
            IplImage* pyrImage = NULL;  
          
            CvMat* pMatFrame = NULL;  
            CvMat* pMatProcessed = NULL;  
            CvMat* pMatBackground = NULL;  
          
            CvCapture* pCapture = NULL;  
          
            cvNamedWindow("video", 0);  
            cvNamedWindow("background",0);  
            cvNamedWindow("processed",0);  
            //Create trackbar  
            cvCreateTrackbar("Low","processed",&thresh_low,255,NULL);  
          
            cvResizeWindow("video",400,400);  
            cvResizeWindow("background",400,400);  
            cvResizeWindow("processed",400,400);  
          
            cvMoveWindow("video", 0, 0);  
            cvMoveWindow("background", 400, 0);  
            cvMoveWindow("processed", 800, 0);  
              
            if( !(pCapture = cvCaptureFromCAM(1)))  
            {  
                fprintf(stderr, "Can not open camera./n");  
                return -2;  
            }  
          
            //first frame  
            pImgFrame = cvQueryFrame( pCapture );  
            pImgBackground = cvCreateImage(cvSize(pImgFrame->width, pImgFrame->height),  IPL_DEPTH_8U,1);  
            pImgProcessed = cvCreateImage(cvSize(pImgFrame->width, pImgFrame->height),  IPL_DEPTH_8U,1);  
            pyrImage = cvCreateImage(cvSize(pImgFrame->width/2, pImgFrame->height/2),  IPL_DEPTH_8U,1);  
          
            pMatBackground = cvCreateMat(pImgFrame->height, pImgFrame->width, CV_32FC1);  
            pMatProcessed = cvCreateMat(pImgFrame->height, pImgFrame->width, CV_32FC1);  
            pMatFrame = cvCreateMat(pImgFrame->height, pImgFrame->width, CV_32FC1);  
          
            cvSmooth(pImgFrame, pImgFrame, CV_GAUSSIAN, 3, 0, 0);  
            cvCvtColor(pImgFrame, pImgBackground, CV_BGR2GRAY);  
            cvCvtColor(pImgFrame, pImgProcessed, CV_BGR2GRAY);  
          
            cvConvert(pImgProcessed, pMatFrame);  
            cvConvert(pImgProcessed, pMatProcessed);  
            cvConvert(pImgProcessed, pMatBackground);  
            cvSmooth(pMatBackground, pMatBackground, CV_GAUSSIAN, 3, 0, 0);  
          
            while(pImgFrame = cvQueryFrame( pCapture ))  
            {  
                cvShowImage("video", pImgFrame);  
                cvSmooth(pImgFrame, pImgFrame, CV_GAUSSIAN, 3, 0, 0);  
          
                cvCvtColor(pImgFrame, pImgProcessed, CV_BGR2GRAY);  
                cvConvert(pImgProcessed, pMatFrame);  
          
                cvSmooth(pMatFrame, pMatFrame, CV_GAUSSIAN, 3, 0, 0);  
                cvAbsDiff(pMatFrame, pMatBackground, pMatProcessed);  
                //cvConvert(pMatProcessed,pImgProcessed);  
                //cvThresholdBidirection(pImgProcessed,thresh_low);  
                cvThreshold(pMatProcessed, pImgProcessed, 30, 255.0, CV_THRESH_BINARY);  
                  
                cvPyrDown(pImgProcessed,pyrImage,CV_GAUSSIAN_5x5);  
                cvPyrUp(pyrImage,pImgProcessed,CV_GAUSSIAN_5x5);  
                //Erode and dilate  
                cvErode(pImgProcessed, pImgProcessed, 0, 1);  
                cvDilate(pImgProcessed, pImgProcessed, 0, 1);     
                  
                //background update  
                cvRunningAvg(pMatFrame, pMatBackground, 0.0003, 0);                   
                cvConvert(pMatBackground, pImgBackground);  
                  
                  
                cvShowImage("background", pImgBackground);  
                cvShowImage("processed", pImgProcessed);  
                  
                //cvZero(pImgProcessed);  
                if( cvWaitKey(10) == 27 )  
                {  
                    break;  
                }  
            }  
          
            cvDestroyWindow("video");  
            cvDestroyWindow("background");  
            cvDestroyWindow("processed");  
          
            cvReleaseImage(&pImgProcessed);  
            cvReleaseImage(&pImgBackground);  
          
            cvReleaseMat(&pMatFrame);  
            cvReleaseMat(&pMatProcessed);  
            cvReleaseMat(&pMatBackground);  
          
            cvReleaseCapture(&pCapture);  
          
            return 0;  
        }  
  • 相关阅读:
    【字符串题目】poj 3096 Surprising Strings
    【转载】:【博弈论】博弈的学习和总结
    【博弈论】hihocoder
    转载:SPFA算法学习
    马克思所言:
    【NOIP2013】火柴排队
    【NOIP2013】【P1441】花匠
    【JZOI2002】【BZOJ1477】【P1371】青蛙的约会
    【P1373】奶牛的卧室
    2016.9.16 の 測試
  • 原文地址:https://www.cnblogs.com/ligun123/p/2457433.html
Copyright © 2020-2023  润新知