2014-02-07 65 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); 
} 

希望这将解决你的问题:)