统计均值前景检测算法(Mean-variation)

这是很早以前写的一个算法(貌似先前是参照某本书来写的),现贴出来。 

转帖,请注明出处: http://cvchina.net/blog-423-182.html    
                                http://hi.baidu.com/belial/item/1cc308ed947d293c86d9dee9
这是该算法的.h文件:
class StatAverageModel  
{
public:
 StatAverageModel();
 StatAverageModel(CvCapture* pCapture,int Iteration);
 void Detect(IplImage* frame,float highSclae,float lowScale);// default value high=7.0,low=6.0
 IplImage* getForeground(){return pForeImg;};
 virtual ~StatAverageModel();

private:
 void setHighThreshold(float scale);
 void setLowThreshold(float scale);
 IplImage* pFrame;
 IplImage* pavgF,* pdiffF,*pprevf,*pHif,*plowF;
 IplImage* pscratch,*pscratch2;
 IplImage* pgray1,*pgray2,*pgray3;
 IplImage* plow1,*plow2,*plow3;
 IplImage* phi1,*phi2,*phi3;
 IplImage* pmaskt;
 IplImage* pForeImg; 
 int gIteration;
 int gHeight;
 int gWidth;
 int tmpNum;
};

下面是该算法的.cpp文件:
/*
if you use the mean and variation to model the background ,you can do as follows:
  1. calculate the sum of image sequences, you can apply the function: cvAcc();
  2. also have another choice: cvRunningAvg();
for the variation of each pixel, we can compute the accumulate squre image with the function
 cvSquareAcc();
then the variation cam be computed with : simga^2= 1/N(x1^2+x2^2+...+xn^2)-(1/N(x1+x2+...+xn)^2)
  统计平均法的基本思想:
  计算每个像素的平均值和标准差(或者相似的,但计算速度更快的平均差值)作为背景模型。
*/
StatAverageModel::StatAverageModel()
{
}
StatAverageModel::StatAverageModel(CvCapture* pCapture,int Iteration)
{
 pFrame=cvQueryFrame(pCapture);
 pFrame=cvQueryFrame(pCapture);
 gIteration=Iteration;
 gHeight=pFrame->height;
 gWidth=pFrame->width;
 CvSize size=cvGetSize(pFrame);
 pavgF=cvCreateImage(size,IPL_DEPTH_32F,3);
 pdiffF=cvCreateImage(size,IPL_DEPTH_32F,3);
 pprevf=cvCreateImage(size,IPL_DEPTH_32F,3);
 plowF=cvCreateImage(size,IPL_DEPTH_32F,3);
 pHif=cvCreateImage(size,IPL_DEPTH_32F,3);
 
 pscratch=cvCreateImage(size,IPL_DEPTH_32F,3);
 pscratch2=cvCreateImage(size,IPL_DEPTH_32F,3);
 plow1=cvCreateImage(size,IPL_DEPTH_32F,1);
 plow2=cvCreateImage(size,IPL_DEPTH_32F,1);
 plow3=cvCreateImage(size,IPL_DEPTH_32F,1);
 
 phi1=cvCreateImage(size,IPL_DEPTH_32F,1);
 phi2=cvCreateImage(size,IPL_DEPTH_32F,1);
 phi3=cvCreateImage(size,IPL_DEPTH_32F,1);
 pgray1=cvCreateImage(size,IPL_DEPTH_32F,1);
 pgray2=cvCreateImage(size,IPL_DEPTH_32F,1);
 pgray3=cvCreateImage(size,IPL_DEPTH_32F,1);
 pmaskt=cvCreateImage(size,IPL_DEPTH_8U,1);
 pForeImg=cvCreateImage(size,IPL_DEPTH_8U,1);
 tmpNum=1;
 cvConvertScale(pFrame,pscratch,1.0,0);
 cvCopy(pscratch,pprevf);
}
void StatAverageModel::setHighThreshold(float scale)
{
 cvConvertScale(pdiffF,pscratch,scale);
 cvAdd(pscratch,pavgF,pHif);
 cvSplit(pHif,phi1,phi2,phi3,NULL);
}
void StatAverageModel::setLowThreshold(float scale)
{
 cvConvertScale(pdiffF,pscratch,scale);
 cvAdd(pscratch,pavgF,plowF);
 cvSplit(plowF,plow1,plow2,plow3,NULL);
}
void StatAverageModel::Detect(IplImage* frame,float highScale,float lowScale)
{
 cvZero(pscratch);
 cvConvertScale(frame,pscratch,1.0,0);
 if (tmpNum<=gIteration)
 {
  cvAcc(pscratch,pavgF);
  cvAbsDiff(pscratch,pprevf,pscratch2);
  cvAcc(pscratch2,pdiffF);
  tmpNum++;
  if (tmpNum==gIteration)
  {
   cvConvertScale(pavgF,pavgF,(double)(1.0/gIteration));//均值
   cvConvertScale(pdiffF,pdiffF,(double)(1.0/gIteration));//累积差值的均值代替标准差
   cvAddS(pdiffF,cvScalar(1.0,1.0,1.0),pdiffF);  
   cvCopy(pscratch,pprevf);
   setHighThreshold(highScale);
   setLowThreshold(lowScale);
  }
  cvCopy(pscratch,pprevf);  
 }
 else
 {
  cvSplit(pscratch,pgray1,pgray2,pgray3,NULL);
  cvInRange(pgray1,plow1,phi1,pForeImg);
  cvInRange(pgray2,plow2,phi2,pmaskt);
  cvOr(pmaskt,pForeImg,pForeImg);
  cvZero(pmaskt);
  cvInRange(pgray3,plow3,phi3,pmaskt);
  cvOr(pmaskt,pForeImg,pForeImg);
  cvSubRS(pForeImg,cvScalar(255,0,0),pForeImg);
 }
}

StatAverageModel::~StatAverageModel()
{
 cvReleaseImage(&pFrame);
 cvReleaseImage(&pavgF);
 cvReleaseImage(&pdiffF);
 cvReleaseImage(&pprevf);
 cvReleaseImage(&pHif);
 cvReleaseImage(&plowF);
 cvReleaseImage(&pscratch);
 cvReleaseImage(&pscratch2);
 cvReleaseImage(&pgray1);
 cvReleaseImage(&pgray2);
 cvReleaseImage(&pgray3);
 cvReleaseImage(&plow1);
 cvReleaseImage(&plow2);
 cvReleaseImage(&plow3);
 cvReleaseImage(&phi1);
 cvReleaseImage(&phi2);
 cvReleaseImage(&phi3);
 cvReleaseImage(&pmaskt);
 cvReleaseImage(&pForeImg);
}
/*
 调用例子:
 // default value high=7.0,low=6.0
 StatAverageModel* pInstance=new StatAverageModel(pCapture,100);
 while(pFrame=cvQueryFrame(pCapture))
 { 
  FrmNum++;
  pInstance->Detect(pFrame,7.0,6.0);
  pForeImg=pInstance->getForeground();
  pForeImg->origin=1;
  cvShowImage("frame",pFrame);
  cvShowImage("fore",pForeImg);  
  cvWaitKey(5); 
 }
*/


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值