LoginSignup
30
29

More than 5 years have passed since last update.

OpenCVのエラーコード,エラーメッセージ表示機能,例外処理機能

Last updated at Posted at 2015-12-02

この記事はOpenCV Advent Calendar 2015の3日目の記事です.

はじめに

OpenCVは,エラー内容に応じたエラーコードを定義しているだけでなく,エラーメッセージ表示機能,例外処理機能を提供しています.

この記事では,

  • OpenCVで定義されるエラーコードの意味を理解することで「開発者がエラーメッセージからソースコードのどの箇所でどのような問題が起きているかを把握できるようになる」

だけでなく,

  • OpenCVが提供するエラーメッセージ表示機能,例外処理機能の使い方を理解することで「開発者が適切なエラーメッセージを表示したり,例外処理の実装を行えるようにする」

ことを目的としています.

エラーコード一覧表

以下の表にOpenCVが定義するエラーコードとその意味をまとめています.
ソースコード上ではcore/include/opencv2/core/base.hppで定義されているため,興味のある方は読んでみるとよいでしょう.

エラーコード 意味
StsOk0 正常
StsBackTrace BackTraceのための疑似的なエラー
StsError 不明なエラー
StsInternal 内部エラー
StsNoMem メモリ不足
StsBadArg 不正な引数/パラメータ
StsBadFunc 非サポートの関数/機能
StsNoConv 収束しない場合のエラー
StsAutoTrace AutoTraceの呼び出し
HeaderIsNull イメージヘッダーがNULL
BadImageSize 不正なイメージサイズ
BadOffset 不正なオフセット値
BadDataPtr 不正なDataPtr
BadStep 不正なステップ値
BadModelOrChSeq 不正なモデル/シーケンス
BadNumChannels 無効なチャンネル数
BadNumChannel1U 無効なチャンネル数
(1U:1チャンネル符号なし)
BadDepth 不正なdepth値
BadAlphaChannel 無効なアルファチャンネル
BadOrder 不正なOrder指定
BadOrigin 不正なOrigin指定
BadAlign 不正なアライメント
BadCallBack 不正なコールバック
BadTileSize 不正なタイルサイズ
BadCOI 不正なCOI(Channel of Interest)指定
BadROISize 不正なROI(Region of Interest)指定
MaskIsTiled マスクがタイル配列
StsNullPtr ヌルポインタが渡ってくるべきでない
箇所でヌルポインタが渡された
StsVecLengthErr vector配列の長さが適切でない
StsFilterStructContentErr 不正なフィルター構造
StsKernelStructContentErr 不正なカーネル構造
StsFilterOffsetErr 不正なフィルターのオフセット値
StsBadSize 不正なサイズ
StsDivByZero ゼロ除算の発生
StsInplaceNotSupported in-place操作が非サポート
StsObjectNotFound オブジェクトが見付からない
StsUnmatchedFormats アンマッチなフォーマット指定
StsBadFlag 不正なフラグ指定
StsBadPoint 不正な座標値指定
StsBadMask 不正なマスク
StsUnmatchedSizes アンマッチなサイズ指定
StsUnsupportedFormat 非サポートのフォーマット指定
StsOutOfRange パラメータが範囲外の値
StsParseError パースエラー
StsNotImplemented 未実装の関数/機能
StsBadMemBlock メモリブロック破壊
StsAssert アサーションエラー
GpuNotSupported CUDA機能を無効にしたOpenCVライブラリで
CUDA機能を使用した場合のエラー
GpuApiCallError CUDA API呼び出し時のエラー
OpenGlNotSupported OpenGL機能を無効にしたOpenCVライブラリで
OpenGL機能を使用した場合のエラー
OpenGlApiCallError OpenGL API呼び出し時のエラー
OpenCLApiCallError OpenCL API呼び出し時のエラー
OpenCLDoubleNotSupported OpenCLデバイスが倍精度浮動小数点数
(double型)を非サポート
OpenCLInitError OpenCL初期化時のエラー
OpenCLNoAMDBlasFft OpenCL AMD BLAS機能が利用できない

エラーメッセージ表示

CV_Errorマクロを使う方法

OpenCVで提供されるCV_Errorマクロを用いることでエラーメッセージ表示を容易に記述することができます.このマクロの第一引数はエラーコード,第二引数はエラーメッセージの文字列です。
詳細は公式ドキュメントを参照ください.

以下にCV_Errorマクロの使用例を記述します.

CV_Error(cv::Error::BadNumChannels, "Unsupported channels count");

この例ではエラーコードとしてBadNumChannelsを指定しており,以下のようなエラーメッセージが表示されます.
OpenCV Error: Bad number of channels (Unsupported channels count) in hoge, file fuga.cpp, line 12

このエラーメッセージは以下のような意味を表しています.

メッセージ 意味
Bad number of channels エラーコードに対応した文字列.
この例ではBadNumChannelsに対応した文字列.
(Unsupported channels count) CV_Errorマクロの第二引数に指定した文字列
in hoge エラー発生関数.
この例ではhoge関数内でエラーが発生したことを表す.
file fuga.cpp, line 12 エラー発生したファイル名と行番号.
この例ではfuga.cppの12行目でエラーが発生したことを表す.

また,Bad number of channelsという文字列はBadNumChannelsというエラーコードに対応した文字列です.他のエラーコードにも同様に各エラーコードに対応した文字列が用意されています.ソースコード上ではmodules/core/src/system.cppのcvErrorStr関数で定義されているため,興味のある方は読んでみるとよいでしょう.

CV_Error_マクロ

CV_Errorマクロではあらかじめ決まった書式でエラーメッセージの表示が行われます.
書式指定を用いたエラーメッセージを出力を行いたい場合はCV_Error_マクロにより実現できます.

CV_Assertマクロを使う方法

CV_Assertマクロを用いることで指定した条件式を満たさない場合にエラーメッセージを表示させることができます.詳細は公式ドキュメントを参照ください.

以下にCV_Assertマクロの使用例を記述します.

int i = -1;
CV_Assert(i >= 0);

この例ではCV_Assert呼び出し時にi >= 0という条件を満たさないので
CV_Assertマクロ内でcv::error関数が呼ばれ,以下のようなエラーメッセージが表示されます.

OpenCV Error: Assertion failed (i >= 0) in hoge, file fuga.cpp, line 8

このエラーメッセージは以下のような意味を表しています.

メッセージ 意味
Assertion failed エラーコードに対応した文字列.
この例ではアサーションエラー発生(StsAssert)に対応した文字列.
(i >= 0) エラーとなった理由.
この例では(i >= 0)という条件式を満たしていないため.
in hoge エラー発生関数.
この例ではhoge関数内でエラーが発生したことを表す.
file fuga.cpp, line 8 エラー発生したファイル名と行番号.
この例ではfuga.cppの8行目でエラーが発生したことを表す.

CV_Assertマクロを使う方法の注意点

CV_Errorマクロを使ったエラーメッセージ表示では開発者がエラーコードを指定することができますが,CV_Assertマクロでは内部的にエラーコードがcv::Error::StsAssertとなります.
(アサーションが発生するので当然と言えば当然ですが)

例外処理

OpenCVで提供されるcv::Exceptionを用いることで例外処理を容易に記述することができます.
この関数の第一引数はエラーコード,第二引数はエラーメッセージの文字列,
第三引数は関数名,第四引数はファイル名,第五引数は行数です.詳細は公式ドキュメントを参照ください.

サンプルコード

サンプルコード(CV_Errorマクロ)

CV_Errorマクロに対してエラー内容に応じたエラーコードを指定し,
エラーメッセージ表示を行うサンプルコードです.

error_test.cpp
#include <opencv2/core.hpp> // coreモジュールにて定義
#include <iostream>

// 1チャンネルの画像しか受け付けない関数
void testFunc(cv::InputArray src_)
{
    cv::Mat src = src_.getMat();

    // 入力画像のチャンネル数が1以外の場合にエラーとする
    // ここではエラーコードとしてcv::Error::BadNumChannelsを指定
    if (src.channels() != 1)
        CV_Error(cv::Error::BadNumChannels, "Unsupported channels count");
}

int main(int argc, const char* argv[])
{
    // 3チャンネルの画像データを生成する
    cv::Mat img(cv::Size(512, 512), CV_8UC3, cv::Scalar(0, 0, 255));

    // testFunc関数を実行する
    testFunc(img);

    return 0;
}

このサンプルでは,1チャンネルの画像しか受け付けないtestFunc関数に対して
3チャンネルの画像を入力(=無効なチャンネル数を指定)した例のため,
CV_Errorマクロの第一引数(エラーコード)にcv::Error::BadNumChannelsを指定しています.

また,このサンプルを実行すると以下のようなエラーメッセージが表示されます.
このとき,エラーメッセージにはエラー内容だけでなくエラーが起きた関数名,ファイル名,行番号も表示されます.

OpenCV Error: Bad number of channels (Unsupported channels count) in testFunc, file error_test.cpp, line 12

サンプルコード(cv::Exception)

cv::Exceptionにエラーコード,エラーメッセージ,関数名,ファイル名,行番号を指定し,
例外をキャッチした際にエラーメッセージ表示を行うサンプルコードです.

exception_test.cpp
#include <opencv2/core.hpp> // coreモジュールにて定義
#include <iostream>

// 常にExceptionを投げる関数
void testFunc2(void)
{
    // エラーコード,エラーメッセージ,関数名,
    // ファイル名,行番号を指定してExceptionを投げる
    throw cv::Exception(cv::Error::StsError,
        "Unspecified error", CV_Func, __FILE__, __LINE__);
}

int main(int argc, const char* argv[])
{
    try
    {
        // testFunc2関数を実行する
        testFunc2();
    }
    catch (cv::Exception& e)
    {
        // 例外をキャッチしたらエラーメッセージを表示
        std::cerr << e.what() << std::endl;
        return -1;
    }

    return 0;
}

このサンプルを実行すると以下のようなエラーメッセージが表示されます.
このとき,エラーメッセージにはcv::Exceptionに指定したエラーメッセージ,
関数名,ファイル名,行番号が表示されます.

exception_test.cpp:10: error: (-2) Unspecified error in function testFunc2

おわりに

  • OpenCVが定義するエラーコード,エラーメッセージの意味を理解してデバッグに活用しましょう
  • OpenCVが提供するCV_Errorマクロ,cv::Exceptionを活用して適切なエラー処理,例外処理を実装しましょう

備考

筆者は以下の環境で動作確認しました.

  • OpenCV 3.0.0
  • Windows 8.1 Pro(64bit)
  • Visual Studio 2013 Update5
30
29
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
29