转自http://yu2xiangyang.blog.163.com/blog/static/373156382010928104218509/
平均背景法只能用于背景场景不包含运动的部分,而且要求光线包吃不变。
三个源文件:
第一个:main.cpp
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
#include "bianliang.h"
IplImage *IavgF, *IdiffF, *IprevF, *IhiF, *IlowF;
IplImage *Iscratch, *Iscratch2;
IplImage *Igray1, *Igray2, *Igray3;
IplImage *Ilow1, *Ilow2, *Ilow3;
IplImage *Ihi1, *Ihi2, *Ihi3;
IplImage *Imask, *Imaskt;
float Icount;
int main(int argc, char *argv[ ] )
{
CvCapture *capture = cvCaptureFromCAM( 0 ); //从摄像头截取图象
IplImage *img = cvQueryFrame ( capture );
IplImage *Idst = cvCreateImage ( cvGetSize( img ), 8, 3 );
AllocateImages ( img );
cvNamedWindow( "haha", 1 );
cvNamedWindow( "hehe", 1 );
while ( ( img = cvQueryFrame ( capture ) ) != NULL ){
accumulateBackground ( img ); //累计图象和图象间的差值
if ( Icount >= 10 )
break;
}
createModelsfromStats ( ); //计算均值和标准差(标准差在这里为 平均差值)
cvCvtScale ( IavgF, Idst, 1 , 0 );
cvShowImage ( "hehe", Idst ); //显示均值图象
while ( ( img = cvQueryFrame ( capture ) ) != NULL ){
backgroundDiff( img ); //计算图象的背景和前景
cvShowImage ( "haha", Imask ); //显示二值化的前景和背景
if ( ( cvWaitKey (100) ) == 27 )
break;
}
cvReleaseCapture ( &capture );
DeallocateImages ( );
cvDestroyWindow( "haha" );
return 0;
}
第二个是头文件: bianliang.h
void AllocateImages (IplImage * );
void accumulateBackground ( IplImage * );
void createModelsfromStats ( );
void setHighThreshold( float );
void setLowThreshold( float );
void backgroundDiff( IplImage * );
void DeallocateImages ( );
第三个文件是 hanshu.cpp
#include "stdafx.h"
#include "highgui.h"
#include "cxcore.h"
#include "cv.h"
#include "bianliang.h"
extern IplImage *IavgF, *IdiffF, *IprevF, *IhiF, *IlowF;
extern IplImage *Iscratch, *Iscratch2;
extern IplImage *Igray1, *Igray2, *Igray3;
extern IplImage *Ilow1, *Ilow2, *Ilow3;
extern IplImage *Ihi1, *Ihi2, *Ihi3;
extern IplImage *Imask, *Imaskt;
extern float Icount;
void AllocateImages ( IplImage *I ){
CvSize sz = cvGetSize( I );
IavgF = cvCreateImage( sz, IPL_DEPTH_32F, 3 );
IdiffF = cvCreateImage( sz, IPL_DEPTH_32F, 3 );
IprevF = cvCreateImage( sz, IPL_DEPTH_32F, 3 );
IhiF = cvCreateImage( sz, IPL_DEPTH_32F, 3 );
IlowF = cvCreateImage( sz, IPL_DEPTH_32F, 3 );
Ilow1 = cvCreateImage( sz, IPL_DEPTH_32F, 1 );
Ilow2 = cvCreateImage( sz, IPL_DEPTH_32F, 1 );
Ilow3 = cvCreateImage( sz, IPL_DEPTH_32F, 1 );
Ihi1 = cvCreateImage( sz, IPL_DEPTH_32F, 1 );
Ihi2 = cvCreateImage( sz, IPL_DEPTH_32F, 1 );
Ihi3 = cvCreateImage( sz, IPL_DEPTH_32F, 1 );
cvZero ( IavgF );
cvZero ( IdiffF );
cvZero ( IprevF );
cvZero ( IhiF );
cvZero ( IlowF );
Icount = 0.00001 ;
Iscratch = cvCreateImage ( sz, IPL_DEPTH_32F, 3 );
Iscratch2 = cvCreateImage ( sz, IPL_DEPTH_32F, 3 );
Igray1 = cvCreateImage ( sz, IPL_DEPTH_32F, 1 );
Igray2 = cvCreateImage ( sz, IPL_DEPTH_32F, 1 );
Igray3 = cvCreateImage ( sz, IPL_DEPTH_32F, 1 );
Imask = cvCreateImage ( sz, IPL_DEPTH_8U, 1 );
Imaskt = cvCreateImage ( sz, IPL_DEPTH_8U, 1 );
cvZero( Iscratch );
cvZero( Iscratch2 );
}
void accumulateBackground ( IplImage *I ){
static int first = 1;
cvCvtScale ( I, Iscratch, 1, 0 );
if ( !first ){
cvAcc ( Iscratch, IavgF );
cvAbsDiff ( Iscratch, IprevF, Iscratch2 );
cvAcc ( Iscratch2, IdiffF );
Icount += 1.0;
}
first = 0;
cvCopy( Iscratch, IprevF );
}
void createModelsfromStats( ){
cvConvertScale ( IavgF, IavgF, (double)(1.0 / Icount) );
cvConvertScale ( IdiffF, IdiffF, (double)(1.0 / Icount) );
cvAddS ( IdiffF, cvScalar ( 1.0, 1.0, 1.0 ), IdiffF );
setHighThreshold ( 10.0 );
setLowThreshold( 10.0 );
}
void setHighThreshold ( float scale ){
cvConvertScale ( IdiffF, Iscratch, scale );
cvAdd ( Iscratch, IavgF, IhiF );
cvSplit ( IhiF, Ihi1, Ihi2, Ihi3, 0 );
}
void setLowThreshold ( float scale ){
cvConvertScale ( IdiffF, Iscratch, scale );
cvSub ( IavgF, Iscratch, IlowF );
cvSplit ( IlowF, Ilow1, Ilow2, Ilow3, 0 );
}
void backgroundDiff( IplImage *I ){
cvCvtScale ( I, Iscratch, 1, 0 );
cvSplit ( Iscratch, Igray1, Igray2, Igray3 , 0 );
cvInRange ( Igray1, Ilow1, Ihi1, Imask );
cvInRange ( Igray2, Ilow2, Ihi2, Imaskt );
cvOr ( Imask, Imaskt, Imask );
cvInRange ( Igray3, Ilow3, Ihi3, Imaskt );
cvOr ( Imask, Imaskt, Imask );
cvSubRS ( Imask, cvScalarAll( 255.0 ), Imask );
}
void DeallocateImages ( ){
cvReleaseImage ( &IavgF );
cvReleaseImage ( &IdiffF );
cvReleaseImage ( &IprevF );
cvReleaseImage ( &IhiF );
cvReleaseImage ( &IlowF );
cvReleaseImage ( &Ilow1 );
cvReleaseImage ( &Ilow2 );
cvReleaseImage ( &Ilow3 );
cvReleaseImage ( &Ihi1 );
cvReleaseImage ( &Ihi2 );
cvReleaseImage ( &Ihi3);
cvReleaseImage ( &Iscratch );
cvReleaseImage ( &Iscratch2 );
cvReleaseImage ( &Igray1 );
cvReleaseImage ( &Igray2 );
cvReleaseImage ( &Igray3 );
cvReleaseImage ( &Imaskt);
cvReleaseImage ( &Imask );
}
文件编译结果: