Background Subtraction in Matlab
The identification of changing or moving areas in the field of view of a camera is a fundamental pre-processing step in computer vision and video processing. Example applications include visual surveillance (e.g., people counting, action recognition, anomaly detection, post-event forensics), smart environments (e.g., room occupancy monitoring, fall detection, parking occupancy detection), and video retrieval (e.g., activity localization and tracking). 1
Background subtraction is a well known approach for detecting moving objects. To subtract foreground from background, we will calculate the difference between the current frame and the background frame.
In this tutorial, I am going to implement a system for background subtraction for a video of a stationary camera. I will use the video frames from changedetection website under the Dataset >2012> Baseline category.
First, I will implement median method over a selected time window of frames to estimate the value of background for each pixel. Then I will subtract each frame from the background to detect moving pixels.
median_background(highway_path);
function median_background(absolute_folder_path)
path = strcat(absolute_folder_path , '\input\*.jpg');
srcFiles = dir(path);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%% Median background %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for k = 1 : 200 % Window size can be adjusted
filename = strcat(absolute_folder_path, '\input\', srcFiles(k).name);
CurrentFrame = imread(filename);
CurrentFrame = rgb2gray(CurrentFrame);
imgSet{k} = CurrentFrame;
end
dim = ndims(imgSet{1});
M = cat(dim+1,imgSet{:});
median_background = median(M,dim+1);
Background = median_background;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for i = 1: length(srcFiles)
filename = strcat(absolute_folder_path, '\input\', srcFiles(i).name);
CurrentFrame = imread(filename);
CurrentFrame = rgb2gray(CurrentFrame);
% I found out that imsubtract doesn't work the way I think. We can't use it for background subtraction
%FrameDiff = imsubtract(CurrentFrame, Background);
FrameDiff = abs(double(CurrentFrame) - double(Background));
Foreground = zeros(size(Background));
Foreground_logical = (FrameDiff > 30); % Tresholding, can be adjusted
Foreground = (double(CurrentFrame)).*Foreground_logical;
% Again tresholding can be done to remove remaining noise
%Foreground = bwareaopen(Foreground, 10);
% Output folder to write final images
output = strcat(absolute_folder_path, '\output\', int2str(i), '.jpg');
% Write output images to a folder
imwrite(Foreground, output);
end
end
Example input frames:
Example output frames:
Footnotes
- Description taken from changedetection