近來,有不少人咨詢我關於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;
IplConvKernel* element;
IplImage *g_SegementMask; //分割掩膜
IplImage *g_UpdateMask; // 更新掩膜
IplImage *g_Gray;
int ** LifeLength; // 記錄前景點的生命長度,如果前景點的生命長度到達一定的阈值,則將其融入背景中去,且要隨機兩次。
};