Water's Home

Just another Life Style

0%

Lucas-Kanade & Farneback

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);
    }