高斯混合模型 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偵測後所得到的前景物
體
根據 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
沒有留言:
張貼留言