如何使用FAST算法稳定视频?

时间:2015-12-16 19:21:02

标签: c++ opencv

我是opencv的新手,我正在尝试使用FAST算法稳定视频(http://www.edwardrosten.com/work/fast.html)。 我写了一些代码,但结果不是很好,我怎样才能改善视频稳定性? 这是我的代码:

#include <opencv2/opencv.hpp>
#include <iostream>
#include <cassert>
#include <cmath>
#include <fstream>

using namespace cv;
using namespace std;

int main(int argc, const char * argv[]) {

Mat frame, frame_edg, prev_frame,warped;
Mat T,last_T;
vector<KeyPoint> corners,prev_corners;
vector<Point2f> corners2f,prev_corners2f;
int key = 0;

VideoCapture cap("video.mp4");//inizializzo l'oggetto VideoCapture con il mio video

if (!cap.isOpened()) {//controllo se è stato aperto
    cout<<"Impossbile aprire il video"<<endl;
    return -1;
}
double fps = cap.get(CV_CAP_PROP_FPS);//ricavo i frame per secondo
cout<<"Frame per secondo: "<<fps<<endl;

namedWindow("Sequenza Originale",CV_WINDOW_AUTOSIZE);//creo una finestra auto-dimensionante
namedWindow("Sequenza in grigio",CV_WINDOW_AUTOSIZE);
namedWindow("Warped");

while (key!=27) {

    cap >> frame;
    cvtColor(frame, frame, CV_BGR2GRAY);
    equalizeHist(frame, frame);
    vector <Point2f> prev_corners2, cur_corners2;
    vector <uchar> status;
    vector <float> err;


    imshow("Sequenza Originale", frame);
    if (!prev_frame.empty())
    {
        FAST(frame, corners, 5);//corner detection
        FAST(prev_frame, prev_corners, 5);//corner detection
        KeyPoint::convert(corners, corners2f);
        KeyPoint::convert(prev_corners, prev_corners2f);
        calcOpticalFlowPyrLK(prev_frame, frame, prev_corners2f, corners2f, status, err);//matching
        // weed out bad matches
        for(size_t i=0; i < status.size(); i++) {
            if(status[i]) {
                prev_corners2.push_back(prev_corners2f[i]);
                cur_corners2.push_back(corners2f[i]);
            }
        }
        T=estimateRigidTransform(cur_corners2, prev_corners2, false);
        // in rare cases no transform is found. We'll just use the last known good transform.
        if(T.data == NULL) {
            last_T.copyTo(T);
        }

        T.copyTo(last_T);
        warpAffine(frame, warped, T, Size(frame.cols,frame.rows));
        imshow("Warped", warped);
        prev_frame = frame.clone();
    }
    if(prev_frame.empty())
    {
        prev_frame = frame.clone();
    }
    key = waitKey(30);

}
destroyAllWindows();
return 0;
}

1 个答案:

答案 0 :(得分:0)

由于您正在使用功能,因此结果可能不太稳定,因为功能可能会出现并消失,从而导致抖动。您可能希望尝试基于找到最小化整个帧中相应像素之间的强度差异的变换的方法。

当我摆弄视频稳定时,我使用ESM作为主要工具。我不确定现在是否有可用的实现,但如果你对jacobians和矩阵操作有信心,那就不难推出自己的实现。您可以从链接的纸张中看到图5作为示例 - 它可以用于相当稳健地跟踪/稳定平面区域。但是你的框架可能不是真正的平面,所以你必须实现某种异常值拒绝。你还必须弄清楚你将如何比较帧 - 最后一个与前一个,或最后一个。我正在研究某种间隔拍摄视频的稳定性,所以使用后一种方法,但对于真实视频,你可能会使用前者,因为它可以随着时间的推移漂移相机位置。