簡體   English   中英

視頻穩定

[英]Video Stabilization

我正在研究視頻穩定領域。 我使用OpenCV實現一個應用程序。

我的進度如下:

沖浪點提取

匹配

estimateRigidTransform

warpAffine

但是結果視頻不穩定。 誰能幫助我解決這個問題,或者提供一些源代碼鏈接來改善我的狀況?

示例視頻: 河馬視頻

這是我的代碼[編輯]

#include "stdafx.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <opencv2/nonfree/features2d.hpp>
#include <opencv2/opencv.hpp>

const double smooth_level = 0.7;
using namespace cv;
using namespace std;
struct TransformParam
{
    TransformParam() {}
    TransformParam(double _dx, double _dy, double _da) {
    dx = _dx;
    dy = _dy;
    da = _da;
}
   double dx; // translation x
   double dy; // translation y
   double da; // angle
};
int main( int argc, char** argv )
{
     VideoCapture cap ("test12.avi");  
     Mat cur, cur_grey;
     Mat prev, prev_grey;


     cap >> prev;
     cvtColor(prev, prev_grey, COLOR_BGR2GRAY);

     // Step 1 - Get previous to current frame transformation (dx, dy, da) for all frames
     vector <TransformParam> prev_to_cur_transform; // previous to current

     int k=1;
     int max_frames =  cap.get(CV_CAP_PROP_FRAME_COUNT);
     VideoWriter writeVideo ("stable.avi",0,30,cvSize(prev.cols,prev.rows),true);
     Mat last_T;
     double avg_dx = 0, avg_dy = 0, avg_da = 0;
     Mat smooth_T(2,3,CV_64F);
     while(true) {
        cap >> cur;

        if(cur.data == NULL) {
           break;
        }

        cvtColor(cur, cur_grey, COLOR_BGR2GRAY);

        // vector from prev to cur
        vector <Point2f> prev_corner, cur_corner;
        vector <Point2f> prev_corner2, cur_corner2;
        vector <uchar> status;
        vector <float> err;

        goodFeaturesToTrack(prev_grey, prev_corner, 200, 0.01, 30);
        calcOpticalFlowPyrLK(prev_grey, cur_grey, prev_corner, cur_corner, status, err);

       // weed out bad matches
       for(size_t i=0; i < status.size(); i++) {
           if(status[i]) {
               prev_corner2.push_back(prev_corner[i]);
              cur_corner2.push_back(cur_corner[i]);
           }
       }

       // translation + rotation only
       Mat T = estimateRigidTransform(prev_corner2, cur_corner2, 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);

      // decompose T
      double dx = T.at<double>(0,2);
      double dy = T.at<double>(1,2);
      double da = atan2(T.at<double>(1,0), T.at<double>(0,0));
      prev_to_cur_transform.push_back(TransformParam(dx, dy, da));

      avg_dx = (avg_dx * smooth_level) + (dx * (1- smooth_level));
      avg_dy = (avg_dy * smooth_level) + (dy * (1- smooth_level));
      avg_da = (avg_da * smooth_level) + (da * (1- smooth_level));

      smooth_T.at<double>(0,0) = cos(avg_da);
      smooth_T.at<double>(0,1) = -sin(avg_da);
      smooth_T.at<double>(1,0) = sin(avg_da);
      smooth_T.at<double>(1,1) = cos(avg_da);

      smooth_T.at<double>(0,2) = avg_dx;
      smooth_T.at<double>(1,2) = avg_dy;

      Mat stable;
      warpAffine(prev,stable,smooth_T,prev.size());

      Mat canvas = Mat::zeros(cur.rows, cur.cols*2+10, cur.type());
      prev.copyTo(canvas(Range::all(), Range(0, prev.cols)));
      stable.copyTo(canvas(Range::all(), Range(prev.cols+10, prev.cols*2+10)));

      imshow("before and after", canvas);
      waitKey(20);
      writeVideo.write(stable);
      cur.copyTo(prev);
      cur_grey.copyTo(prev_grey);
      k++;
   }
 }

首先,您可以模糊圖像。 這會有所幫助。 其次,您可以通過最簡單地實現指數平滑A(t + 1)= a * A(t)+(1-a)* A(t + 1)來平滑矩陣,並使用[0; 1]范圍。 第三,您可以關閉某些類型的轉換,例如旋轉,移位等。這是代碼示例:

t = estimateRigidTransform(new, old, 0); // 0 means not all transformations (5 of 6)
if(!t.empty()){
//  t(Range(0,2), Range(0,2)) = Mat::eye(2, 2, CV_64FC1); // turning off rotation
//  t.at<double>(0,2) = 0; t.at<double>(1,2) = 0; // turning off shift dx and dy
    tAvrg = tAvrg*a + t*(1-a); // a - smooth level in [0;1] range, play with it
    warpAffine(new, stable, tAvrg, Size(new.cols, new.rows));
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM