MATLAB: Displacement of particles in a video

displacement

In my code, it reads a video and converts it to a number of instantaneous frames. Then it binaries the balls and finds the centroids of each of the points. I have two columns vector with all the coordinates (x and y) for time t.
I now need to do this from the following frame and create a second set of columns vectors with the locations at t + 1 to find the centroids displaced in time. I want to eventually find the displacement to compute particle velocity.
I am struggling to work out how to create the second column vector for the next time step to see displacement. Would anybody be able to point me in the right direction?
%% Get video into MATLAB
%Input video using videoreader and name it 'obj'
obj = VideoReader('highamballvideo.mov')
%% Read the frames in the video
%Define the frames in the video which you want MATLAB to read, in this case 20-34
frames_no = [20:34];
%Tell it to read the frames in the video (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
mov(k).cdata = vidFrames(:,:,:,k); %for all rows and columns in k
mov(k).colormap = []; %create an empty matrix
end
%Watch the video
figure(1), movie(mov, 1, obj.FrameRate), title('Original movie');
%Show all frames in a montaged figure
figure(2), montage(vidFrames(:,:,:,1:15)),title('Montage of frames 20 to 34');
%% Track particle centroids in video
%Jonny's script
%Define the frames between which particles are going to be tracked
start_frame = 10;
end_frame = 100;
%Define the radii of the circles to get MATLAB to search for
min_radius = 4;
max_radius = 20;
quality = .9;
%Binarize, identify circles, plot centroids in all the specified frames for time 't'
for loop = start_frame:end_frame; %for all frames in the range defined
clf %clear current figure
%binarize the frames
frame = rgb2gray(read(obj,loop)); %turn all stated frames in the video from color to greyscale
%find circles within the frames with radii between 4-20 (line 47-50)
centres=imfindcircles(frame,[min_radius,max_radius],'Sensitivity',quality,'Method','TwoStage')
%display image with scaled colors
imagesc(frame);
hold on
%here we get two vectors of the centroids (coordinates) and plot them through each frame
xs = centres(:,1); %first column of the vector is x-coordinates
ys = centres(:,2); %second column of the vector is y-coordinates
scatter(xs,ys,'r') % plot these coordinates as a scatter, on top of the image, in red
%Use drawnow to display the changes on the screen after each iteration through the loop.
drawnow
end

Best Answer

There are two points to consider
  1. Since the number of circles can change between frames.
  2. The imfindcircles circles can give the circles in an arbitrary order. A circle that appears at the top for 1st frame may appear somewhere else.
For the first issue, you will need to save the centers if circles in a cell array. They can handle matrices of varying sizes.
%Binarize, identify circles, plot centroids in all the specified frames for time 't'
centres = cell(size(start_frame:end_frame));
count = 1;
for loop = start_frame:end_frame; %for all frames in the range defined
clf %clear current figure
%binarize the frames
frame = rgb2gray(read(obj,loop)); %turn all stated frames in the video from color to greyscale
%find circles within the frames with radii between 4-20 (line 47-50)
centres{count}=imfindcircles(frame,[min_radius,max_radius],'Sensitivity',quality,'Method','TwoStage')
%display image with scaled colors
imagesc(frame);
hold on
%here we get two vectors of the centroids (coordinates) and plot them through each frame
xs = centres{count}(:,1); %first column of the vector is x-coordinates
ys = centres{count}(:,2); %second column of the vector is y-coordinates
scatter(xs,ys,'r') % plot these coordinates as a scatter, on top of the image, in red
%Use drawnow to display the changes on the screen after each iteration through the loop.
drawnow
count = count + 1;
end
variable centres contains center locations for each frame.
For the second, I suggest using pdist2() function to find the distance between circle centers in frame t and the circle centers in frame t+1. Two circles that have the least distance will correspond to each other.
Related Question