OpenCV 2.0 用サンプル - 画像入出力,映像入出力
Win32 コンソールアプリケーションプロジェクトで作っていく.C++ Interface なんて未知の分野だが,OpenCV2.0\doc\opencv.pdf を参考にしたら何とかなるようだ.
環境と内容
- Windows XP Pro SP3
- VC++ 2008 EE
- プロジェクト種別「Win32 コンソール アプリケーション」
- Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1
- CMake 2.6.4
- OpenCV 2.0.0a
内容は4つある.
- 画像読み込みと保存と表示
- 映像読込と再生
- 映像ファイルの情報を画面に表示
- AVI ファイルを AVI ファイルに書き出す
画像読み込みと保存と表示 via VS2008 集成openCV过程
解放はデストラクタに書いてあるんだろう.きっと.
#include "stdafx.h" #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 const char *FILENAME = "c:/data/image/lena.png"; const char *WINDOW_NAME = "lena.png"; int _tmain(int argc, _TCHAR* argv[]) { cv::Mat image = cv::imread(FILENAME); if ( !image.empty() ) { cv::imwrite("test.png", image); cv::namedWindow(WINDOW_NAME, CV_WINDOW_AUTOSIZE); cv::imshow(WINDOW_NAME, image); cv::waitKey(); } return 0; }
映像読込と再生
映像終端を超えると cv::imshow が例外を投げる.追っかけてみたら,image が空になっていたから empty() を試してみたらビンゴ.次に示すのは,cv:VideoCapture からフレーム数を取得し,カウンタを回して止めた.
長い映像に暇をもてあまして閉じるボタンをクリックした.ウインドウが消えたが,次のフレームから復活した.この挙動,以前とは違うよな.カチカチカチ.途中終了をつけてやりたいので ESC キーをスイッチにしてやった.
#include "stdafx.h" #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 const char *FILENAME = "c:/data/video/fez20091005-185827[000].avi"; //const char *FILENAME = "c:/data/video/90frame.avi"; const char *WINDOW_NAME = "play window"; const int KEYCODE_ESC = 0x1b; int _tmain(int argc, _TCHAR* argv[]) { cv::VideoCapture capture(FILENAME); if( capture.isOpened() ) { cv::Mat image; cv::namedWindow(WINDOW_NAME, CV_WINDOW_AUTOSIZE); double frame_count = capture.get(CV_CAP_PROP_FRAME_COUNT); int key; int i = 0; while( frame_count-- ) { capture >> image; cv::imshow( WINDOW_NAME, image); key = cv::waitKey(1); if( key == KEYCODE_ESC ) { break; } } } return 0; }
無限ループにするなら,capture >> image; 後に image.empty() をチェックするといいだろう.
if( image.empty() ) { break; }
映像ファイルの情報を画面に表示
映像プロパティの ID リストは highgui.h 287行から.二次元配列の行数取得は BohYoh.com-C/C++ FAQ 2次元配列の要素数を取得するにはどうすればよいですか。 から.
#include "stdafx.h" #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 //const char *FILENAME = "c:/data/video/90frame.avi"; const char *FILENAME = "c:/data/video/fez20091005-185827[000].avi"; const char *HIGHGUI_PROPID[] = { "CV_CAP_PROP_POS_MSEC ", "CV_CAP_PROP_POS_FRAMES ", "CV_CAP_PROP_POS_AVI_RATIO", "CV_CAP_PROP_FRAME_WIDTH ", "CV_CAP_PROP_FRAME_HEIGHT ", "CV_CAP_PROP_FPS ", "CV_CAP_PROP_FOURCC ", "CV_CAP_PROP_FRAME_COUNT ", "CV_CAP_PROP_FORMAT ", "CV_CAP_PROP_MODE ", "CV_CAP_PROP_BRIGHTNESS ", "CV_CAP_PROP_CONTRAST ", "CV_CAP_PROP_SATURATION ", "CV_CAP_PROP_HUE ", "CV_CAP_PROP_GAIN ", "CV_CAP_PROP_EXPOSURE ", "CV_CAP_PROP_CONVERT_RGB ", "CV_CAP_PROP_WHITE_BALANCE", "CV_CAP_PROP_RECTIFICATION", }; const int HIGHGUI_PROPID_COUNT = sizeof( HIGHGUI_PROPID ) / sizeof( HIGHGUI_PROPID[0] ) ; void print_videinfo(cv::VideoCapture capture) { if ( capture.isOpened() ) { for( int i = 0; i < HIGHGUI_PROPID_COUNT; i++ ) { printf("%s: %lf\n", HIGHGUI_PROPID[i], capture.get(i)); } } } int _tmain(int argc, _TCHAR* argv[]) { cv::VideoCapture capture(FILENAME); printf("%s\n", FILENAME); print_videinfo(capture); getchar(); return 0; }
AVI ファイルを AVI ファイルに書き出す
while( frame_count-- ); と書いていて,デバッグを20分続けていた.
- ESC キーでの中断機能あり
- なんとなく video_property というクラスを作っちゃった
- CV_FOURCC_DEFAULT は IYUV(highgui.h 326行目)
- OpenCV 2.0 で AVI ファイルを AVI ファイルに書き出す(第2版) - BiBoLoG
- OpenCV 2.0 で AVI ファイルを AVI ファイルに書き出す(第3版) - BiBoLoG
#define CV_FOURCC_PROMPT -1 /* Open Codec Selection Dialog (Windows only) */ #define CV_FOURCC_DEFAULT CV_FOURCC('I', 'Y', 'U', 'V') /* Use default codec for specified filename (Linux only) */
#include "stdafx.h" #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 const char *IN_VIDEO = "c:/data/video/fez20091005-185827[000].avi"; //const char *IN_VIDEO = "c:/data/video/90frame.avi"; const char *OUT_VIDEO = "c:/data/video/test.avi"; const char *WINDOW_NAME = "preview window"; const int KEYCODE_ESC = 0x1b; class video_property { private: int count; int width; int height; double fps; public: int get_count(void) { return this->count; } int get_width(void) { return this->width; } int get_height(void) { return this->height; } double get_fps(void) { return this->fps; } video_property( cv::VideoCapture capture ) { set(capture); }; void set( cv::VideoCapture capture) { if ( capture.isOpened() ) { this->count = (int) capture.get( CV_CAP_PROP_FRAME_COUNT ); this->width = (int) capture.get( CV_CAP_PROP_FRAME_WIDTH ); this->height = (int) capture.get( CV_CAP_PROP_FRAME_HEIGHT ); this->fps = capture.get( CV_CAP_PROP_FPS ); }else{ this->count = this->width = this->height = 0; this->fps = 0.0; } } void print(void) { printf("%-26s: %d\n", "CV_CAP_PROP_FRAME_COUNT", this->count ); printf("%-26s: %d\n", "CV_CAP_PROP_FRAME_WIDTH", this->width ); printf("%-26s: %d\n", "CV_CAP_PROP_FRAME_HEIGHT", this->height); printf("%-26s: %lf\n", "CV_CAP_PROP_FPS", this->fps ); } }; int _tmain(int argc, _TCHAR* argv[]) { cv::VideoCapture capture(IN_VIDEO); printf("%s\n", IN_VIDEO); if( capture.isOpened() ) { video_property prop(capture); prop.print(); cv::VideoWriter writer( OUT_VIDEO, CV_FOURCC_DEFAULT, prop.get_fps(), cv::Size(prop.get_width(), prop.get_height())); if( writer.isOpened() ) { cv::namedWindow(WINDOW_NAME, CV_WINDOW_AUTOSIZE); int frame_count = prop.get_count(); cv::Mat image; int key; while( frame_count ) { capture >> image; cv::imshow( WINDOW_NAME, image); key = cv::waitKey(1); writer << image; if( key == KEYCODE_ESC ) break; } } } return 0; }