2012-10-13 88 views
1

我想做一些openCV視頻處理。我在Mac上使用Xcode 4中的openCV,所以實際上我的代碼是Objective C++。從視頻文件中抓取幀的最快方法OpenCV

我想盡可能快地訪問視頻的所有幀(不顯示它並且沒有掉落)並對它們進行計算。

我的代碼,以獲得幀:

CvCapture* capture = cvCaptureFromFile("A MOVIE FILE HERE"); 

IplImage* frame; 

while(1) { 
    frame = cvQueryFrame(capture); 

    if (!frame) break; 

     // openCV Stuff here... 

    char c = cvWaitKey(1); 
    if(c==27) break; 
} 

我知道速度大量取決於編解碼器/分辨率/比特率 - 但似乎我不能超過120%的速度讀取任何...想法如何更快抓幀?

+0

'cvWaitKey()'根本不需要。 – karlphillip

回答

0

我已經注意到幾次,cv::waitKey()/cvWaitKey()是不準確的簡短(< 10毫秒)次。實際上,就我而言,它似乎在10ms以下的任何值下至少可以睡10ms。也許有人可以帶來更多的精度,但我建議從你的循環中刪除它(如果可以的話)。

我希望它的工作原理, 好運

+0

感謝您的快速回復,已經嘗試過 - 忘記提及這一點。沒有真正加快速度。對我來說,分辨率保持不變並不重要 - 只有框架必須沒有掉落。我不知道是否有方法從低分辨率的視頻文件中捕獲?由於我正在處理很長的素材 - 我不想將這些文件手動轉換爲較低的分辨率。 不知道是否類似: 'cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_HEIGHT,320); cvSetCaptureProperty(capture,CV_CAP_PROP_FRAME_WIDTH,200);' 的作品?沒有做任何事情。 – kava

+0

您是否試圖分開抓取和解碼操作以查看哪一步最長? –

1

其實只有一個,減慢你的程序的事情 - 這是waitKey昆汀Geissmann已經提到。如果你說:

試過,已經忘記提及了。沒有真的加快 的東西。

比我不相信你,因爲我剛剛在我的環境中測試過它,並且速度提高了30-40%。

這裏的基準代碼:

#define WAIT_ON 
int main() 
{ 
    cv::Mat frame; 
    cv::VideoCapture capture = cv::VideoCapture("video/in.avi"); 
    int k; 

    double benchTime = (double)cv::getTickCount(); 
    while (1) 
    { 
     capture >> frame; 
     if (!frame.data) 
     { 
      break; 
     } 

#ifdef WAIT_ON 
     k = cv::waitKey(1); 
     if (k == 27) 
     { 
      break; 
     } 
#endif 
    } 

    std::cout << ((double)cv::getTickCount() - benchTime)/cv::getTickFrequency() << std::endl; 
} 

視頻輸入:854x480, 24fps, 2:00

隨着WAIT_ON宏:〜11秒

沒有:〜7.3秒

更新:

爲了減少在視頻流圖像分辨率設置這些參數:

CV_CAP_PROP_FRAME_WIDTH Width of the frames in the video stream. 
CV_CAP_PROP_FRAME_HEIGHT Height of the frames in the video stream. 

set method到其他(320x240)。

+0

@kava是否提高了速度? – ArtemStorozhuk

+0

不幸的是它沒有 - 當我註釋掉cvWaitKey()時沒有視頻抓取/回放。它只是掛在第一幀。似乎我需要cvWaitKey()?!我期待找到一種以較低分辨率處理幀的方法。我正在使用FullHD Material,但它足以處理它們,像320x200。我需要cvConvertImage()還是有另一種'以較低分辨率讀取文件'的方法?當我以四分之一大小播放FullHD文件時,Quicktimeplayer會做什麼? – kava

+0

@kava歡迎回來!你忘了這個問題已經很久了,現在你決定再次提高速度了?查看我答案的更新部分。 – ArtemStorozhuk

-1

功能

cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, 320); 
cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 200); 

不影響視頻本身,如果你想改變幀的分辨率,可以使用類似:

cv::Size videoSize = cv::Size ((int) 320, (int) 200); 
cv::resize(srcFrame,resFrame, videoSize); 

這將改善的時候,你需要處理每一幀,因爲它們會更小。 希望它有幫助