OpenCV のエラーハンドリングは,IPL(Image Processing Library)の場合と似ています.エラーが発生した場合でも,関数はエラーコードを返しません.その代わりに, Error を呼び出すマクロ CV_ERROR を用いてエラーを発生させます.その中で, SetErrStatus によりエラー状態をセットし,標準あるいはユーザ定義のエラーハンドラ(メッセージボックスを表示したり,ログを書き出したりできます.詳しくは, RedirectError を参照してください)を呼び出します.1スレッドに1つ,現在のエラー状態(整数値)を保存するグローバル変数が存在します.このエラー状態は,関数 GetErrStatus によって取得できます.
エラーハンドリングには3つのモードが存在します( SetErrMode および GetErrMode を参照してください):
実際は, Leaf モードと Parent モードの動作は,エラーハンドラによって実装され,これらは上述の説明通りの挙動を示します.しかし GuiBoxReport の場合は多少挙動が異なり,全く異なる動作を実装するカスタムエラーハンドラも存在します.
エラーの発生やチェックなどを行うマクロ.
/* 関数内の処理文を挟むことで,それらをプロローグ(リソースの初期化)と
エピローグ(確保されたリソースの解放)から分離する特別なマクロ */
#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の関数とその使用方法を以下に示します.
#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__; // 処理の終了.エピローグはこのマクロの後に書きます.
// 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;
}
現在のエラー状態を返します.
この関数は,現在のエラー状態,つまり直前の SetErrStatus 呼び出しによってセットされた値,を返します. Leaf モードでは,エラー発生後直ちにプログラムが終了するので,関数呼び出し後も常に制御可能にしておくためには, SetErrMode を呼び出して,エラーモードを Parent あるいは Silent にセットしておかなくてはいけません.
エラー状態をセットします.
パラメタ: |
|
---|
この関数は,指定された値をエラー状態としてセットします.大抵の場合,この関数は,エラー発生後の復帰時にエラー状態をリセットする( CV_StsOk をセットする)ために利用されます.その他の場合では, Error や CV_ERROR を呼び出すのが普通です.
現在のエラーモードを返します.
この関数は,現在のエラーモード,つまり直前の SetErrMode 呼び出しによってセットされた値を返します.
エラーモードをセットします.
#define CV_ErrModeLeaf 0 #define CV_ErrModeParent 1 #define CV_ErrModeSilent 2
param mode: エラーモード.
この関数は,指定されたエラーモードをセットします.エラーモードの違いに関しては,このセクションの最初の説明を参照してください.
エラーを発生させます.
パラメタ: |
|
---|
この関数は,( SetErrStatus を介して)指定された値をエラー状態としてセットします.さらに,エラーモードが Silent でなければ,エラーハンドラを呼び出します.
エラー状態コードのテキスト情報を返します.
パラメタ: |
|
---|
この関数は,指定されたエラー状態コードに対するテキスト情報を返します.また,状態が不明な場合,この関数は NULL ポインタを返します.
新たなエラーハンドラをセットします.
パラメタ: |
|
---|
typedef int (CV_CDECL *CvErrorCallback)( int status, const char* func_name,
const char* err_msg, const char* file_name, int line );
この関数は,標準ハンドラや,特定のインタフェースを持つカスタムハンドラを,新たなエラーハンドラとしてセットします.エラーハンドラは,関数 Error と同じ引数を持ちます.ハンドラが 0 ではない値を返した場合は,プログラムが終了し,それ以外の場合は実行され続けます.エラーハンドラは,このような戻り値を決定するために, GetErrMode を利用して現在のエラーモードを確認する場合があります.
標準的なエラーハンドリングを提供します.
パラメタ: |
|
---|
関数 cvNullDevReport , cvStdErrReport , そして cvGuiBoxReport は,標準的なエラーハンドリングを提供します. cvGuiBoxReport は,Win32 システムではデフォルトのエラーハンドラで, cvStdErrReport は,その他のシステムでのデフォルトのエラーハンドラです. cvGuiBoxReport は,エラーの説明といくつかの選択肢を表示するメッセージボックスをポップアップします.以下は,前述のサンプル内で説明されているようにエラーを発生させた場合に,表示されるメッセージボックスの例です.
エラーメッセージボックス
エラーハンドラとして cvStdErrReport がセットされている場合,上述のメッセージが標準エラー出力に表示され,現在のエラーモードに応じて,プログラムが終了,あるいは,継続動作します.
標準エラー出力に表示されるエラーメッセージ( ``Leaf`` モード)
OpenCV ERROR: Bad argument (input_array or output_array are not valid matrices)
in function cvResizeDCT, D:UserVPProjectsavl_probaa.cpp(75)
Terminating the application...
メモリバッファを確保します.
パラメタ: |
|
---|
この関数は, size バイトの領域を確保し,その確保されたバッファへのポインタを返します.エラーが起こった場合は,この関数はエラーを報告し,NULL ポインタを返します.デフォルトでは, cvAlloc は icvAlloc を呼び出し,その中で malloc が呼ばれます.しかし,関数 SetMemoryManager を用いて,ここにユーザ定義のメモリ確保/解放関数を割り当てることも可能です.
メモリバッファを解放します.
パラメタ: |
|
---|
この関数は,関数 Alloc によって確保されたメモリバッファを解放します.ダブルポインタを利用するのは,関数終了時にバッファへのポインタをクリアするためです. *buffer が既にNULLの場合は,この関数は何もしません.
tick数を返します.
この関数は,プラットフォーム依存のイベント発生時点からの tick 数(起動時からの CPU tick数,1970年からのミリ秒単位の時間,など)を返します.これは,関数やユーザコードの実行時間を正確に計測する場合に役立ちます.tick数を時間単位に変換するには, GetTickFrequency を利用してください.
1マイクロ秒毎のticks数を返します.
この関数は,1マイクロ秒あたりのtick数を返します.したがって, GetTickCount を GetTickFrequency で割った値が,プラットフォーム依存のイベントからのマイクロ秒単位の経過時間になります.
他のモジュールを登録します.
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: モジュールに関する情報.
この関数は,登録モジュールリストに新しいモジュールを追加します.登録されたモジュールに関する情報は,関数 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 を参照してください.
登録されたモジュールおよびプラグインに関する情報を取得します.
パラメタ: |
|
---|
この関数は,登録されたモジュールの1つ,あるいは全てに関する情報を返します.取得した情報はライブラリ内部に保存されるので,ユーザは,返された文字列を解放したり変更したりするべきではありません.
最適化/非最適化モードを切り替えます.
パラメタ: |
|
---|
この関数は,cxcore,OpenCV などを純粋なC言語で実装したものだけを利用するモードと,可能な部分はIPPやMKLの関数を用いて最適化したものを利用するモードとを切り替えます. cvUseOptimized(0) が呼ばれると,すべての最適化ライブラリがアンロードされます.この関数は,デバッグ時,IPPやMKLをプログラム実行時にアップグレードする場合,実行時に速度比較を行う場合,などに役立ちます.戻り値として,ロードされた最適化関数の数が返されます.デフォルトでは最適化プラグインがロードされるので,プログラムの先頭で cvUseOptimized(1) を呼ぶ必要はないことに注意してください(実際,開始時の処理時間が長くなってしまうだけです).
カスタム/デフォルトメモリ管理関数にアクセスします.
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の場合,デフォルトのメモリ管理関数が復元されます.
\
\
画像領域の確保/解放にIPLの関数を利用する・しない,の切り替えを行います.
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の関数がデータの処理に利用される場合は,この関数は不要です.