LucasKanade Tracker
// Check if there are points to track
if(!trackingPoints\[0\].empty())
{
// Status vector to indicate whether the flow for the corresponding features has been found
vector statusVector;
// Error vector to indicate the error for the corresponding feature
vector errorVector;
// Check if previous image is empty
if(prevGrayImage.empty())
{
curGrayImage.copyTo(prevGrayImage);
}
// Calculate the optical flow using Lucas-Kanade algorithm
calcOpticalFlowPyrLK(prevGrayImage, curGrayImage, trackingPoints\[0\], trackingPoints\[1\], statusVector, errorVector, windowSize, 3, terminationCriteria, 0, 0.001);
int count = 0;
// Minimum distance between any two tracking points
int minDist = 7;
for(int i=0; i < trackingPoints\[1\].size(); i++)
{
if(pointTrackingFlag)
{
// If the new point is within 'minDist' distance from an existing point, it will not be tracked
if(norm(currentPoint - trackingPoints\[1\]\[i\]) <= minDist)
{
pointTrackingFlag = false;
continue;
}
}
// Check if the status vector is good
if(!statusVector\[i\])
continue;
trackingPoints\[1\]\[count++\] = trackingPoints\[1\]\[i\];
// Draw a filled circle for each of the tracking points
int radius = 8;
int thickness = 2;
int lineType = 8;
circle(image, trackingPoints\[1\]\[i\], radius, Scalar(0,255,0), thickness, lineType);
}
trackingPoints\[1\].resize(count);
}
// Refining the location of the feature points
if(pointTrackingFlag && trackingPoints\[1\].size() < maxNumPoints)
{
vector tempPoints;
tempPoints.push\_back(currentPoint);
// Function to refine the location of the corners to subpixel accuracy.
// Here, 'pixel' refers to the image patch of size 'windowSize' and not the actual image pixel
cornerSubPix(curGrayImage, tempPoints, windowSize, cvSize(-1,-1), terminationCriteria);
trackingPoints\[1\].push\_back(tempPoints\[0\]);
pointTrackingFlag = false;
}
Farneback Tracker
// Check if the image is valid
if(prevGray.data)
{
// Initialize parameters for the optical flow algorithm
float pyrScale = 0.5;
int numLevels = 3;
int windowSize = 15;
int numIterations = 3;
int neighborhoodSize = 5;
float stdDeviation = 1.2;
// Calculate optical flow map using Farneback algorithm
calcOpticalFlowFarneback(prevGray, curGray, flowImage, pyrScale, numLevels, windowSize, numIterations, neighborhoodSize, stdDeviation, OPTFLOW\_USE\_INITIAL\_FLOW);
// Convert to 3-channel RGB
cvtColor(prevGray, flowImageGray, COLOR\_GRAY2BGR);
// Draw the optical flow map
drawOpticalFlow(flowImage, flowImageGray);
// Display the output image
imshow(windowName, flowImageGray);
}