Search code examples
matlabimage-processingcomputer-visionvideo-processingmotion

Motion History Image in Matlab


I am working on a project about action recognition using motion history images in matlab. I am new to this field. I did background subtraction using frame differencing method to get images that have only the moving person. Now I want to compute MHI. I found the following code for MHI. I did not understand what is fg{1} and how to use it. Any help will be appreciated. Thank you.

vid= VideoReader('PS7A1P1T1.avi');
n = vid.NumberOfFrames; 

fg = cell(1, n);

 for i = 1:n
      frame = read(vid,i); 
      frame = rgb2gray(frame);
      fg{i} = frame;
 end
%---------------------------------------------------------------
%background subtraction using frame differencing method 
thresh = 25;            
bg = fg{1};           % read in 1st frame as background frame 
% ----------------------- set frame size variables ----------------------- 
fr_size = size(bg);              
width = fr_size(2); 
height = fr_size(1); 
% --------------------- process frames ----------------------------------- 
for i = 2:n 

    fr = fg{i};       % read in frame 

    fr_diff = abs(double(fr) - double(bg));  % cast operands as double to avoid negative overflow 

    for j=1:width                 % if fr_diff > thresh pixel in foreground 
        for k=1:height 
            if ((fr_diff(k,j) > thresh)) 
                fg {i}(k,j) = fr(k,j); 
            else 
                fg {i}(k,j) = 0; 
            end 
        end 
    end 

    bg = fr; 

    imshow(fg{i}) 

end 

out = MHI(fg);

//---------------------------------------- function MHI = MHI(fg)

% Initialize the output, MHI a.k.a. H(x,y,t,T)
MHI = fg;

% Define MHI parameter T
T = 15; % # of frames being considered; maximal value of MHI.

% Load the first frame
frame1 = fg{1};

% Get dimensions of the frames
[y_max x_max] = size(frame1);

% Compute H(x,y,1,T) (the first MHI)
MHI{1} = fg{1} .* T;

% Start global loop for each frame
for frameIndex = 2:length(fg)

    %Load current frame from image cell
    frame = fg{frameIndex};

    % Begin looping through each point
    for y = 1:y_max
        for x = 1:x_max
            if (frame(y,x) == 255)
                MHI{frameIndex}(y,x) = T;
            else
                if (MHI{frameIndex-1}(y,x) > 1)
                    MHI{frameIndex}(y,x) = MHI{frameIndex-1}(y,x) - 1;
                else
                    MHI{frameIndex}(y,x) = 0;
                end
            end
        end
    end
end

Solution

  • fg{1} is most likely the first frame of a grayscale video. Given your comments, you are using the VideoReader class to read in frames. As such, read in each frame individually, convert to grayscale then place on a cell in a cell array. When you're done, call the script.

    Here's the code modified from your comments to suit this task:

    vid = VideoReader('PS7A1P2T1.avi');
    n = vid.NumberOfFrames; 
    
    fg = cell(1, n);
    
    for i = 1:n
       frame = read(vid,i); 
       frame = rgb2gray(frame);
       fg{i} = frame;
    end
    

    You can then call the MHI script:

    out = MHI(fg);