请先配置好OpenCv1.0环境,如果已经配置好Opencv 1.0,则可以新建一个Win32 Console Application工程,直接将代码复制到工程中。
为了能够让软件正常运行,必须注意两点:
1.在Vc6.0中,“project-> setting ->c/c++",在category栏下右边下拉列表中,选择"Code Generation",在"Use run-time library"标签下,选中"Debug MultiThreaded"。
2.一般Opencv配置中,并不包含avaux.lib库,请在软件中包含avaux.lib库。
3.示例程序中处理的文件为Avi格式,Avi编码有很多种,尽量很用通用的编码格式。
混合高斯背景建模源码如下:
#include <afxwin.h> //这个头文件必须放在前边
#include <afxdlgs.h>
#include <STDIO.H>
#include <CV.H>
#include <CXCORE.H>
#include <HIGHGUI.H>
#include <CVAUX.H>
int main( int argc, char** argv )
{
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
//cerr << _T("Fatal Error: MFC initialization failed") << endl;
}
//声明IplImage指针
IplImage* tmp_frame = NULL;
CvMemStorage * m_storage = cvCreateMemStorage(0);
CvSeq *m_contour = NULL;
IplImage* dst = 0;
CString Filter,str;
Filter = "(*.avi)|*.AVI| every files (*.*)|*.*||";
CFileDialog FileDlg (TRUE, NULL, NULL, OFN_HIDEREADONLY, Filter);
if (FileDlg.DoModal () == IDOK)//hit "ok"
{
str = FileDlg.GetPathName();
}
// video capture
CvCapture* m_capture = cvCaptureFromFile( str );
tmp_frame = cvQueryFrame(m_capture);
dst = cvCreateImage(cvGetSize(tmp_frame), 8, 1);
dst->origin = 1;
cvCvtColor(tmp_frame, dst, CV_BGR2GRAY);
// cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
if(!tmp_frame)
{
fprintf(stderr, "读取视频文件失败,请重新打开真彩色(24位)视频!.
");
return -1;
}
cvNamedWindow("video", 1);
cvNamedWindow("背景图像", 1);
cvNamedWindow("前景图像", 1);
cvMoveWindow("video", 30, 0);
cvMoveWindow("背景图像", 360, 0);
cvMoveWindow("前景图像", 690, 0);
IplImage* dst1 = NULL;
dst1 = cvCreateImage(cvGetSize(tmp_frame), IPL_DEPTH_8U, 1);
dst1->origin = 1;
cvCvtColor(tmp_frame, dst1, CV_BGR2GRAY);
//创建多高斯模型
CvGaussBGStatModelParams params;
params.win_size = 10;//1/alpha //影响背景,这个值越小,则中心位置偏移的速度越快,对缓慢光线变化越不敏感
params.bg_threshold = 0.75; //CV_BGFG_MOG_BACKGROUND_THRESHOLD;//前B个权重w的和//0.7比0.9容易检测到行人,但是更容易受干扰
params.std_threshold =2.5;//CV_BGFG_MOG_STD_THRESHOLD;//sigma
params.weight_init = 0.05; //CV_BGFG_MOG_WEIGHT_INIT;//初始权重w
params.variance_init = 6*6;//CV_BGFG_MOG_SIGMA_INIT*CV_BGFG_MOG_SIGMA_INIT;//方差
params.minArea = 30;//CV_BGFG_MOG_MINAREA //识别目标的最小区域
params.n_gauss = 5;//CV_BGFG_MOG_NGAUSSIANS;//高斯模型数量
CvBGStatModel* bg_model = cvCreateGaussianBGModel(dst1,¶ms); //初始化背景模型参数
for( int fr = 1;tmp_frame; tmp_frame = cvQueryFrame(m_capture), fr++ )
{
cvCvtColor(tmp_frame, dst1, CV_BGR2GRAY); //转化为灰度图像
cvUpdateBGStatModel( dst1, bg_model); //更新混合高斯背景模型
//******************************以下为画图部分,与高斯建模无关
// 以左下角为坐标原点
bg_model->foreground->origin = bg_model->background->origin = 1;
cvErode(bg_model->foreground, bg_model->foreground,0,1);
//滤除噪声
cvDilate(bg_model->foreground, bg_model->foreground,0,1);
//滤除噪声
cvShowImage("video", tmp_frame);
cvShowImage("背景图像", bg_model->background);
cvCopy(bg_model->foreground, dst);
cvSmooth(dst, dst, CV_GAUSSIAN, 5);
//提取轮廓 到contour序列中
//cvFindContours 仅能处理 [单通道、颜色深度为8位的图像] 的轮廓提取
cvFindContours( dst,m_storage, &m_contour, sizeof(CvContour),
CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
for( ; m_contour != 0; m_contour = m_contour->h_next )
{
CvScalar color = CV_RGB( 255, 0, 255 );
CvScalar color_rect = CV_RGB( 0, 255, 255);
CvRect m_contour_rect = cvBoundingRect(m_contour, 1);
if(fabs(cvContourArea(m_contour)) > 400.0 )
{
cvRectangle(dst, cvPoint(m_contour_rect.x, m_contour_rect.y),
cvPoint((m_contour_rect.x + m_contour_rect.width),(m_contour_rect.y + m_contour_rect.height)),
color_rect, 2, 8, 0);
/* replace CV_FILLED with 1 to see the outlines */
cvDrawContours( dst, m_contour, color, color, -1, CV_FILLED, 8, cvPoint(0,0));
cvShowImage("前景图像", dst);
}
}
int k = cvWaitKey(10); //等待10毫秒
if( k == 'q' ) break;
}
cvReleaseBGStatModel( &bg_model );
cvReleaseCapture(&m_capture);
cvReleaseImage(&dst);
if(m_storage) cvClearMemStorage(m_storage);
cvDestroyWindow("背景图像");
cvDestroyWindow("前景图像");
return 0;
}
示例程序中只是对灰度图像进行处理,软件执行的效果并不好,并不说明混合高斯建模方法不好,Opencv只是提供了一个示例程序,编程很粗糙,需要算法工程师在此基础上发挥各自的才能针对特定的场合进行优化。