Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

OpenCV Image frames not stabilizing

I am trying to perform a video stabilization technique using OpenCV and c++. This techniques involves the SURF detection and description, calculating homography and warping perspective based on the homography for each subsequent image frame. From the articles I have seen, I got the impression that this should produce a stabilized video but this is not the case. I can't seem to find out what I'm doing wrong. The following is my code

Mat prev_frame, curr_frame;
int minHessian = 400;
Ptr<SURF> detector = SURF::create( minHessian );
std::vector<KeyPoint> prev_keypoints, curr_keypoints;
Mat prev_descriptors, curr_descriptors;


VideoCapture cap("patio.mp4");

if (!cap.isOpened())
    return -1;

cap >> curr_frame;

detector->detectAndCompute( curr_frame, Mat(), curr_keypoints, curr_descriptors );

namedWindow("Original Video");
namedWindow("Modified Video");
moveWindow("Modified Video", 600, 0);

FlannBasedMatcher matcher;
std::vector< DMatch > matches;

for(;;){

    prev_frame = curr_frame.clone();
    prev_keypoints = curr_keypoints;
    prev_descriptors = curr_descriptors.clone();

    curr_keypoints.clear();
    curr_descriptors = Mat();
    cap >> curr_frame;

    if( !prev_frame.data || !curr_frame.data )
    { std::cout<< " --(!) Error reading images " << std::endl; return -1; }

    detector->detectAndCompute( curr_frame, Mat(), curr_keypoints, curr_descriptors );

    if (curr_keypoints.size() < 20) {
        continue;
    }

    matcher.match( prev_descriptors, curr_descriptors, matches );

    double max_dist = 0; double min_dist = 100;
    for( int i = 0; i < prev_descriptors.rows; i++ )
    {
        double dist = matches[i].distance;
        if( dist < min_dist ) min_dist = dist;
        if( dist > max_dist ) max_dist = dist;
    }

    std::vector< DMatch > good_matches;
    for( int i = 0; i < prev_descriptors.rows; i++ )
    {
        if( matches[i].distance < 3*min_dist )
        {
            good_matches.push_back( matches[i]);
        }
    }
    std::vector<Point2f> prev;
    std::vector<Point2f> curr;
    for( size_t i = 0; i < good_matches.size(); i++ )
    {
        //-- Get the keypoints from the good matches
        prev.push_back( prev_keypoints[ good_matches[i].queryIdx ].pt );
        curr.push_back( curr_keypoints[ good_matches[i].trainIdx ].pt );
    }

    if (prev.size() <=4 || curr.size() <=4){
        continue;
    }
    Mat H = findHomography( prev, curr, RANSAC );

    Mat modified;
    warpPerspective(curr_frame,modified,H,curr_frame.size());

    imshow("Original Video", curr_frame);
    imshow("Modified Video", modified);

    waitKey(30);
}
waitKey(0);

The original and modified videos are in the following links respectively:

https://www.dropbox.com/s/ilqwdocgankfe6n/input.mp4?dl=0

https://www.dropbox.com/s/1kd981j92drkfrn/output.mwv?dl=0

Please Help.