# displacement of particles in a video

18 views (last 30 days)
C.G. on 2 Apr 2020
Edited: Ameer Hamza on 3 Apr 2020
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'
%% 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
%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
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)
%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
##### 2 CommentsShowHide 1 older comment
C.G. on 2 Apr 2020
I have been tasked this by my supervisor, who has written the first part of this code and the instructions above, hence why I am taking this approach.

Ameer Hamza on 2 Apr 2020
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)
%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.
Ameer Hamza on 3 Apr 2020
This shows how to match corresponding circles between two frames
% in first frame, the circles are detected in this order
centres1 = [10 12; % circle 1
15 20; % circle 2
5 15; % circle 3
20 20]; % circle 4
% in second frame, the circles are detected in a different order
centres2 = [16 22; % circle 2
18 23; % circle 4
13 13; % circle 1
3 18]; % circle 3
% here we know the which circles are same, but suppose we didn't know, then
% we can find the corresponding circles like this
Dist = pdist2(centres1, centres2);
[~, idx] = min(Dist, [], 2);
centres2 = centres2(idx, :);
After this, the rows of centres1 and centres2 corresponds to the same circle.