tracking the rotations of a translating ball

10 views (last 30 days)
C.G.
C.G. on 1 May 2020
My code tracks the translation of a series of footballs and plots velocity, but now i want to track the rotation of the balls and plot angular velocity. Would anybody be able to give any advice on how to go about this?
%Input video using videoreader command and name it 'obj'
obj = VideoReader('2D_football_video.mp4')
%% Read the frames in the video
%Define the frames in the video which you want MATLAB to read, in this case it is them all between frames 20-34
frames_no = [20:34];
%Tell it to read the frames in the video (named obj) where 20 is start and 34 finish
vidFrames = read(obj,[20 34]);
%Tell it to get the number of individual frames in the whole video
numFrames = size(vidFrames,4);
%Get individual frames
%Colormap is a table of colors used for index color videos
%c.data is an image sequence matrix
%How many times you repeat a function in a loop is defined by 'k'
%k = the range of values the for loop will run through before ending.
for k = 1: numFrames %k = all the frames between 1 and the total number in the video
mov(k).cdata = vidFrames(:,:,:,k); %for all rows and columns in k
mov(k).colormap = []; % [], create an empty matrix
end
%Watch the video in a new figure using movie command
figure(1), movie(mov, 1, obj.FrameRate), title('Original movie');
%Show a certain range of frames in a montaged figure, in this case between 1 and 15
figure(2), montage(vidFrames(:,:,:,1:15)),title('Montage of frames 20 to 34');
%% Tracking particles
function centres = binariseIdentifyAndTrackCentroids(obj, start_frame, end_frame, min_radius, max_radius, quality)
%Define the frames between which particles are going to be tracked
start_frame = 1;
number_of_frames = 100;
%Define the radii of the circles to get MATLAB to search for
min_radius = 4;
max_radius = 20;
quality = .9; %quality is a number between 0-1 to see how strong a circle must be in order to be found. Values of 1 discard no circles
t = 0.1; % t is the frame rate, used as time in the velocity calculation
% Grid coarseness
n = 5; %spacing in the grid
% Here I am going to do all the same steps but in one move, this will be much more memory efficient.
tmpframe = read(obj,1); %read only the first frame from the video
% Meshgrid creates 2D grid coordinates with x and y coordinates defined by the length of the two inputted vectors
% Grids going from 1 to the length of tmpframe, in spacings of 5 (n)
[X,Y]=meshgrid(1:n:size(tmpframe,2),1:n:size(tmpframe,1));
%Track the particles and plot velocity for t and t+1 (frames 1 + 2)
for loop = 1:numFrames;
%binarize frames 1 and 2 from the video (using rgb2gray)
frame_1 = rgb2gray(read(obj,loop+start_frame-1));
frame_2 = rgb2gray(read(obj,loop+start_frame));
%identify the circles in frames 1 and 2 with radii between the defined min and max
centres_1=imfindcircles(frame_1,[min_radius,max_radius],'Sensitivity',quality,'Method','TwoStage');
centres_2=imfindcircles(frame_2,[min_radius,max_radius],'Sensitivity',quality,'Method','TwoStage');
% dsearchm returns the indicies of the closest points in the 2 vectors
% identifies where each centroid has moved between frames 1 and 2
[index,dist] = dsearchn(centres_2,centres_1);
% here we have the distances not in order
% assign the centres from frames 1 and 2 to x and y coordinate variables
x_1{loop} = centres_1(:,1);
x_2{loop} = centres_2(index,1);
y_1{loop} = centres_1(:,2);
y_2{loop} = centres_2(index,2);
% now we compute the velocity as s = d/t
vel_x{loop} = (x_2{loop}-x_1{loop})/t; %x velocity using frame 2 - frame 1
vel_y{loop} = (y_2{loop}-y_1{loop})/t; %y velocity using frame 2 - frame 1
vel_res{loop} = sqrt(vel_x{loop}.^2 + vel_y{loop}.^2); %the final velocity vector as a function as its x and y components
% now we can make a overall velocity, by reshaping the array
% for all the columns in 'loop', reshape the array 'griddata' to define, size U, V and RES
U(:,:,loop)=reshape(griddata(x_1{loop},y_1{loop},vel_x{loop},X(:),Y(:)),size(X,1),size(X,2));
V(:,:,loop)=reshape(griddata(x_1{loop},y_1{loop},vel_y{loop},X(:),Y(:)),size(X,1),size(X,2));
RES(:,:,loop)=reshape(griddata(x_1{loop},y_1{loop},vel_res{loop},X(:),Y(:)),size(X,1),size(X,2));
end
clf %clear current figure
figure(1)
% Set graphics objects properties: size of the figure (x0,y0,width,height)
set(gcf,'position',[246,738,1701,210])
% This loop will now display what we have just made
for loop = 1:number_of_frames-1;
subplot(1,2,1); %creates a figure with 2 plots side by side
scatter(x_1{loop},y_1{loop},20,vel_res{loop})
hold on
subplot(1,2,2);
%displays RES as an image using the full range of colors where each element of RES corresponds to a rectangular area in the image
imagesc(RES(:,:,loop))
pause(1)
end
end

Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by