Lucas-Kanade & Farneback

LucasKanade Tracker

  1.         // Check if there are points to track
  2.         if(!trackingPoints[0].empty())
  3.         {
  4.             // Status vector to indicate whether the flow for the corresponding features has been found
  5.             vector<uchar> statusVector;
  6.  
  7.             // Error vector to indicate the error for the corresponding feature
  8.             vector<float> errorVector;
  9.  
  10.             // Check if previous image is empty
  11.             if(prevGrayImage.empty())
  12.             {
  13.                 curGrayImage.copyTo(prevGrayImage);
  14.             }
  15.  
  16.             // Calculate the optical flow using Lucas-Kanade algorithm
  17.             calcOpticalFlowPyrLK(prevGrayImage, curGrayImage, trackingPoints[0], trackingPoints[1], statusVector, errorVector, windowSize, 3, terminationCriteria, 0, 0.001);
  18.  
  19.             int count = 0;
  20.  
  21.             // Minimum distance between any two tracking points
  22.             int minDist = 7;
  23.  
  24.             for(int i=0; i < trackingPoints[1].size(); i++)
  25.             {
  26.                 if(pointTrackingFlag)
  27.                 {
  28.                     // If the new point is within 'minDist' distance from an existing point, it will not be tracked
  29.                     if(norm(currentPoint - trackingPoints[1][i]) <= minDist)
  30.                     {
  31.                         pointTrackingFlag = false;
  32.                         continue;
  33.                     }
  34.                 }
  35.  
  36.                 // Check if the status vector is good
  37.                 if(!statusVector[i])
  38.                     continue;
  39.  
  40.                 trackingPoints[1][count++] = trackingPoints[1][i];
  41.  
  42.                 // Draw a filled circle for each of the tracking points
  43.                 int radius = 8;
  44.                 int thickness = 2;
  45.                 int lineType = 8;
  46.                 circle(image, trackingPoints[1][i], radius, Scalar(0,255,0), thickness, lineType);
  47.             }
  48.  
  49.             trackingPoints[1].resize(count);
  50.         }
  51.  
  52.         // Refining the location of the feature points
  53.         if(pointTrackingFlag && trackingPoints[1].size() < maxNumPoints)
  54.         {
  55.             vector<Point2f> tempPoints;
  56.             tempPoints.push_back(currentPoint);
  57.  
  58.             // Function to refine the location of the corners to subpixel accuracy.
  59.             // Here, 'pixel' refers to the image patch of size 'windowSize' and not the actual image pixel
  60.             cornerSubPix(curGrayImage, tempPoints, windowSize, cvSize(-1,-1), terminationCriteria);
  61.  
  62.             trackingPoints[1].push_back(tempPoints[0]);
  63.             pointTrackingFlag = false;
  64.         }

Farneback Tracker

  1.         // Check if the image is valid
  2.         if(prevGray.data)
  3.         {
  4.             // Initialize parameters for the optical flow algorithm
  5.             float pyrScale = 0.5;
  6.             int numLevels = 3;
  7.             int windowSize = 15;
  8.             int numIterations = 3;
  9.             int neighborhoodSize = 5;
  10.             float stdDeviation = 1.2;
  11.  
  12.             // Calculate optical flow map using Farneback algorithm
  13.             calcOpticalFlowFarneback(prevGray, curGray, flowImage, pyrScale, numLevels, windowSize, numIterations, neighborhoodSize, stdDeviation, OPTFLOW_USE_INITIAL_FLOW);
  14.  
  15.             // Convert to 3-channel RGB
  16.             cvtColor(prevGray, flowImageGray, COLOR_GRAY2BGR);
  17.  
  18.             // Draw the optical flow map
  19.             drawOpticalFlow(flowImage, flowImageGray);
  20.  
  21.             // Display the output image
  22.             imshow(windowName, flowImageGray);
  23.         }

Leave a Reply

Your email address will not be published. Required fields are marked *