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,謝謝學弟黃博揚提供



%% - - Initail System - ->>
close all;
clear all;
clc;

%% - - Input Video - ->>
video_file = 'D:\20150922\2x2_B3\after_rot\1\canny20151018_4_otsu_canny_roi.avi';
video      = VideoReader(video_file);

% -- Video Parameter Setting -->
frameRate    = round(video.FrameRate);
nb_frame     = get(video, 'numberOfFrames');
duration     = video.Duration; 
resize_ratio = 1;
frame_offset = 0;

% -- Video Save Setting -->
video_save     = 0;                  %控制存檔與否
videoName      = '檔案名稱.avi';
videoExtension = 'Uncompressed AVI'; %檔案格式

% -- GMM Background Substraction Setting -->
trainFrame = fix(frameRate * duration);
initVariance = 10^2;
minRatio = 0.7;
numGauss = 8;
fgDetector = vision.ForegroundDetector('NumTrainingFrames',trainFrame,...
    'MinimumBackgroundRatio',minRatio,'NumGaussians',numGauss,...
    'InitialVariance',initVariance);
%% - - Read First Frame - ->>
frame = read(video,1 + frame_offset);
frame = imresize(frame,resize_ratio);
[h,w,~] = size(frame);

%% - - Initial Display - ->>
figure(1);
fig = imshow(frame,'border','tight');
hold on;

%% - - Run Tracking Program - ->>
for k = 1 : nb_frame - frame_offset
    tic;
    %% - - Read Frame & Pre-processing - ->>
    frame     = read(video,k + frame_offset);
    frame     = imresize(frame,resize_ratio);
    
    %  -- GMM Background Substraction -->
    segmentation = step(fgDetector,frame);  % foregroundMask = step(H,I), I = input image  
    
    %% - - Corner Detection Setting - ->>
    C = corner(frame(:,:,1), method, N);
    
    %% - - Display Image - ->>
    set(fig,'CData',segmentation);          % fig為圖形的握把物件代稱
    drawnow;
    
    %% - - Save Video - ->>
    if video_save == 1;
        FrameSave(k) = getframe(gcf);
    end
    toc;
end

%% - - Save Video - ->>
if video_save == 1
    VideoSave = VideoWriter(videoName,videoExtension);
    VideoSave.FrameRate = frameRate;
    open(VideoSave);
    writeVideo(VideoSave,FrameSave);
    close(VideoSave);
end



沒有留言:

張貼留言

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