2015年10月20日 星期二

[MATLAB] Gaussian Mixture Model (GMM) 高斯混合模型

高斯混合模型 Gaussian Mixture Model (GMM)


Gaussian Mixture Model (GMM) 高斯混合模型 常用於影像處理中背景消去(Background Subtraction)中建立影像背景模型。同時也可以應用在樣型識別(Pattern Recognition)以及機器學習(Machine Learning)領域中的分群方法(Clustering)。

常見的背景消去法


最簡單靜態的背景消去方法是事先拍一張背景影像B(X,Y,t),接下來再拍攝相同背景含有物體在內的影像I(X,Y,t),接著再將兩張影像相減,得到所有像素的差值,自行訂立一個閥值(Threshold),若大於閥值者,找出該相差值大於閥值像素與其所在位置,即可找到該物體(前景, Foreground )。

               |I(X,Y,t) - B(X,Y,t)| > Threshold

另一種應用於影片的背景消去方法是利用連續的影像,求出連續影像的平均值,以該平均值訂為背景,再利用上述的背景消方法找出物體。

但是上述的方式有以下優缺點

  • 優點 : 簡單、計算快速
  • 缺點 : 準確性不佳、影像幀數高則需要更多記憶體資源、若影像變動大則沒有一個固定的閥值(Ex. 白天到黑夜)

高斯混合模型 Gaussian Mixture Model (GMM) 


為了解決上述的問題,Stauffer, C. and Grimson, W.E.L 等人在其 Adaptive Background Mixture Models for Real-Time Tracking, Computer Vision and Pattern Recognition (1999) 的論文中提出一種具有適應性的方法來嘗試解決上述缺點。

若將一幀影像視作一個統計模型,例如,灰階影像直方圖即是針對像素灰階值,我們可以將某個灰階值出現的可能性視作一個機率事件,而如此,此即為機率模型。而所謂的機率模型,就是在針對不同幀的影像進行一個統計過程,並由未知數X來求得Y的相關資訊。但是所求得的結果不是一個準確的數值,而是代表例如該像素屬於前景物體像素的機率是多少(符合的機率有多高?),而非該像素是否屬於前景像素(Yes/No 的是非問題)。

而機率模型的好處就在於能夠判讀與操作的空間相對大了許多,而非非黑即白的問題。而在數學理論上,高斯模型能夠透過增加模型的個數以符合(fit)特定的機率分布情形。
(詳細的數學計算流程請參考這兩篇博文 聚类(1)——混合高斯模型 Gaussian Mixture Model 、 漫谈 Clustering (3): Gaussian Mixture Model)

若將自然分布(高斯分布)的概念引入這個問題中,我可以將像素視為同時有好幾個模式存在(Ex. 白天模式、傍晚模式、黑夜模式),及同時有好多個高斯模型(Gaussians)存在,此概念為mixture of adaptive Gaussians。若該像素不符合背景的高斯模型(Background Gaussian),則視作前景。我們可以將影像的分布機率視作K個高斯模型混合再一起(Mixture of Gaussians)

當然,GMM本身也是有優缺點


  • 優點 : 每個像素可以有不同的閥值、閥值可以隨不同帧的影像調整、物體可以成為背景的一部分而不破壞背景
  • 缺點 : 無法應對背景快速變動的光影變化、初始化的高斯模型(Gaussian)相當重要、太多參數需要決定
高斯混合模型的MATLAB實現方法

根據 MathWorks 官網的 vision.ForegroundDetector System object 項目中,得知

detector = vision.ForegroundDetector 這行指令所回傳的是經過 GMM偵測後所得到的前景物




下面是以MATLAB所撰寫的程式,使用的版本為R2014b,謝謝學弟黃博揚提供



  1. %% - - Initail System - ->>
  2. close all;
  3. clear all;
  4. clc;
  5.  
  6. %% - - Input Video - ->>
  7. video_file = 'D:\20150922\2x2_B3\after_rot\1\canny20151018_4_otsu_canny_roi.avi';
  8. video = VideoReader(video_file);
  9.  
  10. % -- Video Parameter Setting -->
  11. frameRate = round(video.FrameRate);
  12. nb_frame = get(video, 'numberOfFrames');
  13. duration = video.Duration;
  14. resize_ratio = 1;
  15. frame_offset = 0;
  16.  
  17. % -- Video Save Setting -->
  18. video_save = 0; %控制存檔與否
  19. videoName = '檔案名稱.avi';
  20. videoExtension = 'Uncompressed AVI'; %檔案格式
  21.  
  22. % -- GMM Background Substraction Setting -->
  23. trainFrame = fix(frameRate * duration);
  24. initVariance = 10^2;
  25. minRatio = 0.7;
  26. numGauss = 8;
  27. fgDetector = vision.ForegroundDetector('NumTrainingFrames',trainFrame,...
  28. 'MinimumBackgroundRatio',minRatio,'NumGaussians',numGauss,...
  29. 'InitialVariance',initVariance);
  30. %% - - Read First Frame - ->>
  31. frame = read(video,1 + frame_offset);
  32. frame = imresize(frame,resize_ratio);
  33. [h,w,~] = size(frame);
  34.  
  35. %% - - Initial Display - ->>
  36. figure(1);
  37. fig = imshow(frame,'border','tight');
  38. hold on;
  39.  
  40. %% - - Run Tracking Program - ->>
  41. for k = 1 : nb_frame - frame_offset
  42. tic;
  43. %% - - Read Frame & Pre-processing - ->>
  44. frame = read(video,k + frame_offset);
  45. frame = imresize(frame,resize_ratio);
  46. % -- GMM Background Substraction -->
  47. segmentation = step(fgDetector,frame); % foregroundMask = step(H,I), I = input image
  48. %% - - Corner Detection Setting - ->>
  49. C = corner(frame(:,:,1), method, N);
  50. %% - - Display Image - ->>
  51. set(fig,'CData',segmentation); % fig為圖形的握把物件代稱
  52. drawnow;
  53. %% - - Save Video - ->>
  54. if video_save == 1;
  55. FrameSave(k) = getframe(gcf);
  56. end
  57. toc;
  58. end
  59.  
  60. %% - - Save Video - ->>
  61. if video_save == 1
  62. VideoSave = VideoWriter(videoName,videoExtension);
  63. VideoSave.FrameRate = frameRate;
  64. open(VideoSave);
  65. writeVideo(VideoSave,FrameSave);
  66. close(VideoSave);
  67. end
  68.  


沒有留言:

張貼留言

/* 載入prettify的autoloader */ /* 載入JQuery */