001
#include <stdio.h>
002
#include <cv.h>
003
#include <cxcore.h>
004
#include <highgui.h>
005
int
main(
int
argc
,
char
**
argv )
006
{
007
//声明IplImage指针
008
IplImage
*
pFrame
=
NULL;
009
IplImage
*
pFrImg
=
NULL;
010
IplImage
*
pBkImg
=
NULL;
011
CvMat
*
pFrameMat
=
NULL;
012
CvMat
*
pFrMat
=
NULL;
013
CvMat
*
pBkMat
=
NULL;
014
015
CvCapture
*
pCapture
=
NULL;
016
017
int
nFrmNum
=
0;
018
//创建窗口
019
cvNamedWindow(
"video"
,
1);
020
cvNamedWindow(
"background"
,
1);
021
cvNamedWindow(
"foreground"
,
1);
022
//使窗口有序排列
023
cvMoveWindow(
"video"
,
30
,
0);
024
cvMoveWindow(
"background"
,
360
,
0);
025
cvMoveWindow(
"foreground"
,
690
,
0);
026
027
if(
argc
>
2 )
028
{
029
fprintf(
stderr
,
"Usage: bkgrd [video_file_name]
/n
");
030
return
-
1;
031
}
032
//打开摄像头
033
if (
argc
==
1)
034
if(
!(
pCapture
=
cvCaptureFromCAM(
-
1)))
035
{
036
fprintf(
stderr
,
"Can not open camera.
/n
");
037
return
-
2;
038
}
039
//打开视频文件
040
if(
argc
==
2)
041
if(
!(
pCapture
=
cvCaptureFromFile(
argv
[
1
])))
042
{
043
fprintf(
stderr
,
"Can not open video file %s
/n
"
,
argv
[
1
]);
044
return
-
2;
045
}
046
047
//逐帧读取视频
048
while(
pFrame
=
cvQueryFrame(
pCapture ))
049
{
050
nFrmNum
++;
051
052
//如果是第一帧,需要申请内存,并初始化
053
if(
nFrmNum
==
1)
054
{
055
pBkImg
=
cvCreateImage(
cvSize(
pFrame
->
width
,
pFrame
->
height
),
IPL_DEPTH_8U
,
1);
056
pFrImg
=
cvCreateImage(
cvSize(
pFrame
->
width
,
pFrame
->
height
),
IPL_DEPTH_8U
,
1);
057
pBkMat
=
cvCreateMat(
pFrame
->
height
,
pFrame
->
width
,
CV_32FC1);
058
pFrMat
=
cvCreateMat(
pFrame
->
height
,
pFrame
->
width
,
CV_32FC1);
059
pFrameMat
=
cvCreateMat(
pFrame
->
height
,
pFrame
->
width
,
CV_32FC1);
060
//转化成单通道图像再处理
061
cvCvtColor(
pFrame
,
pBkImg
,
CV_BGR2GRAY);
062
cvCvtColor(
pFrame
,
pFrImg
,
CV_BGR2GRAY);
063
cvConvert(
pFrImg
,
pFrameMat);
064
cvConvert(
pFrImg
,
pFrMat);
065
cvConvert(
pFrImg
,
pBkMat);
066
}
067
else
068
{
069
cvCvtColor(
pFrame
,
pFrImg
,
CV_BGR2GRAY);
070
cvConvert(
pFrImg
,
pFrameMat);
071
//先高斯滤波,以平滑图像
072
//cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0);
073
074
//当前帧跟背景图相减
075
cvAbsDiff(
pFrameMat
,
pBkMat
,
pFrMat);
076
//二值化前景图
077
cvThreshold(
pFrMat
,
pFrImg
,
60
,
255.0
,
CV_THRESH_BINARY);
078
//进行形态学滤波,去掉噪音
079
//cvErode(pFrImg, pFrImg, 0, 1);
080
//cvDilate(pFrImg, pFrImg, 0, 1);
081
//更新背景
082
cvRunningAvg(
pFrameMat
,
pBkMat
,
0.003
,
0);
083
//将背景转化为图像格式,用以显示
084
cvConvert(
pBkMat
,
pBkImg);
085
//显示图像
086
cvShowImage(
"video"
,
pFrame);
087
cvShowImage(
"background"
,
pBkImg);
088
cvShowImage(
"foreground"
,
pFrImg);
089
//如果有按键事件,则跳出循环
090
//此等待也为cvShowImage函数提供时间完成显示
091
//等待时间可以根据CPU速度调整
092
if(
cvWaitKey(
2)
>=
0 )
093
break;
094
095
}
096
}
097
098
//销毁窗口
099
cvDestroyWindow(
"video");
100
cvDestroyWindow(
"background");
101
cvDestroyWindow(
"foreground");
102
//释放图像和矩阵
103
cvReleaseImage(
&
pFrImg);
104
cvReleaseImage(
&
pBkImg);
105
cvReleaseMat(
&
pFrameMat);
106
cvReleaseMat(
&
pFrMat);
107
cvReleaseMat(
&
pBkMat);
108
cvReleaseCapture(
&
pCapture);
109
return
0;
110
}
运行结果:
引自:http://hi.baidu.com/gilbertjuly/blog/item/879044258d5dc23a8644f959.html