Correlation-based Tracking using MOSSE Filters
Draw rectangles around objects with a mouse to track them. The sample uses the RectSelector and MOSSETracker classes.
Sources:
function mosse_demo(vid) % video file, and a default target to track [x,y,w,h] win = []; if nargin < 1 if true vid = fullfile(mexopencv.root(), 'test', 'faceocc2.webm'); win = [118 57 82 98]; elseif true vid = fullfile(mexopencv.root(), 'test', 'dudek.webm'); win = [123 87 132 176]; else vid = fullfile(mexopencv.root(), 'test', 'david.webm'); win = [129 80 64 78]; end if exist(vid, 'file') ~= 2 [~,name,ext] = fileparts(vid); url = 'https://cdn.rawgit.com/opencv/opencv_extra/3.3.1/testdata/cv/tracking/'; urlwrite([url, name, '/data/', name, ext], vid); end elseif isempty(vid) if ~mexopencv.isOctave() && mexopencv.require('vision') vid = which('visionface.avi'); win = [275 125 75 100]; else vid = 0; end end % open video feed, and get first frame cap = cv.VideoCapture(vid); pause(1); assert(cap.isOpened(), 'Failed to open video'); frame = cap.read(); assert(~isempty(frame), 'Failed to read frames'); gray = cv.cvtColor(frame, 'RGB2GRAY'); % prepare plot paused = false; viz_state = true; if viz_state figure('Position',[100 200 1000 600]) subplot(1,4,1:3) hVis = []; end hImg = imshow(frame); % initialize trackers array trackers = {}; if ~isempty(win), onRect(win); end % create ROI region selector if ~mexopencv.isOctave() onHelp(); roi = RectSelector(hImg); roi.callback = @onRect; else %HACK: RectSelector not Octave compatible %HACK: function handle to nested function not supported in Octave roi = struct('isDragging',@()false); end % listen to keyboard input if ~mexopencv.isOctave() %HACK: function handle to nested function not supported in Octave set(ancestor(hImg,'figure'), 'WindowKeyPressFcn',@onType); end % main loop while ishghandle(hImg) playing = ~paused && ~roi.isDragging(); if playing % read new frame frame = cap.read(); if isempty(frame), break; end gray = cv.cvtColor(frame, 'RGB2GRAY'); % track all targets for i=1:numel(trackers) trackers{i}.update(gray); end end out = frame; % draw tracked objects for i=1:numel(trackers) out = trackers{i}.draw_object(out); end % show state from last tracker if viz_state && ~isempty(trackers) [vis, kernel, resp] = trackers{end}.visualize_state(); vis = cat(1, vis, kernel, resp); if isempty(hVis) subplot(144) hVis = imshow(vis); else set(hVis, 'CData',vis); end end % display result set(hImg, 'CData',out); if playing drawnow; else pause(0.1); % slow down a bit if paused end end cap.release(); if isobject(roi), delete(roi); end % --- Callback functions --- function onRect(rect) %ONRECT Callback for ROI selector % % onRect(rect) % % ## Input % * __rect__ selected rectangle [x,y,w,h], or empty % if isempty(rect) || cv.Rect.area(rect) < 3, return; end % track new target disp('Adding target...') trackers{end+1} = MOSSETracker(gray, rect); % un-pause paused = false; end function onType(hfig, e) %ONTYPE Event handler for key press on figure switch e.Key case {'q', 'escape'} close(hfig); case 'h' onHelp(); case {'space', 'p'} disp('Toggle pause...'); paused = ~paused; case {'c', 'r'} disp('Clearing trackers...'); trackers = {}; if viz_state delete(ancestor(hVis,'axes')); hVis = []; end end end function onHelp() %ONHELP Display usage help dialog h = helpdlg({ 'Select object(s) to track using the mouse.' 'Hot keys:' ' q - quit' ' h - help' ' p - pause' ' c - clear targets' }); % wait for user to accept dialog set(h, 'WindowStyle','modal'); waitfor(h); end end
Adding target...