2014-02-07 146 views
2

我想用opencv做視頻穩定(沒有opencv視頻穩定類)。視頻穩定使用opencv

我ALGO的步驟是如下 - >

  1. 衝浪點提取,

  2. 匹配,

  3. 單應性矩陣,

  4. warpPerspective

而輸出視頻根本不穩定:(。它看起來像原始視頻。我無法找到和參考視頻穩定的代碼。我遵循了here的程序。任何人都可以通過告訴我我錯在哪裏或者提供一些源代碼鏈接來改善我的算法來幫助我。

請幫忙。謝謝

+0

這個問題都非常模糊,非常廣泛。如果我們能夠幫助您,您將需要重新措辭並提供更多信息。 –

回答

3

你可以用我的代碼段爲起點(不是很穩定,但似乎它的工作原理):

#include "opencv2/opencv.hpp" 
#include <iostream> 
#include <vector> 
#include <stdio.h> 

using namespace cv; 
using namespace std; 

int main(int ac, char** av) 
{ 
    VideoCapture capture(0); 
    namedWindow("Cam"); 
    namedWindow("Camw"); 
    Mat frame; 
    Mat frame_edg; 
    Mat prev_frame; 
    int k=0; 
    Mat Transform; 
    Mat Transform_avg=Mat::eye(2,3,CV_64FC1); 
    Mat warped; 
    while(k!=27) 
    { 
     capture >> frame; 
     cv::cvtColor(frame,frame,cv::COLOR_BGR2GRAY); 
     cv::equalizeHist(frame,frame); 
     cv::Canny(frame,frame_edg,64,64); 
     //frame=frame_edg.clone(); 
     imshow("Cam_e",frame_edg); 
     imshow("Cam",frame); 

     if(!prev_frame.empty()) 
     { 
      Transform=estimateRigidTransform(frame,prev_frame,0); 
      Transform(Range(0,2),Range(0,2))=Mat::eye(2,2,CV_64FC1); 
      Transform_avg+=(Transform-Transform_avg)/2.0; 
      warpAffine(frame,warped,Transform_avg,Size(frame.cols, frame.rows)); 

      imshow("Camw",warped); 
     } 

     if(prev_frame.empty()) 
     { 
      prev_frame=frame.clone(); 
     } 

     k=waitKey(20);  
    } 
    cv::destroyAllWindows(); 
    return 0; 
} 

你也可以找紙:Chen_Halawa_Pang_FastVideoStabilization.pdf我remeber有MATLAB源代碼提供。

+0

嗨安德烈謝謝你的回覆。你能解釋一下「Transform(Range(0,2),Range(0,2))= Mat :: eye(2,2,CV_64FC1); Transform_avg + =(Transform-Transform_avg)/2.0;」這2行呢?而且我還看到了matlab代碼,我試圖用C++將其轉換。 – MMH

+1

變換(範圍(0,2),範圍(0,2))= Mat :: eye(2,2,CV_64FC1);線除了翻譯外,還包括所有的轉換(旋轉,縮放和剪切)。這是因爲我不需要這種變換補償,它增加了算法的穩定性。 Transform_avg + =(Transform-Transform_avg)/2.0;這是變換位移補償的區別。 1/2是我記得的摩爾穩健性係數(我幾年前寫過這個代碼),它也可以用作低通濾波器。 –

+0

謝謝安德魯,我非常感謝你的回答。但是我的測試視頻並沒有給您提供的代碼片段帶來好的結果。不管怎麼說,多謝拉。 – MMH

0

衝浪不是那麼快。我的工作方式是使用光流。首先,您必須使用GoodFeaturesToTrack()函數計算第一幀的好功能。之後,我使用FindCornerSubPix()函數做一些優化。

現在你在起始幀中有特徵點,接下來你要做的就是確定光流。有幾個光流功能,但我使用的是OpticalFlow.PyrLK(),在其中一個輸出參數中,您可以獲取當前幀中的功能點。通過這個,你可以用FindHomography()函數計算Homography矩陣。接下來,您需要做的就是顛倒這個矩陣,您可以使用google輕鬆找到的解釋,然後調用WarpPerspective()函數來穩定幀。

PS。我在這裏從EmguCV,OpenCV .NET包裝器中放置的函數可能會有一些差異

2

在「warpAffine(frame,warped,Transform_avg,Size(frame.cols,frame.rows));」函數,您必須將FLAG指定爲WARP_INVERSE_MAP才能達到穩定。

示例代碼我寫:

Mat src, prev, curr, rigid_mat, dst; 

VideoCapture cap("test_a3.avi"); 

while (1) 
{ 
    bool bSuccess = cap.read(src); 
    if (!bSuccess) //if not success, break loop 
     { 
       cout << "Cannot read the frame from video file" << endl; 
       break; 
     } 

    cvtColor(src, curr, CV_BGR2GRAY); 

    if (prev.empty()) 
    { 
     prev = curr.clone(); 
    } 

    rigid_mat = estimateRigidTransform(prev, curr, false); 

    warpAffine(src, dst, rigid_mat, src.size(), INTER_NEAREST|WARP_INVERSE_MAP, BORDER_CONSTANT); 


    // ---------------------------------------------------------------------------// 

    imshow("input", src); 
    imshow("output", dst); 

    Mat dst_gray; 
    cvtColor(dst, dst_gray, CV_BGR2GRAY); 
    prev = dst_gray.clone(); 

    waitKey(30); 
} 

希望這將解決你的問題:)