Test of the "Background subtraction library".

Description: Background subtration algorithm to detect moving regions. There is a post-processing stage to filter the noise in the computed moving regions.

Input: a sequence of images.
Output: a trinary image that shows background (black areas), moving
  regions (white areas) and shadows (grey areas). In addition, the
  centroid of each is moving region is displayed.
External code:
* Background subtraction library of Zoran Zivkovic.
Author: Carlos Roberto del Blanco Adán,
       Grupo de Tratamiento de Imágenes, GTI SSR, Madrid
       cda@gti.ssr.upm.es
Date: 03/12/2010
Version 1.0

Contents

clear all; close all; clc;

Library paths

addpath(genpath('./lib'));

Input

sequences.path = '.\data\TwoPeopleOcclusion_1\';
sequences.basename = 'Seg';
sequences.noDigits = '%05d';
sequences.format = 'jpg';
sequences.firstFrame = 1;
sequences.lastFrame = 499;

Initialization.

%Read frame
noFrame =  sprintf(sequences.noDigits, sequences.firstFrame);
imgName = sprintf('%s%s%s.%s', sequences.path, sequences.basename, noFrame, sequences.format);
fr.RGB_uint = imread(imgName);

%Background substraction initialization: a reference background.
bs_param = [0.01 1.5*1.5 1 0.05]; %See Note 1.
h = mexCvBSLib(fr.RGB_uint);
mexCvBSLib(fr.RGB_uint, h, bs_param); %Set parameters.
MyClass created.
%Loop processing.
for ifr = sequences.firstFrame + 1 : sequences.lastFrame

Read frame

    noFrame =  sprintf(sequences.noDigits, ifr);
    imgName = sprintf('%s%s%s.%s', sequences.path, sequences.basename, noFrame, sequences.format);
    fr.RGB_uint = imread(imgName);

Background Subtraction.

    %Three different levels: background, shadows, foreground.
    %The first frames are used to model the background. It should not
    %contain moving objects.
    imMask = mexCvBSLib(fr.RGB_uint, h);

Noise supression.

Median filtering.

    imMask_2 = medfilt2(imMask,[11 11]);
    %Moving regions.
    imMask_mov  = (imMask_2 == 255);
    %Moving regions and shadows.
    imMask_bot  = (imMask_2 == 125 | imMask_2 == 255);

Object properties: centroids and region coordinates.

Centroids represent the object locations.

    mov_st = regionprops(imMask_mov,'Centroid','PixelIdxList','Area');

Filtering objects by size.

    mov_st([mov_st.Area] < 30) = [];
    cen_mov = cat(1, mov_st.Centroid);

Results: Show an image without moving objects.

    if(0 || ifr == 2)
        figure(1);
        imshow(fr.RGB_uint);
        title(['Background, frame:', sprintf('%d',ifr)]);
        snapnow;
    end

Results: Show an image with moving objects.

    if(0 || ifr == 350)
        figure(1);
        imshow(fr.RGB_uint);
        title(['Frame:', sprintf('%d',ifr)]);
        snapnow;
    end

Results: Show moving regions.

    if(0 || ifr == 350)
        figure(1);
        imshow(imMask);
        title(['Moving regions, frame:', sprintf('%d',ifr)]);
        snapnow;
    end

Results: Show moving regions after noise filtering.

    if(0 || ifr == 350)
        figure(1);
        imshow(imMask_2);
        title(['Moving regions, frame:', sprintf('%d',ifr)]);
        snapnow;
    end

Results: plot object centroids.

    if(0 || ifr == 350)
        figure(1);
        imshow(imMask_2);
        hold on;
        if (~isempty(cen_mov))
            plot(cen_mov(:,1), cen_mov(:,2), 'r+');
        end
        hold off;
        axis ij;
        xlim([1, size(imMask_2,2)]);
        ylim([1, size(imMask_2,1)]);
        title(['Centroids of moving regions, frame:', sprintf('%d',ifr)]);
        snapnow;
    end
    drawnow;
end

Ending

mexCvBSLib(h); %Release memory
MyClass destroyed.

Note 1

bs_param = [fAlphaT, fTb, bShadowDetection, fTau].
* fAlphaT: speed of update. If the time interval you want to average
  over is T set alpha=1/T.
* fTb: threshold on the squared Mahalan. dist. To decide if it is well
  described by the background model or not. Related to Cthr from the
  paper. This does not influence the update of the background. A typical
  value could be 4 sigma => Tb=4*4=16;
* bShadowDetection: do shadow detection if ==1.
* fTau: shadow threshold. The shadow is detected if the pixel is darker
  version of the background. Tau is a threshold on how much darker the
  shadow can be. Tau= 0.5 means that if pixel is more than 2 times
  darker then it is not shadow.
More information in :
* "Improved adaptive Gausian mixture model for background subtraction",
  2004.
* "Efficient Adaptive Density Estimapion per Image Pixel for the Task of
  Background Subtraction", 2006.