2014-11-24 101 views
2

我正在做一个C++视频稳定/防抖程序,其中: - 获取参考帧上的兴趣点(使用FAST,SURF,Shi- Matoshi或SIFT,不妨多试几个) - 计算与calcOpticalFlowPyrLK 卢卡斯 - Kanade光流 - 获取单应矩阵 - 更正使用warPerspective晃动的图像(见下面的代码)从视频稳定程序将C/++ OpenCV程序更改为CUDA

//Calculate the Lucas Kanade optical flow 
calcOpticalFlowPyrLK(original, distorted, refFeatures, currFeatures, featuresFound, err); 

//Find the homography between the current frame's features and the reference ones's 
if(homographyRansac){ 
    homography = findHomography(currFeatures, refFeatures, CV_RANSAC); /*CV_RANSAC: Random sample consensus (RANSAC) is an iterative method to 
    estimate parameters of a mathematical model from a set of observed data which contains outliers */ 
}else{ 
    homography = findHomography(currFeatures, refFeatures, 0); 
} 


//We use warpPerspective once on the distorted image to get the resulting fixed image 
if(multiChannel){ 
    //Spliting into channels   
    vector <Mat> rgbChannels(channels), fixedChannels; 
    split(distortedCopy, rgbChannels); 
    recovered = Mat(reSized, CV_8UC3); 
    //We apply the transformation to each channel 
    for(int i = 0; i < channels; i ++){ 
     Mat tmp; 
     warpPerspective(rgbChannels[i], tmp, homography, reSized); 
     fixedChannels.push_back(tmp); 
    } 
    //Merge the result to obtain a 3 channel corrected image 
    merge(fixedChannels, recovered); 
}else{ 
    warpPerspective(distorted, recovered, homography, reSized); 
} 

如果你有我的稳定解决方案的任何替代品,随时可以这样说,但这不是这个话题的主题。由于所有这些都需要大量的时间(我的i5电脑每帧大约需要300ms,因此30分钟的视频需要很长的时间),所以我正在考虑使用CUDA来加快速度。我已经安装并开始工作,但我不确定接下来要做什么。我已经做了一些测试,我知道最耗时的操作是使用calcOpticalFlowPyrLK和warpPerspective分别获得光流和帧校正。所以理想情况下,至少在一开始,我只会使用这两个函数的CUDA版本,而其余部分不变。

这可能吗?或者我需要重写所有内容?

感谢

+0

为什么不在OpenCV 3.0中使用内置的CUDA加速视频稳定器?创建一个“OnePassStabilizer”类的对象,并将其运动估计器设置为“KeypointBasedMotionEstimatorGpu”。只需在代码中包含'opencv2/videostab.hpp'。 – sgarizvi 2014-11-25 10:24:19

+0

我会试一试并回复给你,谢谢! – user1965728 2014-11-25 12:21:25

+0

您能否帮我解释一下,恐怕我不知道如何继续 – user1965728 2014-11-25 12:47:24

回答

4

由于OpenCV的3.0,CUDA一个实现视频稳定可用。除非您确定您的版本更好或更快,否则建议使用已有的实现,而不是自己编写自己的实现。

下面是一个简单的代码,演示如何使用OpenCV视频稳定模块来稳定视频。

#include <opencv2/highgui.hpp> 
#include <opencv2/videostab.hpp> 

using namespace cv::videostab; 

int main() 
{ 
    std::string videoFile = "shaky_video.mp4"; 

    MotionModel model = cv::videostab::MM_TRANSLATION; //Type of motion to compensate 
    bool use_gpu = true; //Select CUDA version or "regular" version 

    cv::Ptr<VideoFileSource> video = cv::makePtr<VideoFileSource>(videoFile,true); 
    cv::Ptr<OnePassStabilizer> stabilizer = cv::makePtr<OnePassStabilizer>(); 

    cv::Ptr<MotionEstimatorBase> MotionEstimator = cv::makePtr<MotionEstimatorRansacL2>(model); 

    cv::Ptr<ImageMotionEstimatorBase> ImageMotionEstimator; 

    if (use_gpu) 
     ImageMotionEstimator = cv::makePtr<KeypointBasedMotionEstimatorGpu>(MotionEstimator); 
    else 
     ImageMotionEstimator = cv::makePtr<KeypointBasedMotionEstimator>(MotionEstimator); 

    stabilizer->setFrameSource(video); 
    stabilizer->setMotionEstimator(ImageMotionEstimator); 
    stabilizer->setLog(cv::makePtr<cv::videostab::NullLog>()); //Disable internal prints 

    std::string windowTitle = "Stabilized Video"; 

    cv::namedWindow(windowTitle, cv::WINDOW_AUTOSIZE); 

    while(true) 
    { 
     cv::Mat frame = stabilizer->nextFrame(); 

     if(frame.empty()) break; 

     cv::imshow(windowTitle,frame); 
     cv::waitKey(10); 
    } 

    return 0; 
} 
+0

非常感谢您的帮助。最后一个问题,就像我说的,我已经安装了OpenCV 3.0和CUDA,并且已经将cuda.lib和cudart.lib添加到链接器中。如果我看一看在global_motion.hpp使用KeypointBasedMotionEstimatorGpu条件是 #如果定义(HAVE_OPENCV_CUDAIMGPROC)&&定义(HAVE_OPENCV_CUDA)&&定义(HAVE_OPENCV_CUDAOPTFLOW)我似乎 无法找到cudaimproc.h也不cudaoptflow.h ,因此我得到了GPU keypointsBasedmotion的错误。我究竟做错了什么?再次感谢 – user1965728 2014-11-27 17:35:27

+0

默认发行版中可用的opencv 3.0二进制文件在没有CUDA支持的情况下编译,因此未定义'HAVE_OPENCV_CUDA'并且缺少CUDA头文件。您必须使用cmake从源代码编译和构建OpenCV。 – sgarizvi 2014-11-27 17:58:03

+0

好的,谢谢,我会试试看。但是,即使我尝试构建上面的短代码,由于4个定义,我得到LNK2005“已定义”和LNK2019“无法解析的外部符号”: cv :: Ptr video = cv :: makePtr (videoFile,真正); cv :: Ptr stabilizer = cv :: makePtr (); cv :: Ptr MotionEstimator = cv :: makePtr (model); cv :: Ptr ImageMotionEstimator; 我没有头文件。你知道这可能是什么原因吗? – user1965728 2014-11-29 13:33:18