calculating velocity from centroids
이전 댓글 표시
I have a code which calculates the position of centroids of multiple particles through each of the video frames. I am now trying to calculate the velocity of all the particles through the video using centroid displacement. I know we can use the difference in position between frames and potentially the frame rate, but writing the code is new to me,
Does anybody know an easy way to calculate this?
%% Get video into MATLAB
%Input video using videoreader and name it 'obj'
obj = VideoReader('highamballvideo.mov')
%% Read the frames in the video
%Tell it to read the frames in the video where 20 is start and 34 finish
frames_no = [20:34];
vidFrames = read(obj,[20 34]);
%Tell it to get the number of individual frames in the 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);
mov(k).colormap = [];
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 particles in video
%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;
for loop = start_frame:end_frame;
clf
frame = rgb2gray(read(obj,loop));
%find circles function
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 and plot them througgh each
%frame
xs = centres(:,1);
ys = centres(:,2);
scatter(xs,ys,'r')
%Use drawnow to display the changes on the screen after each iteration through the loop.
drawnow
end
답변 (2개)
Image Analyst
2020년 3월 17일
0 개 추천
Writing a tracking program is very difficult and I'm not going to do it for you. It could take weeks. I suggest you look for one in the File Exchange or a commercial product. Writing one is not for someone who is new to programming, sorry.
One problem is if some particles leave the field of view and others enter the field of view. How do you handle that? You have to identify which are the same and which are different.
Also, it's easiest if the particles don't move much from frame to frame so that you can identify which are which by seeing, for every particle in the (n+1)st frame, is closest to it's location in the nth frame.
Another problem is what to do if two particles pass very close to one another (overlap or almost overlap) -- you might not know which is which. To determine that you'd perhaps assume they were traveling in a straight line and see which IDs would allow them to continue in a straight line instead of colliding and having tracks that look like a V.
But what if particles could collide, like billiard balls. Now you have to allow for particles to bounce off one another.
One major problem with your code is that your IDs or labels are not consistent. The particle that shows up as xs(1), ys(1) in one frame might not be the same particle that shows up in xs(1), ys(1) in the next frame(s). It may have moved so that that particle is now at xs(23), ys(23) in the next frame. That is why you need to ID/label them.
So you can see it can get very, very involved.
댓글 수: 6
C.G.
2020년 3월 17일
Image Analyst
2020년 3월 17일
While I respect Adam's capabilities, you may soon find out that the solution you accepted may not work. At the very least you'll have to label the particles. I'm sure you already knew that velocity was distance over time, but how do you know that particle #5 in frame #1 is the same as particle #5 in frame #200? Even if the particles move slowly, and you have a properly segmented image (a binary image map of where the particles are), because MATLAB by default labels particles from top to bottom, then from left to right, you won't have the same labeling even if the particle drift slowly. For example, let's say you had two particles, #1 in the upper left, and #2 in the middle of the scene. Now after a long time they swap locations. Now MATLAB will give x(1) and y(1) as the location of particle #2, not particle #1 like it started out. Now if you just blindly compared x and y locations you'd think that the particles didn't move, which is not true. The only way your code would work is if the particles all traveled only in little boxes and the boxes never "traded places" vertically or horizontally - in other words, no particle ever went right of, left or, above, or below another particle. This would require very widely spaced particles with very slow movement. You're simply going to have to label particles for a workable solution. You cannot simply divide your distance vector by the time difference. You're going to also have to have a label vector that keeps track of the ID# (label) for each particle, and sort the distances by label (ID) number before you do the division.
Another option for you to look into is optical flow : https://en.wikipedia.org/wiki/Optical_flow
There is a MATLAB function for that in the Computer Vision Toolbox.
My answer only focuses on the velocity computation after having computing the displacement of the particles. That's what I thought the question was focusing on based on the first two sentences.
"I have a code which calculates the position of centroids of multiple particles through each of the video frames. I am now trying to calculate the velocity of all the particles through the video using centroid displacement."
Image Analyst
2020년 3월 17일
Adam, I knew that because I also know you certainly know all the complexities involved. Sometimes I also just give the user what they ask for and let them deal with the fallout, so nothing against you. ? Your considerable expertise and participation is certainly appreciated very much. ?
We've all seen cases where user asks for X and we give them X even though that's not what they need, even though they think it is but we know it's not. So then they come back and say "it didn't work" and we say "Why not? It did exactly what you asked for. What do you really need?" Then they say "well I need to do Y" and give more context about the problem. Then we'll say "Well if you need Y you don't do X, you need to do Z."
Adam Danz
2020년 3월 17일
100% agree (but no handshake because COVID-19).
Image Analyst
2020년 3월 17일
A perfect example case in point from today: https://www.mathworks.com/matlabcentral/answers/511292-how-can-i-detect-line-lies-between-two-certain-regions#comment_811335
Adam Danz
2020년 3월 17일
"I am now trying to calculate the velocity of all the particles through the video using centroid displacement. I know we can use the difference in position between frames and potentially the frame rate, but writing the code is new to me "
To compute the distance between particles, use pdist, pdist2, hypot, or compute them directly using the distance formula (if you need help, let us know).
Once you have the distance, velocity is merely Distance/Time. The time depends on your frame rate.
framerate = 60; % 60 Hz or 60 fps
velocity = distance / (NumberOfFrames/framerate);
So, if you're computing the velocity between two frames, velocity = distance/(1/framerate).
댓글 수: 3
C.G.
2020년 3월 17일
Adam Danz
2020년 3월 17일
"It is tracking the centroids between frames and calculating the displacement that I am struggling with "
I agree with Image Analyst that there will be lots of hurdles in this process. You may need to come back and ask new quesitons as specific problems arise.
C.G.
2020년 3월 17일
카테고리
도움말 센터 및 File Exchange에서 Image Processing and Computer Vision에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
