視頻前景提取 (II)【IplImage版本】
以下代碼可以求出視頻的前景,用的方法就是拿第一幀做差分。。。
但是以下代碼有個致命的問題,那就是在視頻幀處理的過程中,不斷的create卻不釋放內存,導致了內存溢出。。
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h>
#ifdef _EiC
#define WIN32
#endif
static CvMemStorage* storage = 0;
int main()
{
CvCapture* capture = 0;
IplImage *frame, *frame_copy = 0,*img1=NULL;
char* input_name;
input_name = "002.avi";
storage = cvCreateMemStorage(0);
if( !input_name || (isdigit(input_name[0]) && input_name[1] == '\0') )
//直接從攝像頭讀入
capture = cvCaptureFromCAM( !input_name ? 0 : input_name[0] - '0' );
else
//從AVI視頻讀入
capture = cvCaptureFromAVI( input_name );
cvNamedWindow( "result", 1 );
int flag=0;
if( capture )
{
//如果捕捉到幀了
//對每一幀做處理
for(;;)
{
if( !cvGrabFrame( capture ))
break;
frame = cvRetrieveFrame( capture );
if( !frame )
break;
if(flag==0)
{
//捕捉第一幀
frame_copy = cvCreateImage( cvSize(frame->width,frame->height), IPL_DEPTH_8U, frame->nChannels );
cvCopy(frame,frame_copy,0);
flag=1;
}
img1 = cvCreateImage( cvSize(frame->width,frame->height), IPL_DEPTH_8U, frame->nChannels );
cvAbsDiff(frame,frame_copy,img1);
cvShowImage( "src", frame );
cvShowImage( "result", img1 );
//10ms中按任意鍵進入此if塊
if( cvWaitKey( 10 ) >= 0 )
break;
}
cvReleaseImage( &frame_copy );
cvReleaseImage( &img1 );
cvReleaseCapture( &capture );
}
cvDestroyWindow("src");
cvDestroyWindow("result");
return 0;
}
為了解決這個問題,可以在開始的時候設置標誌位,隻在第一次的時候create圖片:
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h>
#ifdef _EiC
#define WIN32
#endif
int main()
{
CvCapture* capture = 0;
IplImage *frame, *frame_copy = 0,*img1=NULL;
char* input_name;
input_name = "001.avi";
if( !input_name || (isdigit(input_name[0]) && input_name[1] == '\0') )
//直接從攝像頭讀入
capture = cvCaptureFromCAM( !input_name ? 0 : input_name[0] - '0' );
else
//從AVI視頻讀入
capture = cvCaptureFromAVI( input_name );
cvNamedWindow( "result", 1 );
int flag=0;
if( capture )
{
//如果捕捉到幀了
//對每一幀做處理
for(;;)
{
if( !cvGrabFrame( capture ))
break;
frame = cvRetrieveFrame( capture );
if( !frame )
break;
if(flag==0)
{
//捕捉第一幀
if( !frame_copy )
frame_copy = cvCreateImage( cvSize(frame->width,frame->height), IPL_DEPTH_8U, frame->nChannels );
if( frame->origin == IPL_ORIGIN_TL )
cvCopy( frame, frame_copy, 0 );
else
cvFlip( frame, frame_copy, 0 );
flag=1;
}
//為NULL就create一次,不然內存會溢出
if( !img1 )
img1 = cvCreateImage( cvSize(frame->width,frame->height), IPL_DEPTH_8U, frame->nChannels );
cvAbsDiff(frame,frame_copy,img1);
cvShowImage( "src", frame );
cvShowImage( "result", img1 );
//10ms中按任意鍵進入此if塊
if( cvWaitKey( 10 ) >= 0 )
break;
}
cvReleaseImage( &frame_copy );
cvReleaseCapture( &capture );
//不用釋放,因為開始的時候沒有顯式分配內存
//cvReleaseImage( &frame );
//cvReleaseImage( &img1 );
}
cvDestroyWindow("src");
cvDestroyWindow("result");
return 0;
}

最後更新:2017-04-03 05:39:31