% SPAN Version 1.3 (20.08.2008)
% SPatial ANnotation program for the manual frame-by-frame tracking of target points in video clips
% developed by N'Diaye, Gille and Dael
close all
clear all
clc
global Npts S M_button I matfilename txtfilename
% Ask the user for a directory where the video's are stored and change working directory
cd(uigetdir('D:\','Pick a directory'))
% Ask the user for a file name, and set the filename variable
[filename, pathname] = uigetfile({'*.avi','AVI movie'},'Pick a movie clip');
% Change working directory to where this file file is stored
cd('D:\')
% Makes it into a long filename (path + file name)
filename = fullfile(pathname,filename);
% Load the frames of the movie in a 'movie' variable
movie = aviread(filename);
% Compute the number of frames
N = length(movie);
% Ask the user for the number of points he/she wants to click on each frame
Npts = inputdlg({'How many points?'},'Points to click',1,{'6'});
% Convert the answer into a number
Npts = str2num(Npts{1});
% Define the filename where the data will be saved in matlab and text format
[ignore,fname,ext] = fileparts(filename);
matfilename = fullfile(pathname,[fname '.mat']);
txtfilename = fullfile(pathname,[fname '.dat']);
% Open a new figure
figure
% Creates axes where to draw
ha(1) = subplot(5,4,[1 2 3 5 6 7 9 10 11 13 14 15]);
ha(2) = subplot(5,4,[4 8 12 16]);
ha(3) = subplot(5,4,17:19);
ha(4) = subplot(5,4,20);
% Loop on each frame
i = 1;
k = i;
S = ['+.ox'];
button = ones(Npts,1);
M_button = [];
I = [];
while i <= N
% Use the first axis to plot the image
axes(ha(1));
% Plot the image
imagesc(movie(i).cdata)
% Keeps image to its original size to make it look visually unstretched
axis image
axis tight
% Add a title
title(sprintf('Movie : %s ; Image : %d / %d ',fname,i,N));
% "Listen" to Npts clicks from the user on the image & save the
% position in the i-th column of the x and y matrices (which have Npts
% rows)
if ((button(:) == 1) | (button(:) == 2) | (button(:) == 3)) & (size(button,1) == size(ones(Npts,1),1))
[x(i,:),y(i,:),button] = ginput2(Npts,114);
if (size(button,1) == size(ones(Npts,1),1))
M_button(i,:) = [button'];
I(i,:) = [i];
else
M_button = M_button;
end
if k ~= i
button = 114*ones(Npts,1);
else
% Use the second axis to plot the x data
axes(ha(2));
plot(x(1:i,:),repmat([1:i]',[1,size(y,2)]))
% Makes vertical axes to be N frames long and reverse: goes from top to
% bottom
set(ha(2),'Ylim',[0 N],'YDir','reverse');
% Use the third axis to plot the y data
axes(ha(3));
plot(repmat([1:i]',[1,size(y,2)]),y(1:i,:))
set(ha(3),'Xlim',[0 N],'YDir','reverse');
% Use the fourth axis to plot the x-by-y data
axes(ha(4));
plot(x,y)
set(ha(4),'YDir','reverse','YTick',[])
if ((button(:) == 1) | (button(:) == 2) | (button(:) == 3)) & (size(button,1) == size(ones(Npts,1),1))
i = i+1;
k = k+1;
else
i = i;
end
end
elseif button == 114*ones(Npts,1)
button = 28;
k = size(x,1);
while button == 28 | button == 29
[aa,bb,button] = ginput(1);
if button == 28 & i > 1
i = i-1;
elseif button == 29 & i < k
i = i+1;
else
i = i;
end
axes(ha(1));
imagesc(movie(i).cdata)
axis image
axis tight
title(sprintf('Movie : %s ; Image : %d / %d ',fname,i,N));
hold on
for j = 1:Npts
color = ['bgrcmyw'];
if M_button(i,j) == 1
s = 1;
elseif M_button(i,j) == 2
s = 2;
elseif M_button(i,j) == 3
s = 3;
else
s = 4;
end
plot(x(i,j),y(i,j),sprintf('%s %s',S(s),color(j)));
end
axes(ha(2));cla
plot(x(1:i,:),repmat([1:i]',[1,size(y,2)]))
set(ha(2),'Ylim',[0 N],'YDir','reverse');
axes(ha(3));cla
plot(repmat([1:i]',[1,size(y,2)]),y(1:i,:))
set(ha(3),'Xlim',[0 N],'YDir','reverse');
axes(ha(4));cla
plot(x(1:i,:),y(1:i,:))
set(ha(4),'YDir','reverse','YTick',[])
end
else
choice = menu('Choose an option:','Annotate current frame','Scroll through frames');
switch choice
case 1
button = ones(Npts,1);
case 2
button = 114*ones(Npts,1);
end
end
end
% Launch the replay of the annotation
replay_annotation(movie,x,y)