OpenCV 平均背景法 背景分割

转自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 );
}

文件编译结果:

OpenCV 平均背景法 背景分割_第1张图片

你可能感兴趣的:(OpenCV 平均背景法 背景分割)