How can I track and measure the velocity of a moving object in a video?

The video itself is quite simple. It's a high contrast capture of a droplet moving across the screen. How can I calculate the velocity of the droplet given that I already have the scale (pixels to mm)? Any input/direction would be appreciated.

1 Comment

I imagine you have a plain screen with a particle moving around, I would use the plain colour as a mask, then try to substract frame1-frame2, the number of pixels with X difference It's the movement.
But that's just an idea...

Sign in to comment.

 Accepted Answer

You can easily calculate the velocity multiplying the distance of centroids between previous frame and current frame, the frame rate of the video and the scale of the unit is meter/pixel.
scale = 1/320; % meter/pixel
frameRate = 30; % frame/second
velocity = velociy_pix * frameRate * scale; % pixel/frame * frame/second * meter/pixel
Here is an example code that calculates the velocity of a moving ball (requires Computer Vision System Toolbox):
%%Create a video for detection
writerObj = VideoWriter('movingBall.avi');
open(writerObj);
bgI = zeros(240,320,'uint8');
pos_org = [160 120];
r = 10;
for k = 1: 300
f = 0.2*(1-exp(-k/200));
pos = pos_org + 50*[cos(2*pi*f/30*k) sin(2*pi*f/30*k)];
I = insertShape(bgI, 'FilledCircle', [pos r], 'Color', 'white');
I = I + uint8(randn(size(I)))*10;
writeVideo(writerObj,im2frame(I));
end
close(writerObj);
%%Calculate velocity of the ball
videoFileReader = vision.VideoFileReader('movingBall.avi');
S = info(videoFileReader);
frameRate = S.VideoFrameRate; % frame/second
scale = 1/320; % m/pixel
videoPlayer = vision.VideoPlayer('Position',[100 100 600 400]);
oldPoints = [];
while ~isDone(videoFileReader)
videoFrame = step(videoFileReader);
G = rgb2gray(videoFrame);
BW = G > 0.5;
BW2 = bwareaopen(BW, 30);
BW3 = imfill(BW2, 'holes');
stats = regionprops('table',BW3,'Centroid');
points = table2array(stats);
if ~isempty(oldPoints)
% Calculate velocity (pixels/frame)
vel_pix = sqrt(sum((points-oldPoints).^2,2));
vel = vel_pix * frameRate * scale; % pixels/frame * frame/seconds * meter/pixels
else
vel_pix = 0;
vel = 0;
end
% Visualize the velocity
videoFrameOut = insertObjectAnnotation(videoFrame, 'circle', ...
[points 10*ones(size(points,1),1)], ...
cellstr(num2str(vel,'%2.2f')));
step(videoPlayer, videoFrameOut);
oldPoints = points;
end
release(videoFileReader);
release(videoPlayer);

10 Comments

how can we calculate the velocity for multiple objects
How can one calculate the velocities/ track multiple similar objects with the above described method, if one does not have access to the vision toolbox?
If you do not have access to computer vision toolbox you could call upon the third party OpenCV library.
How does one do that? Also, can you please help/guide with modifying the above code to achieve the end for multiple objects. Thank you
Hello Tohru Kikawada, I am using a part of your code and I am getting error in one of the line i.e vel_pix = sqrt(sum((points-oldPoints).^2,2)); stating that 'Matrix dimensions must agree.' so I have tried many ways to solve this problem but again and again I am facing same error, can you please show a way to counter this error.
In the sameway can we do for multiple objects?
Hi,
I am using this code on the particle tracking video and getting this error. Can you help?
Error:
Matrix dimensions must agree.
Error in velocity (line 39)
vel_pix = sqrt(sum((points-oldPoints).^2,2));
How can I estimate the velocity of water in a channel, the flow is turbulent ? I want to track a specific point and estimate its velocity but I cant write the code to specify this point as interset point.
Can you help?

Sign in to comment.

More Answers (0)

Asked:

on 24 Jan 2017

Commented:

on 12 Sep 2023

Community Treasure Hunt

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

Start Hunting!