今天仔细研究了一下差分法求运动的轮廓,简单用程序实现了一下,结果如下,
差分法比较容易获得运动的轮廓,对于不运动的身体部分则不会显示,
这样的好处是可以得到需要关注的运动部分,不运动的则不关心,
但是如果需要得到整个人体的轮廓,该如何呢?
我试着用程序记录前4帧的数据,然后叠加出来显示,看来效果不是很好。 还要继续考虑...
关键部分的代码如下:
main.cpp
#ifdef _ch_
#pragma package <opencv>
#endif
#ifndef _eic
// motion templates sample code
#include "cv.h"
#include "highgui.h"
#include <time.h>
#include <math.h>
#include <ctype.h>
#include <stdio.h>
#endif
// various tracking parameters (in seconds)
const double mhi_duration = 1;
const double max_time_delta = 0.5;
const double min_time_delta = 0.05;
// number of cyclic frame buffer used for motion detection
// (should, probably, depend on fps)
const int n = 4;
// ring image buffer
iplimage **buf = 0;
int last = 0;
// temporary images
iplimage *mhi = 0; // mhi
iplimage *orient = 0; // orientation
iplimage *mask = 0; // valid orientation mask
iplimage *segmask = 0; // motion segmentation map
cvmemstorage* storage = 0; // temporary storage
iplimage* abs_image = 0;
iplimage* add_abs_image = 0;
iplimage* abs_images[3];
iplimage* grey =0;
iplimage* pre_grey = 0;
iplimage* dst = 0;
cvseq* contour = 0;
int test( iplimage* src,iplimage* pre_src );
int main(int argc, char** argv)
{
//iplimage* motion = 0;
cvcapture* capture = 0;
iplimage* pre_image = 0;
iplimage* image = 0;
int frame_count =0;
if( argc == 1 || (argc == 2 && strlen(argv[1]) == 1 && isdigit(argv[1][0])))
//capture = cvcapturefromcam( argc == 2 ? argv[1][0] - '0' : 0 );
capture = cvcapturefromfile("e:\\abc.avi");
else if( argc == 2 )
capture = cvcapturefromavi( argv[1] );
if( capture )
{
//cvnamedwindow( "motion", 1 );
cvnamedwindow( "source", 1 );
cvnamedwindow( "components", 1 );
for(;;)
{
if( !cvgrabframe( capture ))
break;
image = cvretrieveframe( capture );
if (!pre_image)
{
pre_image = cvcreateimage( cvgetsize(image), 8, 3 );
abs_image = cvcreateimage( cvgetsize(image), 8, 1 );
add_abs_image = cvcreateimage( cvgetsize(image), 8, 1 );
grey = cvcreateimage( cvgetsize(image), 8, 1 );
pre_grey = cvcreateimage( cvgetsize(image), 8, 1 );
dst = cvcreateimage( cvgetsize(image), 8, 3 );
abs_image->origin = image->origin;
add_abs_image->origin = image->origin;
dst->origin = image->origin;
storage = cvcreatememstorage(0);
abs_images[0] = cvcreateimage( cvgetsize(image), 8, 1 );
abs_images[1] = cvcreateimage( cvgetsize(image), 8, 1 );
abs_images[2] = cvcreateimage( cvgetsize(image), 8, 1 );
abs_images[3] = cvcreateimage( cvgetsize(image), 8, 1 );
cvzero(abs_images[0]);
cvzero(abs_images[1]);
cvzero(abs_images[2]);
cvzero(abs_images[3]);
}