近来,有不少人咨询我关于VIBE算法的问题,而且对于有些细节问题懵懵懂懂,索要源码类的,考虑这个算法的应用以及很多人对此有比较深的兴趣,遂将其放在博客上供大家学习。该版本的代码是在学校的时候写的,里面也加入了一些其他的后处理内容,尽管还有不足,但是对于加深对VIBE算法的理解肯定有一定帮助。另外,由于最新版本的代码在公司电脑上,不便提供。关于理论方面的请参考下面二篇文章:
1)VIBE-A powerful random technique to estimatie the background in video sequences.
2) VIBE-A universal background subtraction algorithms for video sequences
VIBE的头文件Vibe.hpp如下:
#pragma once
#include "stdafx.h"
#define WINSIZE 3
class Vibe
{
public:
Vibe(void);
Vibe(IplImage *img);
void SetMinMatch(int nthreshold){g_MinMatch=nthreshold;}
void SetRadius(int radius){g_Radius=radius;}
void SetSampleNum(int num){g_SampleNum=num;}
void SetThreshold(double t){g_threshold=t;}
IplImage* GetForeground(){return g_ForeImg;}
IplImage* GetSegMask(){return g_SegementMask;}
void Detect(IplImage *img);
void ForegroundCombineEdge(); // 结合边缘信息
void DeleteSmallAreaInForeground(double minArea=20);//删除小面积区域
// 实现背景更新机制
void Update();
// 实现后处理,主要用形态学算子
void PostProcess();
public:
~Vibe(void);
private:
void ClearLongLifeForeground(int i_lifeLength=200); // 清除场景中存在时间较长的像素,i_lifeLength用于控制允许存在的最长时间
double AreaDense(IplImage *pFr,int AI,int AJ,int W,int H); //计算(i,j)处邻域大小为W×H的密度
int GetRandom(int istart,int iend); // 默认istart=0,iend=15
int GetRandom(int random);
int GetRandom();// 产生一个随机数
// 计算两个像素之间的欧式距离
double CalcPixelDist(CvScalar bkCs,CvScalar curCs);
// 按照Kim的方法来计算颜色畸变
double CalcuColorDist(CvScalar bkCs,CvScalar curCs);
int g_SampleNum;// Sample number for the models,默认为20
int g_MinMatch; // 当前像素与背景模型匹配的最少个数,默认为2
int g_Height;
int g_Width;
int g_Radius;// 球体的半径,默认为20
int g_offset; //边界的宽和高
double g_threshold; // 距离度量的阈值
unsigned char ***g_Model;// 保存背景模型
IplImage *g_ForeImg;// 保存前景图
IplImage *g_Edge;