How can I track and measure the velocity of a moving object in a video?
    48 views (last 30 days)
  
       Show older comments
    
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
  Jorge Mario Guerra González
      
 on 24 Jan 2017
				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...
Accepted Answer
  Tohru Kikawada
    
 on 24 Jan 2017
        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
  muhammad choudhry
      
 on 13 Aug 2020
				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));
  Dalia
 on 12 Sep 2023
				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?
More Answers (0)
See Also
Categories
				Find more on Tracking and Motion Estimation in Help Center and File Exchange
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!