如何使用FAST算法稳定视频

How to stabilize a video with FAST algorithm?

本文关键字:视频 算法 何使用 FAST      更新时间:2023-10-16

我是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;
}

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

当我摆弄视频稳定时,我使用ESM作为主要工具。我不确定现在是否有可用的实现,但如果您对雅可比和矩阵运算充满信心,那么推出自己的实现并不难。你可以从链接的论文中看到图5作为一个例子——它可以用来相当稳健地跟踪/稳定平面区域。但是你的框架可能不是真正的平面,所以你必须实现某种异常拒绝。你还必须弄清楚如何比较帧——最后一帧与前一帧,或者最后一帧和第一帧。我正在为一些延时视频进行稳定处理,所以使用了后一种方法,但对于真实的视频,你可能会使用前一种,因为它允许相机位置随着时间的推移而漂移。