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.