可変フレームレートの映像ファイルのいくつかは CV_CAP_PROP_FRAME_COUNT のプロパティが 0 になるけど云々
フレーム数計測をやった.
まとめ
マシンは Dell Vostro 400,Core2 Quad,Q6600.コンパイラは VC++ 2008 EE.
number | name | frame count | property | grab() ループ | operator >> |
---|---|---|---|---|---|
1 | test | 90 | 90 | 90 | 90 |
2 | 1.avi | 200 | 200 | 200 | 200 |
3 | 1.flv | 200 | 0 | 200 | 200 |
4 | fez | 27292 | 27292 | 27291 | 27291 |
遊び半分で処理時間を計測した.operator >> よりは grab() が速いね.operator >> と grab() は一致するから,grab() を使おうね.fez は何が災いしたのか,計測してみると 1 小さい.不思議だ.
やってから気づいた.
// grab() + retrieve(image, 0); と等価です. virtual VideoCapture& operator >> (Mat& image);http://opencv.jp/opencv-2.0svn/cpp/reading_and_writing_images_and_video.html?highlight=retrieve#videocapture
こういう仕様なら,フレームを数えるには grab() だけでいい.
各映像ファイル詳細
[test.avi] 256x256 24Bit 無圧縮 5.00fps 90f 7864.64kb/s [RIFF(AVI1.0)] 00:00:18.000 (18.000sec) / 17,701,376Bytes [1.avi] 256x256 24Bit 不明VP6F 0.00fps 200f 297.77kb/s [RIFF(AVI1.0)] 00:00:40.000 (40.000sec) / 1,492,272Bytes [1.flv] 256x256 On2 VP6 5.00fps 400.00kb/s [FlashVideo] 00:00:39.799 (39.799sec) / 1,490,734Bytes [fez20091005-185827[000].avi] 640x400 24Bit H.264 15.00fps 27292f 842.23kb/s MPEG1-LayerIII 44.10kHz 96.00kb/s CBR Mono [RIFF(AVI1.0)] 00:30:19.466 (1819.466sec) / 214,263,802Bytes 真空波動研Lite 090902 / DLL 090902
画面出力
さっきの表の映像を順に,空行区切りで.
elapsed time [ms]: 0.000710517 frameCount (property): 90 elapsed time [ms]: 23.4078 frameCount (grab()): 90 elapsed time [ms]: 27.1176 frameCount (operator >>): 90 elapsed time [ms]: 0.000778186 frameCount (property): 200 elapsed time [ms]: 313.559 frameCount (grab()): 200 elapsed time [ms]: 407.356 frameCount (operator >>): 200 elapsed time [ms]: 0.00198494 frameCount (property): 0 elapsed time [ms]: 312.889 frameCount (grab()): 200 elapsed time [ms]: 401.504 frameCount (operator >>): 200 elapsed time [ms]: 0.00178945 frameCount (property): 27292 elapsed time [ms]: 94552.4 frameCount (grab()): 27291 elapsed time [ms]: 143904 frameCount (operator >>): 27291
コード
タイム計測は http://wiki.livedoor.jp/mikk_ni3_92/d/OpenCV::%BB%FE%B4%D6%B7%D7%C2%AC から頂戴した.
#include <iostream> #include <opencv/cv.h> #include <opencv/highgui.h> #ifdef _DEBUG #pragma comment( lib, "cv200d.lib" ) #pragma comment( lib, "cxcore200d.lib" ) #pragma comment( lib, "highgui200d.lib" ) #else #pragma comment( lib, "cv200.lib" ) #pragma comment( lib, "cxcore200.lib" ) #pragma comment( lib, "highgui200.lib" ) #endif using namespace std; double start, finish; #define stopWatchStart start = static_cast<double>(cv::getTickCount()) #define stopWatchStop finish = static_cast<double>(cv::getTickCount()); \ cout << "elapsed time [ms]: " << (finish - start)/cv::getTickFrequency()*1000 << endl int main ( int argc, char *argv[] ) { if ( argc < 2 ) { cout << "execute it: " << "numofframeFORvfr.exe a-video-file" << endl; return 0; } cv::VideoCapture cap = argv[1]; if ( cap.isOpened() == false ) { cout << "loading was failed: " << argv[1] << endl; return 0; } // property stopWatchStart; int frameCount = (int)cap.get(CV_CAP_PROP_FRAME_COUNT); stopWatchStop; cout << "frameCount (property): " << frameCount << endl; // grab() loop frameCount = 0; stopWatchStart; while ( cap.grab() ) frameCount++; stopWatchStop; cout << "frameCount (grab()): " << frameCount << endl; // load frames frameCount = 0; cap.set(CV_CAP_PROP_POS_MSEC, 0.0); cv::Mat still; stopWatchStart; for ( ;; ) { cap >> still; if ( still.empty() ) break; frameCount++; } stopWatchStop; cout << "frameCount (operator >>): " << frameCount << endl; return 0; }