CXCORE リファレンス マニュアル
- 基本構造体(Basic Structures)
- 配列操作(Operations on Arrays)
- 動的構造体(Dynamic Structures)
- 描画関数(Drawing Functions)
- データ永続性と実行時型情報(Data Persistence and RTTI)
- その他の関数(Miscellaneous Functions)
- エラーハンドリングとシステム関数(Error Handling and System Functions)
- エラーハンドリング(Error Handling)
- システム関数(System Functions)
エラーハンドリングとシステム関数(Error Handling and System Functions)
エラーハンドリング(Error Handling)
OpenCV におけるエラーハンドリングは,IPL(Image Processing Library)と似ている. エラーが発生した場合でも,関数はエラーコードを返さない. その代わり,エラーステータスをcvSetErrStatusを用いてセットし, 標準またはユーザ定義のエラーハンドラ(メッセージボックスの表示や,ログに書き込む,など. cvRedirectError, cvNulDevReport, cvStdErrReport, cvGuiBoxReportを参照) を呼び出す関数cvErrorを呼ぶマクロCV_ERROR を用いてエラーの通知を行う. 各プログラムスレッドについて,それぞれ一つずつ,現在のエラーステータス(一つの整数値)を持つグローバル変数が存在する. このエラーステータスは,関数 cvGetErrStatus を用いて取り出すことが可能である.
エラーハンドリングには,以下の三つのモードが存在する(cvSetErrMode と cvGetErrMode を参照).
- Leaf
- プログラムはエラーハンドラを呼び出した後,途中終了する.デフォルト.エラー発生後,直ちに通知されるので,デバッグ時に有効. しかし,製品(完成版の)システムでは,他の二つのモードの使用が制御しやすいので好ましい.
- Parent
- プログラムは途中終了しないが,エラーハンドラが呼び出される.スタックは巻き戻されない(C++の例外処理を用いないため). ユーザはCxCoreの関数cvGetErrStatusを呼び出し,エラーコードをチェックし,対処を行わなければならない.
- Silent
- Parentモードとほぼ同じだが,エラーハンドラは呼び出されない.
実際は,モードLeaf と Parent の動作はエラーハンドラによって実装される. 上記の説明はcvNulDevReport, cvStdErrReport に関しては正しい. cvGuiBoxReport は多少異なった動作をし,さらに, カスタマイズされたエラーハンドラは,全く違う動作の実装になる可能性がある.
ERROR Handling Macros
エラー表示やチェックなどの機能をもつマクロ群
/* 関数内の処理ステートメントを挟み,それらをプロローグ(リソースの初期化部)とエピローグ (確保されたリソースの解放部)から分離する特別なマクロ */ #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 ) ¥ { ¥ cvError( (Code), cvFuncName, Msg, __FILE__, __LINE__ ); ¥ EXIT; ¥ } /* CXCOREの関数呼び出しの後の状態をチェックする */ #define CV_CHECK() ¥ { ¥ if( cvGetErrStatus() < 0 ) ¥ CV_ERROR( CV_StsBackTrace, "Inner function failed." ); ¥ } /* CXCOREの関数呼び出しとCV_CHECK()呼び出しの簡略表現 */ #define CV_CALL( Statement ) ¥ { ¥ Statement; ¥ CV_CHECK(); ¥ } /* デバッグモードとリリースモード両方に対応した状態チェック */ #define CV_ASSERT( Condition ) ¥ { ¥ if( !(Condition) ) ¥ CV_ERROR( CV_StsInternal, "Assertion: " #Condition " failed" ); ¥ } /* これらのマクロは,それぞれ対応するマクロCV_... と似ているが, 終了ラベルも定義用の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の関数とその使用方法を示す.
エラーハンドリングマクロの使用方法
#include "cxcore.h" #include <stdio.h> 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__; // 処理の終了.エピローグはkのマクロの後に書く. // temp_array を解放する.エラーが発生する前に temp_array の領域確保が終わっていない場合, // cvRleaseMatが処理を行う.今回のような場合は,なにもしない. 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 occurred" ); else printf("Everything is OK" ); return 0; }
GetErrStatus
現在のエラーステータスを返す
int cvGetErrStatus( void );
関数 cvGetErrStatus は,現在のエラーステータスを返す. そのステータス値は,直前の関数cvSetErrStatus呼び出しによってセットされる. Leafモードの場合は,エラー発生後,直ちにプログラムが途中終了するので,関数呼出し後も常に制御可能にしておくためには, cvSetErrModeでエラーモードをParent か Silentにセットしておくべきであることに注意する.
SetErrStatus
エラーステータスをセットする
void cvSetErrStatus( int status );
- status
- エラーステータス.
関数 cvSetErrStatus は,エラーステータスを指定された値にセットする. ほとんどの場合,この関数はエラー処理を行った後にエラーステータスをリセットする(CV_StsOkをセットする)ために用いられる. その他の場合は,cvError あるいは CV_ERROR を呼び出すのが一般的である.
GetErrMode
現在のエラーモードを返す
int cvGetErrMode( void );
関数cvGetErrMode は,現在のエラーモードを返す. モード値は,直前の関数 cvSetErrMode 呼び出しによってセットされる.
SetErrMode
エラーモードをセットする
#define CV_ErrModeLeaf 0
#define CV_ErrModeParent 1
#define CV_ErrModeSilent 2
int cvSetErrMode( int mode );
- mode
- エラーモード.
関数 cvSetErrMode は,指定されたエラーモードをセットする. エラーモードの違いに関しては,このセクションの初めの部分を参照.
Error
エラーを発生させる
int cvError( int status, const char* func_name,
const char* err_msg, const char* file_name, int line );
- status
- エラーステータス.
- func_name
- エラーが発生した関数名.
- err_msg
- エラーについての追加情報/診断結果.
- file_name
- エラーが発生したファイル名.
- line
- エラーが発生した行番号.
関数 cvError は,(cvSetErrStatusを用いて) エラーステータスを指定の値にセットする.さらにエラーモードがSilent以外の場合は,エラーハンドラを呼び出す.
ErrorStr
エラーステータスのコードのテキスト情報を返す
const char* cvErrorStr( int status );
- status
- エラーステータス.
関数 cvErrorStr は,指定したエラーステータスコードのテキスト記述を返す. 不明なステータスの場合はNULLポインタを返す.
RedirectError
新しいエラーハンドラをセットする
typedef int (CV_CDECL *CvErrorCallback)( int status, const char* func_name,
const char* err_msg, const char* file_name, int line );
CvErrorCallback cvRedirectError( CvErrorCallback error_handler,
void* userdata=NULL, void** prev_userdata=NULL );
- error_handler
- 新しいエラーハンドラ.
- userdata
- エラーハンドラへの引数として渡される任意のポインタ.
- prev_userdata
- あらかじめ割り当てられているユーザデータへのポインタのポインタ.
関数 cvRedirectError は,standard handlersの中の一つか, 特定のインタフェースを持つ独自のハンドラを新しいエラーハンドラにセットする. エラーハンドラは,関数cvErrorと同じパラメータを持つ. ハンドラが0以外の値を返した場合,プログラムは途中終了し,それ以外の場合は実行し続ける. エラーハンドラは,このような動作を決めるためにcvGetErrModeで現在のエラーモードを確認している.
cvNulDevReport cvStdErrReport cvGuiBoxReport
標準のエラーハンドリングを提供する
int cvNulDevReport( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata ); int cvStdErrReport( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata ); int cvGuiBoxReport( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata );
- status
- エラーステータス.
- func_name
- エラーが発生した関数名.
- err_msg
- エラーについての追加情報/診断結果.
- file_name
- エラーが発生したファイル名.
- line
- エラーが発生した行番号.
- userdata
- ユーザーデータへのポインタ.標準ハンドラでは無視される.
関数 cvNullDevReport, cvStdErrReport と cvGuiBoxReportは標準のエラーハンドリングを提供する. Win32でのデフォルトエラーハンドラはcvGuiBoxReportであり,他のシステムではcvStdErrReportとなる. cvGuiBoxReportはエラーメッセージを表示するメッセージボックスをポップアップさせ,さらにいくつかのオプションを提供する. 前述のsample codeでのメッセージボックスを用いたエラー処理の例を以下に示す.
エラーメッセージボックス
エラーハンドラがcvStdErrReportにセットされている場合,前述のメッセージが標準エラー出力に出力され, その後プログラムはエラーモードに従って途中終了するか実行を継続する.
標準エラー出力へのエラーメッセージ出力(Leaf モード)
OpenCV ERROR: Bad argument (input_array or output_array are not valid matrices) in function cvResizeDCT, D:¥User¥VP¥Projects¥avl_proba¥a.cpp(75) Terminating the application...