2014-11-24 102 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