Background Subtraction demo
An example using drawContours to clean up a background segmentation result.
This program demonstrates a simple method of connected components clean up of background subtraction. When the program starts, it begins learning the background. You can toggle background learning on and off using the checkbox.
Sources:
Contents
Set up video source: video file or camera
fname = fullfile(mexopencv.root(),'test','768x576.avi'); if exist(fname, 'file') ~= 2 % download video from Github disp('Downloading video...') url = 'https://cdn.rawgit.com/opencv/opencv/3.1.0/samples/data/768x576.avi'; urlwrite(url, fname); end cap = cv.VideoCapture(fname); %cap = cv.VideoCapture(0); pause(2); assert(cap.isOpened(), 'Cannot open video source'); cap.PosFrames = 750; frame = cap.read(); assert(~isempty(frame), 'Cannot read data from the video source');
Create a background subtractor
bs = cv.BackgroundSubtractorMOG2('VarThreshold',10);
ZR = zeros(size(frame,1), size(frame,2), 'uint8');
niters = 3;
Prepare window
hFig = figure('Position',[100 100 840 630], ... 'KeyPressFcn',@(o,e)setappdata(o,'flag',true)); setappdata(hFig, 'flag',false); subplot(221), hImg(1) = imshow(frame); title('video') subplot(222), hImg(2) = imshow(frame); title('BG model') subplot(223), hImg(3) = imshow(ZR); title('FG segmented') subplot(224), hImg(4) = imshow(ZR); title('FG largest component') hCB = uicontrol('Style','checkbox', 'Position',[20 20 200 20], ... 'String','Update Background Model', 'Value',true);
Main loop
while ishghandle(hFig) % get next frame frame = cap.read(); if isempty(frame), break; end % determine whether to update BG model or not, then compute FG mask update_bg_model = get(hCB,'Value'); if update_bg_model learnRate = -1; % automatically chosen learning rate else learnRate = 0; % dont update BG model end fgmask = bs.apply(frame, 'LearningRate',learnRate); % process mask and extract largest connected component bw = cv.dilate(fgmask, 'Iterations',niters); bw = cv.erode(bw, 'Iterations',niters*2); bw = cv.dilate(bw, 'Iterations',niters); [contours, hierarchy] = cv.findContours(bw, ... 'Mode','CComp', 'Method','Simple'); if ~isempty(contours) maxArea = 0; largestComp = 0; idx = 0; while idx >= 0 % compute contour area a = abs(cv.contourArea(contours{idx+1})); if a > maxArea maxArea = a; largestComp = idx; end % iterate through all the top-level contours idx = hierarchy{idx+1}(1); end out_frame = cv.drawContours(ZR, contours, ... 'ContourIdx',largestComp, 'Hierarchy',hierarchy, ... 'Color',255, 'Thickness','Filled'); else out_frame = ZR; end % update images set(hImg(1), 'CData',frame) % video frame if update_bg_model % get the current BG model set(hImg(2), 'CData',bs.getBackgroundImage()) end set(hImg(3), 'CData',fgmask) % FG mask set(hImg(4), 'CData',out_frame) % largest contour in FG mask % Terminate if any user input flag = getappdata(hFig, 'flag'); if isempty(flag)||flag, break; end pause(0.1); end
release camera
cap.release()