`

OpenCV背景去除的几种方法(转)

 
阅读更多

OpenCV背景去除的几种方法

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

1)HSV空间的肤色提取
 
    HSV色彩空间是一个圆锥形的模型,具体如右图所示:


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

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肤色侦测函数的源代码:

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;h<imageCb->height;h++)
        {
		for (int w=0;w<imageCb->width;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、基于混合高斯模型去除背景法

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

//

#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "cxtypes.h"
#include "cvaux.h"
# include <iostream>

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、背景相减背景去除方法

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

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;
}
 
  • 大小: 12.1 KB
分享到:
评论

相关推荐

    Opencv背景去除的几种方法.docx

    本文将对OpenCV中的几种常见背景去除方法进行介绍,并通过源码示例来加深理解。 首先,肤色侦测法是一种基于人类肤色特征的背景去除方法。这种方法依赖于对人类肤色在色度空间中的特征进行建模,并利用这些信息来...

    opencv背景提取

    在“opencv背景提取”这个主题中,我们主要关注的是如何从视频流中提取静止背景,以便识别和追踪移动的物体。高斯背景提取是实现这一目标的一种常用方法。 高斯背景模型是一种基于统计的方法,它假设场景中的静态...

    opencv利用掩码实现逼真贴图 去除白背景

    ### 使用OpenCV实现基于掩码的逼真图像叠加去除白背景 #### 一、引言 在计算机视觉领域,图像处理技术是不可或缺的一部分。其中,掩码(Mask)技术是一种非常实用的方法,常用于实现图像的精准抠取及合成。本文将...

    opencv 背景提取

    GMM是最常用的一种,它假设每个像素点的亮度由几个高斯分布混合而成,通过学习和更新这些高斯分布来反映背景的变化。 二、GMM背景提取 1. 初始化:首先,我们需要对连续的几帧图像进行处理,初始化每个像素点的高斯...

    object-dect.zip_opencv背景差分

    OpenCV提供了几种背景建模算法,如混合高斯模型(Gaussian Mixture Model,GMM)、历史信息法(Adaptive Background Mixture Models, ABM)等。GMM是常用的背景建模方法,它假设背景由多个高斯分布组成,随着时间...

    opencv 轮廓的提取多种方法

    下面,我们将深入探讨OpenCV中提取轮廓的几种方法。 1. **Canny边缘检测** Canny算法是一种经典的边缘检测方法,它通过高斯滤波消除噪声,然后应用非极大值抑制来找到局部最大值,最后通过双阈值检测确定边缘。在...

    第一种方法的输出.rar_opencv_python opencv_提取前景_背景减除_视频背景减除

    在给定的标题“第一种方法的输出.rar_opencv_python opencv_提取前景_背景减除_视频背景减除”以及描述“背景减除提取前景并保存前景视频,利用的是opencv python”中,我们可以深入探讨OpenCV在视频处理中的这一...

    基于OpenCV的车辆轮廓检测

    本文介绍了一种新型的基于开源计算机视觉库OpenCV的车辆轮廓检测方法。针对传统汽车尺寸参数测量手段相对落后的现状,本文提出了一种结合图像处理技术和计算机视觉算法的新方法。通过对采集到的车辆图像进行预处理...

    使用opencv提取单据轮廓并旋转保存

    在OpenCV中,轮廓是一种闭合的曲线,用于描述图像中的对象边界。在处理单据图像时,轮廓提取可以帮助我们识别和分离出单据的边界,以便后续处理。使用`cv2.findContours()`函数可以找到图像中的所有轮廓。这个函数...

    基于OpenCV python3实现证件照换背景的方法

    很多时候我们手头上可能只有一种背景颜色的证件照,这时候就需要借助图像处理技术来实现背景颜色的更换。传统的图像编辑软件如Photoshop虽然能够完成这一任务,但对于非专业人士来说,操作较为复杂且容易出现边缘...

    opencv运动物体检测

    OpenCV提供了几种不同的方法来实现这一目标,包括背景减除、光流法以及基于深度学习的方法。 1. **背景减除**:这是最常用的一种运动物体检测方法。OpenCV提供了多种背景模型,如混合高斯模型(Gaussian Mixture ...

    opencv--jiance.zip_opencv目标检测_基于opencv的_背景差分

    在基于OpenCV的背景差分方法中,首先需要建立一个静态背景模型。这通常通过对一段时间内的帧进行平均或者高斯混合模型来实现。一旦背景模型建立起来,每帧与背景模型进行比较,找出与背景显著不同的区域,这些差异...

    核密度背景建模 opencv kernal

    总的来说,核密度背景建模是计算机视觉中一种重要的技术,它利用OpenCV库提供了强大的工具来处理视频数据,实现背景建模和前景检测。理解并掌握这种技术对于开发智能监控系统或者其他相关应用具有重要意义。通过阅读...

    背景差法OpenCV实现程序代码

    OpenCV提供了几种不同的背景差法实现,包括以下几种: 1. **高斯混合模型(Gaussian Mixture Model, GMM)**:OpenCV的`cv::createBackgroundSubtractorMOG2`函数实现了基于高斯混合模型的背景差法。它假设每个像素...

    Opencv常用前景提取算法

    本文将深入探讨标题中提到的几种OpenCV常用的前景提取方法:高斯混合模型(GMM)、VIBE(ViBe)算法以及帧差法。 首先,我们来看**高斯混合模型(GMM)**。GMM是一种统计建模方法,它假设背景由多个高斯分布组成。...

    光流法opencv实现

    总之,OpenCV提供的光流法工具为开发者提供了一种高效的方法来处理视频中的运动检测问题。通过理解和应用这些工具,我们可以构建强大的视觉系统,实现智能监控、自动驾驶等领域的目标跟踪功能。在实际项目中,根据...

    opencv_目标检测_Opencv实现vibe算法,用于视频前景检测_vibe算法_视频前景检测_VC++

    VIBE(ViBe)算法是一种基于像素级背景模型的视频前景检测方法。它的核心思想是利用历史像素值来构建一个背景模型,并通过比较当前帧像素值与背景模型的差异来判断该像素是否属于前景。VIBE算法的特点是它将每个像素...

    基于OpenCV的红点识别

    2. **颜色空间转换**:OpenCV允许我们将图像从一种色彩空间转换到另一种,如从BGR(标准RGB)到HSV(色调-饱和度-值)。在HSV色彩空间中,红色通常有较宽的范围,这有助于我们更准确地定义红色的阈值。 3. **阈值...

    opencv基于视频的实时车辆识别和分类的改进方法

    本文主要针对这一核心问题,对传统的车辆识别和分类方法进行了改进,并提出了一种新的阴影检测方法。 车辆识别和分类通常涉及到以下几个关键技术点: 1. 背景减除(Background Subtraction):这是车辆检测中的...

    基于opencv2.4.3、VS2010的背景差分法目标检测

    在计算机视觉领域,背景差分法是一种常见的运动目标检测技术,尤其适用于监控视频分析。本项目基于OpenCV 2.4.3库和Visual Studio 2010开发环境,旨在实现这一功能。OpenCV是一个强大的开源计算机视觉库,包含了众多...

Global site tag (gtag.js) - Google Analytics