displacement of particles in a video

조회 수: 14 (최근 30일)
C.G.
C.G. 2020년 4월 2일
편집: Ameer Hamza 2020년 4월 3일
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
  댓글 수: 2
Guillaume
Guillaume 2020년 4월 2일
It's not clear what size of particles (in pixels) you are tracking, nor how many there are. If the particles are sufficiently small have you looked into well established Particle Tracking Velocimetry (PTV) algorithms (for small number of particles) and Particle Image Velocimetry (PIV) algorithms (for large number).
There's even an unofficial toolbox for it somewhere on the Net.
C.G.
C.G. 2020년 4월 2일
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
Ameer Hamza 2020년 4월 2일
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.
  댓글 수: 4
C.G.
C.G. 2020년 4월 3일
That was also my thinking, and I think this is where my confusion lies.
I know to get the displacement i need the distance between centroid locations at each frame, but to use pdist2 I need 2 vectors in which to find the distance between. Is there a way in which you would reccomend to do this?
Ameer Hamza
Ameer Hamza 2020년 4월 3일
편집: Ameer Hamza 2020년 4월 3일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Fluid Dynamics에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by