| 0 意見 ]

最近開始研究GMM,所以收集一下code

OPENCV中混合高斯背景模型的實現

https://engineering.purdue.edu/~bouman/software/cluster/

README file
manual.pdf - Manual explaining how to use software and explaining theory
cluster-3.6.5.zip - Directory containing ANSI C-code designed to compile on a variety of platforms.
cluster-old - Previous releases of the software.
bibtex citation - If you would like to cite this software in you publications, you can use this bibtex citation.

Matlab cluster algorithm - New Matlab version of cluster available!!!

http://blog.csdn.net/wqvbjhc/archive/2010/04/15/5485242.aspx


OPENCV 混合高斯模型
2011-05-02 15:01
混合高斯模型原理
--------------------------------------------------------------------------------
    混合高斯模型跟高斯變量之和看起來有一點像, 注意不要把它們弄混淆了. 混合高斯模型給出的概率密度函數實際上是幾個高斯概率密度函數的加權和:

其中 . 定義事件 , 則 . 據此可以產生服從上述混合高斯概率密度分佈的樣本.
混合分佈的均值為

方差為

計算均值和方差的公式不僅適用於幾個(多維)高斯分佈混合的情況, 還適用於非高斯分佈的情況.
高斯變量之和就沒什麼好說的了, 幾個高斯變量之和是一個新的高斯變量.
高斯背景模型在 運動檢測中的應用
--------------------------------------------------------------------------------
     原理 : 高斯模型就是用高斯概率密度函數(正態分佈曲線)精確地量化事物,將一個事物分解為若干的基於高斯概率密度函數(正態分佈曲線)形成的模型。
    對圖像背景建立高斯模型的原理及過程:圖像灰度直方圖反映的是圖像中某個灰度值出現的頻次,也可以認為是圖像灰度概率密度的估計。如果圖像所包含的目標區域和背景區域相比比較大,且背景區域和目標區域在灰度上有一定的差異,那麼該圖像的灰度直方圖呈現雙峰-谷形狀,其中一個峰對應於目標,另一個峰對應於背景的中心灰度。對於複雜的圖像,尤其是醫學圖像,一般是多峰的。通過將直方圖的多峰特性看作是多個高斯分佈的疊加,可以解決圖像的分割問題。
    在智能監控系統中,對於運動目標的檢測是中心內容,而在運動目標檢測提取中,背景目標對於目標的識別和跟蹤至關重要。而建模正是背景目標提取的一個重要環節。
    我們首先要提起背景和前景的概念,前景是指在假設背景為靜止的情況下,任何有意義的運動物體即為前景。建模的基本思想是從當前幀中提取前景,其目的是使背景更接近當前視頻幀的背景。即利用當前幀和視頻序列中的當前背景幀進行加權平均來更新背景,但是由於光照突變以及其他外界環境的影響,一般的建模後的背景並非十分乾淨清晰,而高斯混合模型是是建模最為成功的方法之一。
     混合高斯模型使用K(基本為3到5個)個高斯模型來表徵圖像中各個像素點的特徵,在新一幀圖像獲得後更新混合高斯模型, 用當前圖像中的每個像素點與混合高斯模型匹配,如果成功則判定該點為背景點, 否則為前景點。 通觀整個高斯模型,主要是有方差和均值兩個參數決定,對均值和方差的學習,採取不同的學習機制,將直接影響到模型的穩定性、精確性和收斂性 。由於我們是對運動目標的背景提取建模,因此需要對高斯模型中方差和均值兩個參數實時更新。為提高模型的學習能力,改進方法對均值和方差的更新採用不同的學習率;為提高在繁忙的場景下,大而慢的運動目標的檢測效果,引入權值均值的概念,建立背景圖像並實時更新,然後結合權值、權值均值和背景圖像對像素點進行前景和背景的分類。
       到這裡為止,混合高斯模型的建模基本完成,我在歸納一下其中的流程,首先初始化預先定義的幾個高斯模型,對高斯模型中的參數進行初始化,並求出之後將要用到的參數。其次,對於每一幀中的每一個像素進行處理,看其是否匹配某個模型,若匹配,則將其歸入該模型中,並對該模型根據新的像素值進行更新,若不匹配,則以該像素建立一個高斯模型,初始化參數,代理原有模型中最不可能的模型。最後選擇前面幾個最有可能的模型作為背景模型,為背景目標提取做鋪墊。


    方法: 目前,運動物體檢測的問題主要分為兩類,攝像機固定和攝像機運動。對於攝像機運動的運動物體檢測問題,比較著名的解決方案是光流法,通過求解偏微分方程求的圖像序列的光流場,從而預測攝像機的運動狀態。對於攝像機固定的情形,當然也可以用光流法,但是由於光流法的複雜性,往往難以實時的計算,所以我採用高斯背景模型。因為,在攝像機固定的情況下,背景的變化是緩慢的,而且大都是光照,風等等的影響,通過對背景建模,對一幅給定圖像分離前景和背景,一般來說,前景就是運動物體,從而達到運動物體檢測的目的。
  單分佈高斯背景模型
  單分佈高斯背景模型認為,對一個背景圖像,特定像素亮度的分佈滿足高斯分佈,即對背景圖像B, (x,y)點的亮度滿足:
  IB (x,y) ~ N(u,d)
  這樣我們的背景模型的每個像素屬性包括兩個參數:平均值u 和 方差d。
  對於一幅給定的圖像G,如果 Exp(-(IG (x,y)-u(x,y))^2/(2*d^2)) > T,認為(x,y)是背景點,反之是前景點。
  同時,隨著時間的變化,背景圖像也會發生緩慢的變化,這時我們要不斷更新每個像素點的參數
  u(t+1,x,y) = a*u(t,x,y) + (1-a)*I(x,y)
  這裡,a稱為更新參數,表示背景變化的速度,一般情況下,我們不更新d(實驗中發現更不更新 d,效果變化不大)。

openCV中高斯混合模型的應用
  高斯混合模型是用於背景提取的方法,OpenCV的cvaux中 cvbgfg_gaussmix.cpp文件根據文獻"An improved adaptive background mixture model for real-time tracking with shadow"中提供的方法編寫了高斯混合模型函數。其中定義了CvGaussBGModel類用於存放高斯混合模型的各個參數。我用OpenCV使用高斯混合模型函數分以下幾步:
  1。需要用到 icvUpdateGaussianBGModel,icvReleaseGaussianBGModel兩個函數,但是源程序中將這兩個函數定義為內部函數,需要做一些修改,首先將cvbgfg_gaussmix.cpp中前面兩個函數的聲明static void CV_CDECL icvReleaseGaussianBGModel( CvGaussBGModel** bg_model );
static int CV_CDECL icvUpdateGaussianBGModel( IplImage* curr_frame, CvGaussBGModel* bg_model );兩行代碼註釋掉。然後在cvbgfg_gaussmix.cpp中間部分兩個函數的定義部分,函數頭static int和static void改成CV_IMPL int 和CV_IMPL void。最後在cvaux.h文件中CVAPI(CvBGStatModel*) cvCreateGaussianBGModel( IplImage* first_frame,
  CvGaussBGStatModelParams* parameters CV_DEFAULT(NULL));這句後面加上以下兩句CVAPI(void) icvReleaseGaussianBGModel( CvGaussBGModel** bg_model );
  CVAPI(int) icvUpdateGaussianBGModel( IplImage* curr_frame, CvGaussBGModel* bg_model );
  程序修改完畢,點rebuild all,全部重新編譯。
  2。在程序初始化部分定義高斯混合模型參數CvGaussBGModel* bg_model=NULL;在讀取第一幀圖像(背景圖像)時,進行高斯背景建模bg_model = (CvGaussBGModel*)cvCreateGaussianBGModel(image, 0);image可以是灰度圖像也可以是彩色圖像。接下來再讀取當前幀時,更新高斯模型
   regioncount=icvUpdateGaussianBGModel(currframe, bg_model );regioncount的含義我不確定,我理解是代表背景中不同顏色區域的個數,這個參數我沒有用到,它只是 icvUpdateGaussianBGModel函數的返回值。
  3。現在bg_model已經保存了經過高斯混合模型分類後的結果,bg_model->background保存了背景圖像,bg_model->foreground保存了前景圖像。
view plaincopy to clipboardprint?
01.  include   
02.  #include   
03.  #include   
04.  #include   
05.  #include //必須引此頭文件  
06.  int main( int argc, char** argv )  
07.  {  
08.  IplImage* pFrame = NULL;    
09.  IplImage* pFrImg = NULL;  
10.  IplImage* pBkImg = NULL;    
11.  CvCapture* pCapture = NULL;    
12.  int nFrmNum = 0;  
13.  cvNamedWindow("video", 1);  
14.  cvNamedWindow("background",1);  
15.  cvNamedWindow("foreground",1);    
16.  cvMoveWindow("video", 30, 0);  
17.  cvMoveWindow("background", 360, 0);  
18.  cvMoveWindow("foreground", 690, 0);  
19.  if( argc > 2 )    
20.  {     
21.  fprintf(stderr, "Usage: bkgrd [video_file_name]\n");     
22.  return -1;    
23.  }  
24.  //打開視頻文件  
25.  if(argc == 2)    
26.  if( !(pCapture = cvCaptureFromFile(argv[1])))     
27.  {    
28.  fprintf(stderr, "Can not open video file %s\n", argv[1]);    
29.  return -2;     
30.  }  
31.  //打開攝像頭  
32.  if (argc == 1)    
33.  if( !(pCapture = cvCaptureFromCAM(-1)))     
34.  {    
35.  fprintf(stderr, "Can not open camera.\n");    
36.  return -2;     
37.  }    
38.  //初始化高斯混合模型參數  
39.  CvGaussBGModel* bg_model=NULL;  
40.  while(pFrame = cvQueryFrame( pCapture ))    
41.  {     
42.  nFrmNum++;           
43.  if(nFrmNum == 1)    
44.  {     
45.  pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),  IPL_DEPTH_8U,3);    
46.  pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),  IPL_DEPTH_8U,1);     
47.  //高斯背景建模,pFrame可以是多通道圖像也可以是單通道圖像  
48.  //cvCreateGaussianBGModel函數返回值為 CvBGStatModel*,  
49.  //需要強制轉換成CvGaussBGModel*  
50.  bg_model = (CvGaussBGModel*)cvCreateGaussianBGModel(pFrame, 0);  
51.  }     
52.  else 
53.  {     
54.  //更新高斯模型  
55.  cvUpdateBGStatModel(pFrame, (CvBGStatModel *)bg_model );  
56.  //pFrImg為前景圖像,只能為單通道  
57.  //pBkImg為背景圖像,可以為單通道或與pFrame通道數相同  
58.  cvCopy(bg_model->foreground,pFrImg,0);  
59.  cvCopy(bg_model->background,pBkImg,0);  
60.  //把圖像正過來  
61.  pBkImg->origin=1;  
62.  pFrImg->origin=1;  
63.  cvShowImage("video", pFrame);     
64.  cvShowImage("background", pBkImg);     
65.  cvShowImage("foreground", pFrImg);        
66.  if( cvWaitKey(2) >= 0 )       
67.  break;     
68.  }     
69.  }  
70.  //釋放高斯模型參數佔用內存    
71.   cvReleaseBGStatModel((CvBGStatModel**)&bg_model);  
72.  cvDestroyWindow("video");  
73.  cvDestroyWindow("background");  
74.  cvDestroyWindow("foreground");    
75.  cvReleaseImage(&pFrImg);  
76.  cvReleaseImage(&pBkImg);    
77.  cvReleaseCapture(&pCapture);    
78.  return 0;  
79.  } 


0 意見

張貼留言