ユーティリティとシステム関数,マクロ ====================================================== .. highlight:: c Error Handling -------------- OpenCV のエラーハンドリングは,IPL(Image Processing Library)の場合と似ています.エラーが発生した場合でも,関数はエラーコードを返しません.その代わりに, :ref:`Error` を呼び出すマクロ ``CV_ERROR`` を用いてエラーを発生させます.その中で, :ref:`SetErrStatus` によりエラー状態をセットし,標準あるいはユーザ定義のエラーハンドラ(メッセージボックスを表示したり,ログを書き出したりできます.詳しくは, :ref:`RedirectError` を参照してください)を呼び出します.1スレッドに1つ,現在のエラー状態(整数値)を保存するグローバル変数が存在します.このエラー状態は,関数 :ref:`GetErrStatus` によって取得できます. エラーハンドリングには3つのモードが存在します( :ref:`SetErrMode` および :ref:`GetErrMode` を参照してください): * **Leaf** . エラーハンドラを呼び出した後に,プログラムが終了します.これはデフォルト値です.エラーが発生すると即座に通知されるので,デバッグ時に役立ちます.しかし,製品版のシステムでは,より細かく制御可能な他の2つのモードの方が適しているかもしれません. * **Parent** . エラーハンドラは呼ばれますが,プログラムは終了しません.また,(C++の例外処理を利用しないので)スタックは巻き戻されません.ユーザは, ``CxCore`` の関数を呼び出した後で, :ref:`GetErrStatus` を用いてエラーコードをチェックし,対処を行います. * **Silent** . これは ``Parent`` モードと似ていますが,エラーハンドラが呼ばれません. 実際は, ``Leaf`` モードと ``Parent`` モードの動作は,エラーハンドラによって実装され,これらは上述の説明通りの挙動を示します.しかし :ref:`GuiBoxReport` の場合は多少挙動が異なり,全く異なる動作を実装するカスタムエラーハンドラも存在します. エラーの発生やチェックなどを行うマクロ. .. code-block:: c /* 関数内の処理文を挟むことで,それらをプロローグ(リソースの初期化)と エピローグ(確保されたリソースの解放)から分離する特別なマクロ */ #define __BEGIN__ { #define __END__ goto exit; exit: ; } /* 「リソース解放ステージ」へ進みます */ #define EXIT goto exit /* CV_ERROR() で使用する関数名をローカルに定義します */ #define CV_FUNCNAME( Name ) \ static char cvFuncName[] = Name /* 現在のコンテクスト内でのエラーを発生させます */ #define CV_ERROR( Code, Msg ) \ /* CXCORE の関数呼び出しの後の状態をチェックします */ #define CV_CHECK() \ /* CXCORE の関数呼び出しと CV_CHECK() 呼び出しの簡略表現です */ #define CV_CALL( Statement ) \ /* デバッグモードとリリースモード両方に対応した状態チェックを行います */ #define CV_ASSERT( Condition ) \ /* これらのマクロは,それぞれ対応するマクロ CV_... と似ていますが, exit ラベルを必要とせず,cvFuncName も定義されている必要がありません */ #define OPENCV_ERROR(status,func_name,err_msg) ... #define OPENCV_ERRCHK(func_name,err_msg) ... #define OPENCV_ASSERT(condition,func_name,err_msg) ... #define OPENCV_CALL(statement) ... .. 詳細を説明する代わりに,代表的なCXCOREの関数とその使用方法を以下に示します. Example: Use of Error Handling Macros ------------------------------------- .. code-block:: c #include "cxcore.h" #include void cvResizeDCT( CvMat* input_array, CvMat* output_array ) { CvMat* temp_array = 0; // 最後には解放されるべきポインタの宣言 CV_FUNCNAME( "cvResizeDCT" ); // cvFuncName の宣言 __BEGIN__; // 処理の開始.このマクロの直後に何らかの宣言があるとしても, // それらは,エピローグ部からはアクセスできません. if( !CV_IS_MAT(input_array) || !CV_IS_MAT(output_array) ) // エラーを発生させるために CV_ERROR() を利用します. CV_ERROR( CV_StsBadArg, "input_array or output_array are not valid matrices" ); // 後のバージョンでは撤廃されるだろう制約条件について, // CV_ASSERT() を用いてチェックします. CV_ASSERT( input_array->rows == 1 && output_array->rows == 1 ); // 安全な関数呼び出しのために CV_CALL を利用します. CV_CALL( temp_array = cvCreateMat( input_array->rows, MAX(input_array->cols, output_array->cols), input_array->type )); if( output_array->cols > input_array->cols ) CV_CALL( cvZero( temp_array )); temp_array->cols = input_array->cols; CV_CALL( cvDCT( input_array, temp_array, CV_DXT_FORWARD )); temp_array->cols = output_array->cols; CV_CALL( cvDCT( temp_array, output_array, CV_DXT_INVERSE )); CV_CALL( cvScale( output_array, output_array, 1./sqrt((double)input_array->cols*output_array->cols), 0 )); __END__; // 処理の終了.エピローグはこのマクロの後に書きます. // temp_array を解放します. // エラー発生前に temp_array が確保されていない場合, // cvReleaseMat が適切に処理を行います.今回のような場合は,特にに何もしません. cvReleaseMat( &temp_array ); } int main( int argc, char** argv ) { CvMat* src = cvCreateMat( 1, 512, CV_32F ); #if 1 /* エラーなし */ CvMat* dst = cvCreateMat( 1, 256, CV_32F ); #else CvMat* dst = 0; /* エラー処理のテスト用 */ #endif cvSet( src, cvRealScalar(1.), 0 ); #if 0 /* エラーハンドラを起動しないようにするためには 0 から 1 へ変更してください */ cvSetErrMode( CV_ErrModeSilent ); #endif cvResizeDCT( src, dst ); // エラーが発生した場合, // メッセージボックスがポップアップするか, // メッセージがログに書き込まれるか, // あるいはユーザー定義の処理が行われます. if( cvGetErrStatus() < 0 ) printf("Some error occured" ); else printf("Everything is OK" ); return 0; } .. .. index:: GetErrStatus .. _GetErrStatus: GetErrStatus ------------ `id=0.290365048843 Comments from the Wiki `__ .. cfunction:: int cvGetErrStatus( void ) 現在のエラー状態を返します. この関数は,現在のエラー状態,つまり直前の :ref:`SetErrStatus` 呼び出しによってセットされた値,を返します. ``Leaf`` モードでは,エラー発生後直ちにプログラムが終了するので,関数呼び出し後も常に制御可能にしておくためには, :ref:`SetErrMode` を呼び出して,エラーモードを ``Parent`` あるいは ``Silent`` にセットしておかなくてはいけません. .. index:: SetErrStatus .. _SetErrStatus: SetErrStatus ------------ `id=0.865756310784 Comments from the Wiki `__ .. cfunction:: void cvSetErrStatus( int status ) エラー状態をセットします. :param status: エラー状態. この関数は,指定された値をエラー状態としてセットします.大抵の場合,この関数は,エラー発生後の復帰時にエラー状態をリセットする( ``CV_StsOk`` をセットする)ために利用されます.その他の場合では, :ref:`Error` や ``CV_ERROR`` を呼び出すのが普通です. .. index:: GetErrMode .. _GetErrMode: GetErrMode ---------- `id=0.71283619918 Comments from the Wiki `__ .. cfunction:: int cvGetErrMode(void) 現在のエラーモードを返します. この関数は,現在のエラーモード,つまり直前の :ref:`SetErrMode` 呼び出しによってセットされた値を返します. .. index:: SetErrMode .. _SetErrMode: SetErrMode ---------- `id=0.0139636677411 Comments from the Wiki `__ .. code-block:: c .. .. cfunction:: int cvSetErrMode( int mode ) エラーモードをセットします. #define CV_ErrModeLeaf 0 #define CV_ErrModeParent 1 #define CV_ErrModeSilent 2 :param mode: エラーモード. この関数は,指定されたエラーモードをセットします.エラーモードの違いに関しては,このセクションの最初の説明を参照してください. .. index:: Error .. _Error: Error ----- `id=0.389399673104 Comments from the Wiki `__ .. cfunction:: int cvError( int status, const char* func_name, const char* err_msg, const char* filename, int line ) エラーを発生させます. :param status: エラー状態. :param func_name: エラーが発生した箇所の関数名. :param err_msg: エラーに関する追加情報/診断結果. :param filename: エラーが発生した箇所のファイル名. :param line: エラーが発生した行番号. この関数は,( :ref:`SetErrStatus` を介して)指定された値をエラー状態としてセットします.さらに,エラーモードが ``Silent`` でなければ,エラーハンドラを呼び出します. .. index:: ErrorStr .. _ErrorStr: ErrorStr -------- `id=0.7474411677 Comments from the Wiki `__ .. cfunction:: const char* cvErrorStr( int status ) エラー状態コードのテキスト情報を返します. :param status: エラー状態. この関数は,指定されたエラー状態コードに対するテキスト情報を返します.また,状態が不明な場合,この関数は NULL ポインタを返します. .. index:: RedirectError .. _RedirectError: RedirectError ------------- `id=0.262973325088 Comments from the Wiki `__ .. cfunction:: CvErrorCallback cvRedirectError( CvErrorCallback error_handler, void* userdata=NULL, void** prevUserdata=NULL ) 新たなエラーハンドラをセットします. :param error_handler: 新しいエラーハンドラ. :param userdata: エラーハンドラに引数としてそのまま渡される,任意のポインタ. :param prev_userdata: 事前に確保されているユーザデータへのポインタ. .. code-block:: c typedef int (CV_CDECL *CvErrorCallback)( int status, const char* func_name, const char* err_msg, const char* file_name, int line ); .. この関数は,標準ハンドラや,特定のインタフェースを持つカスタムハンドラを,新たなエラーハンドラとしてセットします.エラーハンドラは,関数 :ref:`Error` と同じ引数を持ちます.ハンドラが 0 ではない値を返した場合は,プログラムが終了し,それ以外の場合は実行され続けます.エラーハンドラは,このような戻り値を決定するために, :ref:`GetErrMode` を利用して現在のエラーモードを確認する場合があります. .. index:: cvNulDevReport cvStdErrReport cvGuiBoxReport .. _cvNulDevReport cvStdErrReport cvGuiBoxReport: cvNulDevReport cvStdErrReport cvGuiBoxReport -------------------------------------------- `id=0.0700207939979 Comments from the Wiki `__ .. cfunction:: int cvNulDevReport( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata ) .. cfunction:: int cvStdErrReport( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata ) .. cfunction:: int cvGuiBoxReport( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata ) 標準的なエラーハンドリングを提供します. :param status: エラー状態. :param func_name: エラーが発生した箇所の関数名. :param err_msg: エラーに関する追加情報/診断結果. :param filename: エラーが発生した箇所のファイル名. :param line: エラーが発生した行番号. :param userdata: ユーザデータへのポインタ.標準ハンドラでは無視されます. 関数 ``cvNullDevReport`` , ``cvStdErrReport`` , そして ``cvGuiBoxReport`` は,標準的なエラーハンドリングを提供します. ``cvGuiBoxReport`` は,Win32 システムではデフォルトのエラーハンドラで, ``cvStdErrReport`` は,その他のシステムでのデフォルトのエラーハンドラです. ``cvGuiBoxReport`` は,エラーの説明といくつかの選択肢を表示するメッセージボックスをポップアップします.以下は,前述のサンプル内で説明されているようにエラーを発生させた場合に,表示されるメッセージボックスの例です. **エラーメッセージボックス** .. image:: ../../pics/errmsg.png エラーハンドラとして ``cvStdErrReport`` がセットされている場合,上述のメッセージが標準エラー出力に表示され,現在のエラーモードに応じて,プログラムが終了,あるいは,継続動作します. **標準エラー出力に表示されるエラーメッセージ( ``Leaf`` モード)** .. code-block:: c OpenCV ERROR: Bad argument (input_array or output_array are not valid matrices) in function cvResizeDCT, D:UserVPProjectsavl_probaa.cpp(75) Terminating the application... .. .. index:: Alloc .. _Alloc: Alloc ----- `id=0.696595287691 Comments from the Wiki `__ .. cfunction:: void* cvAlloc( size_t size ) メモリバッファを確保します. :param size: バイト単位で表されるバッファサイズ. この関数は, ``size`` バイトの領域を確保し,その確保されたバッファへのポインタを返します.エラーが起こった場合は,この関数はエラーを報告し,NULL ポインタを返します.デフォルトでは, ``cvAlloc`` は ``icvAlloc`` を呼び出し,その中で ``malloc`` が呼ばれます.しかし,関数 :ref:`SetMemoryManager` を用いて,ここにユーザ定義のメモリ確保/解放関数を割り当てることも可能です. .. index:: Free .. _Free: Free ---- `id=0.917211630752 Comments from the Wiki `__ .. cfunction:: void cvFree( void** ptr ) メモリバッファを解放します. :param ptr: 解放されるバッファへのダブルポインタ. この関数は,関数 :ref:`Alloc` によって確保されたメモリバッファを解放します.ダブルポインタを利用するのは,関数終了時にバッファへのポインタをクリアするためです. ``*buffer`` が既にNULLの場合は,この関数は何もしません. .. index:: GetTickCount .. _GetTickCount: GetTickCount ------------ `id=0.931215977855 Comments from the Wiki `__ .. cfunction:: int64 cvGetTickCount( void ) tick数を返します. この関数は,プラットフォーム依存のイベント発生時点からの tick 数(起動時からの CPU tick数,1970年からのミリ秒単位の時間,など)を返します.これは,関数やユーザコードの実行時間を正確に計測する場合に役立ちます.tick数を時間単位に変換するには, :ref:`GetTickFrequency` を利用してください. .. index:: GetTickFrequency .. _GetTickFrequency: GetTickFrequency ---------------- `id=0.777425882609 Comments from the Wiki `__ .. cfunction:: double cvGetTickFrequency( void ) 1マイクロ秒毎のticks数を返します. この関数は,1マイクロ秒あたりのtick数を返します.したがって, :ref:`GetTickCount` を :ref:`GetTickFrequency` で割った値が,プラットフォーム依存のイベントからのマイクロ秒単位の経過時間になります. .. index:: RegisterModule .. _RegisterModule: RegisterModule -------------- `id=0.183308180275 Comments from the Wiki `__ .. code-block:: c .. .. cfunction:: int cvRegisterModule( const CvModuleInfo* moduleInfo ) 他のモジュールを登録します. typedef struct CvPluginFuncInfo { void** func_addr; void* default_func_addr; const char* func_names; int search_modules; int loaded_from; } CvPluginFuncInfo; typedef struct CvModuleInfo { struct CvModuleInfo* next; const char* name; const char* version; CvPluginFuncInfo* func_tab; } CvModuleInfo; :param moduleInfo: モジュールに関する情報. この関数は,登録モジュールリストに新しいモジュールを追加します.登録されたモジュールに関する情報は,関数 :ref:`GetModuleInfo` を使って取得できます.また,この登録されたモジュールも,CXCOREでサポートされる最適化プラグイン(IPP, MKL, ...)をフルに活用します.CXCORE自身や,CV(コンピュータビジョン),CVAUX(補助的コンピュータビジョン),HIGHGUI(可視化,画像/動画の取得)は,モジュールの一例です.登録は通常,共有ライブラリがロードされる際に行われます.登録方法の詳細については, ``cxcore/src/cxswitcher.cpp`` および ``cv/src/cvswitcher.cpp`` を参照してください.また,IPPやMKLがどのようにモジュールとリンクされるかについては, ``cxcore/src/cxswitcher.cpp`` および ``cxcore/src/_cxipp.h`` を参照してください. .. index:: GetModuleInfo .. _GetModuleInfo: GetModuleInfo ------------- `id=0.626743581372 Comments from the Wiki `__ .. cfunction:: void cvGetModuleInfo( const char* moduleName, const char** version, const char** loadedAddonPlugins) 登録されたモジュールおよびプラグインに関する情報を取得します. :param moduleName: 情報を取得するモジュールの名前.すべてのモジュールを指定する場合はNULL を指定します. :param version: 出力パラメータ.バージョン情報を含む,モジュールに関する情報です. :param loadedAddonPlugins: CXCOREが検出・ロード可能な,最適化プラグインの名前とバージョンのリスト. この関数は,登録されたモジュールの1つ,あるいは全てに関する情報を返します.取得した情報はライブラリ内部に保存されるので,ユーザは,返された文字列を解放したり変更したりするべきではありません. .. index:: UseOptimized .. _UseOptimized: UseOptimized ------------ `id=0.152336493672 Comments from the Wiki `__ .. cfunction:: int cvUseOptimized( int onoff ) 最適化/非最適化モードを切り替えます. :param onoff: 最適化 ( :math:`\ne 0` ) ,非最適化 ( :math:`=0` ). この関数は,cxcore,OpenCV などを純粋なC言語で実装したものだけを利用するモードと,可能な部分はIPPやMKLの関数を用いて最適化したものを利用するモードとを切り替えます. ``cvUseOptimized(0)`` が呼ばれると,すべての最適化ライブラリがアンロードされます.この関数は,デバッグ時,IPPやMKLをプログラム実行時にアップグレードする場合,実行時に速度比較を行う場合,などに役立ちます.戻り値として,ロードされた最適化関数の数が返されます.デフォルトでは最適化プラグインがロードされるので,プログラムの先頭で ``cvUseOptimized(1)`` を呼ぶ必要はないことに注意してください(実際,開始時の処理時間が長くなってしまうだけです). .. index:: SetMemoryManager .. _SetMemoryManager: SetMemoryManager ---------------- `id=0.321603922895 Comments from the Wiki `__ .. code-block:: c .. .. cfunction:: void cvSetMemoryManager( CvAllocFunc allocFunc=NULL, CvFreeFunc freeFunc=NULL, void* userdata=NULL ) カスタム/デフォルトメモリ管理関数にアクセスします. typedef void* (CV_CDECL *CvAllocFunc)(size_t size, void* userdata); typedef int (CV_CDECL *CvFreeFunc)(void* pptr, void* userdata); :param allocFunc: メモリ割り当て関数.そのインタフェースは,コンテクストを決定するためなどに使用される ``userdata`` を除けば, ``malloc`` と同様です. :param freeFunc: メモリ解放関数.そのインタフェースは, ``free`` と同様です. :param userdata: カスタム関数に引数としてそのまま渡されるユーザデータ. この関数は, ``cvAlloc`` , ``cvFree`` や高レベル関数(例えば, ``cvCreateImage`` )によって呼び出されるユーザ定義のメモリ管理関数( ``malloc`` と ``free`` の代替)をセットします. ``cvAlloc`` によってデータを割り当てる場合は,その関数が呼ばれることに注意してください.また,再帰呼び出しの無限ループを避けるために,カスタムメモリ割り当て/解放関数から ``cvAlloc`` と ``cvFree`` を呼び出していはいけません. もし, ``alloc_func`` と ``free_func`` のポインタがNULLの場合,デフォルトのメモリ管理関数が復元されます. .. index:: SetIPLAllocators .. _SetIPLAllocators: SetIPLAllocators ---------------- `id=0.0833117387198 Comments from the Wiki `__ .. code-block:: c \ \ .. .. cfunction:: void cvSetIPLAllocators( Cv_iplCreateImageHeader create_header, Cv_iplAllocateImageData allocate_data, Cv_iplDeallocate deallocate, Cv_iplCreateROI create_roi, Cv_iplCloneImage clone_image ) 画像領域の確保/解放にIPLの関数を利用する・しない,の切り替えを行います. typedef IplImage* (CV_STDCALL* Cv_iplCreateImageHeader) (int,int,int,char*,char*,int,int,int,int,int, IplROI*,IplImage*,void*,IplTileInfo*); typedef void (CV_STDCALL* Cv_iplAllocateImageData)(IplImage*,int,int); typedef void (CV_STDCALL* Cv_iplDeallocate)(IplImage*,int); typedef IplROI* (CV_STDCALL* Cv_iplCreateROI)(int,int,int,int,int); typedef IplImage* (CV_STDCALL* Cv_iplCloneImage)(const IplImage*); #define CV_TURN_ON_IPL_COMPATIBILITY() cvSetIPLAllocators( iplCreateImageHeader, iplAllocateImage, iplDeallocate, iplCreateROI, iplCloneImage ) :param create_header: iplCreateImageHeader へのポインタ. :param allocate_data: iplAllocateImage へのポインタ. :param deallocate: iplDeallocate へのポインタ. :param create_roi: iplCreateROI へのポインタ. :param clone_image: iplCloneImage へのポインタ. この関数は,CXCORE の画像領域の割り当て処理および解放処理に関して,IPLの関数を利用するようにします.利便性のために,ラッパーマクロ ``CV_TURN_ON_IPL_COMPATIBILITY`` が存在します.この関数は,IPLとCXCORE/OpenCVが一緒に利用されるアプリケーションや,まだ ``iplCreateImageHeader`` などの呼び出しを行っているアプリケーションでは便利です.IPLの関数がデータ処理のみに対して呼び出され,すべてのメモリ割り当て/解放が CXCORE によって行われる場合,あるいは逆に,すべてのメモリ割り当て/解放が IPL で行われ,OpenCVの関数がデータの処理に利用される場合は,この関数は不要です.