function markMovesInVideo(inVideo, moveTresh, strelOpen, strelClose) %% function markMovesInVideo(inVideo, moveTresh, strelOpen, strelClose) % This function tracks and presents moving regions in a video filmed by a % still camera % %% Syntax % markMovesInVideo(inVideo); % markMovesInVideo(inVideo, moveTresh); % markMovesInVideo(inVideo, moveTresh, strelOpen); % markMovesInVideo(inVideo, moveTresh, strelOpen, strelClose); % %% Description % This functions presents a figure with only moving regions % of the video. The user can control several parameters, to achive the % presentation of regions he is interested in. This function can be though % of as a mammal vision system simulation (some mammals, like dogs, see % only object that move). % %% Input arguments (defaults exist): % inVideo- input video file name % moveTresh- used to deetct movements. Pixels with value above this % treshold are assumed to include movements. % strelOpen- a structuring element, and integer value used to define % a structuring element dimentions, or a matrix of logicals used to % define the presneted ROI dimentions. In other worlds defines the % area around detected movements to be presented. Larger value will % resul in larger region. % strelClose- a structuring element, and integer value used to define % a structuring element dimentions, or a matrix of logicals. Those % define the speed of "aging", or hsitorical data influencue on % current figure. It defines how the ROI of previous frame infleuemce % ROI of current frame. Larger value will result in fatser aging- old % ROI data will be removed fatser. Small value will result in slow % "aging"- areas with movements in previous frames, will be preserved % and presenetd in longer period. % %% Output arguments % None. Movements are presenetd on a figure; % %% Issues & Comments % Camera is assumed to be still % %% Example % inVideo='xylophone.mpg'; % moveTresh=30; % strelOpen=2; % strelClose=2; % implay(inVideo); % markMovesInVideo(inVideo, moveTresh, strelOpen, strelClose); % % %% See also % markMovesInCamera % %% Revision history % First version: Nikolay S. 2011-10-21. % Last update: Nikolay S. 2011-10-24. % % *List of Changes:* % %% Default parameters if nargin<4 strelClose=2; if nargin<3 strelOpen=2; if nargin<2 moveTresh=35; if nargin==0 error('MATLAB:markMovesInVideo:error',... 'Input video file name is missing.') end end end end if isnumeric(strelOpen) strelOpen = strel('disk', strelOpen , 0); elseif ~(strcmpi(class(strelOpen), 'strel') || islogical(strelOpen)) error('MATLAB:markMovesInVideo:error',... 'Bad strelOpen input.') end if isnumeric(strelClose) strelClose = strel('disk', strelClose , 0); elseif ~(strcmpi(class(strelClose), 'strel') || islogical(strelClose)) error('MATLAB:markMovesInVideo:error',... 'Bad strelClose input.') end %% Get input video and its parameters ObjInVideo = VideoReader(inVideo); nFrames=ObjInVideo.NumberOfFrames; frameWidth=ObjInVideo.Width; frameHeight=ObjInVideo.Height; prevMoveMask=false(frameHeight, frameWidth); prevFrame=read(ObjInVideo, 1); nClrs=size(prevFrame, 3); %% Prepare a figure hFigure=figure; hImage=imshow(zeros(size(prevFrame),'uint8')); %% loop through all frames- % detect movement, apply aging, and resent combination for iFrame = 2 : nFrames currFrame=read(ObjInVideo, iFrame); I = imabsdiff(currFrame, prevFrame); % Update the patch to the new level value. graylevel = graythresh(I); level = max(moveTresh, floor(100*graylevel)); % Init current movements mask currMoveMask=false(frameHeight, frameWidth); for iClr=1:nClrs % Detect movement on every color (operation on intensity/grayscale % data is also an option) currMoveMask=currMoveMask | (I(:, :, iClr)>level); end % Apply "aging" to historical data via Morpohological Erode operator prevMoveMask= imerode(prevMoveMask, strelClose); currMoveMask= imdilate(currMoveMask, strelOpen); % Connect isolated % movement elemnets to larger regions via Morpohological Dilate operator currMoveMask=currMoveMask | prevMoveMask; % Combine previous and current masks % Crop only relevant parts of image image2Show=zeros(size(prevFrame),'uint8'); currMoveMask3D=repmat(currMoveMask, [1, 1, nClrs]); image2Show(currMoveMask3D)=currFrame(currMoveMask3D); % While figure isn't closed... if ~ishandle(hFigure) stop(vid); return; end % Update the figure set(hImage, 'CData', image2Show); drawnow; prevFrame = currFrame; prevMoveMask=currMoveMask; end close(hFigure);