About BBS

CXCORE リファレンス マニュアル

最終変更者: 怡土順一, 最終変更リビジョン: 389, 最終変更日時: 2008-07-26 00:14:21 +0900 (土, 26 7月 2008)


基本構造体(Basic Structures)


CvPoint

整数座標系による2次元の点

    typedef struct CvPoint
    {
        int x; /* x 座標.通常は0が原点 */
        int y; /* y 座標.通常は0が原点 */
    }
    CvPoint;

    /* コンストラクタ */
    inline CvPoint cvPoint( int x, int y );

    /* CvPoint2D32f からの変換 */
    inline CvPoint cvPointFrom32f( CvPoint2D32f point );

CvPoint2D32f

浮動小数点型(単精度)座標系による2次元の点

    typedef struct CvPoint2D32f
    {
        float x; /* x 座標.通常は0が原点 */
        float y; /* y 座標.通常は0が原点 */
    }
    CvPoint2D32f;

    /* コンストラクタ */
    inline CvPoint2D32f cvPoint2D32f( double x, double y );

    /* CvPoint からの変換 */
    inline CvPoint2D32f cvPointTo32f( CvPoint point );

CvPoint3D32f

浮動小数点型(単精度)座標系による3次元の点

    typedef struct CvPoint3D32f
    {
        float x; /* x 座標.通常は0が原点 */
        float y; /* y 座標.通常は0が原点 */
        float z; /* z 座標.通常は0が原点 */
    }
    CvPoint3D32f;

    /* コンストラクタ */
    inline CvPoint3D32f cvPoint3D32f( double x, double y, double z );

CvPoint2D64f

浮動小数点型(倍精度)座標系による2次元の点

    typedef struct CvPoint2D64f
    {
        double x; /* x 座標.通常は0が原点 */
        double y; /* y 座標.通常は0が原点 */
    }
    CvPoint2D64f;

    /* コンストラクタ */
    inline CvPoint2D64f cvPoint2D64f( double x, double y );

    /* CvPoint からの変換 */
    inline CvPoint2D64f cvPointTo64f( CvPoint point );

CvPoint3D64f

浮動小数点型(倍精度)座標系による3次元の点

    typedef struct CvPoint3D64f
    {
        double x; /* x 座標.通常は0が原点 */
        double y; /* y 座標.通常は0が原点 */
        double z; /* z 座標.通常は0が原点 */
    }
    CvPoint3D64f;

    /* コンストラクタ */
    inline CvPoint3D64f cvPoint3D64f( double x, double y, double z );

CvSize

矩形のピクセル精度でのサイズ

    typedef struct CvSize
    {
        int width; /* 矩形の幅 */
        int height; /* 矩形の高さ */
    }
    CvSize;

    /* コンストラクタ */
    inline CvSize cvSize( int width, int height );

CvSize2D32f

矩形のサブピクセル精度でのサイズ

    typedef struct CvSize2D32f
    {
        float width; /* 矩形の幅 */
        float height; /* 矩形の高さ */
    }
    CvSize2D32f;

    /* コンストラクタ */
    inline CvSize2D32f cvSize2D32f( double width, double height );

CvRect

矩形のオフセットとサイズ

    typedef struct CvRect
    {
        int x; /* 矩形の左角の x 座標 */
        int y; /* 矩形の上角(あるいは下角)の y 座標 */
        int width; /* 矩形の幅 */
        int height; /* 矩形の高さ */
    }
    CvRect;

    /* コンストラクタ */
    inline CvRect cvRect( int x, int y, int width, int height );

CvScalar

4個までの数を納めるコンテナ

    typedef struct CvScalar
    {
        double val[4];
    }
    CvScalar;

    /* コンストラクタ:val[0] を val0 で初期化.val[1] を val1 で初期化.… */
    inline CvScalar cvScalar( double val0, double val1=0,
                              double val2=0, double val3=0 );
    /* コンストラクタ:val[0]...val[3] を val0123 で初期化 */
    inline CvScalar cvScalarAll( double val0123 );

    /* コンストラクタ:val[0] を val0 で初期化.val[1]...val[3] を 0 で初期化 */
    inline CvScalar cvRealScalar( double val0 );

CvTermCriteria

反復アルゴリズムのための終了条件

#define CV_TERMCRIT_ITER    1
#define CV_TERMCRIT_NUMBER  CV_TERMCRIT_ITER
#define CV_TERMCRIT_EPS     2

typedef struct CvTermCriteria
{
    int    type;  /* CV_TERMCRIT_ITER と CV_TERMCRIT_EPS の組合せ */
    int    max_iter; /* 反復数の最大値 */
    double epsilon; /* 目標精度 */
}
CvTermCriteria;

/* コンストラクタ */
inline  CvTermCriteria  cvTermCriteria( int type, int max_iter, double epsilon );

/* 終了条件をチェックし,type=CV_TERMCRIT_ITER+CV_TERMCRIT_EPS に設定し,
   反復数の max_iterとeprilon の両方が有効になるように変換する */
CvTermCriteria cvCheckTermCriteria( CvTermCriteria criteria,
                                    double default_eps,
                                    int default_max_iters );

CvMat

多重行列

    typedef struct CvMat
    {
        int type; /* CvMat シグネチャ (CV_MAT_MAGIC_VAL).要素の型とフラグ */
        int step; /* 全行のバイト長 */

        int* refcount; /* 内部的に利用されるデータ参照カウンタ */

        union
        {
            uchar* ptr;
            short* s;
            int* i;
            float* fl;
            double* db;
        } data; /* データポインタ */

    #ifdef __cplusplus
        union
        {
            int rows;
            int height;
        };

        union
        {
            int cols;
            int width;
        };
    #else
        int rows; /* 行の数 */
        int cols; /* 列の数 */
    #endif

    } CvMat;

CvMatND

多次元,多チャンネルの密な行列

    typedef struct CvMatND
    {
        int type; /* CvMatND シグネチャ (CV_MATND_MAGIC_VAL).要素の型とフラグ */
        int dims; /* 配列の次元数 */

        int* refcount; /* 内部的に利用されるデータ参照カウンタ */

        union
        {
            uchar* ptr;
            short* s;
            int* i;
            float* fl;
            double* db;
        } data; /* データポインタ */

        /* 各次元での(要素数,要素間のバイト距離)の組 */
        struct
        {
            int size;
            int step;
        }
        dim[CV_MAX_DIM];

    } CvMatND;

CvSparseMat

多次元,多チャンネルの疎な行列

    typedef struct CvSparseMat
    {
        int type;             /* CvSparseMat シグネチャ(CV_SPARSE_MAT_MAGIC_VAL).要素の型とフラグ */
        int dims;             /* 次元数 */
        int* refcount;        /* 参照カウンタ - 使用されない */
        struct CvSet* heap;   /* ハッシュテーブルノードの保存領域(プール) */
        void** hashtable;     /* ハッシュテーブル:各エントリは,同じ「hashvalue の hashsize を法とする剰余」
                                 をノードのリストとして持つ */
        int hashsize;         /* ハッシュテーブルのサイズ */
        int total;            /* 粗な配列ノードの総数 */
        int valoffset;        /* 配列ノードの値のオフセット(バイト単位) */
        int idxoffset;        /* 配列ノードのインデックスのオフセット(バイト単位) */
        int size[CV_MAX_DIM]; /* 次元サイズの配列 */

    } CvSparseMat;

IplImage

IPL 画像ヘッダ

    typedef struct _IplImage
    {
        int  nSize;         /* sizeof(IplImage) */
        int  ID;            /* バージョン (=0)*/
        int  nChannels;     /* OpenCV のほとんどの関数が,1,2,3および4チャンネルをサポートする */
        int  alphaChannel;  /* OpenCV では無視される */
        int  depth;         /* ピクセルの色深度のビット数:
                               IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,
                               IPL_DEPTH_16S, IPL_DEPTH_32S, 
                               IPL_DEPTH_32F, IPL_DEPTH_64F がサポートされる */
        char colorModel[4]; /* OpenCV では無視される */
        char channelSeq[4]; /* 同上 */
        int  dataOrder;     /* 0 - インタリーブカラーチャンネル.1 - 分離カラーチャンネル,
                               cvCreateImage が作成できるのは,インタリーブ画像のみ.*/
        int  origin;        /* 0 - 左上原点,
                               1 - 左下原点(Windowsのビットマップ形式) */
        int  align;         /* 画像の行のアライメント(4 あるいは 8).
                               OpenCV はこれを無視して,代わりに widthStep を使用する. */
        int  width;         /* 画像のピクセル幅 */
        int  height;        /* 画像のピクセル高さ */
        struct _IplROI *roi;/* 画像 ROI.これが NULL でない場合,この特定の領域が処理の対象となる */
        struct _IplImage *maskROI; /* OpenCV では必ずNULL */
        void  *imageId;     /* 同上 */
        struct _IplTileInfo *tileInfo; /* 同上 */
        int  imageSize;     /* 画像データのバイトサイズ
                               (インタリーブデータの場合は,=image->height*image->widthStep) */
        char *imageData;    /* アライメントが調整された画像データへのポインタ */
        int  widthStep;     /* アライメントが調整された画像の行のバイトサイズ */
        int  BorderMode[4]; /* 画像境界の設定.OpenCV では無視される */
        int  BorderConst[4]; /* 同上 */
        char *imageDataOrigin; /* オリジナル画像データへのポインタ
                                  (アライメントが調整されているとは限らない)
                                  - これは画像を正しく解放するために必要. */
    }
    IplImage;

IplImage 構造体は元々,Intel Image Processing Library 固有のものであった. OpenCVでは IplImage フォーマットの一部のみをサポートしている.

上述の制限に加えて OpenCV では ROI の扱いが異なる. OpenCVでは全ての入力および出力画像のサイズ,またはその ROI サイズが正確に一致する必要がある (処理に依存する.例えば cvPyrDown の出力幅(高さ)は,入力幅(高さ)の 1/2±1でなければならない).しかしIPL では重複する領域が処理の対象となる.つまり画像のサイズ,または ROI のサイズが全ての画像において異なる可能性もある.


CvArr

任意の配列

    typedef void CvArr;

メタ型 CvArr* は,1種類以上の配列(例えば IplImage*,CvMat*,CvSeq*など)を引数にとる関数を記述するための仮引数としてのみ利用される. 個々の配列型は,実行時にヘッダの最初の4バイトを分析することで決定される.


配列操作(Operations on Arrays)


初期化(Initialization)


CreateImage

ヘッダの作成とデータ領域の確保

IplImage* cvCreateImage( CvSize size, int depth, int channels );

size
画像の幅と高さ.
depth
画像要素のビットデプス.以下の内のいずれか.
IPL_DEPTH_8U - 符号無し 8 ビット整数
IPL_DEPTH_8S - 符号有り 8 ビット整数
IPL_DEPTH_16U - 符号無し 16 ビット整数
IPL_DEPTH_16S - 符号有り 16 ビット整数
IPL_DEPTH_32S - 符号有り 32 ビット整数
IPL_DEPTH_32F - 単精度浮動小数点数
IPL_DEPTH_64F - 倍精度浮動小数点数
channels
要素(ピクセル)毎のチャンネル数.1, 2, 3, 4 のいずれか.このチャンネルはインタリーブされる.例えば,通常のカラー画像のデータレイアウトは,
b0 g0 r0 b1 g1 r1 ...
となっている.一般的な IPL 画像フォーマットはノンインタリーブ画像を格納することができ,これを処理することができる OpenCV の関数も存在するが,この関数はインタリーブ画像しか作成できない.

関数 cvCreateImage はヘッダを作成し,データ領域を確保する.これは,以下の形式を短縮したものである.

    header = cvCreateImageHeader(size,depth,channels);
    cvCreateData(header);


CreateImageHeader

メモリ確保と初期化を行い,IplImage 構造体を返す

IplImage* cvCreateImageHeader( CvSize size, int depth, int channels );

size
画像の幅と高さ.
depth
画像のカラーデプス(CreateImage を参照).
channels
チャンネル数(CreateImage を参照).

関数 cvCreateImageHeader は,メモリ確保と初期化を行い, IplImage 構造体を返す.これは,

  iplCreateImageHeader( channels, 0, depth,
                        channels == 1 ? "GRAY" : "RGB",
                        channels == 1 ? "GRAY" : channels == 3 ? "BGR" :
                        channels == 4 ? "BGRA" : "",
                        IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_TL, 4,
                        size.width, size.height,
                        0,0,0,0);
と似ているが,この関数はデフォルトでは IPL の関数を用いない(マクロ CV_TURN_ON_IPL_COMPATIBILITY も参照すること).


ReleaseImageHeader

ヘッダを解放する

void cvReleaseImageHeader( IplImage** image );

image
確保したヘッダへのポインタのポインタ.

関数 cvReleaseImageHeader は,ヘッダを解放する.これは,

    if( image )
    {
        iplDeallocate( *image, IPL_IMAGE_HEADER | IPL_IMAGE_ROI );
        *image = 0;
    }
と似ているが,この関数はデフォルトでは IPL の関数を用いない(マクロ CV_TURN_ON_IPL_COMPATIBILITY も参照すること).


ReleaseImage

ヘッダと画像データを解放する

void cvReleaseImage( IplImage** image );

image
確保した画像ヘッダへのポインタのポインタ.

関数 cvReleaseImage は,ヘッダと画像データを解放する. これは,以下の形式を短縮したものである.

    if( *image )
    {
        cvReleaseData( *image );
        cvReleaseImageHeader( image );
    }


InitImageHeader

ユーザによって確保された画像ヘッダを初期化する

IplImage* cvInitImageHeader( IplImage* image, CvSize size, int depth,
                             int channels, int origin=0, int align=4 );

image
初期化される画像ヘッダ.
size
画像の幅と高さ.
depth
画像のカラーデプス(CreateImage を参照).
channels
チャンネル数(CreateImage を参照).
origin
IPL_ORIGIN_TL または IPL_ORIGIN_BL
align
画像の行のアライメント,通常は4,あるいは 8 バイト.

関数 cvInitImageHeader は, ユーザから渡されたポインタが指す画像のヘッダ構造体を初期化し,そのポインタを返す.


CloneImage

画像の完全なコピーを作成する

IplImage* cvCloneImage( const IplImage* image );

image
オリジナル画像.

関数 cvCloneImage は,ヘッダ,ROI,データを含む画像の完全なコピー を作成する.


SetImageCOI

与えられた値を channel of interest(COI)としてセットする

void cvSetImageCOI( IplImage* image, int coi );

image
画像ヘッダ.
coi
COI(Channel of interest).

関数 cvSetImageCOI は,与えられた値を COI(channel of interest)としてセットする. 値 0 は全てのチャンネルが選択されている事を意味し,値 1 は最初のチャンネルが選択されている事を意味する. もしCOI が NULL かつ,パラメータが coi != 0 の場合には,COI が確保される. OpenCV の関数の多くは COI をサポートしていないことに注意すること. 別々の画像/行列チャンネルを処理するには,(cvCopycvSplit によって)別々の画像/行列へチャンネルをコピーし, それを処理してから,必要ならばその結果を(cvCopycvCvtPlaneToPix によって)もう一度コピーし直して返す.


GetImageCOI

COI のインデックスを戻す

int cvGetImageCOI( const IplImage* image );

image
画像ヘッダ.

関数 cvGetImageCOI は,画像の COI(channel of interest)を返す(全チャンネルが選択される場合には,0 が返される).


SetImageROI

与えられた矩形を画像の ROI としてセットする

void cvSetImageROI( IplImage* image, CvRect rect );

image
画像ヘッダ.
rect
ROI を表す矩形.

関数 cvSetImageROI は,与えられた矩形を画像の ROI としてセットする. もし,ROI が NULL で,パラメータ rect の値が画像全体ではない場合には,ROI が確保される. COI とは異なり,OpenCV の関数の多くが ROI をサポートしている. そして,ROI はある意味,別の画像として扱われる(例えば,全てのピクセル座標は ROI の左上あるいは左下(画像の原点に依存)からカウントされる).


ResetImageROI

画像の ROI を解放する

void cvResetImageROI( IplImage* image );

image
画像ヘッダ.

関数 cvResetImageROI は,画像の ROI を解放する. 解放後は全画像が選択されている状態と同じになる. 以下のようにしても,同じように全選択ができるが,この方法では image->roi は解放されない.

cvSetImageROI( image, cvRect( 0, 0, image->width, image->height ));
cvSetImageCOI( image, 0 );


GetImageROI

画像の ROI 座標を返す

CvRect cvGetImageROI( const IplImage* image );

image
画像ヘッダ.

関数 cvGetImageROI は,画像の ROI 座標を返す. ROI が存在しない場合には,矩形 cvRect(0,0,image->width,image->height) が返される.


CreateMat

新たな行列を作成する

CvMat* cvCreateMat( int rows, int cols, int type );

rows
行列の行数.
cols
行列の列数.
type
行列要素の種類.通常,次のような指定形式になる. CV_<bit_depth>(S|U|F)C<number_of_channels>.例えば,
CV_8UC1 は,符号無し 8 ビット 1 チャンネル行列, CV_32SC2 は,符号有り 32 ビット 2 チャンネル行列を意味する.

関数 cvCreateMat は,新たな行列とその内部データのためのヘッダを確保し,作成された行列へのポインタを返す.これは以下の省略形である.

    CvMat* mat = cvCreateMatHeader( rows, cols, type );
    cvCreateData( mat );

行列は行単位で保存され,すべての行は4バイトでアライメントされる.


CreateMatHeader

新たな行列のヘッダを作成する

CvMat* cvCreateMatHeader( int rows, int cols, int type );

rows
行列の行数.
cols
行列の列数.
type
行列要素の種類(cvCreateMatを参照).

関数 cvCreateMatHeaderは,新たな行列のヘッダを作成し,そのポインタを返す. さらに,cvCreateData を用いるか,cvSetData により,ユーザが確保したデータ領域を明示的にセットすることで,行列データが確保される.


ReleaseMat

行列を解放する

void cvReleaseMat( CvMat** mat );

mat
行列へのポインタのポインタ.

関数 cvReleaseMat は,行列データの参照カウンタをデクリメントして,行列ヘッダを解放する.

    if( *mat )
        cvDecRefData( *mat );
    cvFree( (void**)mat );


InitMatHeader

行列ヘッダを初期化する

CvMat* cvInitMatHeader( CvMat* mat, int rows, int cols, int type,
                        void* data=NULL, int step=CV_AUTOSTEP );

mat
初期化する行列のヘッダへのポインタ.
rows
行列の行数.
cols
行列の列数.
type
行列要素の種類.
data
行列のヘッダで指定されるデータへのポインタ(オプション).
step
割り当てられたデータの行長をバイト単位で表す. デフォルトでは,stepには可能な限り小さい値が用いられる.つまり,行列の連続する行間にギャップが存在しない.

関数 cvInitMatHeader は,既に確保された構造体 CvMat を初期化する. これは,OpenCV の行列関数で生データを処理するために用いることもできる.

例えば,以下のコードは二つの行列の積を計算し,通常の行列として格納する.

二つの行列の積の計算

   double a[] = { 1, 2, 3, 4,
                  5, 6, 7, 8,
                  9, 10, 11, 12 };

   double b[] = { 1, 5, 9,
                  2, 6, 10,
                  3, 7, 11,
                  4, 8, 12 };

   double c[9];
   CvMat Ma, Mb, Mc ;

   cvInitMatHeader( &Ma, 3, 4, CV_64FC1, a );
   cvInitMatHeader( &Mb, 4, 3, CV_64FC1, b );
   cvInitMatHeader( &Mc, 3, 3, CV_64FC1, c );

   cvMatMulAdd( &Ma, &Mb, 0, &Mc );
   // この行列 c には,行列 a(3×4) と 行列 b(4×3) の積が入っている


Mat

行列ヘッダを初期化する(軽量版)

CvMat cvMat( int rows, int cols, int type, void* data=NULL );

rows
行列の行数.
cols
行列の列数.
type
行列要素の種類(CreateMat を参照).
data
行列のヘッダで指定されるデータへのポインタ(オプション).

関数 cvMat は, cvInitMatHeader の高速なインライン置換である.つまり,これは以下と等価である.

     CvMat mat;
     cvInitMatHeader( &mat, rows, cols, type, data, CV_AUTOSTEP );


CloneMat

行列のコピーを作成する

CvMat* cvCloneMat( const CvMat* mat );

mat
入力行列.

関数 cvCloneMat は,入力行列のコピーを作成し,そのポインタを返す.


CreateMatND

多次元の密な配列を作成する

CvMatND* cvCreateMatND( int dims, const int* sizes, int type );

dims
配列の次元数.CV_MAX_DIM(デフォルトでは32.ビルド時に変更される可能性もある)を超えてはいけない.
sizes
次元サイズの配列.
type
配列要素の種類.CvMat のものと同じ.

関数 cvCreateMatND は,多次元の密な配列のヘッダとその内部データを確保し,作成された配列のポインタを返す. これは以下の省略形である.

    CvMatND* mat = cvCreateMatNDHeader( dims, sizes, type );
    cvCreateData( mat );

配列データは行単位で保存される.全ての行は4バイトでアライメントされる.


CreateMatNDHeader

新たな行列のヘッダを作成する

CvMatND* cvCreateMatNDHeader( int dims, const int* sizes, int type );

dims
配列の次元数.
sizes
次元サイズの配列.
type
配列要素の種類.CvMat のものと同じ.

関数 cvCreateMatND は,多次元の密な配列のヘッダを確保する. さらに,cvCreateData を用いるか, cvSetData により,ユーザが確保したデータ領域を明示的にセットすることで,配列データが確保される.


ReleaseMatND

多次元配列を解放する

void cvReleaseMatND( CvMatND** mat );

mat
配列へのポインタのポインタ.

関数 cvReleaseMatND は,配列データの参照カウンタをデクリメントして,配列ヘッダを解放する.

    if( *mat )
        cvDecRefData( *mat );
    cvFree( (void**)mat );


InitMatNDHeader

多次元配列のヘッダを初期化する

CvMatND* cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes, int type, void* data=NULL );

mat
初期化する配列のヘッダへのポインタ.
dims
配列の次元数.
sizes
次元サイズの配列.
type
配列要素の種類.CvMat のものと同じ.
data
行列のヘッダで指定されるデータへのポインタ(オプション).

関数 cvInitMatNDHeader は,ユーザによって確保された構造体 CvMatND を初期化する.


CloneMatND

多次元配列の完全なコピーを作成する

CvMatND* cvCloneMatND( const CvMatND* mat );

mat
入力配列.

関数 cvCloneMatND は,入力配列のコピーを作成し,そのポインタを返す.


DecRefData

配列データの参照カウンタをデクリメントする

void cvDecRefData( CvArr* arr );

arr
配列ヘッダ.

関数 cvDecRefData は, 参照カウンタのポインタが NULL ではない場合に CvMat あるいは CvMatND のデータの参照カウンタをデクリメントし, さらにカウンタが 0 になった場合にはデータを解放する. 現在の実装では,データが関数 cvCreateData によって確保された場合にのみ, 参照カウンタは NULL ではなくなる. その他の場合として,以下のものがある.
cvSetData によって,外部データがヘッダに割り当てられた.
行列ヘッダが,より大きな行列あるいは画像の一部になっている.
行列ヘッダが,画像あるいは n 次元行列ヘッダから変換された.

このような場合,参照カウンタは NULL にセットされ,デクリメントされない. データが解放されるか否かに関わらず,データポインタと参照カウンタポインタはこの関数によってクリアされる.


IncRefData

配列データの参照カウンタをインクリメントする

int cvIncRefData( CvArr* arr );

arr
配列ヘッダ.

関数 cvIncRefData は, 参照カウンタポインタが NULL ではない場合に, CvMat あるいは CvMatND のデータの参照カウンタをインクリメントし,新たなカウンタ値を返す. そうでない場合は 0 を返す.


CreateData

配列データを確保する

void cvCreateData( CvArr* arr );

arr
配列ヘッダ.

関数 cvCreateData は,画像,行列あるいは多次元配列のデータを確保する. 行列の場合は OpenCV の確保関数が用いられる.IplImage の場合も OpenCV の関数が用いられる. ただし,CV_TURN_ON_IPL_COMPATIBILITY が呼ばれた場合は例外的に,データを確保するために IPL 関数が用いられる.


ReleaseData

配列データを解放する

void cvReleaseData( CvArr* arr );

arr
配列ヘッダ.

関数 cvReleaseData は,配列データを解放する. CvMat あるいは CvMatND の場合, これは単に cvDecRefData() を呼ぶだけである.つまり,この関数は外部データを解放することができない. cvCreateData の注意事項も参照すること.


SetData

ユーザデータを配列ヘッダに割り当てる

void cvSetData( CvArr* arr, void* data, int step );

arr
配列ヘッダ.
data
ユーザデータ.
step
バイト単位で表された行の長さ.

関数 cvSetData は,ユーザデータを配列のヘッダに割り当てる. ヘッダは,関数 cvCreate*Header,関数 cvInit*Header あるいは 関数 cvMat(行列の場合)を用いて,あらかじめ初期化されるべきである.


GetRawData

配列の低レベル情報を取り出す

void cvGetRawData( const CvArr* arr, uchar** data,
                   int* step=NULL, CvSize* roi_size=NULL );

arr
配列ヘッダ.
data
出力である全画像の原点へのポインタ,あるいは ROI が設定されている場合は ROI の原点へのポインタ.
step
出力であるバイト単位で表された行の長さ.
roi_size
出力であるROI サイズ.

関数 cvGetRawData は,配列データに関する低レベル情報を変数に出力する. すべての出力パラメータは任意であり,いくつかのポインタは NULL にセットされる場合がある. 配列が ROI をもつ IplImage である場合,ROI のパラメータが返される.

以下に,この関数を用いて配列の要素にアクセスする例を示す.

GetRawData を用いて,シングルチャンネル浮動小数点型数配列の要素の絶対値を計算する.

    float* data;
    int step;

    CvSize size;
    int x, y;

    cvGetRawData( array, (uchar**)&data, &step, &size );
    step /= sizeof(data[0]);

    for( y = 0; y < size.height; y++, data += step )
        for( x = 0; x < size.width; x++ )
            data[x] = (float)fabs(data[x]);


GetMat

任意の配列に対する行列ヘッダを返す

CvMat* cvGetMat( const CvArr* arr, CvMat* header, int* coi=NULL, int allowND=0 );

arr
入力配列.
header
テンポラリバッファとして用いられる構造体 CvMat へのポインタ.
coi
COIを記憶するための,オプションの出力パラメータ.
allowND
これが 0 でない場合,この関数は多次元の密な配列(CvMatND*)を扱うことが可能で, 2次元行列(CvMatND が2次元の場合)あるいは 1次元行列(CvMatNDが 1次元,あるいは 2次元より大きい場合)を返す. 配列は連続でなければならない.

関数 cvGetMat は,入力配列に対する行列ヘッダを返す. 入力配列になり得るものは,行列 - CvMat,画像 - IplImage あるいは,多次元の密な配列 - CvMatND*(最後の例は,allowND != 0 の場合のみ)である. 行列の場合,この関数は単に入力ポインタを返す. IplImage* あるいは CvMatND* の場合は, 現在の画像の ROI のパラメータで構造体 header を初期化し,このテンポラリ構造体へのポインタを返す. COI は CvMat ではサポートされないので,これは別に返される.

この関数は,同じコードで 2種類の配列 - IplImage および CvMat - を扱う簡単な方法を提供する. 関数 cvGetImage によって,CvMat から IplImage への逆変換が可能である.

入力配列は,確保あるいは添付された内部データを持たなければならず,そうでない場合は,この関数は失敗する.

入力配列が,平面(二次元)データレイアウトおよび COI を持つ IplImage の場合, この関数は選択された平面へのポインタおよび COI = 0 を返す. OpenCV の関数を用いて,平面データレイアウトを持つマルチチャンネル画像を平面毎に処理する事が可能である.


GetImage

任意の配列に対する画像ヘッダを返す

IplImage* cvGetImage( const CvArr* arr, IplImage* image_header );

arr
入力配列.
image_header
テンポラリバッファとして用いられる構造体 IplImage へのポインタ.

関数 cvGetImage は,入力配列, 行列 - CvMat*,画像 - IplImage*,に対する画像ヘッダを返す. 画像の場合は,この関数は単に入力ポインタを返す.CvMat* の場合は,入力行列のパラメータで構造体 image_header を初期化する. ROI がセットされている場合,IplImage から CvMat へ変換した後に,その CvMat から IplImage に戻すと,異なったヘッダになる可能性がある. 従って,画像の長さをその幅とアライメントから計算するような IPL 関数は,この関数の結果として得られる画像に対しては失敗する可能性がある.


CreateSparseMat

疎な配列を作成する

CvSparseMat* cvCreateSparseMat( int dims, const int* sizes, int type );

dims
配列の次元数.密な行列とは逆に,次元数は実質的には無制限である(216 まで).
sizes
次元サイズの配列.
type
配列要素の種類.CvMat のものと同じ.

関数 cvCreateSparseMat は,多次元の疎な配列を確保する. 初期状態では配列は要素を持たない. つまり,cvGet*D あるいは cvGetReal*D は, 全インデックスに対して 0 を返す.


ReleaseSparseMat

疎な配列を解放する

void cvReleaseSparseMat( CvSparseMat** mat );

mat
配列へのポインタのポインタ.

関数 cvReleaseSparseMat は,疎な配列を解放し,終了時に配列ポインタをクリアする.


CloneSparseMat

疎な配列の完全なコピーを作成する

CvSparseMat* cvCloneSparseMat( const CvSparseMat* mat );

mat
入力配列.

関数 cvCloneSparseMat は,入力配列のコピーを作成し,そのポインタを返す.


要素へのアクセスと部分配列(Accessing Elements and sub-Arrays)


GetSubRect

入力画像または行列の矩形部分配列に相当するヘッダを返す

CvMat* cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect );

arr
入力配列.
submat
結果として得られる部分配列のヘッダへのポインタ.
rect
着目する矩形領域の,0 を基準とした座標.

関数 cvGetSubRectは,入力配列中の指定した矩形領域に相当するヘッダを返す. つまり,入力配列の一部の矩形領域を,独立した配列として扱えるようにする. この関数では ROI を考慮し,実際には ROI の部分配列が取り出される.


GetRow, GetRows

配列中の1行または,指定された範囲の行(複数行)を返す

CvMat* cvGetRow( const CvArr* arr, CvMat* submat, int row );
CvMat* cvGetRows( const CvArr* arr, CvMat* submat, int start_row, int end_row, int delta_row=1 );

arr
入力配列.
submat
結果として得られる部分配列のヘッダへのポインタ.
row
選択した行の,0を基準としたインデックス.
start_row
範囲の最初の(この値を含む)行の,0を基準としたインデックス.
end_row
範囲の最後の(この値を含まない)行の,0を基準としたインデックス.
delta_row
行の範囲のインデックス間隔. この関数は,start_rowからend_row(は含まない)まで,delta_row毎に行を抽出する.

関数GetRowGetRowsは,入力配列中の指定した1行,あるいは範囲の複数行に相当するヘッダを返す.注釈:GetRowcvGetRowsのショートカットである.

cvGetRow( arr, submat, row );  // ~ cvGetRows( arr, submat, row, row + 1, 1 );


GetCol, GetCols

配列中の1列または,指定された範囲の列(複数列)を返す

CvMat* cvGetCol( const CvArr* arr, CvMat* submat, int col );
CvMat* cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col );

arr
入力配列.
submat
結果として得られる部分配列のヘッダへのポインタ.
col
選択した列の,0を基準としたインデックス.
start_col
範囲の最初の(この値を含む)列の,0を基準としたインデックス
end_col
範囲の最後の(この値を含まない)列の,0を基準としたインデックス.

関数GetColGetColsは入力配列中の指定した1列,あるいは範囲の複数列に相当するヘッダを返す.注釈:GetColcvGetColsのショートカットである.

cvGetCol( arr, submat, col ); // ~ cvGetCols( arr, submat, col, col + 1 );


GetDiag

配列の対角列の一つを返す

CvMat* cvGetDiag( const CvArr* arr, CvMat* submat, int diag=0 );

arr
入力配列.
submat
結果として得られる部分配列のヘッダへのポインタ.
diag
対角配列.0はメインの対角列に対応し,-1はメイン対角列の一つ上の斜め列,1はメイン対角列の一つ下の斜め列,という様に対応する.

関数cvGetDiagは,入力配列中の指定された対角列に相当するヘッダを返す.


GetSize

行列または画像の ROI のサイズを返す

CvSize cvGetSize( const CvArr* arr );

arr
配列のヘッダ.

関数cvGetSizeは,入力行列または画像の行数(CvSize::height)と列数(CvSize::width)を返す.画像の場合は ROI のサイズが返される.


InitSparseMatIterator

疎な配列要素のイテレータを初期化する

CvSparseNode* cvInitSparseMatIterator( const CvSparseMat* mat,
                                       CvSparseMatIterator* mat_iterator );

mat
入力配列.
mat_iterator
初期化されるイテレータ.

関数cvInitSparseMatIteratorは,疎な配列要素のイテレータを初期化し,先頭要素へのポインタを返す.配列が空の時はNULLを返す.


GetNextSparseNode

疎な配列において次の要素のポインタを返す

CvSparseNode* cvGetNextSparseNode( CvSparseMatIterator* mat_iterator );

mat_iterator
疎な配列のイテレータ.

関数cvGetNextSparseNodeは,イテレータを次の疎な行列要素へ動かし,そこへのポインタを返す. 現在のバージョンでは,個々の要素はハッシュテーブルに保存されているので,それらに特別な順番はない. 疎な行列内をどのように繰り返し処理していくかを,以下のサンプルに示す.

cvInitSparseMatIteratorcvGetNextSparseNode を用いた疎な浮動小数点型配列の総和計算.

    double sum;
    int i, dims = cvGetDims( array );
    CvSparseMatIterator mat_iterator;
    CvSparseNode* node = cvInitSparseMatIterator( array, &mat_iterator );

    for( ; node != 0; node = cvGetNextSparseNode( &mat_iterator ))
    {
        /* 要素インデックスへのポインタを取得 */
        const int* idx = CV_NODE_IDX( array, node );
        /* 要素値の取得(タイプがCV_32FC1であると仮定) */
        float val = *(float*)CV_NODE_VAL( array, node );
        printf( "(" );
        for( i = 0; i < dims; i++ )
            printf( "%4d%s", idx[i], i < dims - 1 "," : "): " );
        printf( "%g¥n", val );

        sum += val;
    }

    printf( "¥nTotal sum = %g¥n", sum );


GetElemType

配列要素のタイプを返す

int cvGetElemType( const CvArr* arr );

arr
入力配列.

関数GetElemTypeは,cvCreateMatの説明に述べられている以下のような配列要素のタイプを返す.

CV_8UC1 ... CV_64FC4


GetDims, GetDimSize

配列の次元数とそれらのサイズ,または特定の次元のサイズを返す

int cvGetDims( const CvArr* arr, int* sizes=NULL );
int cvGetDimSize( const CvArr* arr, int index );

arr
入力配列.
sizes
配列の次元の大きさを示すオプションの出力ベクトル.2次元配列の場合は1番目に行数(高さ),次は列数(幅)を示す.
index
0を基準にした次元のインデックス(行列では0は行数,1は列数を示す.画像では0は高さ, 1は幅を示す).

関数cvGetDimsは配列の次元とそれらのサイズを返す. IplImageまたは CvMatの場合には,画像や行列の行数に関係なく常に 2 を返す. 関数cvGetDimSizeは特定の次元のサイズ(指定された次元の要素数)を返す.例えば,次のコードは配列要素の数を計算する2つの方法である.

// cvGetDims()を用いる方法
int sizes[CV_MAX_DIM];
int i, total = 1;
int dims = cvGetDims( arr, size );
for( i = 0; i < dims; i++ )
    total *= sizes[i];

// cvGetDims() と cvGetDimSize() を用いる方法
int i, total = 1;
int dims = cvGetDims( arr );
for( i = 0; i < dims; i++ )
    total *= cvGetDimsSize( arr, i );


Ptr*D

特定の配列要素へのポインタを返す

uchar* cvPtr1D( const CvArr* arr, int idx0, int* type=NULL );
uchar* cvPtr2D( const CvArr* arr, int idx0, int idx1, int* type=NULL );
uchar* cvPtr3D( const CvArr* arr, int idx0, int idx1, int idx2, int* type=NULL );
uchar* cvPtrND( const CvArr* arr, const int* idx, int* type=NULL, 
                                          int create_node=1, unsigned* precalc_hashval=NULL );

arr
入力配列.
idx0
要素インデックスの,0を基準とした第1成分.
idx1
要素インデックスの,0を基準とした第2成分.
idx2
要素インデックスの,0を基準とした第3成分.
idx
要素インデックスの配列.
type
オプションの出力パラメータ.行列要素のタイプ.
create_node
疎な行列に対するオプションの入力パラメータ.非0の場合,指定された要素が存在しないときは要素を生成する.
precalc_hashval
疎な行列に対するオプションの入力パラメータ.ポインタがNULLでないとき,関数はノードのハッシュ値を再計算せず,指定された場所から取ってくる. これにより,ペアワイズ操作の速度が向上する.

関数cvPtr*Dは,特定の配列要素へのポインタを返す.1次元からN次元までの密な配列への連続的なアクセスに用いられる関数cvPtr1Dの場合を除いて,配列の次元数は関数の引き数として渡されるインデックスの数と一致しなければならない.

同様に,この関数は,疎な配列に対しても用いられる.指定したノードが存在しない場合,関数はそれを生成し,0をセットする.

配列要素にアクセスするその他の関数(cvGet*D, cvGetReal*D, cvSet*D, cvSetReal*D)も同様であるが,要素のインデックスが範囲外であれば,エラーが起こる.


Get*D

特定の配列要素を返す

CvScalar cvGet1D( const CvArr* arr, int idx0 );
CvScalar cvGet2D( const CvArr* arr, int idx0, int idx1 );
CvScalar cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 );
CvScalar cvGetND( const CvArr* arr, const int* idx );

arr
入力配列.
idx0
要素インデックスの0を基準とした第1成分.
idx1
要素インデックスの0を基準とした第2成分.
idx2
要素インデックスの0を基準とした第3成分.
idx
要素インデックスの配列.

関数cvGet*Dは,特定の配列要素を返す.疎な配列で,指定したノードが存在しない場合,この関数は0を返す(この関数によって新しいノードは生成されない).


GetReal*D

シングルチャンネルの配列の特定の要素を返す

double cvGetReal1D( const CvArr* arr, int idx0 );
double cvGetReal2D( const CvArr* arr, int idx0, int idx1 );
double cvGetReal3D( const CvArr* arr, int idx0, int idx1, int idx2 );
double cvGetRealND( const CvArr* arr, const int* idx );

arr
入力配列. シングルチャンネルでなくてはならない.
idx0
要素インデックスの,0を基準とした第1成分.
idx1
要素インデックスの,0を基準とした第2成分.
idx2
要素インデックスの,0を基準とした第3成分.
idx
要素インデックスの配列.

関数cvGetReal*Dは,シングルチャンネルの配列の特定の要素を返す.配列がマルチチャンネルの場合は,ランタイムエラーが発生する. 注釈:関数cvGet*Dはシングルチャンネルとマルチチャンネルの配列に対して安全に使用することができるが,若干処理速度が遅い.

指定したノードが存在しなければ,この関数は0を返す(この関数によって新しいノードは生成されない).


mGet

シングルチャンネル浮動小数点型行列の特定の要素を返す

double cvmGet( const CvMat* mat, int row, int col );

mat
入力行列.
row
行の0を基準としたインデックス.
col
列の0を基準としたインデックス.

関数cvmGetは,シングルチャンネル浮動小数点型行列の場合における,cvGetReal2Dの高速化版関数である. インライン処理され,配列のタイプや要素のタイプのチェックを行わず,また行と列の範囲のチェックもデバックモードのときしか行わないので高速である.


Set*D

特定の配列要素を変更する

void cvSet1D( CvArr* arr, int idx0, CvScalar value );
void cvSet2D( CvArr* arr, int idx0, int idx1, CvScalar value );
void cvSet3D( CvArr* arr, int idx0, int idx1, int idx2, CvScalar value );
void cvSetND( CvArr* arr, const int* idx, CvScalar value );

arr
入力配列.
idx0
要素インデックスの,0を基準とした第1成分.
idx1
要素インデックスの,0を基準とした第2成分.
idx2
要素インデックスの,0を基準とした第3成分.
idx
要素インデックスの配列.
value
割り当てる値.

関数cvSet*Dは,新しい値を指定した配列要素に割り当てる. 疎な配列の場合,ノードが存在しなければ,この関数はノードを生成する.


SetReal*D

特定の配列要素を変更する

void cvSetReal1D( CvArr* arr, int idx0, double value );
void cvSetReal2D( CvArr* arr, int idx0, int idx1, double value );
void cvSetReal3D( CvArr* arr, int idx0, int idx1, int idx2, double value );
void cvSetRealND( CvArr* arr, const int* idx, double value );

arr
入力配列.
idx0
要素インデックスの,0を基準とした第1成分.
idx1
要素インデックスの,0を基準とした第2成分.
idx2
要素インデックスの,0を基準とした第3成分.
idx
要素インデックスの配列.
value
割り当てる値.

関数cvSetReal*Dはシングルチャンネルの配列の指定した要素に新しい値を割り当てる. 配列がマルチチャンネルのときは,ランタイムエラーが起こる. 注釈:関数cvSet*Dはシングルチャンネルとマルチチャンネルの両方に安全に使用することができるが,若干処理速度が遅い.

疎な配列の場合に,ノードが存在しなれば,この関数はノードを生成する.


mSet

シングルチャンネルの浮動小数点型行列の特定の要素の値を変更する

void cvmSet( CvMat* mat, int row, int col, double value );

mat
行列.
row
行の,0を基準としたインデックス.
col
列の,0を基準としたインデックス.
value
行列の要素の新しい値.

関数cvmSetは,シングルチャンネル浮動小数点型行列の場合における,cvSetReal2Dの高速化版関数である. インライン処理され,配列のタイプや要素のタイプのチェックを行わず,また行と列の範囲のチェックもデバックモードのときしか行わないため高速である.


ClearND

特定の要素の値をクリアする

void cvClearND( CvArr* arr, const int* idx );

arr
入力配列.
idx
要素のインデックスの配列.

関数cvClearNDは,密な配列と疎な配列の指定した要素をクリア(0にセット)する.要素が存在しなければ,この関数は何もしない.


コピーと充填(Copying and Filling)


Copy

一つの配列を別の配列にコピーする

void cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL );

src
コピー元の配列.
dst
コピー先の配列.
mask
8 ビットシングルチャンネル配列の処理マスク.コピー先の配列の変更する要素を指定する.

関数 cvCopy は,入力配列から出力配列に選択された要素をコピーする.

mask(I)!=0 の場合,dst(I)=src(I)

引数の配列が IplImage 型の場合,その ROI と COI が利用される. コピー元配列とコピー先配列は,同じ型,同じ次元,同じサイズでなければならない.この関数は,疎な配列もコピーできる(この場合,マスクはサポートされない).


Set

配列の各要素に与えられた値をセットする

void cvSet( CvArr* arr, CvScalar value, const CvArr* mask=NULL );

arr
値をセットする配列.
value
配列を埋める値.
mask
8 ビットシングルチャンネル配列の処理マスク.配列の変更する要素を指定する.

関数 cvSet は,スカラー値 value を,配列の選択された各要素にコピーする.

mask(I)!=0 の場合,arr(I)=value

配列 arrIplImage 型の場合, ROI は利用されるが,COI がセットされていてはならない.


SetZero

配列をクリアする

void cvSetZero( CvArr* arr );
#define cvZero cvSetZero

arr
クリアされる配列.

関数 cvSetZero は,配列をクリアする. 密な配列(CvMat, CvMatND, IplImage)に対する cvZero(array) は,cvSet(array,cvScalarAll(0),0) と等価である. 疎な配列の場合は,全ての要素が削除される.


SetIdentity

スカラー倍された単位行列を用いて初期化を行う

void cvSetIdentity( CvArr* mat, CvScalar value=cvRealScalar );

arr
初期化される行列(正方である必要はない).
value
対角成分の値.

関数 cvSetIdentity は,スカラー倍された単位行列を用いた初期化を行う.

i=j ならば,    arr(i,j)=value
そうでなければ,         0

Range

与えられた範囲の数で行列を埋める

void cvRange( CvArr* mat, double start, double end );

mat
初期化される行列.これは,整数型あるいは浮動小数点型 32 ビットシングルチャンネルでなくてはならない.
start
範囲の下限(範囲に含まれる).
end
範囲の上限(範囲に含まれない).

関数 cvRange は,次のように行列を初期化する.

arr(i,j)=(end-start)*(i*cols(arr)+j)/(cols(arr)*rows(arr))
例えば,以下のコードは連続した整数の1次元ベクトルを初期化する.
CvMat* A = cvCreateMat( 1, 10, CV_32S );
cvRange( A, 0, A->cols ); // A は,[0,1,2,3,4,5,6,7,8,9] で初期化される.

変形と置換(Transforms and Permutations)


Reshape

データのコピーなしに行列/画像の形状を変える

CvMat* cvReshape( const CvArr* arr, CvMat* header, int new_cn, int new_rows=0 );

arr
入力配列.
header
書き込まれる出力ヘッダ.
new_cn
新しいチャンネル数 .new_cn = 0はチャンネル数が変更されていないことを意味する.
new_rows
新しい行数. new_rows = 0は,行数がnew_cnの値に応じて変更する必要があるのにも関わらず,変更されないままであることを意味する.

関数cvReshapeは,オリジナルの配列と同じデータだが, 異なる形状(異なるチャンネル数,異なる行数,またその両方)を持つCvMatのヘッダを初期化する.

例えば,以下は一つの画像バッファと二つの画像のヘッダ(1番目は 320×240×3の画像,2番目は960×240x1の画像)を作成するためのコードである.

IplImage* color_img = cvCreateImage( cvSize(320,240), IPL_DEPTH_8U, 3 );
CvMat gray_mat_hdr;
IplImage gray_img_hdr, *gray_img;
cvReshape( color_img, &gray_mat_hdr, 1 );
gray_img = cvGetImage( &gray_mat_hdr, &gray_img_hdr );

そして,次の例は3×3の行列から1×9のベクトルへの変換である.

CvMat* mat = cvCreateMat( 3, 3, CV_32F );
CvMat row_header, *row;
row = cvReshape( mat, &row_header, 0, 1 );

ReshapeMatND

データのコピーなしに多次元配列の形状を変える

CvArr* cvReshapeMatND( const CvArr* arr,
                       int sizeof_header, CvArr* header,
                       int new_cn, int new_dims, int* new_sizes );

#define cvReshapeND( arr, header, new_cn, new_dims, new_sizes )   ¥
      cvReshapeMatND( (arr), sizeof(*(header)), (header),         ¥
                      (new_cn), (new_dims), (new_sizes))

arr
入力配列.
sizeof_header
IplImageとCvMat,CvMatNDそれぞれの出力ヘッダを区別するための出力ヘッダのサイズ.
header
書き込まれる出力ヘッダ.
new_cn
新しいチャンネル数. new_cn = 0は,チャンネル数が変更されていないことを意味する.
new_dims
新しい次元数. new_dims = 0は,次元数が同じままであることを意味する.
new_sizes
新しい次元サイズの配列.要素の総数は変化してはいけないので,new_dims-1の値のみ使用される.従って,new_dims = 1であればnew_sizesは使用されない.

関数cvReshapeMatNDは,cvReshape の拡張バージョンである.これは多次元配列を扱うことが可能(普通の画像と行列に対しても使用することが可能)で,さらに次元の変更も可能である.以下の2つのサンプルはcvReshapeでの記述を,cvReshapeMatNDを用いて書き直したものである.

IplImage* color_img = cvCreateImage( cvSize(320,240), IPL_DEPTH_8U, 3 );
IplImage gray_img_hdr, *gray_img;
gray_img = (IplImage*)cvReshapeND( color_img, &gray_img_hdr, 1, 0, 0 );

...

/* 2番目は2x2x2の配列を8x1のベクトルに変換する例である */
int size[] = { 2, 2, 2 };
CvMatND* mat = cvCreateMatND( 3, size, CV_32F );
CvMat row_header, *row;
row = cvReshapeND( mat, &row_header, 0, 1, 0 );

Repeat

出力配列を入力配列でタイル状に埋める

void cvRepeat( const CvArr* src, CvArr* dst );

src
入力配列, 画像または行列.
dst
出力配列, 画像または行列.

関数cvRepeatは,入力配列をタイル状に配置して出力配列を埋める.

dst(i,j)=src(i mod rows(src), j mod cols(src))

出力配列は入力配列より大きいこともあれば,小さいこともある.


Flip

2次元配列を垂直,水平,または両軸で反転する

void cvFlip( const CvArr* src, CvArr* dst=NULL, int flip_mode=0);
#define cvMirror cvFlip

src
入力配列.
dst
出力配列.もしdst = NULLであれば,反転はインプレースモードで行われる.
flip_mode
配列の反転方法の指定.
flip_mode = 0 は,x軸周りでの反転, flip_mode > 0(例えば,1)は,y軸周りでの反転, flip_mode < 0(例えば,-1)は,両軸周りでの反転. 以下の式も参照.

関数cvFlipは,3種類の異なる方法のうち1つを指定して配列を反転させる(行と列のインデックスは0が基準である).

dst(i,j)=src(rows(src)-i-1,j) (flip_mode = 0 の場合)
dst(i,j)=src(i,cols(src1)-j-1) (flip_mode > 0 の場合)
dst(i,j)=src(rows(src)-i-1,cols(src)-j-1) (flip_mode < 0 の場合)

関数の使用例


Split

マルチチャンネルの配列を,複数のシングルチャンネルの配列に分割する.または,配列から一つのチャンネルを取り出す.

void cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1,
              CvArr* dst2, CvArr* dst3 );
#define cvCvtPixToPlane cvSplit

src
入力配列.
dst0...dst3
出力チャンネル.

関数cvSplitは,マルチチャンネルの配列をシングルチャンネルの配列に分割する.この操作には二つのモードがある. 入力配列がNチャンネルの場合,先頭からN番目までの出力チャンネルが NULL でなければ,それらはすべて入力配列から取り出される. そうでなく,N個の出力チャネルのうち一つだけが NULL でない場合は,この特定のチャンネルのみを抽出する.このいずれでもない場合はエラーとなる. N番目以降の出力チャンネルは常に NULL でなくてはならない. IplImageでは,画像から一つのシングルチャンネルを抽出するために,COIを伴うcvCopyも利用される.


Merge

複数のシングルチャネルの配列からマルチチャンネル配列を構成する.または,配列に一つのシングルチャンネルを挿入する

void cvMerge( const CvArr* src0, const CvArr* src1,
              const CvArr* src2, const CvArr* src3, CvArr* dst );
#define cvCvtPlaneToPix cvMerge

src0... src3
入力配列.
dst
出力配列.

関数cvMergeは,前述の関数と反対の操作である.もし出力配列がNチャンネルで,N個の入力チャンネルが NULL でないとき,これらのすべては出力配列にコピーされる.そうでなく,一つの入力配列のみが NULL でなければ,この特定のチャンネルが出力配列にコピーされ,このいずれもでない場合はエラーとなる.N番目以降の入力チャンネルは常に NULL でなくてはならない. IplImageでは,画像に一つのシングルチャンネルを挿入するために,COIを伴うcvCopyも利用される.


MixChannels

入力配列のチャンネルを出力配列の指定されたチャンネルにコピーする

void cvMixChannels( const CvArr** src, int src_count,
                    CvArr** dst, int dst_count,
                    const int* from_to, int pair_count );

src
入力配列の配列.
src_count
入力配列の数.
dst
出力配列の配列.
dst_count
出力配列の数.
from_to
コピーされる平面(チャンネル)のインデックスのペア配列. from_to[k*2]は入力平面の0を基準としたインデックスで,from_to[k*2+1]は出力平面のインデックス.ここで,入力及び出力配列すべてについて,各平面への連続的な番号付けが行われる.from_to[k*2]が負のとき,対応する出力平面は0で埋められる.
pair_count
from_toのペア数,またはコピーされた平面の数.

関数cvMixChannelsは,cvSplitcvMerge,および cvCvtColorのいくつかの書式の汎用形である.これは,平面の順番の変更,アルファチャネルの追加や削除,1枚の平面や複数平面の抽出や挿入などに用いられる.以下に,どのように4チャンネルのRGBA画像を,3チャンネルのBGR画像(つまり,RとBの入れ替え) にするか,そしてアルファチャネルを分離するかを示す.

    CvMat* rgba = cvCreateMat( 100, 100, CV_8UC4 );
    CvMat* bgr = cvCreateMat( rgba->rows, rgba->cols, CV_8UC3 );
    CvMat* alpha = cvCreateMat( rgba->rows, rgba->cols, CV_8UC1 );
    CvArr* out[] = { bgr, alpha };
    int from_to[] = { 0, 2, 1, 1, 2, 0, 3, 3 };
    cvSet( rgba, cvScalar(1,2,3,4) );
    cvMixChannels( (const CvArr**)&rgba, 1, out, 2, from_to, 4 );

RandShuffle

配列の要素をランダムにシャッフルする

void cvRandShuffle( CvArr* mat, CvRNG* rng, double iter_factor=1. );

mat
入力/出力行列.インプレースモードでシャッフルされる.
rng
要素のシャッフルで用いられる Random Number Generator.ポインタがNULLの場合,一時的なRNGが生成され,利用される.
iter_factor
シャッフルの強さを指定するパラメータ.以下を参照.

関数cvRandShuffleは,ランダムに選ばれた配列要素ペアの入れ替えを反復することにより行列をシャッフルする(マルチチャンネル配列の場合,それぞれの要素は複数の成分を含む). 反復回数(つまり,ペアの入れ替え)は round(iter_factor*rows(mat)*cols(mat))であり, iter_factor=0はシャッフルを行わないことを, iter_factor=1はこの関数がrows(mat)*cols(mat)回ランダムなペアを入れ替えることを意味する.


四則演算,論理演算,比較演算(Arithmetic, Logic and Comparison)


LUT

配列のルックアップテーブルによる変換

void cvLUT( const CvArr* src, CvArr* dst, const CvArr* lut );

src
入力配列(各要素は8ビットデータ).
dst
出力配列(任意のデプス,入力配列と同じチャンネル数).
lut
要素数が256であるルックアップテーブル(出力配列と同じデプスでなければならない). マルチチャンネルの入力/出力配列の場合,テーブルはシングルチャンネル(この場合すべてのチャンネル対して,同じテーブルを使う)か,入力/出力配列と同じチャンネル数でなければならない.

関数 cvLUT は,出力配列の各要素値をルックアップテーブルを用いて決定する. 配列のインデックスは入力配列より求められる. src の各要素に対して以下のような処理を行う.

dst(I)=lut[src(I)+DELTA]
ここで,srcのデプスが CV_8U の場合はDELTA=0CV_8S の場合は DELTA=128


ConvertScale

任意の線形変換によって配列の値を変換する

void cvConvertScale( const CvArr* src, CvArr* dst, double scale=1, double shift=0 );

#define cvCvtScale cvConvertScale
#define cvScale  cvConvertScale
#define cvConvert( src, dst )  cvConvertScale( (src), (dst), 1, 0 )

src
入力配列.
dst
出力配列.
scale
スケーリング係数.
shift
スケーリングした入力配列の要素に加える値.

関数 cvConvertScale は,様々な目的を持つため,違う名前での関数(マクロ)としても定義されている. この関数は,入力配列をスケーリングしてコピーし,さらに以下のような変換を行う(あるいは変換のみを行う).

dst(I)=src(I)*scale + (shift,shift,...)

マルチチャンネル配列の全てのチャンネルは独立に処理される.

異なる型への変換では,丸めや飽和を伴う.すなわち,スケーリング+変換の結果が出力先のデータタイプで表現できない値になる場合には,表現できる最も近い実軸上の値で表現する.

scale=1, shift=0 の場合は,何も行わない.これは特別なケースであり,cvConvert と同じ意味である. 入力配列と出力配列が同じタイプの場合,行列や画像のスケーリングと移動を行うことができ,cvScale に相当する.


ConvertScaleAbs

任意の線形変換によって,入力配列の要素を8ビット符号無し整数型の配列に変換する.

void cvConvertScaleAbs( const CvArr* src, CvArr* dst, double scale=1, double shift=0 );
#define cvCvtScaleAbs cvConvertScaleAbs

src
入力配列.
dst
出力配列(デプスは 8u).
scale
ScaleAbs 係数.
shift
スケーリングした入力配列の要素に加える値.

関数 cvConvertScaleAbs は前述の関数と類似しているが,以下に示すように,変換結果の絶対値を出力する.

dst(I)=abs(src(I)*scale + (shift,shift,...))

この関数は,出力配列のタイプとして 8u(8ビット符号無し整数)のみをサポートしている.その他の型の場合は,cvConvertScalecvAbs を組み合わせることで同様の効果が得られる.


Add

二つの配列を要素ごとに加算する

void cvAdd( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );

src1
1番目の入力配列.
src2
2番目の入力配列.
dst
出力配列.
mask
処理マスク.8ビットシングルチャンネル配列(出力配列のどの要素が変更されるかを指定する).

関数 cvAdd は,以下のようにsrc1の各要素にsrc2の各要素を加える.

dst(I)=src1(I)+src2(I) (mask(I)!=0の場合)

すべての配列(マスクを除く)は同じタイプで<,配列のサイズ(またはROIのサイズ)も同じでなければならない.


AddS

スカラーと配列を加算する

void cvAddS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );

src
入力配列.
value
加算するスカラー.
dst
出力配列.
mask
処理マスク.8ビットシングルチャンネル配列(出力配列のどの要素が変更されるかを指定する).

関数 cvAddS は,入力配列 src1 のすべての要素にスカラー value を加え,結果を dst に保存する.

dst(I)=src(I)+value ( mask(I)!=0 の場合 )

すべての配列(マスクを除く)は同じタイプで,配列のサイズ(またはROIのサイズ)も同じでなければならない.


AddWeighted

二つの配列の重み付き和を計算する

void cvAddWeighted( const CvArr* src1, double alpha,
                     const CvArr* src2, double beta,
                     double gamma, CvArr* dst );

src1
1番目の入力配列.
alpha
1番目の配列要素への重み.
src2
2番目の入力配列.
beta
2番目の配列要素への重み.
dst
出力配列.
gamma
加算結果に,さらに加えられるスカラー値.

関数 cvAddWeighted は以下のように二つの配列の重み付き和を計算する.

dst(I)=src1(I)*alpha+src2(I)*beta+gamma

すべての配列は同じタイプで,配列のサイズ(またはROIのサイズ)も同じでなければならない.


Sub

二つの配列の要素ごとの減算を行う

void cvSub( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );

src1
1番目の入力配列.
src2
2番目の入力配列.
dst
出力配列.
mask
処理マスク.8ビットシングルチャンネル配列(出力配列のどの要素が変更されるかを指定する).

関数 cvSub は,以下のようにsrc1の各要素からsrc2の各要素を引く.

dst(I)=src1(I)-src2(I) (mask(I)!=0 の場合 )

すべての配列(マスクを除く)は同じタイプで,配列のサイズ(またはROIのサイズ)も同じでなければならない.


SubS

配列要素からスカラーを減算する

void cvSubS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );

src
入力配列.
value
減算するスカラー
dst
出力配列.
mask
処理マスク.8ビットシングルチャンネル配列(出力配列のどの要素が変更されるかを指定する).

関数 cvSubS は,以下のように入力配列のすべての要素から指定されたスカラーを引く.

dst(I)=src(I)-value if mask(I)!=0

すべての配列(マスクを除く)は同じタイプで,配列のサイズ(またはROIのサイズ)も同じでなければならない.


SubRS

スカラーから配列要素を減算する

void cvSubRS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );

src
入力配列.
value
減算されるスカラー.
dst
出力配列.
mask
処理マスク.8ビットシングルチャンネル配列(出力配列のどの要素が変更されるかを指定する).

関数 cvSubRS は,以下のように指定されたスカラーから入力配列のすべての要素それぞれを引く.

dst(I)=value-src(I) ( mask(I)!=0 の場合 )

すべての配列(マスクを除く)は同じタイプで,配列のサイズ(またはROIのサイズ)も同じでなければならない.


Mul

二つの配列の要素同士を乗算する

void cvMul( const CvArr* src1, const CvArr* src2, CvArr* dst, double scale=1 );

src1
1番目の入力配列.
src2
2番目の入力配列.
dst
出力配列.
scale
任意のスケーリング係数.

関数 cvMul は,以下のように二つの配列の要素同士の乗算を行う.

dst(I)=scale•src1(I)•src2(I)

すべての配列(マスクを除く)は同じタイプで,配列のサイズ(またはROIのサイズ)も同じでなければならない.


Div

二つの配列の要素同士を除算する

void cvDiv( const CvArr* src1, const CvArr* src2, CvArr* dst, double scale=1 );

src1
1番目の入力配列.ポインタが NULL の場合は,すべての要素が 1であると仮定する.
src2
2番目の入力配列.
dst
出力配列.
scale
オプションのスケーリング係数.

関数 cvDiv は,以下のように1番目の入力配列の各要素を2番目の入力配列の各要素で割る.

dst(I)=scale•src1(I)/src2(I), (src1!=NULLの場合)
dst(I)=scale/src2(I),      (src1=NULLの場合)

すべての配列(マスクを除く)は同じタイプで,配列のサイズ(またはROIのサイズ)も同じでなければならない.


And

ビット単位の論理積を計算する

void cvAnd( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );

src1
1番目の入力配列.
src2
2番目の入力配列.
dst
出力配列.
mask
処理マスク.8ビットシングルチャンネル配列(出力配列のどの要素が変更されるかを指定する).

関数 cvAnd は以下のように,二つの配列の要素ごとの論理積(AND)を計算する.

dst(I)=src1(I)&src2(I) (mask(I)!=0 の場合)

浮動小数点型配列の場合,それらのビット表現が処理に使われる.すべての配列(マスクを除く)は同じタイプで,配列のサイズ(またはROIのサイズ)も同じでなければならない.


AndS

配列の各要素とスカラーとのビット単位の論理積を計算する

void cvAndS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );

src
入力配列.
value
処理に用いるスカラー.
dst
出力配列.
mask
処理マスク.8ビットシングルチャンネル配列(出力配列のどの要素が変更されるかを指定する).

関数 AndS は以下のように,配列の各要素と指定されたスカラーのビットごとの論理積を計算する.

dst(I)=src(I)&value if mask(I)!=0

実際の計算の前に,スカラーは配列と同じタイプに変換される.浮動小数点型配列の場合,それらのビット表現が処理に使われる.すべての配列(マスクを除く)は同じタイプで,配列のサイズ(またはROIのサイズ)も同じでなければならない.

以下のサンプルコードは,最上位ビットをクリアすることで浮動小数点型配列の各要素の絶対値を求める方法を示している.

float a[] = { -1, 2, -3, 4, -5, 6, -7, 8, -9 };
CvMat A = cvMat( 3, 3, CV_32F, &a );
int i, abs_mask = 0x7fffffff;
cvAndS( &A, cvRealScalar(*(float*)&abs_mask), &A, 0 );
for( i = 0; i < 9; i++ )
    printf("%.1f ", a[i] );

出力は以下のとおりである.

1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0

Or

二つの配列要素のビット単位の論理和を計算する

void cvOr( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );

src1
1番目の入力配列.
src2
2番目の入力配列.
dst
出力配列.
mask
処理マスク.8ビットシングルチャンネル配列(出力配列のどの要素が変更されるかを指定する).

関数 cvOr は以下のように,二つの配列の要素ごとの論理和(OR)を計算する.

dst(I)=src1(I)|src2(I)

浮動小数点型配列の場合,それらのビット表現が処理に使われる.すべての配列(マスクを除く)は同じタイプで,配列のサイズ(またはROIのサイズ)も同じでなければならない.


OrS

配列の各要素とスカラーとのビット単位の論理和を計算する

void cvOrS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );

src1
入力配列.
value
処理に用いるスカラー.
dst
出力配列.
mask
処理マスク.8ビットシングルチャンネル配列(出力配列のどの要素が変更されるかを指定する).

関数 OrS は以下のように,配列の各要素とスカラーのビットごとの論理和を計算する.

dst(I)=src(I)|value (mask(I)!=0の場合)

実際の計算の前に,スカラーは配列と同じタイプに変換される.浮動小数点型配列の場合,それらのビット表現が処理に使われる.すべての配列(マスクを除く)は同じタイプで,配列のサイズ(またはROIのサイズ)も同じでなければならない.


Xor

二つの配列要素のビット単位の排他的論理和を計算する

void cvXor( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );

src1
1番目の入力配列.
src2
2番目の入力配列.
dst
出力配列.
mask
処理マスク.8ビットシングルチャンネル配列(出力配列のどの要素が変更されるかを指定する).

関数 cvXor は以下のように,二つの配列の要素ごとの排他的論理和(XOR)を計算する.

dst(I)=src1(I)^src2(I) (mask(I)!=0の場合)

浮動小数点型配列の場合,それらのビット表現が処理に使われる.すべての配列(マスクを除く)は同じタイプで,配列のサイズ(またはROIのサイズ)も同じでなければならない.


XorS

配列の各要素とスカラーとのビット単位の排他的論理和を計算する

void cvXorS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );

src
入力配列.
value
処理に用いるスカラー.
dst
出力配列.
mask
処理マスク.8ビットシングルチャンネル配列(出力配列のどの要素が変更されるかを指定する).

関数 XorS は以下のように,配列の各要素とスカラーの,ビットごとの排他的論理和を計算する.

dst(I)=src(I)^value if mask(I)!=0

浮動小数点型配列の場合,それらのビット表現が処理に使われる.すべての配列(マスクを除く)は同じタイプで,配列のサイズ(またはROIのサイズ)も同じでなければならない.

以下は,虚部の最上位ビットのON-OFFを入れ替えることで共役複素ベクトルを求めるサンプルコードである.

float a[] = { 1, 0, 0, 1, -1, 0, 0, -1 }; /* 1, j, -1, -j */
CvMat A = cvMat( 4, 1, CV_32FC2, &a );
int i, neg_mask = 0x80000000;
cvXorS( &A, cvScalar( 0, *(float*)&neg_mask, 0, 0 ), &A, 0 );
for( i = 0; i < 4; i++ )
    printf("(%.1f, %.1f) ", a[i*2], a[i*2+1] );

出力は以下のとおり.

(1.0,0.0) (0.0,-1.0) (-1.0,0.0) (0.0,1.0)

Not

各配列要素のビット単位の反転を行う

void cvNot( const CvArr* src, CvArr* dst );

src1
入力配列.
dst
出力配列.

関数 Not は以下のように,配列の各要素のビットをすべて反転(NOT)する.

dst(I)=~src(I)

Cmp

二つの配列の各要素ごとの比較を行う

void cvCmp( const CvArr* src1, const CvArr* src2, CvArr* dst, int cmp_op );

src1
1番目の入力配列.
src2
2番目の入力配列.どちらの入力配列もシングルチャンネルでなければならない.
dst
出力配列(タイプは 8u か 8s でないといけない).
cmp_op
比較方法を示すフラグ.
CV_CMP_EQ - src1(I) と src2(I) は等しい
CV_CMP_GT - src1(I) は src2(I) より大きい
CV_CMP_GE - src1(I) は src2(I) より大きいか等しい
CV_CMP_LT - src1(I) は src2(I) より小さい
CV_CMP_LE - src1(I) は src2(I) より小さいか等しい
CV_CMP_NE - src1(I) と src2(I) は等しくない

関数 cvCmp は,以下のように二つの配列の対応する要素を比較し,出力配列の値にセットする.

dst(I)=src1(I) op src2(I),

ここで op は '=', '>', '>=', '<', '<=', '!=' のいずれか.

比較結果が真(TRUE)であれば dst(I) には 0xff(要素すべてのビットが 1 )をセットし,それ以外の場合(FALSE)であれば 0 をセットする.すべての配列(出力配列を除く)は同じタイプで,配列のサイズ(またはROIのサイズ)も同じでなければならない.


CmpS

配列要素とスカラーを比較する

void cvCmpS( const CvArr* src, double value, CvArr* dst, int cmp_op );

src
入力配列(シングルチャンネル).
value
それぞれの配列要素と比較されるスカラー.
dst
出力配列(タイプは8u または8s).
cmp_op
比較方法を示すフラグ.
CV_CMP_EQ - src1(I) と value は等しい
CV_CMP_GT - src1(I) は value より大きい
CV_CMP_GE - src1(I) は value より大きいか等しい
CV_CMP_LT - src1(I) は value より小さい
CV_CMP_LE - src1(I) は value より小さいか等しい
CV_CMP_NE - src1(I) と value は等しくない

関数 cvCmpS は以下のように配列要素とスカラーとを比較し,出力配列の値をセットする.

dst(I)=src(I) op scalar,

ここで op は '=', '>', '>=', '<', '<=' or '!=' のいずれか.

比較結果が真(TRUE)であれば dst(I) には 0xff(要素すべてのビットが 1 ) をセットし,それ以外の場合(FALSE)であれば 0 をセットする.すべての配列のサイズ(またはROIのサイズ)は同じでなければならない.


InRange

配列の要素値が他の二つの配列要素で表される範囲内に位置するかをチェックする

void cvInRange( const CvArr* src, const CvArr* lower, const CvArr* upper, CvArr* dst );

src
入力配列.
lower
下限値(その値を含む)を表す配列.
upper
上限値(その値は含まない)を表す配列.
dst
出力配列(タイプは8u または 8s).

関数 cvInRange は以下のように,入力配列のすべての要素について範囲チェックを行う.

dst(I)=lower(I)0 <= src(I)0 < upper(I)0

(シングルチャンネル配列の場合),

dst(I)=lower(I)0 <= src(I)0 < upper(I)0 &&
       lower(I)1 <= src(I)1 < upper(I)1

(2チャンネルなどの場合).

src(I) が範囲内であれば dst(I) には 0xff(要素すべてのビットが '1')をセットし,それ以外の場合は 0 をセットする.すべての配列(出力配列を除く)は同じタイプで,配列のサイズ(またはROIのサイズ)も同じでなければならない.


InRangeS

配列の要素値が二つのスカラーの間に位置するかをチェックする

void cvInRangeS( const CvArr* src, CvScalar lower, CvScalar upper, CvArr* dst );

src
入力配列.
lower
下限値(その値を含む).
upper
上限値(その値は含まない).
dst
出力配列(タイプは8u または 8s).

関数 cvInRangeS は以下のように,入力配列のすべての要素のについて範囲チェックを行う.

dst(I)=lower0 <= src(I)0 < upper0

(シングルチャンネル配列の場合),

dst(I)=lower0 <= src(I)0 < upper0 &&
     lower1 <= src(I)1 < upper1

(2チャンネルなどの場合).

src(I) が範囲内であれば dst(I) には 0xff(要素すべてのビットが '1')をセットし,それ以外の場合は 0 をセットする. すべての配列のサイズ(またはROIのサイズ)は同じでなければならない.


Max

二つの配列の各要素についての最大値を求める

void cvMax( const CvArr* src1, const CvArr* src2, CvArr* dst );

src1
1番目の入力配列.
src2
2番目の入力配列.
dst
出力配列.

関数 cvMax は以下のように,二つの配列の要素ごとの最大値を計算する.

dst(I)=max(src1(I), src2(I))

すべての配列はシングルチャンネルで,タイプ,配列のサイズ(またはROIのサイズ)は同じでなければならない.


MaxS

配列の各要素とスカラーについての最大値を求める

void cvMaxS( const CvArr* src, double value, CvArr* dst );

src
入力配列.
value
スカラー.
dst
出力配列.

関数 cvMaxS は以下のように,配列の各要素とスカラーとの最大値を計算する.

dst(I)=max(src(I), value)

すべての配列はシングルチャンネルで,タイプ,配列のサイズ(またはROIのサイズ)は同じでなければならない.


Min

二つの配列の各要素についての最小値を求める

void cvMin( const CvArr* src1, const CvArr* src2, CvArr* dst );

src1
1番目の入力配列.
src2
2番目の入力配列.
dst
出力配列.

関数 cvMin は以下のように,二つの配列の要素ごとの最小値を計算する.

dst(I)=min(src1(I),src2(I))

すべての配列はシングルチャンネルで,タイプ,配列のサイズ(またはROIのサイズ)は同じでなければならない.


MinS

配列の各要素とスカラーについての最小値を求める

void cvMinS( const CvArr* src, double value, CvArr* dst );

src
入力配列.
value
スカラー.
dst
出力配列.

関数 cvMinS は以下のように,配列の各要素とスカラーとの最小値を計算する.

dst(I)=min(src(I), value)

すべての配列はシングルチャンネルで,タイプ,配列のサイズ(またはROIのサイズ)は同じでなければならない.


AbsDiff

二つの配列の要素ごとの差の絶対値を計算する

void cvAbsDiff( const CvArr* src1, const CvArr* src2, CvArr* dst );

src1
1番目の入力配列.
src2
2番目の入力配列.
dst
出力配列.

関数 cvAbsDiff は以下のように,src1 の各要素と src2 の差の絶対値を計算する.

dst(I)c = abs(src1(I)c - src2(I)c).

すべての配列は同じタイプ,同じサイズ(または同じROIサイズ)でなければならない.


AbsDiffS

配列の要素と定数との差の絶対値を計算する

void cvAbsDiffS( const CvArr* src, CvArr* dst, CvScalar value );
#define cvAbs(src, dst) cvAbsDiffS(src, dst, cvScalarAll(0))

src
入力配列.
dst
出力配列.
value
スカラー.

関数 cvAbsDiffS は以下のように,配列の各要素とスカラーとの差の絶対値を計算する.

dst(I)c = abs(src(I)c - valuec).

すべての配列は同じタイプ,同じサイズ(または同じROIサイズ)でなければならない.


統計(Statistics)


CountNonZero

配列要素において 0 ではない要素をカウントする

int cvCountNonZero( const CvArr* arr );

arr
配列(シングルチャンネルまたはCOIがセットされたマルチチャンネルの画像).

関数 cvCountNonZero は以下のように,入力配列内の 0 でない要素数を返す.

result = sumI arr(I)!=0
配列が IplImage の場合, ROI,COI の両方に対応している.


Sum

配列要素の総和を計算する

CvScalar cvSum( const CvArr* arr );

arr配列.

関数 cvSum は以下のように,配列要素の総和 S を各チャンネルで独立に計算する.

Sc = sumI arr(I)c
配列のタイプが IplImage で COI がセットされている場合,指定されたチャンネルのみを処理し,総和を1番目のスカラー値(S0)として保存する.


Avg

配列要素の平均値を計算する

CvScalar cvAvg( const CvArr* arr, const CvArr* mask=NULL );

arr
配列.
mask
オプションの処理マスク.

関数 cvAvg は,配列要素の平均値 M を各チャンネルで独立に計算する.

N = sumI mask(I)!=0

Mc = 1/N • sumI,mask(I)!=0 arr(I)c
配列のタイプが IplImage で COI がセットされている場合,指定されたチャンネルのみを処理し,平均値を1番目のスカラー値(M0)として保存する.


AvgSdv

配列要素の平均と標準偏差を計算する

void cvAvgSdv( const CvArr* arr, CvScalar* mean, CvScalar* std_dev, const CvArr* mask=NULL );

arr
配列.
mean
計算結果の平均値へのポインタ.必要でない場合は NULL.
std_dev
計算結果の標準偏差へのポインタ.
mask
オプションの処理マスク.

関数 cvAvgSdv は,配列要素の平均と標準偏差を各チャンネルで独立に計算する.

N = sumI mask(I)!=0

meanc = 1/N • sumI,mask(I)!=0 arr(I)c

std_devc = sqrt(1/N • sumI,mask(I)!=0 (arr(I)c - Mc)2)
配列のタイプが IplImage で COI がセットされている場合,指定されたチャンネルのみを処理し,平均値と標準偏差をそれぞれ1番目のスカラー値(M0と S0)として保存する.


MinMaxLoc

配列あるいは部分配列内の最小値と最大値を求める

void cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val,
                  CvPoint* min_loc=NULL, CvPoint* max_loc=NULL, const CvArr* mask=NULL );

arr
入力配列(シングルチャンネルまたはCOIがセットされたマルチチャンネル).
min_val
戻り値の最小値へのポインタ.
max_val
戻り値の最大値へのポインタ.
min_loc
戻り値の最小値を持つ位置へのポインタ.
max_loc
戻り値の最大値を持つ位置へのポインタ.
mask
部分配列を指定するためのオプションのマスク.

関数 MinMaxLoc は,配列要素の中から最小値・最大値とその位置を求める. 各極値は配列全体または選択されたROI(IplImageの場合)をスキャンして求める. maskNULL でない場合は,指定された領域のみをスキャンする. マルチチャンネル配列の場合,入力は COI がセットされた IplImage データタイプでなければならない. 多次元配列の場合は,min_loc->xmax_loc->yには,極値の座標がそのまま入る.


Norm

配列の絶対値ノルム(absolute array norm),絶対値差分ノルム(absolute difference norm),相対値差分ノルム(relative difference norm)を計算する

double cvNorm( const CvArr* arr1, const CvArr* arr2=NULL, int norm_type=CV_L2, const CvArr* mask=NULL );

arr1
1番目の入力画像.
arr2
2番目の入力画像.NULL の場合,arr1の絶対値ノルムが計算され,そうでない場合は,arr1-arr2 の絶対値あるいは相対値ノルムが計算される.
normType
ノルムのタイプ(以下の説明を参照).
mask
オプションの処理マスク.

関数 cvNormarr2 が NULL の場合,以下のように arr1 の絶対値ノルムを計算する.

norm = ||arr1||C = maxI abs(arr1(I)),  (normType = CV_Cの場合)

norm = ||arr1||L1 = sumI abs(arr1(I)),  (normType = CV_L1の場合)

norm = ||arr1||L2 = sqrt( sumI arr1(I)2),  (normType = CV_L2の場合)

この関数は,arr2 が NULL でない場合,以下のように絶対値あるいは相対値ノルムを計算する.

norm = ||arr1-arr2||C = maxI abs(arr1(I)-arr2(I)),  (normType = CV_Cの場合)

norm = ||arr1-arr2||L1 = sumI abs(arr1(I)-arr2(I)),  (normType = CV_L1の場合)

norm = ||arr1-arr2||L2 = sqrt( sumI (arr1(I)-arr2(I))2 ),  (normType = CV_L2の場合)

もしくは

norm = ||arr1-arr2||C/||arr2||C, (normType = CV_RELATIVE_Cの場合)

norm = ||arr1-arr2||L1/||arr2||L1, (normType = CV_RELATIVE_L1の場合)

norm = ||arr1-arr2||L2/||arr2||L2, (normType = CV_RELATIVE_L2の場合)

関数 cvNorm は計算したノルムを返す.マルチチャンネル配列はシングルチャンネルとして取り扱う.すなわち,すべてのチャンネルの結果が統合される.


Reduce

行列をベクトルへ縮小する

void cvReduce( const CvArr* src, CvArr* dst, int op=CV_REDUCE_SUM );

src
入力行列.
dst
1行(または1列)の出力ベクトル(すべての行/列から指定された方法で計算される).
dim
配列をどのように縮小するかを示すインデックス. 0 は行列を1行ベクトルに縮小する. 1 は行列を1列ベクトルに縮小する. -1 はdst のサイズから次元を解析し,自動的に選択する.
op
縮小処理の種類.以下の値のいずれか.
CV_REDUCE_SUM - 出力は各行(または各列)の総和
CV_REDUCE_AVG - 出力は各行(または各列)の平均ベクトル
CV_REDUCE_MAX - 出力は各行(または各列)における最大値
CV_REDUCE_MIN - 出力は各行(または各列)における最小値

関数 cvReduce は,行列の各行(各列)を1次元ベクトルの集合として取り扱い,その集合に対して指示された処理を行うことによって,入力行列をベクトルに縮小する. 例えば,ラスター画像の水平方向(あるいは垂直方向)への射影を計算するために使うことができる.CV_REDUCE_SUMCV_REDUCE_AVG の場合は,精度を保つために出力要素のビットデプスを大きくとるべきである.また,マルチチャンネル配列においても,これら二つのモードがサポートされる.


線形代数(Linear Algebra)


DotProduct

ユークリッド距離に基づく2つの配列の内積を計算する

double cvDotProduct( const CvArr* src1, const CvArr* src2 );

src1
1番目の入力配列.
src2
2番目の入力配列.

関数cvDotProductはユークリッド幾何学における内積を計算し,その結果を返す.

src1•src2 = sumI(src1(I)*src2(I))

マルチチャンネル配列の場合,全てのチャンネルの結果が累算される.特にaを複素ベクトルとすると,cvDotProduct(a,a)||a||2を返す.この関数は,多次元配列を1行,1レイヤーずつ処理することもできる.


Normalize

指定のノルムになるように,あるいは値が指定の範囲になるように,配列を正規化する

void cvNormalize( const CvArr* src, CvArr* dst,
                  double a=1, double b=0, int norm_type=CV_L2,
                  const CvArr* mask=NULL );

src
入力配列.
dst
出力配列.インプレース処理が可能.
a
出力配列の最小値または最大値,あるいは出力配列のノルム.
b
出力配列の最大値または最小値.
norm_type
正規化のタイプ.以下のうち一つを用いることができる.
CV_C - 配列のC-norm(絶対値の最大値)を正規化
CV_L1 - 配列のL1-norm(絶対値の合計)を正規化
CV_L2 - 配列のL2-norm(ユークリッド距離)を正規化
CV_MINMAX - 配列の値が指定の範囲に収まるようにスケーリングとシフトを行う.
mask
操作マスク.特定の配列要素のみを正規化するためのマスク.

関数cvNormalizeは,入力配列をそのノルム,または値が特定の値や範囲になるように正規化する.

norm_type==CV_MINMAXのとき,

    dst(i,j)=(src(i,j)-min(src))*(b'-a')/(max(src)-min(src)) + a',  (mask(i,j)!=0 の場合)
    dst(i,j)=src(i,j)  (それ以外の場合)
ここで b'=MAX(a,b)a'=MIN(a,b)min(src)max(src) はそれぞれ入力配列の全体,または指定された部分集合について計算した全体の最小値と最大値である.

norm_type!=CV_MINMAXのとき,

    dst(i,j)=src(i,j)*a/cvNorm(src,0,norm_type,mask), (mask(i,j)!=0 の場合)
    dst(i,j)=src(i,j)  (それ以外の場合)

以下に,簡単な例を示す.

float v[3] = { 1, 2, 3 };
CvMat V = cvMat( 1, 3, CV_32F, v );

// 単位ベクトルの生成
// これは,以下と等しい.
// for(int i=0;i<3;i++) v[i]/=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
cvNormalize( &V, &V );

CrossProduct

二つの3次元ベクトルの外積を計算する

void cvCrossProduct( const CvArr* src1, const CvArr* src2, CvArr* dst );

src1
1番目の入力ベクトル.
src2
2番目の入力ベクトル.
dst
出力ベクトル.

関数 cvCrossProduct は,二つの3次元ベクトルの外積を計算する.

dst = src1 × src2,
  (dst1 = src12src23 - src13src22 , dst2 = src13src21 - src11src23 , dst3 = src11src22 - src12src21).

ScaleAdd

スケーリングされた配列ともう一つの配列の和を計算する

void cvScaleAdd( const CvArr* src1, CvScalar scale, const CvArr* src2, CvArr* dst );
#define cvMulAddS cvScaleAdd

src1
1番目の入力配列
scale
1番目の配列のためのスケールファクタ.
src2
2番目の入力配列.
dst
出力配列.

関数cvScaleAddは,スケーリングされた配列ともう一つの配列の和を計算する.

dst(I)=src1(I)*scale + src2(I)

全ての配列パラメータは同じタイプで同じサイズでなくてはならない.


GEMM

汎用的な行列の乗算を行う

void cvGEMM( const CvArr* src1, const CvArr* src2, double alpha,
              const CvArr* src3, double beta, CvArr* dst, int tABC=0 );
#define cvMatMulAdd( src1, src2, src3, dst ) cvGEMM( src1, src2, 1, src3, 1, dst, 0 )
#define cvMatMul( src1, src2, dst ) cvMatMulAdd( src1, src2, 0, dst )

src1
1番目の入力配列.
src2
2番目の入力配列.
alpha
乗算結果に対するスケーリング係数.以下の説明を参照.
src3
3番目の入力配列(シフト用).もしシフトしない場合はNULLにできる.
beta
3番目の入力配列に対するスケーリング係数.以下の説明を参照.
dst
出力配列.
tABC
操作フラグ.0または以下の値の組み合わせ.
CV_GEMM_A_T - src1を転置
CV_GEMM_B_T - src2を転置
CV_GEMM_C_T - src3を転置
例:CV_GEMM_A_T+CV_GEMM_C_Tは, alpha*src1T*src2 + beta*src3Tに対応する.

関数cvGEMMは汎用的な行列の乗算を行う.

dst = alpha*op(src1)*op(src2) + beta*op(src3),   ここで, op(X) は X あるいは XT

全ての行列は同じデータタイプ,同じサイズである必要がある.実数あるいは複素数の浮動小数点型の行列がサポートされている.


Transform

すべての配列要素を行列により変換する

void cvTransform( const CvArr* src, CvArr* dst, const CvMat* transmat, const CvMat* shiftvec=NULL );

src
1番目の入力配列.
dst
出力配列.
transmat
変換行列.
shiftvec
オプションのシフトベクトル.

関数cvTransformは,srcの全て要素に行列変換を行い,その結果をdst に保存する.

dst(I)=transmat*src(I) + shiftvec   または   dst(I)k=sumj(transmat(k,j)*src(I)j) + shiftvec(k)

つまり,Nsrc個の要素をもつベクトルとして取り扱い, M×N行列transmatとシフトベクトルshiftvec を用いて, Mチャンネル配列dstの一つの要素へと変換する. shiftvectransmatへ埋め込むという選択もある. この場合,transmatM×N+1の行列でなければならず,最右列はシフトベクトルとして扱われる.

入力配列と出力配列は共にデプスが等しく,サイズあるいは選択されたROIのサイズが同じでなければならない.transmatshiftvecは浮動小数点型の実数行列でなくてはならない.

この関数は,N次元点集合の幾何変換,任意の色空間の線形変換,チャンネルのシャッフル等に使用される.


PerspectiveTransform

ベクトルの透視投影変換を行う

void cvPerspectiveTransform( const CvArr* src, CvArr* dst, const CvMat* mat );

src
3チャンネルの浮動小数点型入力配列.
dst
3チャンネルの浮動小数点型出力配列.
mat
3×3 または 4×4 の変換行列.

関数cvPerspectiveTransformは,以下のように,srcのすべての要素を2次元あるいは3次元ベクトルとして扱い,これを変換する.

(x, y, z) -> (x’/w, y’/w, z’/w) または
(x, y) -> (x’/w, y’/w),

ここで,
(x’, y’, z’, w’) = mat4x4*(x, y, z, 1) または
(x’, y’, w’) = mat3x3*(x, y, 1)

 w = w’   (w’!=0 の場合)
     inf   (そうでない場合)

MulTransposed

行列と転置行列の乗算を行う

void cvMulTransposed( const CvArr* src, CvArr* dst, int order, const CvArr* delta=NULL );

src
入力行列.
dst
出力行列.
order
転置した行列をかける順番.
delta
オプション配列,乗算する前にsrcから引かれる.

関数cvMulTransposedはsrcとその転置行列との乗算を計算する.

この関数は,以下のように計算を行う.

dst=(src-delta)*(src-delta)T

(order=0 の場合)

dst=(src-delta)T*(src-delta)

(そうでない場合).


Trace

行列のトレースを返す

CvScalar cvTrace( const CvArr* mat );

mat
入力行列.

関数cvTraceは,行列matの対角成分の和を返す.

tr(src1)=sumimat(i,i)

Transpose

行列の転置を行う

void cvTranspose( const CvArr* src, CvArr* dst );
#define cvT cvTranspose

src
入力行列.
dst
出力行列.

関数cvTransposeは行列srcを転置する.

dst(i,j)=src(j,i)

注釈:複素行列の場合,複素数の共役化は行わない.共役は別に計算されるべきである.例として,cvXorS のサンプルコードを参照すること.


Det

行列式を返す

double cvDet( const CvArr* mat );

mat
入力行列.

関数cvDetは,正方行列matの行列式を返す. 小さい行列に対しては直接法が,大きい行列に対してはガウスの消去法が使用される. 正の行列式を持つ対称行列については,U=V=NULLとしてSVDを実行し, その後Wの対角要素の内積として行列式を計算することも可能である.


Invert

逆行列または擬似逆行列を求める

double cvInvert( const CvArr* src, CvArr* dst, int method=CV_LU );
#define cvInv cvInvert

src
入力行列.
dst
出力行列.
method
逆行列を求める手法.
CV_LU - 最適なピボット選択によるガウスの消去法
CV_SVD - 特異値分解(SVD)
CV_SVD_SYM - 対称正定値行列のための特異値分解

関数cvInvertsrcの逆行列を計算し,その結果をdstに入れる.

LUの場合,この関数はsrcの行列式を返す(srcは正方行列でなくてなならない). 行列式が0の場合, 逆行列は計算できずdstは0で埋められる.

SVDの場合,この関数はsrcの条件数の逆数(大きい特異値に対する小さい特異値の比)を返す. また,srcが全て0のときは0を返す. もし,srcが非正則行列の場合,SVDを用いる方法では擬似逆行列を計算する.


Solve

線形問題または最小二乗法問題を解く

int cvSolve( const CvArr* A, const CvArr* B, CvArr* X, int method=CV_LU );

A
入力行列.
B
線形システムの右辺.
X
出力解.
method
逆行列の解法.
CV_LU - 最適なピボット選択によるガウスの消去法
CV_SVD - 特異値分解
CV_SVD_SYM - 対称正定値行列のための特異値分解.

関数cvSolveは,線形問題または最小二乗問題を解く(後者は特異値分解を用いて解くことが可能である).

dst = arg minX||A*X-B||

methodにCV_LU を指定した場合,Aが正則行列であれば1を返し,そうでなければ0を返す. 後者の場合は,dstの値は有効ではない.


SVD

浮動小数点型の実数行列の特異値分解を行う

void cvSVD( CvArr* A, CvArr* W, CvArr* U=NULL, CvArr* V=NULL, int flags=0 );

A
入力M×N行列.
W
特異値行列の結果 (M×N または N×N)または ベクトル(N×1).
U
任意の左直交行列 (M×M または M×N). もしCV_SVD_U_Tが指定された場合,上で述べた,行と列の数は入れ替わる.
V
任意の右直交行列(N×N).
flags
操作フラグ.0または以下の値の組み合わせ.
  • CV_SVD_MODIFY_A を指定すると,計算中に行列Aの変更を行うことができる. このフラグの指定は処理速度を向上させる.
  • CV_SVD_U_T means that the tranposed matrix U is returned. Specifying the flag はUの転置行列を返すことを意味する.このフラグの指定は処理速度を向上させる.
  • CV_SVD_V_TVの転置行列を返すことを意味する.このフラグの指定は処理速度を向上させる.

関数cvSVDは,行列Aを二つの直交行列と一つの対角行列の積に分解する.

A=U*W*VT

ここで,Wは特異値の対角行列であり,特異値の1次元のベクトルとしてエンコードされる.すべての特異値は非負の値を持ち,降順にソートされる (UVの行も共に).

SVDアルゴリズムは数値的にロバストであり,その典型的な応用は,以下のようになる.


SVBkSb

特異値の後退代入を行う

void cvSVBkSb( const CvArr* W, const CvArr* U, const CvArr* V,
                const CvArr* B, CvArr* X, int flags );

W
特異値の行列またはベクトル.
U
左直交行列(転置されているかもしれない)
V
右直交行列(転置されているかもしれない)
B
行列Aの擬似逆行列に乗ずるための行列.オプションのパラメータ. 省略されている場合,それは適切なサイズの単位行列であると仮定される(そのためXAの再構成された擬似逆行列となる).
X
出力行列.後退代入の結果.
flags
操作フラグ.cvSVDでのflagsと一致していなければならない.

関数cvSVBkSbは,分解される行列AcvSVDを参照)と行列Bのための後退代入を計算する.

X=V*W-1*UT*B

ここで,

W-1(i,i)=1/W(i,i) (W(i,i) > epsilon•sumiW(i,i) の場合)
         0        (それ以外の場合)

また,epsilonは行列のデータタイプに依存する小さな数値である.

この関数はcvSVDと共に,cvInvertcvSolveの内部で用いられる.これら(svd と bksb) の低レベル関数を使用する理由は,高レベル関数(inv と solve)において一時的な行列の確保を避けるためである.


EigenVV

対称行列の固有値と固有ベクトルを計算する

void cvEigenVV( CvArr* mat, CvArr* evects, CvArr* evals, double eps=0 );

mat
入力対称正方行列.処理中に変更される.
evects
固有ベクトルの出力行列.連続した行として保存される.
evals
固有値ベクトルの出力ベクトル.降順に保存される(もちろん固有値と固有ベクトルの順番は一致する).
eps
対角化の精度(一般的に,DBL_EPSILON=≈10-15 で十分である).

関数cvEigenVVは,行列matの固有値と固有ベクトルを計算する.

mat*evects(i,:)' = evals(i)*evects(i,:)' (MTALAB表記)

行列matの内容はこの関数によって破壊される.

現在,この関数はcvSVDより遅く,精度も低い. そこで,matが正定値行列であることが既知のとき (例えば共変動行列)は, 行列matの固有値,固有ベクトルを求めるために(特に,固有ベクトルが必要とされない場合), cvSVDを使用することが推奨される. これは,

cvEigenVV(mat, eigenvals, eigenvects);
の代わりに
cvSVD(mat, eigenvals, eigenvects, 0, CV_SVD_U_T + CV_SVD_MODIFY_A);
を呼ぶということである.


CalcCovarMatrix

ベクトル集合の共変動行列を計算する

void cvCalcCovarMatrix( const CvArr** vects, int count, CvArr* cov_mat, CvArr* avg, int flags );

vects
入力ベクトル.これらはすべて同じタイプで同じサイズでなくてはならない. ベクトルは1次元である必要はなく,2次元(例えば,画像)などでも構わない.
count
入力ベクトルの数.
cov_mat
浮動小数点型の正方な出力共変動行列.
avg
入力または出力配列(フラグに依存する) - 入力ベクトルの平均ベクトル.
flags
操作フラグ.以下の値の組み合わせ.
CV_COVAR_SCRAMBLED - 出力共変動行列は次のように計算される.
scale*[vects[0]-avg,vects[1]-avg,...]T*[vects[0]-avg,vects[1]-avg,...]
すなわち,共変動行列はcount×countである. そのような一般的でない共変動行列は,非常に大きなベクトル集合に対する高速な主成分分析のために使用される(例えば,顔認識のための固有顔). この「スクランブルされた」行列の固有値は,真共変動行列の固有値と一致し, そして「真の」固有ベクトルは「スクランブルされた」共変動行列の固有ベクトルから容易に計算できる.
CV_COVAR_NORMAL - 出力共変動行列は次のように計算される.
scale*[vects[0]-avg,vects[1]-avg,...]*[vects[0]-avg,vects[1]-avg,...]T
つまり,cov_matはすべての入力ベクトルの要素の合計と同じサイズの一般的な共変動行列となる. CV_COVAR_SCRAMBLEDCV_COVAR_NORMALのどちらか一つは必ず指定されなくてはならない.
CV_COVAR_USE_AVG - このフラグが指定された場合,関数は入力ベクトルから平均を計算せず,引数で指定された平均ベクトルを使用する. 平均が何らかの方法で既に計算されている場合,または共変動行列が部分的に計算されている場合 (この場合,avgは入力ベクトルの一部の平均ではなく,全ての平均ベクトルである)に有用である.
CV_COVAR_SCALE - このフラグが指定された場合, 共変動行列は入力ベクトルの数によってスケーリングされる.
CV_COVAR_ROWS - 全ての入力ベクトルは単一の行列(vects[0])の行として保存されることを意味する. この場合,countは無視される.そしてavgは適切な大きさの1行のベクトルでなければならない.
CV_COVAR_COLS - 全ての入力ベクトルは単一の行列(vects[0])の列として保存されることを意味する. この場合,countは無視される.そしてavgは適切な大きさの1列のベクトルでなければならない.

関数cvCalcCovarMatrixは,共変動行列と,オプションで入力ベクトル集合の平均を計算する. この関数は,主成分分析やマハラノビス距離によるベクトルの比較等に用いられる.


Mahalonobis

2つのベクトルのマハラノビス距離を計算する

double cvMahalanobis( const CvArr* vec1, const CvArr* vec2, CvArr* mat );

vec1
1番目の1次元入力ベクトル.
vec2
2番目の1次元入力ベクトル.
mat
逆共変動行列.

関数cvMahalonobisは,二つのベクトル間の重み付き距離を計算し,それを返す.

d(vec1,vec2)=sqrt( sumi,j {mat(i,j)*(vec1(i)-vec2(i))*(vec1(j)-vec2(j))} )

cvCalcCovarMatrixを用いて共変動行列が計算され, さらにcvInvert関数(行列が非正則行列である可能性があるので,methodにCV_SVDが選択されたもの)を用いて逆行列を求める.


CalcPCA

ベクトル集合の主成分分析を行う

void cvCalcPCA( const CvArr* data, CvArr* avg,
                CvArr* eigenvalues, CvArr* eigenvectors, int flags );

data
入力データ.それぞれのベクトルは単一行(CV_PCA_DATA_AS_ROW)か,単一列(CV_PCA_DATA_AS_COL)である.
avg
平均ベクトル.関数内で計算されるか,ユーザによって与えられる.
eigenvalues
出力である共変動行列の固有値.
eigenvectors
出力である共変動行列の固有ベクトル(つまり,主成分).一つの行が一つのベクトルを意味する.
flags
操作フラグ.以下の値の組み合わせ.
CV_PCA_DATA_AS_ROW - 行としてベクトルが保存される(つまり,あるベクトルすべての要素は連続的に保存される)
CV_PCA_DATA_AS_COL - 列としてベクトルが保存される(つまり,あるベクトル成分に属する値は連続的に保存される)
(上の2つのフラグは互いに排他的である)
CV_PCA_USE_AVG - 事前に計算された平均ベクトルを用いる

関数cvCalcPCAは,ベクトル集合の主成分分析を行う. まず,cvCalcCovarMatrixを用いて共変動行列を計算し,固有値,固有ベクトルを求める. 固有値,固有ベクトルの出力個数は,MIN(rows(data),cols(data))と等しいか,または少ない.


ProjectPCA

指定された部分空間にベクトルを投影する

void cvProjectPCA( const CvArr* data, const CvArr* avg,
                   const CvArr* eigenvectors, CvArr* result );

data
入力データ.それぞれのベクトルは単一行か,単一列である.
avg
平均ベクトル.単一行ベクトルの場合,それはdataの行として入力ベクトルが保存されていることを意味する. そうでない場合は,単一列ベクトルであり,そのときのベクトルはdataの列として保存されている.
eigenvectors
固有ベクトル(主成分).一つの行が一つのベクトルを意味する.
result
出力である分解係数の行列.行の数はベクトルの数と同じでなくてはならない. 列の数はeigenvectorsの列の数より小さいか同じでなくてはならない. 列の数が少ない場合,入力ベクトルは,第cols(result)主成分までを基底とする部分空間に投影される.

関数cvProjectPCAは,入力ベクトルを正規直交基底(eigenvectors)で表現される部分空間に投影する. 内積を計算する前に,avgベクトルが入力ベクトルから減算される.

result(i,:)=(data(i,:)-avg)*eigenvectors' // CV_PCA_DATA_AS_ROW 配置の場合

BackProjectPCA

投影係数から元のベクトルを再構築する

void cvBackProjectPCA( const CvArr* proj, const CvArr* avg,
                       const CvArr* eigenvects, CvArr* result );

proj
入力データ.cvProjectPCAresultと同様のフォーマット.
avg
平均ベクトル.もし単一行ベクトルの場合,出力ベクトルがresultの行として保存されていることを意味する. そうでない場合は,単一列ベクトルであり,そのときはresultの列として保存される.
eigenvectors
固有ベクトル(主成分).一つの行が一つのベクトルを意味する.
result
出力である再構築されたベクトルの行列.

関数cvBackProjectPCAは,投影係数からベクトルを再構築する.

result(i,:)=proj(i,:)*eigenvectors + avg // CV_PCA_DATA_AS_ROW 配置の場合

数学関数(Math Functions)


Round, Floor, Ceil

浮動小数点型の変数を整数型に変換する

int cvRound( double value );
int cvFloor( double value );
int cvCeil( double value );

value
浮動小数点型の入力値.

関数cvRound, cvFloor,cvCeilは,浮動小数点型の入力値を丸め手法(Round, Floor, Ceil)の一つを利用して整数型に変換する.cvRoundは,引数に最も近い整数値を返す.cvFloorは,引数より大きくない最大の整数値を返す.cvCeilは,引数より小さくない最小の整数値を返す.いくつかのアーキテクチャにおいて,これらの関数はC言語の標準的なキャスト演算よりも非常に高速である. 引数の絶対値が231より大きい場合,結果は求まらない.また,特別な値(±Inf, NaN)は扱うことができない.


Sqrt

平方根を計算する

float cvSqrt( float value );

value
浮動小数点型の入力値.

関数cvSqrtは,引数の平方根を計算する. 引数が負の値の場合,結果は求まらない.


InvSqrt

平方根の逆数を計算する

float cvInvSqrt( float value );

value
浮動小数点型の入力値.

関数cvInvSqrtは,引数の平方根の逆数を計算する.これは,通常,1./sqrt(value)を計算するよりも高速である. 引数が0または負の値のとき,結果は求まらない.また,特別な値(±Inf, NaN)は扱うことができない.


Cbrt

立方根を計算する

float cvCbrt( float value );

value
浮動小数点型の入力値.

関数cvCbrtは,引数の立方根を計算する.これは,通常,pow(value,1./3)を計算するよりも高速である. 一方,負の引数も正しく処理される.また,特別な値(±Inf, NaN)は扱うことができない.


FastArctan

2次元のベクトルの角度を計算する

float cvFastArctan( float y, float x );

x
2次元ベクトルのx座標.
y
2次元ベクトルのy座標.

関数cvFastArctanは入力された2次元ベクトルの角度を計算する. 角度は度(degree)単位で扱われ,0°から360°の範囲で変化する.精度は ~0.1°.


IsNaN

引数が数値でないかどうかを確認する

int cvIsNaN( double value );

value
浮動小数点型の入力値.

関数cvIsNaNは,引数が数値(IEEE754 standard に定義されている)でなければ1を返し,その他の場合は0を返す.


IsInf

引数が無限大であるかどうかを確認する

int cvIsInf( double value );

value
浮動小数点型の入力値.

関数cvIsInfは,引数が±無限大(IEEE754 standard に定義されている)であれば1を返し,その他の場合は0を返す.


CartToPolar

2次元ベクトルの角度と大きさを計算する

void cvCartToPolar( const CvArr* x, const CvArr* y, CvArr* magnitude,
                    CvArr* angle=NULL, int angle_in_degrees=0 );

x
x座標の配列.
y
y座標の配列.
magnitude
大きさの出力配列.必要でなければNULLがセットされる.
angle
角度の出力配列.必要でなければNULLがセットされる.角度はラジアン(0..2π),または度(0..360°)で測定される.
angle_in_degrees
角度を表すためにラジアン(デフォルト値),または度のどちらを用いるかを示すフラグ.

関数cvCartToPolarは,2次元ベクトル(x(I),y(I))の大きさと角度のどちらか,またはその両方を計算する.

magnitude(I)=sqrt( x(I)2+y(I)2 ),
angle(I)=atan( y(I)/x(I) )

角度は≈0.1°の精度で計算される.(0,0)の場合,角度は0にセットされる.


PolarToCart

極座標形式で表現された2次元ベクトルのデカルト座標を計算する

void cvPolarToCart( const CvArr* magnitude, const CvArr* angle,
                    CvArr* x, CvArr* y, int angle_in_degrees=0 );

magnitude
大きさの配列.NULLの場合,大きさはすべて1と仮定される.
angle
角度の配列.単位はラジアン,または度である.
x
x座標の出力配列で,必要でなければNULLがセットされる.
y
y座標の出力配列で,必要でなければNULLがセットされる.
angle_in_degrees
このフラグは角度を表すために,ラジアン(デフォルト値)または度のどちらを用いるかを示す.

関数cvPolarToCartは,すべてのベクトルのx座標とy座標のどちらか, またその両方のmagnitude(I)*exp(angle(I)*j), j=sqrt(-1)を計算する.

x(I)=magnitude(I)*cos(angle(I)),
y(I)=magnitude(I)*sin(angle(I))

Pow

すべての配列要素を累乗する

void cvPow( const CvArr* src, CvArr* dst, double power );

src
入力配列.
dst
出力配列.入力と同じタイプでなければならない.
power
累乗の指数.

関数cvPowは,入力配列のすべての要素を以下のようにp乗する.

dst(I)=src(I)p, (p が整数の場合),
dst(I)=abs(src(I))p, (それ以外の場合)

累乗の指数が整数でない場合は,入力配列要素の絶対値が用いられる. しかし,いくつかの追加処理によって負の値に対しても正しい値を得ることができる.以下に,配列要素の立方根を計算する例を示す.

CvSize size = cvGetSize(src);
CvMat* mask = cvCreateMat( size.height, size.width, CV_8UC1 );
cvCmpS( src, 0, mask, CV_CMP_LT ); /* 負の要素を検出 */
cvPow( src, dst, 1./3 );
cvSubRS( dst, cvScalarAll(0), dst, mask ); /* 負の入力に対する結果を反転する */
cvReleaseMat( &mask );

整数や0.5,-0.5など一部のpowerの値に対しては,特に高速なアルゴリズムが用いられる.


Exp

すべての配列要素について自然対数の底(ネイピア数)eのべき乗を求める

void cvExp( const CvArr* src, CvArr* dst );

src
入力配列.
dst
出力配列.倍精度の浮動小数点型(double),または入力配列と同じタイプでなければならない.

関数cvExpは入力配列のすべての要素に対して,それを指数とする自然対数の底eのべき乗を求める.

dst(I)=exp(src(I))

最大相対誤差は≈7e-6.現在,この関数は,指数表現されない(denormalize)値を出力時に0に変換する.


Log

すべての配列要素の絶対値の自然対数を計算する

void cvLog( const CvArr* src, CvArr* dst );

src
入力配列.
dst
出力配列.倍精度の浮動小数点型(double),または入力配列と同じタイプでなければならない

関数cvLogは,入力配列のすべての要素の絶対値の自然対数を計算する.

dst(I)=log(abs(src(I))), (src(I)!=0の場合)
dst(I)=C,  (src(I)=0の場合)
ここで,C は大きな負の数である (現在の実装では≈-700).


SolveCubic

3次方程式の実根を求める

int cvSolveCubic( const CvMat* coeffs, CvMat* roots );

coeffs
式の係数で,3個または4個の要素を持つ配列.
roots
実根の出力配列.三つの要素を持つ.

関数cvSolveCubicは,3次方程式の実根を求める.

coeffs[0]*x3 + coeffs[1]*x2 + coeffs[2]*x + coeffs[3] = 0
(coeffsが4要素のベクトルの場合)

or

x3 + coeffs[0]*x2 + coeffs[1]*x + coeffs[2] = 0
(coeffsが3要素のベクトルの場合)

この関数は求めた実根の数を返し,配列rootsに根を格納する. 一つの根しかない場合,出力配列はには0が追加される.


乱数生成(Random Number Generation)


RNG

乱数生成器の状態を初期化する

CvRNG cvRNG( int64 seed=-1 );

seed
ランダムシーケンスを開始するために使用される64ビットの数値.

関数cvRNGは乱数生成器を初期化し,その状態を返す. 状態へのポインタは関数cvRandIntcvRandRealcvRandArrに渡される.現在の実装では,multiply-with-carry RNGが利用されている.


RandArr

配列を乱数で埋め,RNGの状態を更新する

void cvRandArr( CvRNG* rng, CvArr* arr, int dist_type, CvScalar param1, CvScalar param2 );

rng
cvRNGによって初期化されたRNGの状態.
arr
出力配列.
dist_type
分布のタイプ.
CV_RAND_UNI - 一様分布
CV_RAND_NORMAL - 正規分布(ガウス分布)
param1
分布の第一パラメータ.一様分布では,発生する乱数の下限値(この値を含む)である. 正規分布では,乱数の平均値である.
param2
分布の第二パラメータ.一様分布では,発生する乱数の上限値(この値は含まない)である. 正規分布では,乱数の標準偏差である.

関数cvRandArrは,一様または正規分布の乱数で出力配列を埋める. 正規分布の浮動小数点型の値を2次元配列中のランダムな位置に加算する例を以下に示す.

/* noisy_screenを,「めちゃくちゃな」浮動小数点型の2次元配列にする */
CvRNG rng_state = cvRNG(0xffffffff);
int i, pointCount = 1000;
/* 点の座標の配列を確保する */
CvMat* locations = cvCreateMat( pointCount, 1, CV_32SC2 );
/* ランダムな点の値の配列 */
CvMat* values = cvCreateMat( pointCount, 1, CV_32FC1 );
CvSize size = cvGetSize( noisy_screen );

cvRandInit( &rng_state,
            0, 1, /* 現在はダミーパラメータを使用し,さらにそれらを調整する */
            0xffffffff /* ここでは,固定された種を使用する */,
            CV_RAND_UNI /* 一様分布の指定 */ );

/* 位置の初期化 */
cvRandArr( &rng_state, locations, CV_RAND_UNI, 
           cvScalar(0,0,0,0), cvScalar(size.width,size.height,0,0) );

/* 正規分布値を生成するRNGを作るためにRNGを修正する */
rng_state.disttype = CV_RAND_NORMAL;
cvRandSetRange( &rng_state,
                30 /* 偏差 */,
                100 /* 点の明るさの平均 */,
                -1 /* すべての次元を初期化する */ );
/* 値を生成 */
cvRandArr( &rng_state, values, CV_RAND_NORMAL,
           cvRealScalar(100), // average intensity
           cvRealScalar(30) // deviation of the intensity
           );

/* 点の集合 */
for( i = 0; i < pointCount; i++ )
{
    CvPoint pt = *(CvPoint*)cvPtr1D( locations, i, 0 );
    float value = *(float*)cvPtr1D( values, i, 0 );
    *((float*)cvPtr2D( noisy_screen, pt.y, pt.x, 0 )) += value;
}

/* 一時的な配列を解放することを忘れないように */
cvReleaseMat( &locations );
cvReleaseMat( &values );

/* RNG状態は解放の必要はない */

RandInt

32ビット符号なし整数を返し,RNGを更新する

unsigned cvRandInt( CvRNG* rng );

rng
RandInitによって初期化され, オプションでRandSetRangeによってカスタマイズされたRNGの状態(後者の関数は,この関数の結果に影響を及ぼさない).

関数cvRandIntは,一様分布した32ビット符号なし整数型の乱数を返し,RNGの状態を更新する. これは,C言語のランタイムライブラリでいうところのrand() 関数に類似している. しかし,rand()が0からRAND_MAX(2**16 または 2**32,プラットホームに依存する)までの数を返すの対して,この関数では常に32ビットの数を生成する. この関数は点座標やパッチサイズ,テーブルインデックスなどのスカラーの乱数を生成するのに役立つ. ここで,ある範囲の整数は剰余演算によって生成され,浮動小数点型の数は,指定範囲を0..1にスケーリングすることで生成することができる. cvRandIntを利用して,前述の例を書き直したものを以下に示す.

/* 入力とタスクは前のサンプルと同じである. */
CvRNG rng_state = cvRNG(0xffffffff);
int i, pointCount = 1000;
/* ... - ここで配列は確保されない */
CvSize size = cvGetSize( noisy_screen );
/* オーバヘッドを減らすため,正規分布した数値のためのバッファを生成する */
#define bufferSize 16
float normalValueBuffer[bufferSize];
CvMat normalValueMat = cvMat( bufferSize, 1, CV_32F, normalValueBuffer );
int valuesLeft = 0;

for( i = 0; i < pointCount; i++ )
{
    CvPoint pt;
    /* ランダムな点の生成 */
    pt.x = cvRandInt( &rng_state ) % size.width;
    pt.y = cvRandInt( &rng_state ) % size.height;

    if( valuesLeft <= 0 )
    {
        /* バッファが空の場合,正規分布した数値でバッファを埋める */
        cvRandArr( &rng_state, &normalValueMat, 
                   CV_RAND_NORMAL, cvRealScalar(100), cvRealScalar(30) );
        valuesLeft = bufferSize;
    }
    *((float*)cvPtr2D( noisy_screen, pt.y, pt.x, 0 ) = normalValueBuffer[--valuesLeft];
}

/* 行列のヘッダとデータはスタックに持っているため,normalValueMatを解放する必要はない.
   これは小さい固定サイズの行列で実行する際に,良く知られている効果的な方法である*/

RandReal

浮動小数点型の乱数を返し,RNGを更新する

double cvRandReal( CvRNG* rng );

rng
cvRNGによって初期化された,RNGの状態.

関数cvRandRealは,0から1(1は含まれない)の範囲に一様分布する浮動小数点型の乱数を返す.


離散変換(Discrete Transforms)


DFT

1次元あるいは2次元浮動小数点型配列に対して離散フーリエ変換(DFT),逆離散フーリエ変換(IDFT)を行う

#define CV_DXT_FORWARD  0
#define CV_DXT_INVERSE  1
#define CV_DXT_SCALE    2
#define CV_DXT_ROWS     4
#define CV_DXT_INV_SCALE (CV_DXT_SCALE|CV_DXT_INVERSE)
#define CV_DXT_INVERSE_SCALE CV_DXT_INV_SCALE

void cvDFT( const CvArr* src, CvArr* dst, int flags, int nonzero_rows=0 );

src
入力配列(実数または複素数).
dst
入力配列と同じサイズ・タイプの出力配列.
flags
変換フラグ.以下の値の組み合わせ.
CV_DXT_FORWARD - 1次元または2次元の順変換を行う.結果のスケーリングは行わない.
CV_DXT_INVERSE - 1次元または2次元の逆変換を行う.結果のスケーリングは行わない. CV_DXT_FORWARDCV_DXT_INVERSE は,もちろん同時には指定できない.
CV_DXT_SCALE - 結果を配列要素数で割り,スケーリングする.通常は CV_DXT_INVERSE と同時に用いる.ショートカットとして CV_DXT_INV_SCALE を用いても良い.
CV_DXT_ROWS - 入力配列のそれぞれの行に対して独立に,順変換あるいは逆変換を行う. このフラグは複数のベクトルの同時変換を許可し,オーバーヘッド(一つの計算の何倍も大きくなることもある)を減らすためや,3次元以上の高次元に対して変換を行うために使用される.
nonzero_rows
入力配列の非0である行の数(2次元順変換の場合),あるいは出力配列で注目する行の数(2次元逆変換の場合). この値が負,0,あるいは行の数より大きい場合は無視される. このパラメータにより,DFTを用いて2次元の畳み込みや相関演算を行う際の計算速度が向上する.詳しくは,以下のサンプルを参照.

関数 cvDFT は,以下に示すように1次元あるいは2次元浮動小数点型配列の順変換・逆変換を行う.

N個の要素を持つ1次元ベクトルのフーリエ変換:
y = F(N) • x, ここで, F(N)jk=exp(-i • 2Pi • j • k/N),i=sqrt(-1)

N個の要素を持つ1次元ベクトルの逆フーリエ変換:
x'= (F(N))-1 • y = conj(F(N)) • y
x = (1/N) • x

M × N個の要素を持つ2次元ベクトルのフーリエ変換:
Y = F(M)• X •F(N)

M × N個の要素を持つ2次元ベクトルの逆フーリエ変換:
X'= conj(F(M))• Y • conj(F(N))
X = (1/(M • N)) • X'

IPLで用いられる,実数(シングルチャンネル)packedフォーマットのデータが,フーリエ変換の結果あるいは逆フーリエ変換の入力を表現するために用いられる.

Re Y0,0      Re Y0,1    Im Y0,1    Re Y0,2     Im Y0,2  ...  Re Y0,N/2-1   Im Y0,N/2-1  Re Y0,N/2
Re Y1,0      Re Y1,1    Im Y1,1    Re Y1,2     Im Y1,2  ...  Re Y1,N/2-1   Im Y1,N/2-1  Re Y1,N/2
Im Y1,0      Re Y2,1    Im Y2,1    Re Y2,2     Im Y2,2  ...  Re Y2,N/2-1   Im Y2,N/2-1  Im Y2,N/2
............................................................................................
Re YM/2-1,0   Re YM-3,1   Im YM-3,1  Re YM-3,2   Im YM-3,2 ...  Re YM-3,N/2-1  Im YM-3,N/2-1 Re YM-3,N/2
Im YM/2-1,0   Re YM-2,1   Im YM-2,1  Re YM-2,2   Im YM-2,2 ...  Re YM-2,N/2-1  Im YM-2,N/2-1 Im YM-2,N/2
Re YM/2,0    Re YM-1,1   Im YM-1,1  Re YM-1,2   Im YM-1,2  ... Re YM-1,N/2-1  Im YM-1,N/2-1 Im YM-1,N/2

注釈:N が偶数なら最終列が存在し,M が偶数なら最終行が存在する.

1次元実数変換の場合,結果は上の行列の1行目のようになる.

DFTを用いた2次元畳み込みの計算

   CvMat* A = cvCreateMat( M1, N1, CV_32F );
   CvMat* B = cvCreateMat( M2, N2, A->type );

   // 畳み込み結果の一部(abs(M2-M1)+1×abs(N2-N1)+1)のみを持つ可能性もある
   CvMat* conv = cvCreateMat( A->rows + B->rows - 1, A->cols + B->cols - 1, A->type );

   // AとBを初期化
   ...

   int dft_M = cvGetOptimalDFTSize( A->rows + B->rows - 1 );
   int dft_N = cvGetOptimalDFTSize( A->cols + B->cols - 1 );

   CvMat* dft_A = cvCreateMat( dft_M, dft_N, A->type );
   CvMat* dft_B = cvCreateMat( dft_M, dft_N, B->type );
   CvMat tmp;

   // Aを dft_Aにコピーし,dft_A の右部残りを0で埋める
   cvGetSubRect( dft_A, &tmp, cvRect(0,0,A->cols,A->rows));
   cvCopy( A, &tmp );
   cvGetSubRect( dft_A, &tmp, cvRect(A->cols,0,dft_A->cols - A->cols,A->rows));
   cvZero( &tmp );
   // 以下のcvDFT()では,パラメータnonzero_rowsを用いているため,
   // dft_Aの下部を0で埋める必要はない

   cvDFT( dft_A, dft_A, CV_DXT_FORWARD, A->rows );

   // 2番目の配列に対しても同様に繰り返す
   cvGetSubRect( dft_B, &tmp, cvRect(0,0,B->cols,B->rows));
   cvCopy( B, &tmp );
   cvGetSubRect( dft_B, &tmp, cvRect(B->cols,0,dft_B->cols - B->cols,B->rows));
   cvZero( &tmp );
   // 以下のcvDFT()では,パラメータnonzero_rowsを用いているため,
   // dft_Bの下部を0で埋める必要はない

   cvDFT( dft_B, dft_B, CV_DXT_FORWBRD, B->rows );

   cvMulSpectrums( dft_A, dft_B, dft_A, 0 /* 畳み込みではなく相関を得るためには 
                                                     CV_DXT_MUL_CONJ を指定する */ );

   cvDFT( dft_A, dft_A, CV_DXT_INV_SCALE, conv->rows ); // 上部のみを計算する
   cvGetSubRect( dft_A, &tmp, cvRect(0,0,conv->cols,conv->rows) );

   cvCopy( &tmp, conv );


GetOptimalDFTSize

与えられたベクトルのサイズに対する最適なDFTのサイズを返す

int cvGetOptimalDFTSize( int size0 );

size0
ベクトルのサイズ.

関数 cvGetOptimalDFTSize は,size0以上の最小値N を返し, 得られたサイズNのベクトルに対するDFTは高速に計算できる. 現在の実装では,ある p, q, r について,N=2p×3q×5r

size0 が非常に大きな値(INT_MAX に非常に近い)の場合,この関数は負の値を返す.


MulSpectrums

二つのフーリエスペクトラムの要素ごとの乗算を行う

void cvMulSpectrums( const CvArr* src1, const CvArr* src2, CvArr* dst, int flags );

src1
1番目の入力配列.
src2
2番目の入力配列.
dst
入力配列と同じタイプ・サイズの出力配列.
flags
以下の値の組み合わせ.
CV_DXT_ROWS - 配列の各行を個別のスペクトラムとして扱う (cvDFT のパラメータを参照).
CV_DXT_MUL_CONJ - 乗算の前に2番目の入力配列の共役を計算する

関数 cvMulSpectrums は,実フーリエ変換あるいは複素フーリエ変換の結果として得られた二つのCCS-packed行列,または複素行列の要素ごとの乗算を行う.

この関数とcvDFTを共に用いることで,二つの配列の高速な畳み込み計算が可能である.


DCT

1次元あるいは2次元浮動小数点型配列の順方向・逆方向離散コサイン変換を行う

#define CV_DXT_FORWARD  0
#define CV_DXT_INVERSE  1
#define CV_DXT_ROWS     4

void cvDCT( const CvArr* src, CvArr* dst, int flags );

src
入力配列(実数の1次元あるいは2次元配列).
dst
入力と同じサイズ・タイプの出力配列.
flags
変換フラグ.以下の値の組み合わせ.
CV_DXT_FORWARD - 1次元あるいは2次元の順変換.
CV_DXT_INVERSE - 1次元あるいは2次元の逆変換.
CV_DXT_ROWS - 入力配列のそれぞれの行に対して,独立に順変換あるいは逆変換を行う. このフラグは複数ベクトルの同時変換を許可し, オーバーヘッド(一つの計算の何倍も大きくなることもある)を減らすためや,3次元以上の高次元に対して変換を行うために使用される.

関数 cvDCT は以下のように,1次元あるいは2次元浮動小数点型配列に対して順方向・逆方向離散コサイン変換を行う.

N個の要素を持つ1次元ベクトルの順方向コサイン変換:
y = C(N)•x, ここで C(N)jk=sqrt((j==0?1:2)/N)•cos(Pi•(2k+1)•j/N)

N個の要素を持つ1次元ベクトルの逆方向コサイン変換:
x = (C(N))-1•y = (C(N))T•y

M×N 個の要素を持つ2次元ベクトルの順方向コサイン変換:
Y = (C(M))•X•(C(N))T

M×N 個の要素を持つ2次元ベクトルの逆方向コサイン変換:
X = (C(M))T•Y•C(N)

動的構造体(Dynamic Structures)


メモリストレージ(Memory Storages)


CvMemStorage

動的に拡張可能なメモリストレージ

typedef struct CvMemStorage
{
    struct CvMemBlock* bottom;/* 最初に確保されたブロック */
    struct CvMemBlock* top; /* 新たなブロックを確保する場所 */
    struct CvMemStorage* parent; /* 現在のメモリブロック − スタックの先頭 */
    int block_size; /* ブロックの大きさ */
    int free_space; /* topブロック内の自由領域(バイト単位) */
} CvMemStorage;

メモリストレージは低レベルの構造体で,動的に拡張可能なデータ構造を持ち,シーケンスや輪郭,グラフ,細分化などに使われる. これは同じサイズのメモリブロックのリストとして編成されている. bottomフィールドはブロックのリストの先頭,topは現在使われているブロックを意味するが, リストの最後のブロックは必ずしも必要ではない.後者(ここではtop)以外のbottomからtopまでのブロックは全て占有されている. topを除くtopから最後までのすべてのブロックは空き領域で,topブロック自体は部分的に占有されている. free_spaceは,topの後ろに残されているバイト単位で示された自由領域を意味する.

関数cvMemStorageAllocで明示的に, もしくはcvSeqPushcvGraphAddEdge などの高レベル関数によって間接的に確保された新たなメモリ領域は,そこに納まる場合には常に現在のブロックの最後に確保される. 確保後free_spaceは,適切なアライメントを保持するために,確保したバッファサイズにパディングを加えた分ずつ減らされる. 確保されたバッファがtopの利用可能な領域に納まらない場合, リストの次のストレージブロックがtopとして用いられ, free_spaceは確保前の全ブロックサイズにリセットされる.

もし空きブロックがない場合,新しいブロックが確保され (または親から借りて,cvCreateChildMemStorageを参照), リストの最後に追加される.このようにこのストレージはスタックとして振る舞い, bottomがスタックの底, topfree_spaceのペアがスタックの先頭を示す. スタックの先頭はcvSaveMemStoragePosで保存, cvRestoreMemStoragePosで復元, cvClearStorageでリセットされる.


CvMemBlock

メモリストレージブロック

typedef struct CvMemBlock
{
    struct CvMemBlock* prev;
    struct CvMemBlock* next;
} CvMemBlock;

typedef struct CvMemBlock
{
struct CvMemBlock* prev;
struct CvMemBlock* next;
} CvMemBlock;

構造体CvMemBlockは,メモリストレージの1ブロックを表現する. 実際のメモリブロックのデータはヘッダの後にあり, メモリブロックのi番目のバイトは((char*)(mem_block_ptr+1))[i]で取り出すことができる. しかし通常,直接アクセスする必要はない.


CvMemStoragePos

メモリストレージの位置

typedef struct CvMemStoragePos
{
    CvMemBlock* top;
    int free_space;
} CvMemStoragePos;

この構造体はスタックの先頭位置を保持しており, cvSaveMemStoragePosで保存, cvRestoreMemStoragePosで復元できる.


CreateMemStorage

メモリストレージを生成する

CvMemStorage* cvCreateMemStorage( int block_size=0 );

block_size
ストレージブロックのバイト単位のサイズ.0の場合,デフォルト値(現在は≈64K)が使われる.

関数cvCreateMemStorageはメモリストレージを生成し,そのポインタを返す.初期状態ではストレージは空である. block_sizeを除くヘッダのフィールドは全て0に設定されている.


CreateChildMemStorage

子メモリストレージを生成する

CvMemStorage* cvCreateChildMemStorage( CvMemStorage* parent );

parent
親メモリストレージ.

関数 cvCreateChildMemStorageは,メモリ確保/解放機構の違いを除いて, 単純なメモリストレージに似た子メモリストレージを生成する. 子ストレージが新しいブロックをブロックリストに追加する必要がある場合, 子は親からブロックを取り出すことを試みる. 親に占有されていない利用可能な最初のブロックが取り出され,その部分は親のブロックリストから排除される. 利用可能なブロックがない場合,もし親の親が存在すれば,親はそこからブロックを確保するか借りる. つまり,それぞれのストレージが別のストレージの親や子になるような,チェインやさらに複雑な構造のメモリストレージが可能になる. 子ストレージが解放されるかクリアされた場合,その全てのブロックは親に返される.別の見方をすると,子ストレージは単純なストレージと同じである.

子ストレージは以下の状況において有用である.幾つかのストレージに分かれて存在する動的データを処理して, その結果を同じストレージに置く必要があるような状況を想像してほしい. 最も単純に,一時的なデータを入出力データと同じストレージに置く方法では,処理後のストレージは以下のようになる.

子ストレージを利用せずに動的なデータ処理を行った場合

子ストレージを利用せずに動的なデータ処理を行った場合

このようにストレージの中央にごみが残ってしまう. しかし処理の始めに子メモリストレージを生成して,一時的なデータをそこに書き込み,最後に解放した場合,ごみは入力/出力ストレージに残らない.

子ストレージを利用して動的なデータ処理を行った場合

子ストレージを利用して動的なデータ処理を行った場合


ReleaseMemStorage

メモリストレージを解放する

void cvReleaseMemStorage( CvMemStorage** storage );

storage
解放するストレージのポインタ.

関数cvReleaseMemStorageは,ストレージの全メモリブロックを解放し,もし親がいれば親に返す. その際にストレージヘッダも解放され,ストレージへのポインタもクリアされる. 全ての子ストレージは親を解放する前に解放しておく必要がある.


ClearMemStorage

メモリストレージをクリアする

void cvClearMemStorage( CvMemStorage* storage );

storage
メモリストレージ.

関数cvClearMemStorageは,ストレージの先頭(空き領域の境界)を,一番最初に戻す. この関数はメモリを解放しない.もしストレージが親を持つ場合,この関数は親に全てのブロックを返す.


MemStorageAlloc

ストレージ内にメモリバッファを確保する

void* cvMemStorageAlloc( CvMemStorage* storage, size_t size );

storage
メモリストレージ.
size
バッファサイズ.

関数cvMemStorageAllocは,ストレージ内にメモリバッファを確保する. バッファサイズは,ストレージのブロックサイズを超えてはいけない. 超えた場合にはランタイムエラーが発生する. バッファアドレスは,CV_STRUCT_ALIGN(現時点では=sizeof(double))バイトにアライメントされる.


MemStorageAllocString

ストレージ内にテキスト文字列を確保する

typedef struct CvString
{
    int len;
    char* ptr;
}
CvString;

CvString cvMemStorageAllocString( CvMemStorage* storage, const char* ptr, int len=-1 );

storage
メモリストレージ.
ptr
文字列.
len
文字列の長さ(終端の'¥0'は数えない).負の場合,この関数が長さを計算する.

関数cvMemStorageAllocStringは,メモリストレージ内に文字列のコピーを生成する. この関数はユーザが渡した,もしくは計算された文字列の長さとコピーされた文字列へのポインタを持つ構造体を返す.


SaveMemStoragePos

メモリストレージの位置を保存する

void cvSaveMemStoragePos( const CvMemStorage* storage, CvMemStoragePos* pos );

storage
メモリストレージ.
pos
出力するストレージ先頭の位置.

関数cvSaveMemStoragePosは,ストレージの先頭の現在位置をパラメータposに保存する. 関数cvRestoreMemStoragePosで,この位置を復元することができる.


RestoreMemStoragePos

メモリストレージの位置を復元する

void cvRestoreMemStoragePos( CvMemStorage* storage, CvMemStoragePos* pos );

storage
メモリストレージ.
pos
新しいストレージの先頭位置.

関数 cvRestoreMemStoragePosは,パラメータposからストレージの先頭を復元する. この関数と関数cvClearMemStorageは,メモリブロック内で占有されたメモリを解放する唯一の方法である. ストレージの占有部分の途中のメモリを解放する方法は無いことに十分注意すること.


シーケンス(Sequences)


CvSeq

拡張可能な要素のシーケンス

#define CV_SEQUENCE_FIELDS() ¥
    int flags; /* 様々なフラグ */ ¥
    int header_size; /* シーケンスのヘッダサイズ */ ¥
    struct CvSeq* h_prev; /* 一つ前のシーケンスへのポインタ */ ¥
    struct CvSeq* h_next; /* 一つ後のシーケンスへのポインタ */ ¥
    struct CvSeq* v_prev; /* 一つ前のシーケンスへのポインタ(セカンダリ,構造によって意味が異なる) */ ¥
    struct CvSeq* v_next; /* 一つ後のシーケンスへのポインタ(セカンダリ,構造によって意味が異なる) */ ¥
    int total; /* 要素の総数 */ ¥
    int elem_size;/* シーケンス要素のサイズ(バイト単位) */ ¥
    char* block_max;/* 最新のブロックの最大値 */ ¥
    char* ptr; /* 現在の書き込みポインタ */ ¥
    int delta_elems; /* シーケンスを拡張させる際に,領域確保する要素数(シーケンスの粒度) */ ¥
    CvMemStorage* storage; /* seqが保存される領域 */ ¥
    CvSeqBlock* free_blocks; /* 空きブロックリスト */ ¥
    CvSeqBlock* first; /* 先頭シーケンスブロックへのポインタ */


typedef struct CvSeq
{
    CV_SEQUENCE_FIELDS()
} CvSeq;

構造体 CvSeq は,OpenCVの動的データ構造すべての基本となるものである.

上記の補助マクロを介した特殊な定義により,追加パラメータを伴う構造体CvSeq の拡張が容易に行える. CvSeq を拡張するために,新しい構造体を定義し,マクロCV_SEQUENCE_FIELDS()によって列挙される CvSeq のフィールドの後にユーザー定義フィールドをおいてもよい.

シーケンスには,密なシーケンスと疎なシーケンスの2種類が存在する. 密なシーケンスの基本タイプは CvSeq であり,このシーケンスは拡張可能な1次元配列 (ベクトル(vectors),スタック(stacks),キュー(queues),デック(deques))を表現するのに用いられる. これらのタイプにはデータの中間部分に空白部がない.すなわち,シーケンスの中間部分における要素の削除や追加の際には,最も近い終端の要素からシフトされる. 疎なシーケンスは,CvSetをその基本クラスとして持つ.詳細は後述する. それらは,ノードフラグによって「データがある」か「空き」かが示されているノードシーケンスである. このタイプのシーケンスは,要素の集合(sets),グラフ(graph),ハッシュテーブル(hash tables)等の順序のないデータ構造に用いられる.

フィールド header_size は,シーケンスヘッダの実サイズが入っており, そのサイズは,sizeof(CvSeq)より大きいか等しくなけらばならない.

フィールド h_prev, h_next, v_prev, v_next は,別々のシーケンス群から階層構造を生成するために使用できる. フィールド h_prevh_next は,同一階層での前後のシーケンスを指し, さらに,フィールド v_prevv_next は縦方向での前後のシーケンス(自分の親と最初の子)を指す. しかし,これらは単に名前にすぎず,これらのポインタを異なる意味で使用することが可能である.

フィールド first は,ブロックの先頭シーケンスを指す.この構造については以下で述べる.

フィールド total は,密なシーケンスでは実要素数,疎なシーケンスでは領域確保されたノード数を示す.

フィールド flags は,上位16ビットで個々の動的特性 (密なシーケンスではCV_SEQ_MAGIC_VAL ,疎なシーケンスではCV_SET_MAGIC_VAL)と, シーケンスに関するその他の雑多な情報を持つ. 下位 CV_SEQ_ELTYPE_BITS ビットは,要素タイプのIDを示す. ほとんどのシーケンス処理関数は要素タイプではなく,elem_sizeに保存された要素サイズを使用する. シーケンスがCvMatタイプの一つであるような数値データからなる場合, シーケンスの要素タイプは対応するCvMatの要素タイプと一致する (例えば,2次元の点データのシーケンスではCV_32SC2が,浮動小数点型のシーケンスにはCV_32FC1が用いられるなど). マクロ CV_SEQ_ELTYPE(seq_header_ptr) は,シーケンスの要素のタイプを取り出す. 数値シーケンスを扱う関数では elem_size が,その要素タイプから計算されたものと等しいかどうかがチェックされる. さらに,CvMat に準拠したタイプでは,ヘッダcvtypes.hで定義された以下の追加要素タイプが存在する:

標準的なシーケンス要素の種類

    #define CV_SEQ_ELTYPE_POINT          CV_32SC2  /* (x,y) */
    #define CV_SEQ_ELTYPE_CODE           CV_8UC1   /* フリーマンコード: 0..7 */
    #define CV_SEQ_ELTYPE_GENERIC        0 /* 一般的なシーケンス要素タイプ */
    #define CV_SEQ_ELTYPE_PTR            CV_USRTYPE1 /* =6 */
    #define CV_SEQ_ELTYPE_PPOINT         CV_SEQ_ELTYPE_PTR  /* &elem: 他のシーケンス要素へのポインタ */
    #define CV_SEQ_ELTYPE_INDEX          CV_32SC1  /* #elem: 他のシーケンス要素のインデックス */
    #define CV_SEQ_ELTYPE_GRAPH_EDGE     CV_SEQ_ELTYPE_GENERIC  /* &next_o, &next_d, &vtx_o, &vtx_d */
    #define CV_SEQ_ELTYPE_GRAPH_VERTEX   CV_SEQ_ELTYPE_GENERIC  /* 先頭の辺, &(x,y) */
    #define CV_SEQ_ELTYPE_TRIAN_ATR      CV_SEQ_ELTYPE_GENERIC  /* 二分木の頂点(ノード)   */
    #define CV_SEQ_ELTYPE_CONNECTED_COMP CV_SEQ_ELTYPE_GENERIC  /* 接続成分  */
    #define CV_SEQ_ELTYPE_POINT3D        CV_32FC3  /* (x,y,z)  */

次の,CV_SEQ_KIND_BITS ビットは,シーケンスの種類を指定する.

標準的なシーケンスの種類

    /* 一般的な(特別な指定無しの)シーケンスの種類 */
    #define CV_SEQ_KIND_GENERIC     (0 << CV_SEQ_ELTYPE_BITS)

    /* 密なシーケンスのサブタイプ */
    #define CV_SEQ_KIND_CURVE       (1 << CV_SEQ_ELTYPE_BITS)
    #define CV_SEQ_KIND_BIN_TREE    (2 << CV_SEQ_ELTYPE_BITS)

    /* 疎なシーケンス(または集合)のサブタイプ */
    #define CV_SEQ_KIND_GRAPH       (3 << CV_SEQ_ELTYPE_BITS)
    #define CV_SEQ_KIND_SUBDIV2D    (4 << CV_SEQ_ELTYPE_BITS)

残りのビットは,これ以外のシーケンスの種類や要素タイプを指定するために用いられる. 例えば,点(CV_SEQ_KIND_CURVE|CV_SEQ_ELTYPE_POINT )から構成される曲線では,タイプ CV_SEQ_POLYGON に属するフラグCV_SEQ_FLAG_CLOSED や,他のフラグがそのサブタイプを表現するために用いられる. 多くの輪郭処理関数は,入力シーケンスのタイプをチェックし,そのタイプがサポート外である場合はエラーを発生する. ファイル cvtypes.h には,サポートされている定義済みシーケンスタイプやその他の属性を取得する補助マクロの全リストが記述されている. 以下はシーケンスを構成するための基本要素の定義である.


CvSeqBlock

連続したシーケンスブロック

typedef struct CvSeqBlock
{
    struct CvSeqBlock* prev; /* 前のシーケンスブロック */
    struct CvSeqBlock* next; /* 次のシーケンスブロック */
    int start_index; /* ブロックの先頭要素のインデックス +
    sequence->first->start_index */
    int count; /* ブロック内の要素数 */
    char* data; /* ブロックの先頭要素へのポインタ */
} CvSeqBlock;

シーケンスブロックは,循環双方向リストを構成する. そのためポインタ prevnext は決してNULL にはならず,シーケンス中の前後のシーケンスブロックを指す. つまり,最終ブロックの next は先頭ブロックを,先頭ブロックの prev は最終ブロックをそれぞれ指している. フィールド start_indexcount はシーケンスの中でブロックの位置を追跡する際に役立つ. 例えば,シーケンスが10要素からなっており,それが3,5,2要素に分かれており,先頭ブロックがパラメータstart_index = 2で与えられている場合, このシーケンスブロックの (start_index, count) のペアは,それぞれ (2,3), (5, 5), (10, 2) となる. 先頭ブロックのパラメータ start_index は,ある要素がシーケンスの先頭に追加されている場合を除いて,通常 0 である.


CvSlice

シーケンスのスライス

typedef struct CvSlice
{
    int start_index;
    int end_index;
} CvSlice;

inline CvSlice cvSlice( int start, int end );
#define CV_WHOLE_SEQ_END_INDEX 0x3fffffff
#define CV_WHOLE_SEQ  cvSlice(0, CV_WHOLE_SEQ_END_INDEX)

/* シーケンスのスライス長を計算する */
int cvSliceLength( CvSlice slice, const CvSeq* seq );

シーケンスを処理する関数のうちいくつかは,デフォルトでシーケンス全体(CV_WHOLE_SEQ)がセットされているパラメータ CvSlice slice を使用する. start_indexend_index が負かシーケンス長を超えている場合でも, start_indexは境界に含まれ(スライスに含まれる),end_index は境界に含まれない(スライスに含まれない). これらが等しい場合は,スライスは空である(すなわち要素が無い)とみなされる. シーケンスは循環構造として取り扱われるため,シーケンス最後の数個の要素と,それに続くシーケンス最初の数個の要素をスライスとして選択できる. 例えば,10個の要素をもつシーケンスの cvSlice(-2, 3) は,最終の一つ前(8th),最終(9th),先頭(0th), 2番目(1th) そして3番目(2nd)の要素からなる. この関数はスライスの引数を以下の方法で正規化する. まずスライス長を調べるために cvSliceLength を呼び出し, cvGetSeqElem の引数と同様に, スライスの start_index が正規化される(すなわち,負のインデックスが使用できる). 実際のスライスは,正規化された start_index に始まり, cvSliceLength 要素まで処理される(シーケンスが循環構造であると仮定していることに重ねて注意).

スライスを引数としてとらない関数でシーケンスの一部だけ処理したい場合は,関数 cvSeqSlice を用いてサブシーケンスを抽出したり,cvCvtSeqToArray で連続バッファとして保存する事で可能になる(オプションとして,続けて cvMakeSeqHeaderForArray を呼ぶ ).


CreateSeq

シーケンスを生成する

CvSeq* cvCreateSeq( int seq_flags, int header_size,
                    int elem_size, CvMemStorage* storage );

seq_flags
生成されたシーケンスのフラグ.生成されたシーケンスが,特定のシーケンスタイプを引数にとるような関数に一切渡されない場合は,この値に0を指定してもかまわない.そうでない場合は,定義済みのシーケンスタイプのリストから適切なタイプが選択されなければならない.
header_size
シーケンスのヘッダサイズ.sizeof(CvSeq)以上でなければならない. また,特別なタイプかその拡張が指示されている場合,そのタイプは基本タイプのヘッダと合致していなければならない.
elem_size
シーケンスの要素サイズ(バイト単位).サイズはシーケンスタイプと合致しなければならない.例えば,点群のシーケンスを作成する場合,要素タイプにCV_SEQ_ELTYPE_POINTを指定し,パラメータ elem_sizesizeof(CvPoint) と等しくなければならない.
storage
シーケンスが保存される場所.

関数 cvCreateSeq は,シーケンスを作成し,そのポインタを返す. この関数は,シーケンスヘッダをストレージ内の連続した一つのブロックとして領域確保し, 引数として渡された値を構造体のフィールド flagselem_sizeheader_sizestorageに引数で渡した値をセットする. そして,delta_elems にデフォルト値(関数 cvSetSeqBlockSize で再設定できる)をセットし,その他のヘッダフィールド(先頭から sizeof(CvSeq) バイト以降のスペースも含む)をクリアする.


SetSeqBlockSize

シーケンスのブロックサイズを設定する

void cvSetSeqBlockSize( CvSeq* seq, int delta_elems );

seq
シーケンス.
delta_elems
シーケンス要素のブロックサイズ.

関数 cvSetSeqBlockSize は,メモリ確保サイズを指定する. シーケンスバッファ上の空き領域を使い果たした場合,関数は delta_elems シーケンス要素分の領域確保を行う. 確保したブロックが前のブロックの直後になる場合,二つのブロックは接続されるが,それ以外では,新しいシーケンスブロックが生成される. そのため,このパラメータを大きくすることによってシーケンスブロックの断片化は押さえられるものの, ストレージ中の多くのスペースが浪費されることになる. シーケンス生成時に,パラメータ delta_elems にはデフォルト値≈1K がセットされる. シーケンス生成後,この関数をいつでも呼ぶことができ,以降の領域確保の際にその値が使われる. この関数によって,渡されたパラメータ値をメモリストレージの制限に合わせるために変更することができる.


SeqPush

シーケンスの末尾に要素を追加する

char* cvSeqPush( CvSeq* seq, void* element=NULL );

seq
シーケンス.
element
追加される要素.

関数 cvSeqPush は,シーケンスの末尾に要素を追加し,割り付けられた要素へのポインタを返す. 入力の element が NULL の場合,この関数は単に要素一つ分の領域を確保する.

以下のコードは,この関数を用いて新しいシーケンスを作成する方法を示す.

CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* seq = cvCreateSeq( CV_32SC1, /* 整数型要素のシーケンス */
                          sizeof(CvSeq), /* ヘッダサイズ - 拡張フィールド無し */
                          sizeof(int), /* 要素サイズ */
                          storage /* 保存領域 */ );
int i;
for( i = 0; i < 100; i++ )
{
    int* added = (int*)cvSeqPush( seq, &i );
    printf( "%d is added¥n", *added );
}

...
/* 最後にメモリストレージを解放する */
cvReleaseMemStorage( &storage );

関数 cvSeqPush の計算量はO(1)であるが,大規模なシーケンスデータの書き込みにはより高速な手法が存在する (cvStartWriteSeqと関連する関数を参照).


SeqPop

シーケンスの末尾から要素を削除する

void cvSeqPop( CvSeq* seq, void* element=NULL );

seq
シーケンス.
element
オプションパラメータ.ポインタが非0の場合,削除した要素をこの場所にコピーする.

関数 cvSeqPop はシーケンスから一つの要素を削除する.シーケンスが既に空の場合は,エラーを返す.この関数の計算量は O(1) である.


SeqPushFront

シーケンスの先頭に要素を追加する.

char* cvSeqPushFront( CvSeq* seq, void* element=NULL );

seq
シーケンス.
element
追加される要素.

関数 cvSeqPushFrontcvSeqPush と同様であるが, 新しい要素はシーケンスの先頭に追加される.この関数の計算量は O(1) である.


SeqPopFront

シーケンスの先頭から要素を削除する

void cvSeqPopFront( CvSeq* seq, void* element=NULL );

seq
シーケンス.
element
オプションパラメータ.ポインタが非0の場合,削除要素をこの場所にコピーする.

関数 cvSeqPopFront はシーケンスの先頭から,一つの要素を削除する.シーケンスが既に空の場合は,エラーを返す.この関数の計算量は O(1) である.


SeqPushMulti

複数の要素をシーケンスのどちらかの端(先頭か末尾)に追加する

void cvSeqPushMulti( CvSeq* seq, void* elements, int count, int in_front=0 );

seq
シーケンス.
elements
追加される要素群.
count
追加される要素数.
in_front
変更するシーケンスの端を指定するフラグ.
CV_BACK (=0) - 要素をシーケンスの末尾に追加する
CV_FRONT(!=0) - 要素をシーケンスの先頭に追加する

関数 cvSeqPushMulti は,複数の要素をシーケンスのどちらかの端に追加する. 要素群は入力配列中の順番どおりにシーケンスに追加されるが,違うシーケンスブロックに分割されることもある.


SeqPopMulti

複数の要素をシーケンスのどちらかの端(先頭か末尾)から削除する

void cvSeqPopMulti( CvSeq* seq, void* elements, int count, int in_front=0 );

seq
シーケンス.
elements
削除される要素.
count
削除される要素数.
in_front
変更するシーケンスの端を指定するフラグ.
CV_BACK (=0) - シーケンスの末尾から要素を削除する
CV_FRONT(!=0) - シーケンスの先頭から要素を削除する

関数 cvSeqPopMulti は,複数の要素をシーケンスのどちらかの端から削除する. 削除される要素数がシーケンス中の要素数より大きい場合は,関数はできるだけ多くの要素を削除する.


SeqInsert

シーケンスの中に要素を挿入する

char* cvSeqInsert( CvSeq* seq, int before_index, void* element=NULL );

seq
シーケンス.
before_index
要素が挿入されるインデックス(このインデックスの前に挿入される). 0(指定可能なパラメータの最小値)の前への挿入は cvSeqPushFront と同じ意味であり, seq->total(指定可能なパラメータの最大値)の前への挿入は cvSeqPush と同じ意味である.
element
挿入される要素.

関数 cvSeqInsert は(elementへの)ポインタがNULLでない場合, シーケンス内の要素を指定した挿入位置から近い側のシーケンスの端にシフトし, element の内容をその位置にコピーする.この関数は,挿入された要素へのポインタを返す.


SeqRemove

シーケンスの中から要素を削除する

void cvSeqRemove( CvSeq* seq, int index );

seq
シーケンス.
index
削除される要素のインデックス.

関数 cvSeqRemove は,与えられたインデックスをもつ要素を削除する. インデックスが範囲外の場合,この関数はエラーを発生する.空のシーケンスから要素を削除しようとすることは,この状況の一例である. この関数は,近い側のシーケンスの端とindex 番目(これは削除されない)の位置の間に存在するシーケンス要素をシフトする事によって, 要素を削除する.


ClearSeq

シーケンスをクリアする

void cvClearSeq( CvSeq* seq );

seq
シーケンス.

関数 cvClearSeq は,シーケンスの全ての要素をクリアする. この関数はメモリをストレージに返さないが,後で新しい要素がシーケンスに追加された時,このメモリを再利用する. この関数の時間計算量は, O(1) である..


GetSeqElem

インデックスで指定されたシーケンス要素のポインタを返す

char* cvGetSeqElem( const CvSeq* seq, int index );
#define CV_GET_SEQ_ELEM( TYPE, seq, index )  (TYPE*)cvGetSeqElem( (CvSeq*)(seq), (index) )

seq
シーケンス.
index
要素のインデックス.

関数 cvGetSeqElem は,与えられたインデックスを持つ要素をシーケンスの中から求め,そのポインタを返す. 要素が見つからない場合,0を返す. この関数では,負のインデックスの指定も可能である.例えば,-1はシーケンスの最後の要素,-2は最後の一つ前を指す等. シーケンスが一つのシーケンスブロックで構成されているか,目的の要素が先頭のブロックにある場合は,マクロ CV_GET_SEQ_ELEM( elemType, seq, index ) を使用した方がよい.このマクロのパラメータ elemTypeはシーケンス要素のタイプ(例えば,CvPoint),seq はシーケンス, index は目的の要素のインデックスである. マクロは,先ず最初に指定された要素が先頭のブロック内にあるかどうかをチェックし,あればその位置を返し, なければマクロからメイン関数 GetSeqElem を呼び出す. 負のインデックスに対しては,常に cvGetSeqElem を呼び出す. ブロック数が要素数より非常に小さいと仮定した場合は,関数の時間計算量はO(1)になる.


SeqElemIdx

ポインタで指定されたシーケンスの要素のインデックスを返す

int cvSeqElemIdx( const CvSeq* seq, const void* element, CvSeqBlock** block=NULL );

seq
シーケンス.
element
シーケンス要素へのポインタ.
block
オプションの引数.NULL でない場合,要素を含むシーケンスブロックのアドレスがこの場所に保存される.

関数 cvSeqElemIdx は,指定されたシーケンス要素のインデックスを返す.その要素が存在しない場合は負の値を返す.


CvtSeqToArray

シーケンスをメモリ内の連続した一つのブロックにコピーする

void* cvCvtSeqToArray( const CvSeq* seq, void* elements, CvSlice slice=CV_WHOLE_SEQ );

seq
シーケンス.
elements
十分に大きな領域を持つ出力配列へのポインタ.データへのポインタであり,行列のヘッダではない.
slice
配列へコピーするシーケンス内の部分.

関数 cvCvtSeqToArray は,シーケンスの全体または一部を指定されたバッファにコピーし,そのバッファへのポインタを返す.


MakeSeqHeaderForArray

配列からシーケンスを生成する

CvSeq* cvMakeSeqHeaderForArray( int seq_type, int header_size, int elem_size,
                                void* elements, int total,
                                CvSeq* seq, CvSeqBlock* block );

seq_type
生成するシーケンスのタイプ.
header_size
シーケンスヘッダのサイズ.パラメータseqは,このヘッダと同じサイズか,これより大きい構造体へのポインタを指していなければならない.
elem_size
シーケンス要素のサイズ.
elements
シーケンスを構成する要素.
total
シーケンス内の要素数.配列の要素数はこのパラメータ値と等しくなければならない.
seq
シーケンスヘッダとして用いられるローカル変数へのポインタ.
block
単一シーケンスブロックのヘッダを示すローカル変数へのポインタ.

関数 cvMakeSeqHeaderForArray は,配列用にシーケンスヘッダを初期化する. シーケンスヘッダもシーケンスブロックも両方とも,ユーザによって領域確保される(例えば,スタック上に). この関数ではデータのコピーは行われない. 結果として得られるシーケンスは,単一ブロックで構成され,ストレージポインタとしてNULLを持つ. そのため,その要素を読むことは可能であるが,このシーケンスに要素を追加しようとすると,多くの場合はエラーになる.


SeqSlice

シーケンススライスのための別のヘッダを作成する

CvSeq* cvSeqSlice( const CvSeq* seq, CvSlice slice,
                   CvMemStorage* storage=NULL, int copy_data=0 );

seq
シーケンス.
slice
抽出するシーケンスの一部分.
storage
新しいシーケンスヘッダとコピーされたデータ(もしデータがあれば)を保存する出力ストレージ. NULLの場合,この関数は入力シーケンスに含まれるストレージを使用する.
copy_data
抽出されたスライスの要素をコピーする(copy_data!=0)か,しない(copy_data=0)かを示すフラグ.

関数 cvSeqSlice は,入力シーケンスの指定したスライスに相当する新しいシーケンスを作成する. 新しいシーケンスでは,その要素を元のシーケンスと共有するか,独自でそのコピーを持つかのいずれかである. シーケンスの一部だけを処理する必要があるが,その処理関数がスライスパラメータを持たない場合に,必要なサブシーケンスをこの関数で抽出することができる.


CloneSeq

シーケンスのコピーを作成する

CvSeq* cvCloneSeq( const CvSeq* seq, CvMemStorage* storage=NULL );

seq
シーケンス.
storage
新しいシーケンスヘッダとコピーされたデータ(もしデータがあれば)を保存する出力ストレージ. NULLの場合,入力シーケンスに含まれるストレージを使用する.

関数 cvCloneSeq は,入力シーケンスの完全なコピーを作成し,そのポインタを返す. cvCloneSeq(seq, storage)cvSeqSlice(seq, CV_WHOLE_SEQ, storage, 1) に等しい.


SeqRemoveSlice

シーケンススライスを削除する

void cvSeqRemoveSlice( CvSeq* seq, CvSlice slice );

seq
シーケンス.
slice
削除するシーケンスの一部分.

関数 cvSeqRemoveSlice は,指定されたシーケンスからスライスを削除する.


SeqInsertSlice

シーケンス内に配列を挿入する

void cvSeqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr );

seq
シーケンス.
slice
配列が挿入される場所へのインデックス(インデックスの前に挿入される).
from_arr
追加される要素の配列.

関数 cvSeqInsertSlice は, from_arr 配列の全ての要素をシーケンスの指定された位置に挿入する. 配列 from_arr は,行列あるいは,他のシーケンスでもよい.


SeqInvert

シーケンス要素の順序を反転させる

void cvSeqInvert( CvSeq* seq );

seq
シーケンス.

関数 cvSeqInvert は,シーケンス内の順序を反転させる(先頭の要素は末尾に,末尾の要素は先頭へ,という風に).


SeqSort

シーケンスの要素を,指定した比較関数を用いてソートする

/* a < b ? -1 : a > b ? 1 : 0 */
typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata);

void cvSeqSort( CvSeq* seq, CvCmpFunc func, void* userdata=NULL );

seq
ソートされるシーケンス
func
要素の関係に応じて,負・0・正の値を返す比較関数(上記の宣言と,下の例を参照.). 最後の引数userdataが使われない事を除けば同様の関数が,Cの関数 qsort でも使われる.
userdata
比較関数に渡されるユーザパラメータ.グローバル変数の使用を避けるために有効である.

関数 cvSeqSort は,指定した基準を用いてシーケンスをソートする.以下に,この関数の使用例を示す.

/* 2次元の点を上から下,左から右へソートする */
static int cmp_func( const void* _a, const void* _b, void* userdata )
{
    CvPoint* a = (CvPoint*)_a;
    CvPoint* b = (CvPoint*)_b;
    int y_diff = a->y - b->y;
    int x_diff = a->x - b->x;
    return y_diff ? y_diff : x_diff;
}

...

CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* seq = cvCreateSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage );
int i;

for( i = 0; i < 10; i++ )
{
    CvPoint pt;
    pt.x = rand() % 1000;
    pt.y = rand() % 1000;
    cvSeqPush( seq, &pt );
}

cvSeqSort( seq, cmp_func, 0 /* ここではユーザーデータは使用しない */ );

/* ソートされたデータを出力 */
for( i = 0; i < seq->total; i++ )
{
    CvPoint* pt = (CvPoint*)cvSeqElem( seq, i );
    printf( "(%d,%d)¥n", pt->x, pt->y );
}

cvReleaseMemStorage( &storage );

SeqSearch

シーケンスから指定要素を検索する

/* a < b ? -1 : a > b ? 1 : 0 */
typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata);

char* cvSeqSearch( CvSeq* seq, const void* elem, CvCmpFunc func,
                   int is_sorted, int* elem_idx, void* userdata=NULL );

seq
シーケンス.
elem
検索する要素.
func
要素の関係に応じて,負・0・正の値を返す比較関数(cvSeqSort も参照).
is_sorted
シーケンスがソート済みか否かを示すフラグ.
elem_idx
出力パラメータ.見つかった要素のインデックス.
userdata
比較関数に渡されるユーザーパラメータ.グローバル変数の使用を避けるために有効である.

関数 cvSeqSearch はシーケンスの中から要素を検索する. シーケンスがソートされていれば,O(log(N))の二分探索法が用いられる. その他の場合は,単純な線形探索が用いられる. 要素が見つからない場合,この関数はNULLポインタを返し,インデックスにはシーケンスの要素数をセットする. 線形探索を用いて要素を見つけた場合,インデックスにはseq(i)>elemである最小のインデックスiがセットされる.


StartAppendToSeq

シーケンスへのデータ書き込み処理を初期化する

void cvStartAppendToSeq( CvSeq* seq, CvSeqWriter* writer );

seq
シーケンスへのポインタ.
writer
ライタ(Writer)の状態.この関数で初期化される.

関数 cvStartAppendToSeq は,シーケンスへのデータ書き込み処理を初期化する. 書き込まれる要素は,マクロ CV_WRITE_SEQ_ELEM(written_elem, writer) によってシーケンスの最後に追加される. 書き込み処理の間にシーケンスに対する他の処理が行われると,誤った結果が引き起こされたり,シーケンス自体が壊れる可能性があることに注意 (これらの問題を回避するには cvFlushSeqWriter の説明を参照のこと).


StartWriteSeq

新しいシーケンスを作成し,ライタ(writer)を初期化する

void cvStartWriteSeq( int seq_flags, int header_size, int elem_size,
                      CvMemStorage* storage, CvSeqWriter* writer );

seq_flags
作成されたシーケンスのフラグ. 生成されたシーケンスが,特定のシーケンスタイプを引数にとるような関数に一切渡されない場合は,この値に0を指定してもかまわない. そうでない場合は,定義済みのシーケンスタイプのリストから適切なタイプが選択されなければならない.
header_size
シーケンスヘッダのサイズ.sizeof(CvSeq)以上でなければならない. また,特別なタイプか拡張が指示されている場合,そのタイプは基本タイプのヘッダサイズと合致しなければならない.
elem_size
シーケンスの要素サイズ(バイト単位).サイズはシーケンスタイプと合致しなければならない. 例えば,点群のシーケンス(要素タイプは CV_SEQ_ELTYPE_POINT)を作成する場合, パラメータ elem_sizesizeof(CvPoint) と等しくなければならない.
storage
シーケンスの位置.
writer
ライタの状態.この関数で初期化される.

関数 cvStartWriteSeq は,cvCreateSeqcvStartAppendToSeq の組み合わせである. 生成されたシーケンスへのポインタは writer->seq に保存され, 最後に呼び出されるべき関数 cvEndWriteSeq から返される.


EndWriteSeq

シーケンス書き込み処理を終了する

CvSeq* cvEndWriteSeq( CvSeqWriter* writer );

writer
ライタの状態.

関数 cvEndWriteSeq は書き込み処理を終了し,書き込まれたシーケンスへのポインタを返す. この関数は空きブロックをメモリストレージに返すために最後の不完全なシーケンスブロックを切り捨てる. この処理によって,シーケンスは安全に読み書きできるようになる.


FlushSeqWriter

ライタの状態からシーケンスヘッダを更新する

void cvFlushSeqWriter( CvSeqWriter* writer );

writer
ライタの状態.

関数 cvFlushSeqWriter は,書き込みプロセス中でも要求(例えば,特定の状態をチェックするなど)があればいつでも,ユーザーがシーケンス要素を読み出せるようにする.この関数は,シーケンスからの読み出しを可能にするためにヘッダを更新する. しかし,ライタを閉じないので,いつでも書き込み処理を続けることができる. 頻繁に flush を使用するようなアルゴリズムにおいては,代わりにcvSeqPushを用いることも考慮する.


StartReadSeq

シーケンスからの連続読み出し処理を初期化する

void cvStartReadSeq( const CvSeq* seq, CvSeqReader* reader, int reverse=0 );

seq
シーケンス.
reader
リーダ(reader)の状態.この関数で初期化される.
reverse
シーケンス走査方向の指定.reverse が 0 の場合,リーダは先頭のシーケンス要素に位置する.それ以外は最後の要素に位置する.

関数 cvStartReadSeq は,リーダの状態を初期化する. この後,先頭から末尾までの全シーケンス要素は,続いて呼ばれるマクロCV_READ_SEQ_ELEM( read_elem, reader )(順方向読み出しの場合)あるいは, マクロ CV_REV_READ_SEQ_ELEM( read_elem, reader )(逆方向読み出しの場合)を用いて,読み出しが可能になる. どちらのマクロもシーケンス要素を read_elem にセットし,読み出しポインタを次の要素位置に移動させる. シーケンスブロックの循環構造は,読み出し処理にも適用される. これはマクロ CV_READ_SEQ_ELEM によってシーケンス末尾の要素が既に読み出された後, マクロが再度呼ばれるとシーケンス先頭の要素が読み出されるということである.CV_REV_READ_SEQ_ELEM においても同様である. 読み出し処理はシーケンスの変更もテンポラリバッファの生成もしないので,この処理を終了させる関数は存在しない. リーダ構造体のフィールド ptr は,次に読み出されるシーケンスの現在の要素を指している. 以下のコードは,シーケンスのライタとリーダの使用例である.

CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* seq = cvCreateSeq( CV_32SC1, sizeof(CvSeq), sizeof(int), storage );
CvSeqWriter writer;
CvSeqReader reader;
int i;

cvStartAppendToSeq( seq, &writer );
for( i = 0; i < 10; i++ )
{
    int val = rand()%100;
    CV_WRITE_SEQ_ELEM( val, writer );
    printf("%d is written¥n", val );
}
cvEndWriteSeq( &writer );

cvStartReadSeq( seq, &reader, 0 );
for( i = 0; i < seq->total; i++ )
{
    int val;
#if 1
    CV_READ_SEQ_ELEM( val, reader );
    printf("%d is read¥n", val );
#else /* 代わりの方法.シーケンスの要素数が大きい場合や,コンパイル時に
         サイズやタイプがわからない場合はこちらの使用が望ましい */
    printf("%d is read¥n", *(int*)reader.ptr );
    CV_NEXT_SEQ_ELEM( seq->elem_size, reader );
#endif
}
...

cvReleaseStorage( &storage );

GetSeqReaderPos

現在のリーダの位置を返す

int cvGetSeqReaderPos( CvSeqReader* reader );

reader
リーダの状態.

関数 cvGetSeqReaderPos は,現在のリーダの位置(0 ... reader->seq->total - 1 の範囲)を返す.


SetSeqReaderPos

リーダを指定の位置に移動する

void cvSetSeqReaderPos( CvSeqReader* reader, int index, int is_relative=0 );

reader
リーダの状態.
index
移動先の位置.位置決めモード(次のパラメータis_relativeを参照)が使用されている場合, 実際の位置は indexreader->seq->totalで割った剰余になる.
is_relative
非0の場合,index は現在位置からの相対値.

関数 cvSetSeqReaderPos は,読み込み位置を絶対位置か相対位置で表された位置に移動する.


セット(Sets)


CvSet

ノードの集合

    typedef struct CvSetElem
    {
        int flags; /* 空きノードなら負,他の場合0か正の値 */
        struct CvSetElem* next_free; /* 空きノードの場合,次の空きノードへのポインタ */
    }
    CvSetElem;

    #define CV_SET_FIELDS()    ¥
        CV_SEQUENCE_FIELDS()   /* CvSeqから継承する */ ¥
        struct CvSetElem* free_elems; /* 空きノードのリスト */

    typedef struct CvSet
    {
        CV_SET_FIELDS()
    } CvSet;

構造体CvSet は,OpenCVの疎なデータ構造の基本である.

上述の宣言のとおり,CvSetCvSeqを継承し, それにfree_elems(空きノードリスト)を加えたものである. 空きかそうでないかが記述されたセットの各ノードは,内部的なシーケンスの要素である. 密なシーケンスの要素に対するような制限はないが,セット(と,ここから派生する構造体)の要素は整数型のフィールドで始める必要があり, 構造体CvSetElemに合致させる事ができなければならない. なぜなら,これら二つのフィールド(整数とそれに続くポインタ)は,空きノードリストを持つノードセットの構成に必要だからである. 空きノードの場合,flags フィールドは負の値となる(フィールドの最上位ビット(MSB)がセットされている). そしてnext_freeは,次の空きノードを指す(先頭の空きノードは,CvSetfree_elemsフィールドから参照される).ノードが使用されている場合,flags フィールドは0以上の値で,(set_elem->flags & CV_SET_ELEM_IDX_MASK) の式を用いて取り出されるようなノードインデックスを持つ.ノードの残り部分(next_free)はユーザによって決められる. 特に,使用されているノードは空きノードのようにリンクされていないので,2番目のフィールド(next_free)は, このようなリンクや他の目的のために用いることができる. マクロCV_IS_SET_ELEM(set_elem_ptr)は,指定したノードが使用されているかどうかを判断するために利用することができる.

最初,セットとリストは空である.セットから新しいノード要求があった場合,空きノードリストからノードが取り出され,その後リストは更新される. 空きノードリストが空の場合は,新しいシーケンスブロックが確保され,ブロック内のすべてのノードが空きノードリストに追加される. 従って,セットの total フィールドには,使用されているノード数と空きノードの数の合計が入る. 使用されていたノードが解放されたときには,空きノードリストに加えられる.最後に解放されるノードは,最初に使用されたものである.

OpenCVにおいて CvSet は,グラフ(CvGraph), 疎な多次元配列(CvSparseMat), 平面の細分割(CvSubdiv2D)などを表現するために使用される.


CreateSet

空のセットを生成する

CvSet* cvCreateSet( int set_flags, int header_size,
                    int elem_size, CvMemStorage* storage );

set_flags
生成するセットのタイプ.
header_size
セットのヘッダのサイズ(sizeof(CvSet)以上).
elem_size
セットの要素のサイズ(CvSetElem 以上).
storage
セットのためのコンテナ.

関数cvCreateSetは指定されたヘッダのサイズと要素のサイズを持つ空のセットを生成し,そのセットへのポインタを返す. この関数は cvCreateSeq に多少の処理を追加したものに過ぎない.


SetAdd

セットに新しいノード(要素)を追加する

int cvSetAdd( CvSet* set_header, CvSetElem* elem=NULL, CvSetElem** inserted_elem=NULL );

set_header
セット.
elem
オプションの入力引数.挿入する要素. NULLでない場合,新たに確保したノードにデータをコピーする (コピーした後,先頭の整数フィールドの最上位ビットはクリアされる).
inserted_elem
オプションの出力引数.割り当てられた要素へのポインタ.

関数cvSetAddは,新しいノードを割り当てる. オプションとして入力要素データをノードにコピーし,ノードへのポインタとインデックスを返す. インデックス値は,ノードのflagsフィールドの下位のビットから得る.この関数はO(1)の計算量を持つが, セットのノードを確保するためのより高速な関数が存在する(cvSetNewを参照).


SetRemove

セットから要素を削除する

void cvSetRemove( CvSet* set_header, int index );

set_header
セット.
index
削除する要素のインデックス.

関数cvSetRemoveは,セットから指定されたインデックスの要素を取り除く. もし指定された場所のノードがない場合,この関数は何もしない.この関数はO(1)の計算量を持つ, しかし,既に取り除く要素の場所が既知である場合は,cvSetRemoveByPtr の方が高速である.


SetNew

セットに要素を加える(高速版)

CvSetElem* cvSetNew( CvSet* set_header );

set_header
セット.

関数cvSetNewは,cvSetAdd の高速インライン処理バージョンである. この関数は新しいノードを確保し,インデックスではなくノードへのポインタを返す.


SetRemoveByPtr

ポインタで指定したセットの要素を削除する

void cvSetRemoveByPtr( CvSet* set_header, void* elem );

set_header
セット.
elem
削除される要素.

関数cvSetRemoveByPtrは,要素のポインタを用いる cvSetRemove の高速インライン処理バージョンである. この関数はノードが使用されているかそうでないかを確認しない.そのため,ユーザは注意して使用しなければならない.


GetSetElem

インデックスによってセットの要素を検索する

CvSetElem* cvGetSetElem( const CvSet* set_header, int index );

set_header
セット.
index
シーケンスの中のセットの要素のインデックス.

関数cvGetSetElemは,インデックスによってセットの要素を検索する. この関数は見つけた要素へのポインタを返す,インデックスが無効であるか,対応するノードが空きの場合は0を返す. この関数は負のインデックスをサポートし,これはノードの場所を得るために cvGetSeqElem を用いる際に使われる.


ClearSet

セットをクリアする

void cvClearSet( CvSet* set_header );

set_header
クリアされるセット.

関数cvClearSetは,セットからすべての要素を取り除く.これはO(1)の計算量を持つ.


グラフ(Graphs)


CvGraph

重み付きの有向または無向グラフ

    #define CV_GRAPH_VERTEX_FIELDS()    ¥
        int flags; /* 頂点フラグ */   ¥
        struct CvGraphEdge* first; /* 最初の辺 */ 

    typedef struct CvGraphVtx
    {
        CV_GRAPH_VERTEX_FIELDS()
    }
    CvGraphVtx;

    #define CV_GRAPH_EDGE_FIELDS()      ¥
        int flags; /* 辺フラグ */     ¥
        float weight; /* 辺の重み */ ¥
        struct CvGraphEdge* next[2]; /* 辺リストにおける次の辺.始点(0),終点(1) */ ¥
        struct CvGraphVtx* vtx[2]; /* 始点(0),終点(1) */

    typedef struct CvGraphEdge
    {
        CV_GRAPH_EDGE_FIELDS()
    }
    CvGraphEdge;

    #define  CV_GRAPH_FIELDS()                  ¥
        CV_SET_FIELDS() /* 頂点のセット */   ¥
        CvSet* edges;   /* 辺のセット*/

    typedef struct CvGraph
    {
        CV_GRAPH_FIELDS()
    }
    CvGraph;

構造体 CvGraph は,OpenCVで使用されるグラフの基本構造である.

グラフ構造体は,CvSet(一般的なグラフの特性とグラフ頂点を記述)を継承し, さらにメンバーとしてもう一つのセット(グラフの辺を記述)を含んでいる.

頂点,辺,グラフヘッダの構造体は,他の拡張可能なOpenCVの構造体と同じ方法(構造体の拡張やカスタマイズをシンプルにするマクロを用いて)で宣言される. 頂点と辺の構造体は明示的には CvSetElem を継承していないが, それらはセットの要素の二つの条件(先頭に整数フィールドflagsを持ち,CvSetElem構造体と合致する)を満足している. フィールド flags は,頂点と辺が存在していることを示すだけでなく,他の目的 (例えば,グラフの走査(cvCreateGraphScanner 等を参照))にも用いられるので, このフィールドを直接使用しないほうが良い.

グラフは辺のセットとして表現され,各辺はそこに接続する辺のリストを持つ.情報の重複をできる限り避けるために,違う頂点への接続リストが交互に配置される.

グラフは有向か無向かのいずれかである.無向グラフの場合,頂点AからBへの接続と,頂点BからAへの接続の区別はなく, グラフ上にはどちらか一方しか同時に存在できない.これらの接続はそれぞれ辺 <A, B> ,<B, A> と表現される.


CreateGraph

空のグラフを生成する

CvGraph* cvCreateGraph( int graph_flags, int header_size, int vtx_size,
                        int edge_size, CvMemStorage* storage );

graph_flags
生成したグラフのタイプ.無向グラフの場合,CV_SEQ_KIND_GRAPH, 有向グラフの場合,CV_SEQ_KIND_GRAPH | CV_GRAPH_FLAG_ORIENTED
header_size
グラフのヘッダサイズ (sizeof(CvGraph)以上).
vtx_size
グラフの頂点サイズ(カスタマイズされた頂点の構造体は CvGraphVtx で始まらなければならない( CV_GRAPH_VERTEX_FIELDS() を使用)).
edge_size
グラフの辺サイズ(カスタマイズされた辺の構造体は CvGraphEdge で始まらなければならない( CV_GRAPH_EDGE_FIELDS() を使用)).
storage
グラフコンテナ.

関数 cvCreateGraph は,空のグラフを生成し,そのポインタを返す.


GraphAddVtx

グラフに頂点を追加する

int cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* vtx=NULL,
                   CvGraphVtx** inserted_vtx=NULL );

graph
グラフ.
vtx
追加される頂点の初期化に使用される,オプションの入力引数(sizeof(CvGraphVtx)の領域を超えたユーザー定義フィールドのみコピーされる).
inserted_vertex
オプションの出力引数.NULLでない場合,新しい頂点のアドレスがここに書かれる.

関数 cvGraphAddVtx はグラフに頂点を追加し,頂点のインデックスを返す.


GraphRemoveVtx

グラフから頂点を削除する(インデックス指定)

int cvGraphRemoveVtx( CvGraph* graph, int index );

graph
グラフ.
vtx_idx
削除される頂点のインデックス.

関数 cvGraphRemoveVtx は,指定した頂点とその頂点に接続するすべての辺をグラフから削除する. 入力された頂点がグラフに存在しない場合は,エラーを出力する. 戻り値は削除された辺の数,あるいは頂点がグラフに存在しない場合は-1である.


GraphRemoveVtxByPtr

グラフから頂点を削除する(ポインタ指定)

int cvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx );

graph
グラフ.
vtx
削除される頂点へのポインタ.

関数 cvGraphRemoveVtxByPtr は,指定した頂点とその頂点に接続するすべての辺をグラフから削除する. 入力された頂点がグラフに存在しない場合は,エラーを出力する. 戻り値は削除された辺の数,あるいは頂点がグラフに存在しない場合は-1である.


GetGraphVtx

インデックスを用いてグラフの頂点を検索する

CvGraphVtx* cvGetGraphVtx( CvGraph* graph, int vtx_idx );

graph
グラフ.
vtx_idx
頂点のインデックス.

関数 cvGetGraphVtx は,グラフの頂点をインデックスから検索し,そのポインタを返す. 頂点がグラフ内に存在しない場合は,NULLを返す.


GraphVtxIdx

グラフ頂点のインデックスを返す

int cvGraphVtxIdx( CvGraph* graph, CvGraphVtx* vtx );

graph
グラフ.
vtx
グラフ頂点へのポインタ.

関数 cvGraphVtxIdx は,ポインタで指定されたグラフ頂点のインデックスを返す.


GraphAddEdge

グラフに辺を追加する(インデックス指定)

int cvGraphAddEdge( CvGraph* graph, int start_idx, int end_idx,
                    const CvGraphEdge* edge=NULL, CvGraphEdge** inserted_edge=NULL );

graph
グラフ.
start_idx
辺の始点を示すインデックス.
end_idx
辺の終点を示すインデックス.無向グラフの場合,順序はどちらでもよい.
edge
オプションの入力パラメータ.辺の初期化のためのデータ.
inserted_edge
入力された辺のアドレスを保存するための,オプションの出力パラメータ.

関数 cvGraphAddEdge は,指定した二つの頂点を接続する. この関数は,追加に成功すると1を返し,すでに二つの頂点を接続する辺が存在する場合は0を返し, 頂点のどちらかが存在しない,始点と終点が同じとき,他の重大な問題があるときには-1を返す. 後者の場合(すなわち,結果が負のとき),この関数はデフォルトでエラーも出力する.


GraphAddEdgeByPtr

グラフに辺を追加する(ポインタ指定)

int cvGraphAddEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_vtx,
                         const CvGraphEdge* edge=NULL, CvGraphEdge** inserted_edge=NULL );

graph
グラフ.
start_vtx
辺の始点を示す頂点へのポインタ.
end_vtx
辺の終点を示す頂点へのポインタ.無向グラフの場合,順序はどちらでもよい.
edge
オプションの入力パラメータ,辺の初期化データ.
inserted_edge
辺の集合の中で入力された辺のアドレスを保存するための,オプションの出力パラメータ.

関数 cvGraphAddEdgeByPtr は指定した二つの頂点を接続する. この関数は,追加に成功すると1を返し,すでに二つの頂点を接続する辺が存在する場合は0を返し, 頂点のどちらかが存在しない,始点と終点が同じとき,他の重大な問題があるときには-1を返す. 後者の場合(すなわち,結果が負のとき),関数はデフォルトでエラーも出力する.


GraphRemoveEdge

グラフから辺を削除する(インデックス指定)

void cvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx );

graph
グラフ.
start_idx
辺の始点を示す頂点のインデックス.
end_idx
辺の終点を示す頂点のインデックス.無向グラフの場合,順序はどちらでもよい.

関数 cvGraphRemoveEdge は,指定された二つの頂点を接続する辺を削除する. 頂点が(この順序で)接続されていない場合,この関数は何もしない.


GraphRemoveEdgeByPtr

グラフから辺を削除する(ポインタ指定)

void cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_vtx );

graph
グラフ.
start_vtx
辺の始点を示す頂点へのポインタ.
end_vtx
辺の終点を示す頂点へのポインタ.無向グラフの場合,順序はどちらでもよい.

関数 cvGraphRemoveEdgeByPtr は,指定された二つの頂点を接続する辺を削除する. 頂点が(この順序で)接続されていない場合,この関数は何もしない.


FindGraphEdge

グラフから辺を検出する(インデックス指定)

CvGraphEdge* cvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx );
#define cvGraphFindEdge cvFindGraphEdge

graph
グラフ.
start_idx
辺の始点を示す頂点のインデックス.
end_idx
辺の終点を示す頂点のインデックス.無向グラフの場合,順序はどちらでもよい.

関数 cvFindGraphEdge は,指定した二つの頂点を接続する辺を検出し,そのポインタを返す. 辺が存在しない場合はNULLを返す.


FindGraphEdgeByPtr

グラフから辺を検出する(ポインタ指定)

CvGraphEdge* cvFindGraphEdgeByPtr( const CvGraph* graph, const CvGraphVtx* start_vtx,
                                   const CvGraphVtx* end_vtx );
#define cvGraphFindEdgeByPtr cvFindGraphEdgeByPtr

graph
グラフ.
start_vtx
辺の始点を示す頂点へのポインタ.
end_vtx
辺の終点を示す頂点へのポインタ.無向グラフの場合,順序はどちらでもよい.

関数 cvFindGraphEdgeByPtr は,指定した二つの頂点を接続する辺を検出し,そのポインタを返す. 辺が存在しない場合はNULLを返す.


GraphEdgeIdx

グラフの辺のインデックスを返す

int cvGraphEdgeIdx( CvGraph* graph, CvGraphEdge* edge );

graph
グラフ.
edge
辺へのポインタ.

関数 cvGraphEdgeIdx は,グラフの辺のインデックスを返す.


GraphVtxDegree

頂点に接続している辺の数を数える(インデックス指定)

int cvGraphVtxDegree( const CvGraph* graph, int vtx_idx );

graph
グラフ.
vtx
頂点のインデックス.

関数 cvGraphVtxDegree は,指定した頂点に接続した(入る/出る両方向の)辺の数を返す. 辺の数を数えるために,以下のコードが用いられる.

    CvGraphEdge* edge = vertex->first; int count = 0;
    while( edge )
    {
        edge = CV_NEXT_GRAPH_EDGE( edge, vertex );
        count++;
    }

マクロ CV_NEXT_GRAPH_EDGE( edge, vertex ) は, vertex へ接続する,edge の次の辺を返す.


GraphVtxDegreeByPtr

頂点に接続している辺の数を数える(ポインタ指定)

int cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vtx );

graph
グラフ.
vtx
頂点へのポインタ.

関数 cvGraphVtxDegreeByPtr は,指定した頂点に接続した(入る/出る両方向の)辺の数を返す.


ClearGraph

グラフをクリアする

void cvClearGraph( CvGraph* graph );

graph
グラフ.

関数 cvClearGraph は,グラフから全ての頂点と辺を削除する. この関数の時間計算量は O(1)である.


CloneGraph

グラフをコピーする

CvGraph* cvCloneGraph( const CvGraph* graph, CvMemStorage* storage );

graph
コピーするグラフ.
storage
コピーのためのコンテナ.

関数 cvCloneGraph は,グラフの完全コピーを作成する. グラフの頂点や辺が外部データへのポインタを持つ場合,そのポインタはコピーしたグラフでも共有される. この関数は頂点や辺の集合を最適化(デフラグメント)するため,新しいグラフの頂点と辺のインデックスが元のグラフのものと違う可能性がある.


CvGraphScanner

グラフ走査状態のための構造体

    typedef struct CvGraphScanner
    {
        CvGraphVtx* vtx;       /* 現在の頂点(あるいは辺の始点) */
        CvGraphVtx* dst;       /* 現在の辺の接続先頂点 */
        CvGraphEdge* edge;     /* 現在の辺 */

        CvGraph* graph;        /* 走査中のグラフ */
        CvSeq*   stack;        /* 走査中の頂点スタック */
        int      index;        /* 走査済みの頂点の下限インデックス */
        int      mask;         /* イベントマスク */
    }
    CvGraphScanner;

構造体 CvGraphScanner は,深さ優先走査のために用いられる. 以下の関数の説明を参照.


CreateGraphScanner

グラフの深さ優先走査のための構造体を生成する

CvGraphScanner* cvCreateGraphScanner( CvGraph* graph, CvGraphVtx* vtx=NULL,
                                       int mask=CV_GRAPH_ALL_ITEMS );

graph
グラフ.
vtx
走査開始頂点.NULLの場合,走査は先頭の頂点(頂点シーケンスのうち最小のインデックスを持つ頂点)から始まる.
mask
イベントマスク.どのイベントにユーザが着目したいのかを指定する (関数 cvNextGraphItem はユーザーにコントロールを返す). CV_GRAPH_ALL_ITEMS(すべてのイベントに着目)か,以下のフラグの組み合わせ.
  • CV_GRAPH_VERTEX - はじめてアクセスした頂点で停止する
  • CV_GRAPH_TREE_EDGE - tree edgeで停止する (tree edge は最後にアクセスした頂点と次にアクセスされる頂点を接続する辺のこと)
  • CV_GRAPH_BACK_EDGE - back edgeで停止する (back edge は最後にアクセスした頂点と探索木内でのその親のいずれかを接続する辺のこと)
  • CV_GRAPH_FORWARD_EDGE - forward edgeで停止する (forward edge は最後にアクセスした頂点と探索木内でのその子のいずれかを接続する辺のこと. forward edge は有向グラフの走査においてのみ有効)
  • CV_GRAPH_CROSS_EDGE - cross edgeで停止する (cross edge は異なる探索木同士か同じ木の枝同士を接続する辺のこと. cross edges は有向グラフの走査においてのみ有効)
  • CV_GRAPH_ANY_EDGE - 任意の辺で停止する(tree, back, forward そしてcross edges
  • CV_GRAPH_NEW_TREE - すべての新しい探索木の先頭で停止する. 走査プロセスが,走査開始頂点(initial vertex)から到達可能なすべての頂点と辺にアクセスする場合 (アクセスされた頂点は辺とともに一つの木(tree)を構成する),グラフ中でまだアクセスされていない頂点を探索し, その頂点からの探索を再開する.新しい木の開始前(最初に cvNextGraphItem が呼ばれる,全く初めての場合も含む)に, CV_GRAPH_NEW_TREE イベントを生成する.
    無向グラフにおいては,各探索木が,グラフの接続される一つの成分に対応する.
  • CV_GRAPH_BACKTRACKING - 逆探索(バックトラッキング,既にアクセスされた頂点を逆に戻っていく)中に,すべてのアクセス済みの頂点で停止する.

関数 cvCreateGraphScanner は深さ,優先走査/探索のための構造体を生成する. 初期化された構造体は,関数 cvNextGraphItem (逐次走査処理)で用いられる.


NextGraphItem

グラフ走査処理を1ステップ,あるいは数ステップ進める

int cvNextGraphItem( CvGraphScanner* scanner );

scanner
グラフ走査状態.この関数で更新される.

関数 cvNextGraphItem は,ユーザーが着目したイベント (cvCreateGraphScannermask 引数で指定される) に合致するか, すべての走査が終了するまで,グラフ内を順に走査する. 前者の場合,この関数は上記の mask パラメータで指定されたイベントを返し,次の呼び出しで走査を再開する. 後者の場合,CV_GRAPH_OVER (-1) を返す. イベントが CV_GRAPH_VERTEXCV_GRAPH_BACKTRACKINGCV_GRAPH_NEW_TREE の場合, 現在の走査中の頂点は scanner->vtx に保存される. 辺に関係しているイベントの場合,現在走査対象の辺は scanner->edge に, 一つ前にアクセスした頂点は scanner->vtx に, 辺のもう一方(終点)の頂点は scanner->dst にそれぞれ保存される.


ReleaseGraphScanner

グラフの走査処理を終了する

void cvReleaseGraphScanner( CvGraphScanner** scanner );

scanner
スキャナへのポインタのポインタ.

関数 cvGraphScanner は,グラフの走査処理を終了し,スキャナを解放する.


木(Trees)


CV_TREE_NODE_FIELDS

ツリーノードの種類を宣言するための補助マクロ

#define CV_TREE_NODE_FIELDS(node_type)                          ¥
    int       flags;         /* 様々なフラグ */                 ¥
    int       header_size;   /* シーケンスヘッダのサイズ */      ¥
    struct    node_type* h_prev; /* 一つ前のシーケンスへのポインタ */        ¥
    struct    node_type* h_next; /* 一つ後のシーケンスへのポインタ */        ¥
    struct    node_type* v_prev; /* 一つ前のシーケンスへのポインタ(セカンダリ,構造によって意味が異なる) */ ¥
    struct    node_type* v_next; /* 一つ後のシーケンスへのポインタ(セカンダリ,構造によって意味が異なる) */

マクロCV_TREE_NODE_FIELDS()は,すべての動的構造の基本タイプである CvSeqのように, 階層構造(ツリー)として組織化できるデータ構造を宣言するために使用される. このマクロを用いて宣言されたノードから構成されるツリーは,このセクションで述べる各関数を用いて処理することができる.


CvTreeNodeIterator

ツリーノードのイテレータのための構造体

typedef struct CvTreeNodeIterator
{
    const void* node;
    int level;
    int max_level;
}
CvTreeNodeIterator;

構造体 CvTreeNodeIterator は,ツリーを走査するために用いられる. ツリーのノードの宣言には,マクロCV_TREE_NODE_FIELDS(...)を用いる必要がある.


InitTreeNodeIterator

ツリーノードのイテレータを初期化する

void cvInitTreeNodeIterator( CvTreeNodeIterator* tree_iterator,
                             const void* first, int max_level );

tree_iterator
初期化されるツリーのイテレータ.
first
先頭ノード.ここから走査を開始する.
max_level
ツリー走査範囲の最大レベル(first ノードが第1レベルであると仮定する). 例えば,1 はfirstと同じレベルのノードのみが処理されることを意味する, また,2はfirstと同じレベルのノードとその子ノードが処理される.

関数 cvInitTreeNodeIterator は,ツリーのイテレータを初期化する.ツリーは深さ優先で走査される.


NextTreeNode

現在のノードを返し,イテレータを次のノードに移動させる.

void* cvNextTreeNode( CvTreeNodeIterator* tree_iterator );

tree_iterator
初期化されるツリーのイテレータ.

関数 cvNextTreeNode は,現在対象となっているノードを返し,その後イテレータを更新する(次のノードに移動させる). つまり,この関数の動作は,通常のC言語のポインタでの *p++ 表現,あるいはC++のコレクションイテレータとほぼ同じである. これ以上のノードがない場合,この関数はNULLを返す.


PrevTreeNode

現在のノードを返し,イテレータを前のノードに移動させる.

void* cvPrevTreeNode( CvTreeNodeIterator* tree_iterator );

tree_iterator
初期化されるツリーのイテレータ.

関数 cvPrevTreeNode は現在対象となっているノードを返し,その後イテレータを更新する(一つ前のノードに移動させる). つまり,この関数の動作は,通常のCのポインタでの *p-- 表現,あるいはC++のコレクションイテレータとほぼ同じである. これ以上のノードがない場合,関数はNULLを返す.


TreeToNodeSeq

すべてのノードへのポインタを一つのシーケンスに集める

CvSeq* cvTreeToNodeSeq( const void* first, int header_size, CvMemStorage* storage );

first
ツリーの先頭ノード.
header_size
作成したシーケンスのヘッダサイズ(sizeof(CvSeq) が用いられることが多い).
storage
シーケンスのためのコンテナ.

関数 cvTreeToNodeSeq は,ノード first から到達可能なすべてのノードへのポインタを一つのシーケンスにまとめる. ポインタは深さ優先順に順次書き込まれる.


InsertNodeIntoTree

ツリーに新しいノードを追加する

void cvInsertNodeIntoTree( void* node, void* parent, void* frame );

node
挿入されるノード.
parent
ツリー内に既に存在している親ノード.
frame
トップレベルノード.parentframe が同じである場合, nodev_prevフィールドには,parent ではなく,NULLがセットされる.

関数 cvInsertNodeIntoTree は,ツリーに別のノードを追加する. この関数はメモリの領域確保を行わず,単にツリーノードのリンクを変更するだけである.


RemoveNodeFromTree

ツリーからノードを削除する

void cvRemoveNodeFromTree( void* node, void* frame );

node
削除されるノード.
frame
トップレベルノード.node->v_prev = NULL かつ node->h_prev = NULL (つまり,nodeframeの最初の子ノードである)である場合, frame->v_nextnode->h_next にセットされる (つまり,最初の子ノードかframeが変更される).

関数 cvRemoveNodeFromTree は,ツリーからノードを削除する. この関数はメモリの領域解放を行わず,単にツリーノードのリンクを変更するだけである.


描画関数(Drawing Functions)

描画関数は行列や画像,任意のカラーデプスで使われる. アンチエイリアス処理は8ビット画像にのみ実装されている. すべての関数はパラメータcolor(CV_RGBマクロか,cvScalar関数を用いて作成される)を持ち, これはカラー画像ではrgb値,グレースケール画像では輝度を意味する.

描く図の一部,もしくは全てが画像の領域外にある場合には,その部分は切り取られる. カラー画像の場合,チャンネルの順番は...である. 順番を変更したい場合は,cvScalarを用いて順番を指定するか,cvCvtColor あるいは cvTransformを用いて,描画前,もしくは描画後に画像を変換すればよい.


曲線と形状(Curves and Shapes)


CV_RGB

カラー値を作成する

#define CV_RGB( r, g, b )  cvScalar( (b), (g), (r) )

Line

2点を結ぶ線分を描画する

void cvLine( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color,
             int thickness=1, int line_type=8, int shift=0 );

img
画像.
pt1
線分の1番目の端点.
pt2
線分の2番目の端点.
color
線分の色.
thickness
線分の太さ.
line_type
線分の種類.
8 (または0) - 8連結による線分.
4 - 4連結による線分.
CV_AA - アンチエイリアスされた線分.
shift
座標の小数点以下の桁を表すビット数.

関数cvLineは,点pt1と点pt2を結ぶ線分を画像上に描画する. 描画される線分は画像やROIにより切り取られる. 整数値座標でアンチエイリアスされていない線分では,8連結,または4連結のブレゼンハム(Bresenham)アルゴリズムが使われる. 太い線分の端は丸く描画される.アンチエイリアスされた線分は,ガウシアン(Gaussian)フィルタを用いて描かれる. 線分の色を指定するには,マクロCV_RGB(r, g, b)を用いる.


Rectangle

枠のみ,もしくは塗りつぶされた矩形を描画する

void cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color,
                  int thickness=1, int line_type=8, int shift=0 );

img
矩形が描画される画像.
pt1
矩形の一つの頂点.
pt2
矩形の反対側の頂点.
color
線の色(RGB),もしくは輝度(グレースケール画像).
thickness
矩形を描く線の太さ.負の値,例えばCV_FILLEDを指定した場合は塗りつぶされる.
line_type
線の種類,詳細はcvLineを参照.
shift
座標の小数点以下の桁を表すビット数.

関数cvRectangleは,点pt1と点pt2を対角とする矩形を描画する.


Circle

円を描画する

void cvCircle( CvArr* img, CvPoint center, int radius, CvScalar color,
               int thickness=1, int line_type=8, int shift=0 );

img
円が描画される画像.
center
円の中心.
radius
円の半径.
color
円の色.
thickness
線の幅.負の値を指定した場合は塗りつぶされる.
line_type
線の種類,詳細はcvLineを参照.
shift
中心座標と半径の小数点以下の桁を表すビット数.

関数cvCircleは,与えた中心と半径に応じて枠だけ,もしくは塗りつぶされた円を描く.描画される円はROIによって切り取られる. 円の色はマクロCV_RGB ( r, g, b )で指定できる.


Ellipse

枠だけの楕円,楕円弧,もしくは塗りつぶされた扇形の楕円を描画する

void cvEllipse( CvArr* img, CvPoint center, CvSize axes, double angle,
                double start_angle, double end_angle, CvScalar color,
                int thickness=1, int line_type=8, int shift=0 );

img
楕円が描画される画像.
center
楕円の中心.
axes
楕円の軸の長さ.
angle
回転角度.
start_angle
楕円弧の開始角度.
end_angle
楕円弧の終了角度.
color
楕円の色.
thickness
楕円弧の線の幅.
line_type
楕円弧の線の種類.詳細はcvLineを参照.
shift
中心座標と軸の長さの小数点以下の桁を表すビット数.

関数cvEllipseは,枠だけの楕円,楕円弧,もしくは塗りつぶした楕円を描画する. 描画される楕円はROIによって切り取られる. アンチエイリアスされた線や太い線を指定した場合には,線形近似が用いられる.角度は度で指定する. パラメータの意味を以下の図で説明する.

楕円弧を描画するためのパラメータ

楕円弧を描画するためのパラメータ


EllipseBox

枠だけの楕円,もしくは塗りつぶされた楕円を描画する

void cvEllipseBox( CvArr* img, CvBox2D box, CvScalar color,
                   int thickness=1, int line_type=8, int shift=0 );

img
楕円が描かれる画像.
box
描画したい楕円を囲む矩形領域.
thickness
楕円境界線の幅.
line_type
楕円境界線の種類.詳細はcvLineを参照.
shift
矩形領域の頂点座標の小数点以下の桁を表すビット数.

関数cvEllipseBoxは枠だけの楕円,もしくは塗りつぶされた楕円を描画する. この関数は,cvCamShiftcvFitEllipseで得られた結果から楕円を描画する際に便利である. 描画される楕円はROIによって切り取られる.アンチエイリアスされた線や太い線を指定した場合には,線形近似が用いられる.


FillPoly

ポリゴン内部を塗りつぶす

void cvFillPoly( CvArr* img, CvPoint** pts, int* npts, int contours,
                 CvScalar color, int line_type=8, int shift=0 );

img
ポリゴンが描かれる画像.
pts
ポリゴンへのポインタ配列.
npts
ポリゴン頂点数の配列.
contours
塗りつぶされた領域を区切る輪郭の数.
color
ポリゴンの色.
line_type
線の種類.詳細はcvLineを参照.
shift
頂点座標の小数点以下の桁を表すビット数.

関数cvFillPolyは,幾つかのポリゴンにより区切られた領域を塗りつぶす. この関数では複雑な領域,例えば領域内に穴を持つものや,自己交差したものなども塗りつぶす.


FillConvexPoly

凸ポリゴンを塗りつぶす

void cvFillConvexPoly( CvArr* img, CvPoint* pts, int npts,
                       CvScalar color, int line_type=8, int shift=0 );

img
ポリゴンが描かれる画像.
pts
一つのポリゴンへのポインタの配列.
npts
ポリゴンの頂点数.
color
ポリゴンの色.
line_type
線の種類.詳細はcvLineを参照.
shift
頂点座標の小数点以下の桁を表すビット数.

関数cvFillConvexPolyは凸ポリゴンの内部を塗りつぶす. この関数は,関数cvFillPolyより高速に動作する. また,凸ポリゴンだけでなく,その輪郭が水平なスキャンラインと2回以下しか交差しないような単純なポリゴンはすべて塗りつぶすことができる.


PolyLine

ポリライン(枠だけのポリゴン)を描画する

void cvPolyLine( CvArr* img, CvPoint** pts, int* npts, int contours, int is_closed,
                 CvScalar color, int thickness=1, int line_type=8, int shift=0 );

img
ポリラインが描かれる画像.
pts
ポリラインへのポインタの配列.
npts
ポリラインの頂点数の配列.
contours
ポリラインの個数.
is_closed
ポリラインを閉じるかどうかを指定する.閉じる場合,それぞれの領域の最後の頂点と最初の頂点を結ぶ線分を描画する.
color
線の色.
thickness
線の太さ.
line_type
線の種類.詳細はcvLineを参照.
shift
頂点座標の小数点以下の桁を表すビット数.

関数cvPolyLineは,一つ,もしくは複数のポリラインを描画する.


テキスト(Text)


InitFont

フォント構造体を初期化する

void cvInitFont( CvFont* font, int font_face, double hscale,
                 double vscale, double shear=0,
                 int thickness=1, int line_type=8 );

font
この関数で初期化されるフォント構造体へのポインタ
font_face
フォント名の識別子.現在は,Hershey fonts (http://sources.isc.org/utils/misc/hershey-font.txt) の一部のみサポートされている.
CV_FONT_HERSHEY_SIMPLEX - 普通サイズのsans-serif フォント
CV_FONT_HERSHEY_PLAIN - 小さいサイズのsans-serif フォント
CV_FONT_HERSHEY_DUPLEX - 普通サイズのsans-serif フォント (CV_FONT_HERSHEY_SIMPLEX よりも複雑)
CV_FONT_HERSHEY_COMPLEX - 普通サイズのserif フォント
CV_FONT_HERSHEY_TRIPLEX - 普通サイズのserif フォント (CV_FONT_HERSHEY_COMPLEX よりも複雑)
CV_FONT_HERSHEY_COMPLEX_SMALL - CV_FONT_HERSHEY_COMPLEX の小さいバージョン
CV_FONT_HERSHEY_SCRIPT_SIMPLEX - 手書きスタイルのフォント
CV_FONT_HERSHEY_SCRIPT_COMPLEX - CV_FONT_HERSHEY_SCRIPT_SIMPLEX の複雑なバージョン
パラメータは上記の値と,イタリックもしくは斜字を意味するオプションCV_FONT_ITALICフラグを合成することができる.
hscale
幅の比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の幅で表示される. 0.5fにした場合, 文字は元々の半分の幅で表示される.
vscale
高さの比率.1.0fにした場合,文字はそれぞれのフォントに依存する元々の高さで表示される. 0.5fにした場合, 文字は元々の半分の高さで表示される.
shear
垂直線からの文字の相対的な角度.ゼロの場合は非イタリックフォントで,例えば,1.0f≈45°を意味する.
thickness
文字の太さ.
line_type
線の種類.詳細はcvLineを参照.

関数cvInitFontは,文字描画関数に渡されるフォント構造体を初期化する.


PutText

文字列を描画する

void cvPutText( CvArr* img, const char* text, CvPoint org, const CvFont* font, CvScalar color );

img
入力画像.
text
描画する文字列.
org
最初の文字の左下の座標.
font
フォント構造体へのポインタ.
color
文字の色.

関数cvPutTextは,指定したフォントと色で文字列を画像中に描画する. 描画された文字はROIによって切り取られる.指定したフォントに含まれない記号は四角で置き換えられる.


GetTextSize

文字列の幅と高さを取得する

void cvGetTextSize( const char* text_string, const CvFont* font, CvSize* text_size, int* baseline );

text_string
入力文字列.
font
フォント構造体へのポインタ.
text_size
結果として得られる文字列のサイズ.文字の高さには,ベースラインより下の部分の高さは含まれない.
baseline
文字の最下点から見たベースラインのy座標.

関数cvGetTextSizeは,指定したフォントでの入力文字列を包含する矩形を計算する.


点集合と輪郭(Point Sets and Contours)


DrawContours

画像の外側輪郭線,または内側輪郭線を描画する

void cvDrawContours( CvArr *img, CvSeq* contour,
                     CvScalar external_color, CvScalar hole_color,
                     int max_level, int thickness=1,
                     int line_type=8, CvPoint offset=cvPoint(0,0) );

img
輪郭を描画する元画像.輪郭はROIで切り取られる.
contour
最初の輪郭へのポインタ.
external_color
外側輪郭線の色.
hole_color
内側輪郭線(穴)の色.
max_level
描画される輪郭の最大レベル. 0にした場合,contourのみが描画される. 1にした場合,先頭の輪郭と,同レベルのすべての輪郭が描画される. 2にした場合,先頭の輪郭と同レベルのすべての輪郭と,先頭の輪郭の一つ下のレベルのすべての輪郭が描画される.以下同様. 負の値にした場合,この関数はcontourの後に続く同レベルの輪郭を描画しないが, contourの子の輪郭をabs(max_level)-1のレベルまで描画する.
thickness
描画される輪郭線の太さ.負(例えば=CV_FILLED)にした場合には,内部を塗りつぶす.
line_type
線の種類.詳細はcvLineを参照.
offset
全ての座標を指定した値だけシフトする.これは,輪郭をROI内の画像から生成して,ROIのオフセットを考慮する必要がある場合に便利である.

関数cvDrawContoursは,thickness>=0の場合には外側輪郭線を画像上に描画し, thickness<0の場合には輪郭の内部を塗りつぶす.

(例)輪郭関数を用いた連結要素の検出

#include "cv.h"
#include "highgui.h"

int main( int argc, char** argv )
{
    IplImage* src;
    // コマンドラインの第1パラメータは2値(白黒)画像のファイル名を指定する
    if( argc == 2 && (src=cvLoadImage(argv[1], 0))!= 0)
    {
        IplImage* dst = cvCreateImage( cvGetSize(src), 8, 3 );
        CvMemStorage* storage = cvCreateMemStorage(0);
        CvSeq* contour = 0;

        cvThreshold( src, src, 1, 255, CV_THRESH_BINARY );
        cvNamedWindow( "Source", 1 );
        cvShowImage( "Source", src );

        cvFindContours( src, storage, &contour, 
                        sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
        cvZero( dst );

        for( ; contour != 0; contour = contour->h_next )
        {
            CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );
            /* 輪郭を見るためには,CV_FILLEDを1にする */
            cvDrawContours( dst, contour, color, color, -1, CV_FILLED, 8 );
        }

        cvNamedWindow( "Components", 1 );
        cvShowImage( "Components", dst );
        cvWaitKey(0);
    }
}

輪郭を見るためには,上述のサンプルの CV_FILLED を 1 に置き換える.


InitLineIterator

ラインイテレータを初期化する

int cvInitLineIterator( const CvArr* image, CvPoint pt1, CvPoint pt2,
                        CvLineIterator* line_iterator, int connectivity=8,
                        int left_to_right=0 );

image
対象画像.
pt1
線分の一つ目の端点.
pt2
線分のニつ目の端点.
line_iterator
ラインイテレータ状態構造体へのポインタ.
connectivity
走査した線分の接続性.4または8.
left_to_right
pt1pt2とは無関係に線分をいつも左から右に走査する(left_to_right≠0)か, pt1からpt2への決まった方向で走査するか(left_to_right=0)を指定するフラグ.

関数cvInitLineIteratorはラインイテレータを初期化し,2端点間のピクセル数を返す. 両方の点は共に画像内に存在しなければならない. ラインイテレータが初期化された後,2端点を結ぶ線分上のすべての点はCV_NEXT_LINE_POINTにより取得される. 線上の点は,4連結 または 8連結ブレゼンハム(Bresenham)アルゴリズムを用いて一つずつ計算される.

(例)ラインイテレータを用いた色のついた線上のピクセル値の総和の計算

    CvScalar sum_line_pixels( IplImage* image, CvPoint pt1, CvPoint pt2 )
    {
        CvLineIterator iterator;
        int blue_sum = 0, green_sum = 0, red_sum = 0;
        int count = cvInitLineIterator( image, pt1, pt2, &iterator, 8, 0 );

        for( int i = 0; i < count; i++ ){
            blue_sum += iterator.ptr[0];
            green_sum += iterator.ptr[1];
            red_sum += iterator.ptr[2];
            CV_NEXT_LINE_POINT(iterator);

            /* ピクセルの座標を表示:どうやって座標を計算するか,のデモンストレーション */
            {
            int offset, x, y;
            /* ROIは設定されていないと仮定している.もし設定されている場合には考慮する必要がある.*/
            offset = iterator.ptr - (uchar*)(image->imageData);
            y = offset/image->widthStep;
            x = (offset - y*image->widthStep)/(3*sizeof(uchar) /* ピクセルのサイズ */);
            printf("(%d,%d)¥n", x, y );
            }
        }
        return cvScalar( blue_sum, green_sum, red_sum );
    }

ClipLine

線分を画像領域で切り取る

int cvClipLine( CvSize img_size, CvPoint* pt1, CvPoint* pt2 );

img_size
画像の大きさ.
pt1
線分の1番目の端点.この値はこの関数によって変更される.
pt2
線分の2番目の端点.この値はこの関数によって変更される.

関数cvClipLine は,画像領域内に存在する線分の領域を計算する. もし線分が完全に画像外ならば0を返し,そうでなければ1を返す.


Ellipse2Poly

楕円弧をポリラインで近似する

int cvEllipse2Poly( CvPoint center, CvSize axes,
                    int angle, int arc_start,
                    int arc_end, CvPoint* pts, int delta );

center
弧の中心.
axes
楕円の軸の長さ.cvEllipseを参照.
angle
楕円の回転角度.cvEllipseを参照.
start_angle
楕円弧の開始角度.
end_angle
楕円弧の終了角度.
pts
この関数で塗りつぶされる点の配列.
delta
ポリラインの連続した頂点間の角度,近似精度.出力される点の総数は最大で ceil((end_angle - start_angle)/delta) + 1.

関数cvEllipse2Polyは,指定した楕円弧を近似するポリラインの頂点を計算する. これはcvEllipseで利用される.


データ永続性と実行時型情報(Data Persistence and RTTI)


ファイルストレージ(File Storage)


CvFileStorage

ファイルストレージ

    typedef struct CvFileStorage
    {
        ...       // 隠しフィールド
    } CvFileStorage;

構造体CvFileStorageは, ディスク内にあるファイルと関連付けられたファイルストレージの「ブラックボックス」的な表現である. 後述する様々な関数はCvFileStorageを引数に持ち,スカラー値で構成される階層的なコレクションや, 行列やシーケンス,グラフなどの標準的なCXCoreオブジェクト,ユーザ定義オブジェクトなどのセーブとロードをユーザに提供する.

CXCoreは,XML(http://www.w3c.org/XML)や YAML (http://www.yaml.org)形式のデータの読み書きが可能である. 以下はXMLとYAMLによる浮動小数点型の3×3単位行列Aの表現である.CXCoreの関数を用いると次のようになる.

XML:
<?xml version="1.0">
<opencv_storage>
<A type_id="opencv-matrix">
  <rows>3</rows>
  <cols>3</cols>
  <dt>f</dt>
  <data>1. 0. 0. 0. 1. 0. 0. 0. 1.</data>
</A>
</opencv_storage>
YAML:
%YAML:1.0
A: !!opencv-matrix
  rows: 3
  cols: 3
  dt: f
  data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1.]

この例で見られるように,XMLでは階層構造の表現にネスト(入れ子)されたタグを用い,YAMLでは(Pythonと類似した)インデントを用いる.

同じCXCore関数を用いて両データ形式の読み書きが可能であり,形式は開かれたファイルの拡張子で判別される. 拡張子はXMLの場合.xml,YAMLの場合は.ymlである.


CvFileNode

ファイルストレージノード

/* ファイルノードタイプ */
#define CV_NODE_NONE        0
#define CV_NODE_INT         1
#define CV_NODE_INTEGER     CV_NODE_INT
#define CV_NODE_REAL        2
#define CV_NODE_FLOAT       CV_NODE_REAL
#define CV_NODE_STR         3
#define CV_NODE_STRING      CV_NODE_STR
#define CV_NODE_REF         4 /* 使用されない */
#define CV_NODE_SEQ         5
#define CV_NODE_MAP         6
#define CV_NODE_TYPE_MASK   7

/* オプションのフラグ */
#define CV_NODE_USER        16
#define CV_NODE_EMPTY       32
#define CV_NODE_NAMED       64

#define CV_NODE_TYPE(tag)  ((tag) & CV_NODE_TYPE_MASK)

#define CV_NODE_IS_INT(tag)        (CV_NODE_TYPE(tag) == CV_NODE_INT)
#define CV_NODE_IS_REAL(tag)       (CV_NODE_TYPE(tag) == CV_NODE_REAL)
#define CV_NODE_IS_STRING(tag)     (CV_NODE_TYPE(tag) == CV_NODE_STRING)
#define CV_NODE_IS_SEQ(tag)        (CV_NODE_TYPE(tag) == CV_NODE_SEQ)
#define CV_NODE_IS_MAP(tag)        (CV_NODE_TYPE(tag) == CV_NODE_MAP)
#define CV_NODE_IS_COLLECTION(tag) (CV_NODE_TYPE(tag) >= CV_NODE_SEQ)
#define CV_NODE_IS_FLOW(tag)       (((tag) & CV_NODE_FLOW) != 0)
#define CV_NODE_IS_EMPTY(tag)      (((tag) & CV_NODE_EMPTY) != 0)
#define CV_NODE_IS_USER(tag)       (((tag) & CV_NODE_USER) != 0)
#define CV_NODE_HAS_NAME(tag)      (((tag) & CV_NODE_NAMED) != 0)

#define CV_NODE_SEQ_SIMPLE 256
#define CV_NODE_SEQ_IS_SIMPLE(seq) (((seq)->flags & CV_NODE_SEQ_SIMPLE) != 0)

typedef struct CvString
{
    int len;
    char* ptr;
}
CvString;

/* 読み込んだファイルストレージに含まれる要素の全てのキー(names)は,
   ルックアップ作業の高速化のためハッシュに記憶される */
typedef struct CvStringHashNode
{
    unsigned hashval;
    CvString str;
    struct CvStringHashNode* next;
}
CvStringHashNode;

/* ファイルストレージの基本要素 - スカラー,またはコレクション */
typedef struct CvFileNode
{
    int tag;
    struct CvTypeInfo* info; /* 型情報(ユーザ定義オブジェクト用,そうでない場合は0) */
    union
    {
        double f; /* 浮動小数点のスカラー値 */
        int i;    /* 整数のスカラー値 */
        CvString str; /* 文字列 */
        CvSeq* seq; /* シーケンス(整列されたファイルノードのコレクション) */
        struct CvMap* map; /* マップ(名前付けされたファイルノードのコレクション) */
    } data;
}
CvFileNode;

この構造体は,ファイルストレージからのデータ取り込みにのみ用いられる(例えばファイルからのデータのロード). データがファイルに書き込まれる場合,最小限のバッファリングで連続的に実行される.このファイルストレージには一切のデータが保存されない.

反対に,ファイルからデータが読み込まれた場合,全てのファイルは解析されて,メモリ内では木構造として表現される. 木構造のそれぞれのノードはCvFileNodeで表現される. ファイルノードNの型は,CV_NODE_TYPE(N->tag)として取得できる. 幾つかのファイルノード(葉)は,文字列や,整数型値,浮動小数点型値などのスカラーである. 他のファイルノードはファイルノードのコレクションであり,それはスカラー値かそのノードでのコレクションである. コレクションにはシーケンスとマップの2つの型がある(ここではYAMLの表記法を使うが,XMLストリームでも同様である). シーケンス(CvSeq と混同しないように)は名前付けされていないファイルノードの整列されたコレクションで, マップは名前付けされたファイルノードの整列されていないコレクションである. このように,シーケンスの要素には,インデックス(cvGetSeqElem)によりアクセスされ, マップの要素には名前(cvGetFileNodeByName)でアクセスされる. 以下の表はファイルノードの型の違いを示す.

CV_NODE_TYPE(node->tag)
整数CV_NODE_INTnode->data.i
浮動小数点CV_NODE_REALnode->data.f
文字列CV_NODE_STRnode->data.str.ptr
シーケンスCV_NODE_SEQnode->data.seq
マップCV_NODE_MAPnode->data.map*

*
map フィールドに直接アクセスする必要は無い(CvMapは隠された構造体である). このマップの要素は,「マップ」ファイルノードのポインタを引数に持つ関数 cvGetFileNodeByNameを使って取得できる.

ユーザ(カスタム)オブジェクトはCvMatCvSeq等の標準的なCxCoreの型か, cvRegisterTypeInfoで登録された型のインスタンスである. これらのオブジェクトは,ファイルストレージが開かれて解析された後,初期状態ではファイル内でマップ(上述のXMLとYAMLのサンプルファイルのように)として表現されている. その後,オブジェクトはリクエスト(関数cvReadcvReadByNameを使った場合) に応じてデコード(元々の表現に変換)される.


CvAttrList

属性のリスト

typedef struct CvAttrList
{
    const char** attr; /* (attribute_name,attribute_value)のペアからなるNULLで終わる配列 */
    struct CvAttrList* next; /* 属性リストの次の塊へのポインタ */
}
CvAttrList;

/* 構造体CvAttrListの初期化 */
inline CvAttrList cvAttrList( const char** attr=NULL, CvAttrList* next=NULL );

/* 属性の値を返すか,もしそのような属性が存在しない場合には0(NULL)を返す */
const char* cvAttrValue( const CvAttrList* attr, const char* attr_name );

現在の実装では,属性はユーザオブジェクトを書き込む際の特別なパラメータを渡すために使われる(cvWriteを参照). タグの中にあるXMLの属性やオブジェクトの型指定(type_id属性)はサポートされない.


OpenFileStorage

データ読み書きのためのファイルをオープンする

CvFileStorage* cvOpenFileStorage( const char* filename, CvMemStorage* memstorage, int flags );

filename
ストレージに関連づけられたファイルの名前.
memstorage
一時的なデータや,CvSeqCvGraphなどの動的構造体の保存に使われるメモリストレージ.NULLの場合,一時的なメモリが確保されて使用される.
flags
以下の内の一つを指定.
CV_STORAGE_READ - データ読み込みのためのファイルオープン
CV_STORAGE_WRITE - データ書き込みのためのファイルオープン

関数cvOpenFileStorageは,データの読み書きのためのファイルを開く. 書き込みの場合は,新しいファイルが作成されるか,ファイルが存在する場合には上書きされる.また,読み書きされるファイルの種類は拡張子で判別される. XMLの場合は.xmlYAMLの場合は.ymlまたは.yamlである. この関数の戻り値は構造体CvFileStorageへのポインタである.


ReleaseFileStorage

ファイルストレージの解放

void cvReleaseFileStorage( CvFileStorage** fs );

fs
解放するファイルへのポインタのポインタ.

関数cvReleaseFileStorageはファイルを閉じて,一時的な構造体をすべて解放する. この関数は,すべての入出力操作が終了した後に実行されなければならない.


データの書き込み(Writing Data)


StartWriteStruct

新しい構造体の書き込みを開始する

void cvStartWriteStruct( CvFileStorage* fs, const char* name,
                          int struct_flags, const char* type_name=NULL,
                          CvAttrList attributes=cvAttrList());

fs
ファイルストレージ.
name
書き込む構造体の名前.読み込む場合は,この名前で構造体にアクセスできる.
struct_flags
次の値の組合せ.
CV_NODE_SEQ - 書き込む構造体はシーケンス(CvFileStorageを参照), つまり要素は名前を持たない.
CV_NODE_MAP - 書き込む構造体はマップ(CvFileStorageを参照), つまり全ての要素が名前を持つ.
これら二つのうち一つだけを指定しなければならない.
CV_NODE_FLOW - YAMLストリームに対してのみ意味を持つオプションフラグ. 構造体は,よりコンパクトなflow(blockではなく)として保存される. このフラグは全要素がスカラーである構造体か配列に対して用いることが推奨される.
type_name
オプションパラメータ - オブジェクトの型の名前. XMLの場合,構造体開始タグのtype_id属性として書かれる. YAMLの場合,構造体名に続くコロンの後に書かれる(CvFileStorageの説明の中にある例を参照). 主にユーザオブジェクトと共に使われる.ストレージが読まれたとき,エンコードされた型名がオブジェクトの型を決定する (CvTypeInfocvFindTypeInfoを参照).
attributes
このパラメータは現在は使われていない.

関数cvStartWriteStructは,シーケンスかマップが複合した構造体(コレクション)の書き込みを開始する. スカラーか構造体で構成された全ての構造体のフィールドが書き込まれた後で,cvEndWriteStructを実行しなければならない. この関数は,いくつかのオブジェクトをグループ化する場合や, ユーザオブジェクト(CvTypeInfoを参照)の書き込み関数を実装する場合にも使われることがある.


EndWriteStruct

構造体の書き込みを終了する

void cvEndWriteStruct( CvFileStorage* fs );

fs
ファイルストレージ.

関数cvEndWriteStructは,構造体の書き込みを終了する.


WriteInt

整数型の値を書き込む

void cvWriteInt( CvFileStorage* fs, const char* name, int value );

fs
ファイルストレージ.
name
書き込まれる値の名前.親の構造体がシーケンスの場合は,NULLにしなければならない.
value
書き込まれる値.

関数cvWriteIntは,1つの整数値(名前あり,または無し)をファイルに書き込む.


WriteReal

浮動小数点型の値を書き込む

void cvWriteReal( CvFileStorage* fs, const char* name, double value );

fs
ファイルストレージ.
name
書き込まれる値の名前.親の構造体がシーケンスの場合は,NULLにしなければならない.
value
書き込まれる値.

関数cvWriteRealは,単精度浮動小数点型の値(名前あり,または無し)をファイルに書き込む. 特別な値はエンコードされる:Not A NumberはNaN に,±Infinityは +.Inf (-.Inf) になる.

以下の例では新たな型の登録を行なわず,終了条件のような独自の構造体を保存する低レベルの書き込み関数の使い方を示す.

void write_termcriteria( CvFileStorage* fs, const char* struct_name,
                         CvTermCriteria* termcrit )
{
    cvStartWriteStruct( fs, struct_name, CV_NODE_MAP, NULL, cvAttrList(0,0));
    cvWriteComment( fs, "termination criteria", 1 ); // 単なるコメント
    if( termcrit->type & CV_TERMCRIT_ITER )
        cvWriteInteger( fs, "max_iterations", termcrit->max_iter );
    if( termcrit->type & CV_TERMCRIT_EPS )
        cvWriteReal( fs, "accuracy", termcrit->epsilon );
    cvEndWriteStruct( fs );
}

WriteString

文字列を書き込む

void cvWriteString( CvFileStorage* fs, const char* name,
                     const char* str, int quote=0 );

fs
ファイルストレージ.
name
書き込まれる文字列の名前.親の構造体がシーケンスの場合は,NULLにしなければならない.
str
書き込まれる文字列.
quote
0以外の場合,書き込まれる文字列は必要かどうかに関わらず引用符で挟まれる. 0の場合,必要な場合にのみ引用符が使われる(例えば,文字列が数字で始まっていたり,スペースを含む場合).

関数cvWriteStringは,文字列をファイルストレージに書き込む.


WriteComment

コメントを書き込む

void cvWriteComment( CvFileStorage* fs, const char* comment, int eol_comment );

fs
ファイルストレージ.
comment
一行または複数行の,書き込まれるコメント.
eol_comment
0以外の場合,この関数は現在の行の最後にコメントを入れようと試みる. フラグが0で,コメントが複数,または現在の行の最後に納まらない場合は,コメントは新しい行から始められる.

関数cvWriteCommentは,ファイルストレージにコメントを書き込む. このコメントはデバッグや説明を記述するために使われるもので,読み込み時には読み飛ばされる.


StartNextStream

次のストリームを開始する

void cvStartNextStream( CvFileStorage* fs );

fs
ファイルストレージ.

関数cvStartNextStreamは,ファイルストレージ内の次のストリームを開始する. YAMLとXMLはどちらも複数の「ストリーム」をサポートしている. これはファイルの連結や書き込みプロセスの再開に役立つ.


Write

ユーザオブジェクトを書き込む

void cvWrite( CvFileStorage* fs, const char* name,
               const void* ptr, CvAttrList attributes=cvAttrList() );

fs
ファイルストレージ.
name
書き込まれるオブジェクトの名前.親の構造体がシーケンスの場合は,NULLにしなければならない.
ptr
オブジェクトへのポインタ.
attributes
オブジェクトの属性.これは特定の型に対して固有である(以下を参照).

関数cvWriteは,オブジェクトをファイルストレージに書き込む. まずcvTypeOfを用いて適切な型情報を見つける.そして,型情報のwriteメソッドが呼び出される.

属性は書き込み手続きをカスタマイズするために使われる.標準の型では以下の属性をサポートしている (全ての*dt属性は,cvWriteRawDataと同じフォーマットを持つ).

CvSeq
  • header_dt - CvSeq,または CvChain(シーケンスがフリーマンチェインの場合),または CvContour (シーケンスが輪郭か点列の場合)に続く,シーケンスヘッダのユーザフィールドの説明.
  • dt - シーケンス要素の説明.
  • recursive - 属性が存在し,「0」でも「false」でも無い場合,シーケンス(輪郭)のすべての木は保存される.
CvGraph
    グラフ頂点のユーザフィールドの説明.
  • header_dt - CvGraphに続く,グラフヘッダのユーザフィールドの説明.
  • vertex_dt - グラフ頂点のユーザフィールドの説明.
  • edge_dt - グラフエッジのユーザフィールドの説明(エッジの重みは常に書かれるため,明示的に指定する必要が無いことに注意).

以下はCvFileStorageの解説にあるYAMLを生成するコードである.

#include "cxcore.h"

int main( int argc, char** argv )
{
    CvMat* mat = cvCreateMat( 3, 3, CV_32F );
    CvFileStorage* fs = cvOpenFileStorage( "example.yml", 0, CV_STORAGE_WRITE );

    cvSetIdentity( mat );
    cvWrite( fs, "A", mat, cvAttrList(0,0) );

    cvReleaseFileStorage( &fs );
    cvReleaseMat( &mat );
    return 0;
}


WriteRawData

複数の数値を書き込む

void cvWriteRawData( CvFileStorage* fs, const void* src,
                      int len, const char* dt );

fs
ファイルストレージ.
src
書き込む配列へのポインタ.
len
書き込む配列の要素数.
dt
次に示すフォーマットを持つ配列の個々の要素の仕様. ([count]{'u'|'c'|'w'|'s'|'i'|'f'|'d'})...,で,これらの記号は基本的なC言語の型と同じである.
  • 'u' - 8ビット符号なし数
  • 'c' - 8ビット符号あり数
  • 'w' - 16ビット符号なし数
  • 's' - 16ビット符号あり数
  • 'i' - 32ビット符号あり数
  • 'f' - 単精度浮動小数点型数
  • 'd' - 倍精度浮動小数点型数
  • 'r' - ポインタ.下位32ビットは,符号あり整数として書き込まれる. この型は,書き込まれる要素同士がリンク構造を持つような構造体を格納するのに利用できる.
countはある型の値のオプションカウンタである. 例えばdt='2if'は,それぞれの配列要素が2つの整数,その後に一つの単精度浮動小数点数が続く構造であることを意味する. この仕様と同等の表記としては,'iif''2i1f' などがある. 別の例として dt='u'は,配列がバイト列であることを意味し, dt='2d'は,配列が倍精度浮動小数点型数のペアで構成されることを意味する.

関数cvWriteRawDataは,一つ一つの要素が複数の数値の集まりである配列を書き込む. この関数は cvWriteIntcvWriteRealの繰り返しで置き換えられるが,単一の実行のほうが効率的である. 名前を持つ要素が一つも無いため,マップよりはシーケンスに書き込むべきであることに注意する.


WriteFileNode

ファイルノードを他のファイルストレージに書き込む

void cvWriteFileNode( CvFileStorage* fs, const char* new_node_name,
                      const CvFileNode* node, int embed );
fs
書き込み先のファイルストレージ.
new_file_node
書き込み先ファイルストレージ内のファイルノードの新しい名前. 元の名前を維持するためには,cvGetFileNodeName(node)を用いる.
node
書き込まれるノード.
embed
書き込まれるノードがコレクションで,このパラメータが0でない場合,階層の余分なレベルは生成されない. その代わりに,nodeの全ての要素は現在書き込まれている構造体に書き込まれる. 当然,マップ要素はマップにのみ書き込まれ,シーケンス要素はシーケンスにのみ書き込まれる.

関数cvWriteFileNodeは,ファイルストレージにファイルノードのコピーを書き込む. この関数の用途として,いくつかのファイルストレージを一つにまとめる,XMLとYAMLのフォーマットを交換する,などが挙げられる.


データの読み込み(Reading Data)

データはファイルストレージから二つの段階を経て取り込まれる.まず要求されたデータを含むファイルノードを探索し, その後にそのノードから手動,もしくは特別なreadメソッドを用いて取り込む.


GetRootFileNode

ファイルストレージのトップレベルノードの一つを取り込む

CvFileNode* cvGetRootFileNode( const CvFileStorage* fs, int stream_index=0 );

fs
ファイルストレージ.
stream_index
0から始まるストリームのインデックス. cvStartNextStreamを参照. 多くの場合,ファイル中に存在するのは一つのストームであるが,複数にもなり得る.

関数cvGetRootFileNodeは,トップレベルファイルノードの一つを返す. トップレベルノードは名前を持たず,それらはストリームに相当し,ファイルストレージ内に次々と保存されている. インデックスが範囲外の場合,この関数はNULLポインタを返す. この関数にstream_index=0,1,...を順に指定して呼び出し,NULLポインタが返されるまで繰り返すことで, すべてのトップレベルノードを得ることができる.この関数はファイルストレージの再帰的な走査のために使われる.


GetFileNodeByName

マップ内またはファイルストレージ内からノードを探索する

CvFileNode* cvGetFileNodeByName( const CvFileStorage* fs,
                                 const CvFileNode* map,
                                 const char* name );

fs
ファイルストレージ.
map
親マップ.NULLの場合,この関数は一番最初のものから開始して,全てのトップレベルノード(ストリーム)内を探索する.
name
ファイルノード名.

関数cvGetFileNodeByNameは,nameのファイルノードを探索する. ノードの探索はmap内で行われ,ポインタがNULLであれば,ストレージのトップレベルファイルノードを含めて行なわれる. マップに対してこの関数を,シーケンスに対してcvGetSeqElem (またはシーケンスリーダ)を用いることで,ファイルストレージの走査が可能になる. あるキーに対する複数のクエリを高速に処理する(例えば構造体の配列など)ためには,cvGetHashedKeycvGetFileNodeを組み合わせて使うと良い.


GetHashedKey

与えた名前に対するユニークなポインタを返す

CvStringHashNode* cvGetHashedKey( CvFileStorage* fs, const char* name,
                                  int len=-1, int create_missing=0 );

fs
ファイルストレージ.
name
ノード名.
len
名前の長さ(事前に分かっている場合),または計算する必要がある場合は-1.
create_missing
absent keyをハッシュテーブルに追加するかどうかを指定するフラグ.

関数cvGetHashedKeyは,特定のファイルノード名に対する唯一のポインタを返す. このポインタは関数cvGetFileNodeByName より高速な関数cvGetFileNodeに渡すことができる. 後者の関数は文字列の内容を比較するのではなく,ポインタの比較により文字列を比較するためである.

次の例では,点列が二つのエントリを持つマップのシーケンスとして表されている.例えば,

%YAML:1.0
points:
  - { x: 10, y: 10 }
  - { x: 20, y: 20 }
  - { x: 30, y: 30 }
  # ...
そこで,ハッシュ化された"x"と"y"のポインタを得ることで,点のデコードを高速化することが可能になる.

(例)ファイルストレージから構造体の配列を読み込む

#include "cxcore.h"
#include <stdio>

int main( int argc, char** argv )
{
    CvFileStorage* fs = cvOpenFileStorage( "points.yml", 0, CV_STORAGE_READ );
    CvStringHashNode* x_key = cvGetHashedKey( fs, "x", -1, 1 );
    CvStringHashNode* y_key = cvGetHashedKey( fs, "y", -1, 1 );
    CvFileNode* points = cvGetFileNodeByName( fs, 0, "points" );

    if( CV_NODE_IS_SEQ(points->tag) )
    {
        CvSeq* seq = points->data.seq;
        int i, total = seq->total;
        CvSeqReader reader;
        cvStartReadSeq( seq, &reader, 0 );
        for( i = 0; i < total; i++ )
        {
            CvFileNode* pt = (CvFileNode*)reader.ptr;
#if 1 /* 高速バージョン */
            CvFileNode* xnode = cvGetFileNode( fs, pt, x_key, 0 );
            CvFileNode* ynode = cvGetFileNode( fs, pt, y_key, 0 );
            assert( xnode && CV_NODE_IS_INT(xnode->tag) &&
                    ynode && CV_NODE_IS_INT(ynode->tag));
            int x = xnode->data.i; // あるいは x = cvReadInt( xnode, 0 );
            int y = ynode->data.i; // あるいは y = cvReadInt( ynode, 0 );
#elif 1 /* 低速バージョン.x_keyとy_keyを使わない */
            CvFileNode* xnode = cvGetFileNodeByName( fs, pt, "x" );
            CvFileNode* ynode = cvGetFileNodeByName( fs, pt, "y" );
            assert( xnode && CV_NODE_IS_INT(xnode->tag) &&
                    ynode && CV_NODE_IS_INT(ynode->tag));
            int x = xnode->data.i; // あるいは x = cvReadInt( xnode, 0 );
            int y = ynode->data.i; // あるいは y = cvReadInt( ynode, 0 );
#else /* 超低速だが使いやすいバージョン */
            int x = cvReadIntByName( fs, pt, "x", 0 /* デフォルト値 */ );
            int y = cvReadIntByName( fs, pt, "y", 0 /* デフォルト値 */ );
#endif
            CV_NEXT_SEQ_ELEM( seq->elem_size, reader );
            printf("%d: (%d, %d)¥n", i, x, y );
        }
    }
    cvReleaseFileStorage( &fs );
    return 0;
}

マップヘのアクセス方法に関わらず,単純なシーケンスを使うものに比べて,これはまだかなり低速であることに注意してほしい. 例えば上の例においては,点を一つのシーケンスにおける整数のペアとしてエンコードする方がより効率的である.


GetFileNode

マップまたはファイルストレージ内のノードを見つける

CvFileNode* cvGetFileNode( CvFileStorage* fs, CvFileNode* map,
                           const CvStringHashNode* key, int create_missing=0 );

fs
ファイルストレージ.
map
親マップ.NULLの場合,この関数はトップレベルノードを探す.もしmapkeyの両方がNULLの場合には, この関数はトップレベルノードを持つマップであるルートファイルノードを返す.
key
cvGetHashedKeyで取得されるノード名ヘの唯一のポインタ.
create_missing
absent nodeをマップに追加するかどうかを指定するフラグ.

関数cvGetFileNodeは,ファイルノードを見つける. これはcvGetFileNodeByNamecvGetHashedKeyを参照)の高速バージョンである. マップ内に無い場合,この関数は(パースを行う関数が利用して)新しいノードを挿入することが可能である.


GetFileNodeName

ファイルノードの名前を返す

const char* cvGetFileNodeName( const CvFileNode* node );

node
ファイルノード.

関数cvGetFileNodeNameファイルノードの名前を返す. ファイルノードが名前を持たないか,nodeNULL の場合にはNULLを返す.


ReadInt

ファイルノードから整数値を読み込む

int cvReadInt( const CvFileNode* node, int default_value=0 );

node
ファイルノード.
default_value
nodeがNULLの場合の戻り値.

関数cvReadIntは,ファイルノードで表現された整数値を返す. ファイルノードがNULLの場合,default_valueを返す (つまり,cvGetFileNodeの直後でNULLポインタのチェックを行わず,この関数を使うと便利である). ファイルノードがCV_NODE_INT型を持つ場合,node->data.iを返す. ファイルノードがCV_NODE_REAL型を持つ場合,node->data.fを整数に変換して返す. それ以外の場合,戻り値は不定である.


ReadIntByName

ファイルノードを探索し,その値を返す

int cvReadIntByName( const CvFileStorage* fs, const CvFileNode* map,
                     const char* name, int default_value=0 );

fs
ファイルストレージ.
map
親マップ.NULLの場合,この関数はトップレベルノードを探索する.
name
ノード名.
default_value
ファイルノードが見つからない場合の戻り値.

関数cvReadIntByNameは,cvGetFileNodeByNamecvReadIntの単純な合成である.

.

ReadReal

ファイルノードから浮動小数点型の値を取り込む

double cvReadReal( const CvFileNode* node, double default_value=0. );

node
ファイルノード.
default_value
nodeがNULLの場合の戻り値.

関数cvReadRealは,ファイルノードで表現される浮動小数点型の値を返す. ファイルノードがNULLの場合,default_valueを返す (つまり,cvGetFileNodeの直後でNULLポインタのチェックを行なわず,この関数を使うと便利である). ファイルノードが CV_NODE_REAL型を持つ場合,node->data.fを返す. ファイルノードがCV_NODE_INT型を持つ場合,node->data.fを浮動小数点型に変換して返す. それ以外の場合,戻り値は不定である.


ReadRealByName

ファイルノードを探してその値を返す

double cvReadRealByName( const CvFileStorage* fs, const CvFileNode* map,
                          const char* name, double default_value=0. );

fs
ファイルストレージ.
map
親マップ.NULLの場合,この関数はトップレベルノードを探す.
name
ノード名.
default_value
ファイルノードが見つからない場合の戻り値.

関数cvReadRealByNameは,cvGetFileNodeByNamecvReadRealの単純な合成である.


ReadString

ファイルノードから文字列を取り出す

const char* cvReadString( const CvFileNode* node, const char* default_value=NULL );

node
ファイルノード.
default_value
nodeがNULLの場合の戻り値.

関数cvReadStringは,ファイルノードで表現された文字列を返す. ファイルノードがNULLの場合にはdefault_valueを返す (つまり,cvGetFileNodeの直後でNULLポインタのチェックを行なわず,この関数を使うと便利である). ファイルノードがCV_NODE_STR型を持つ場合にはnode->data.str.ptrを返す. それ以外の場合,戻り値は不定である.


ReadStringByName

ファイルノードを探索して,その値を返す

const char* cvReadStringByName( const CvFileStorage* fs, const CvFileNode* map,
                                const char* name, const char* default_value=NULL );

fs
ファイルストレージ.
map
親マップ.NULLの場合,この関数はトップレベルノードを探索する.
name
ノード名.
default_value
ファイルノードが見つからない場合の戻り値.

関数cvReadStringByNameは,cvGetFileNodeByNamecvReadStringの単純な合成である.


Read

オブジェクトをデコードし,そのポインタを返す

void* cvRead( CvFileStorage* fs, CvFileNode* node,
              CvAttrList* attributes=NULL );

fs
ファイルストレージ.
node
ルートオブジェクトノード.
attributes
使用されないパラメータ.

関数cvReadは,ユーザオブジェクトをデコードし (オブジェクトをファイルストレージのサブツリーからネイティブな表現で作成),それを返す. デコードされるオブジェクトは,readメソッドをサポートする登録された型のインスタンスでなけらばならない (CvTypeInfoを参照). オブジェクトの型はファイル内でエンコードされた型名で決定される. もしオブジェクトが動的構造体の場合,メモリストレージ内にも生成され, cvOpenFileStorageに渡される. ここでNULLポインタが渡された場合,一時的なメモリストレージの中ではcvReleaseFileStorage が呼ばれた時に解放される. もしオブジェクトが動的構造体でない場合,ヒープ内に生成され,特別な関数か標準のcvRelease を使って解放する必要がある.


ReadByName

オブジェクトを探索し,デコードする

void* cvReadByName( CvFileStorage* fs, const CvFileNode* map,
                    const char* name, CvAttrList* attributes=NULL );

fs
ファイルストレージ.
map
親マップ.NULLの場合,この関数はトップレベルノードを探索する.
name
ノード名.
attributes
使用されないパラメータ.

関数cvReadByNameは,cvGetFileNodeByNamecvReadの単純な合成である.


ReadRawData

複数の数値を読み込む

void cvReadRawData( const CvFileStorage* fs, const CvFileNode* src,
                    void* dst, const char* dt );

fs
ファイルストレージ.
src
数値を読み込むファイルノード(シーケンス).
dst
書き込み先の配列へのポインタ.
dt
配列の個々の要素の仕様.仕様はcvWriteRawDataと同じ.

関数cvReadRawDataは,スカラーのシーケンスで表されたファイルノードから要素を読み込む.


StartReadRawData

ファイルノードのシーケンスリーダの初期化

void cvStartReadRawData( const CvFileStorage* fs, const CvFileNode* src,
                         CvSeqReader* reader );

fs
ファイルストレージ.
src
読み込むファイルノード(シーケンス).
reader
シーケンスリーダへのポインタ.

関数cvStartReadRawDataは,ファイルノードからデータを読み込むためのシーケンスリーダを初期化する. 初期化されたリーダはcvReadRawDataSliceに渡すことができる.


ReadRawDataSlice

複数の数値のシーケンスを読み込む

void cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader,
                         int count, void* dst, const char* dt );

fs
ファイルストレージ.
reader
シーケンスリーダ.cvStartReadRawDataで初期化する.
count
読み込む要素数.
dst
出力配列へのポインタ.
dt
各配列要素の仕様.仕様はcvWriteRawDataと同じ.

関数cvReadRawDataSliceは,ファイルから,シーケンスで表現される一つまたは複数の要素をユーザ定義配列へ読み込む. 読み込むシーケンス要素の総数はcountと各配列要素の要素数の積である. 例えばdt='2if'の場合,この関数はcount*3のシーケンス要素を読み込む. リーダがcvSetSeqReaderPosで再配置されると, ファイルノードシーケンスの幾つかの部分は読み飛ばされるか,重複して読み込まれる可能性がある.


実行時型情報と汎用関数(RTTI and Generic Functions)


CvTypeInfo

型情報

typedef int (CV_CDECL *CvIsInstanceFunc)( const void* struct_ptr );
typedef void (CV_CDECL *CvReleaseFunc)( void** struct_dblptr );
typedef void* (CV_CDECL *CvReadFunc)( CvFileStorage* storage, CvFileNode* node );
typedef void (CV_CDECL *CvWriteFunc)( CvFileStorage* storage,
                                      const char* name,
                                      const void* struct_ptr,
                                      CvAttrList attributes );
typedef void* (CV_CDECL *CvCloneFunc)( const void* struct_ptr );

typedef struct CvTypeInfo
{
    int flags; /* 使用されない */
    int header_size; /* sizeof(CvTypeInfo) */
    struct CvTypeInfo* prev; /* リスト内で一つ前に登録された型 */
    struct CvTypeInfo* next; /* リスト内で一つ後に登録された型 */
    const char* type_name; /* ファイルストレージに書き込まれた型の名前 */

    /* メソッド */
    CvIsInstanceFunc is_instance; /* 渡されたオブジェクトがその型に属するかをチェックする */
    CvReleaseFunc release; /* オブジェクトを解放する(メモリなど) */
    CvReadFunc read; /* ファイルストレージからオブジェクトを読み込む */
    CvWriteFunc write; /* ファイルストレージにオブジェクトを書き込む */
    CvCloneFunc clone; /* オブジェクトのコピーを生成する */
}
CvTypeInfo;

構造体CvTypeInfoは,標準型もしくはユーザ定義型のいずれかに関する情報を含む. その型のインスタンスは,対応するCvTypeInfo構造体へのポインタを持つ可能性がある. どのような場合でも,関数cvTypeOfを使うことで,与えられたオブジェクトの型情報を見つけることができる. また別の方法として,オブジェクトをファイルストレージから読み込む時に使うcvFindType を用いて型の名前から見つけることもできる. ユーザは新しい型をcvRegisterTypeを使って,型情報構造体を型リストの先頭に登録できる. このように,一般的な標準の型から特別な型を作成し,基本的なメソッドをオーバーライドすることが可能である.


RegisterType

新しい型を登録する

void cvRegisterType( const CvTypeInfo* info );

info
型情報構造体.

関数cvRegisterTypeは,infoに記述された新しい型を登録する. この関数は構造体のコピーを作成するので,ユーザは関数呼び出し後にその構造体を削除しなければならない.


UnregisterType

型の登録を取り消す

void cvUnregisterType( const char* type_name );

type_name
登録を取り消す型の名前.

関数cvUnregisterTypeは,指定した名前の型の登録を取り消す. もしその名前が不明であれば,cvTypeOfを使って型のインスタンスから探すか, もしくはcvFirstTypeから型リストを順に見て型情報を探し, cvUnregisterType(info->type_name)を実行することで取り消すことができる.


FirstType

型リストの先頭を返す

CvTypeInfo* cvFirstType( void );

関数cvFirstTypeは,登録されている型のリストの先頭のものを返す. CvTypeInfo構造体のprevnextフィールドを使うことで,リストをすべて走査できる.


FindType

名前から型を見つける

CvTypeInfo* cvFindType( const char* type_name );

type_name
型の名前.

関数cvFindTypeは,登録された型を名前で探す. NULLを返した場合,指定した名前の型は存在しない.


TypeOf

オブジェクトの型を返す

CvTypeInfo* cvTypeOf( const void* struct_ptr );

struct_ptr
オブジェクトへのポインタ.

関数cvTypeOfは,与えられたオブジェクトの型を見つける. 登録された型のリストを走査し,それぞれの型情報構造体の関数/メソッドis_instanceを呼び, それらの一つが非0を返すか,すべてのリストを走査し終えるまで繰り返す.後者の場合,この関数はNULLを返す.


Release

オブジェクトを解放する

void cvRelease( void** struct_ptr );

struct_ptr
オブジェクトのポインタのポインタ.

関数cvReleaseは,与えられたオブジェクトの型を見つけ,与えられたポインタのポインタを引数にreleaseを呼ぶ.


Clone

オブジェクトのコピーを作成する

void* cvClone( const void* struct_ptr );

struct_ptr
コピーするオブジェクト.

関数cvCloneは,与えたオブジェクトの型を見つけ,渡されたオブジェクトを引数にcloneを呼ぶ.


Save

オブジェクトをファイルに保存する

void cvSave( const char* filename, const void* struct_ptr,
             const char* name=NULL,
             const char* comment=NULL,
             CvAttrList attributes=cvAttrList());

filename
ファイル名.
struct_ptr
保存するオブジェクト.
name
オブジェクト名(オプション).NULLの場合,名前はfilenameから生成される.
comment
ファイルの最初に置かれるコメント(オプション).
attributes
cvWriteに渡される属性(オプション).

関数cvSaveは,オブジェクトをファイルに保存する. これは,cvWriteへの簡単なインタフェースを提供する.


Load

オブジェクトをファイルから読み込む

void* cvLoad( const char* filename, CvMemStorage* memstorage=NULL,
              const char* name=NULL, const char** real_name=NULL );

filename
ファイル名.
memstorage
CvSeqCvGraph などの動的構造体のためのメモリストレージ.行列や画像には用いられない.
name
オブジェクト名(オプション).NULLの場合,ファイルストレージにある最初のトップレベルオブジェクトが読み込まれる.
real_name
読み込まれたオブジェクトの名前が代入される出力パラメータ(オプション)name=NULLの場合に役立つ.

関数cvLoadは,ファイルからオブジェクトを読み込む. これはcvReadへの簡単なインタフェースを提供する. オブジェクトが読み込まれた後,ファイルストレージは閉じられて一時的なバッファは全て消去される. 従って,シーケンスや輪郭,グラフなどの動的構造体を読み込むためには,この関数に正しい出力先メモリストレージを与える必要がある.


その他の関数(Miscellaneous Functions)


CheckArr

入力配列のすべての要素について,無効な値が存在しないかをチェックする

int cvCheckArr( const CvArr* arr, int flags=0,
                 double min_val=0, double max_val=0);
#define cvCheckArray cvCheckArr

arr
チェック対象の配列.
flags
処理フラグ.0 あるいは以下の値の組み合わせ.
CV_CHECK_RANGE - セットされている場合,配列のすべての要素について [minVal,maxVal) の範囲内であるかどうかをチェックする. それ以外の場合,すべての要素が NaN か ±(Infinity) でないかだけをチェックする.
CV_CHECK_QUIET - セットされている場合,要素に無効な値や範囲外のものがあっても,エラーを発生させない.
min_val
有効な値域の下限値(この値以上).CV_CHECK_RANGE がセットされているときのみ有効.
max_val
有効な値域の上限値(この値未満).CV_CHECK_RANGE がセットされているときのみ有効.

関数 cvCheckArr は,すべての配列要素が NaN あるいは ±(Infinity)でないかをチェックする. CV_CHECK_RANGE がセットされている場合は,すべての配列要素がminVal より大きいか等しく, かつ maxVal よりも小さいかをチェックする. チェックが正しく終わった場合(すべての要素が有効で指定範囲内であるとき)関数は0以外を返し,それ以外の場合は0を返す. エラーがあった場合,CV_CHECK_QUIET フラグがセットされていなければ,関数はランタイムエラーとして取り上げる.


KMeans2

ベクトル集合を,与えられたクラスタ数に分割する

void cvKMeans2( const CvArr* samples, int cluster_count,
                CvArr* labels, CvTermCriteria termcrit );

samples
浮動小数点型の入力サンプル行列.1行あたり一つのサンプル.
cluster_count
集合を分割するクラスタ数.
labels
出力の整数ベクトル.すべてのサンプルについて,それぞれがどのクラスタに属しているかが保存されている.
termcrit
最大繰り返し数と(または),精度(1ループでの各クラスタ中心位置移動距離)の指定.

関数 cvKMeans2 は,入力サンプルを各クラスタに分類するために cluster_count 個のクラスタの中心を求める k-means 法を実装する.出力 labels(i) は,配列 samples のi番目の行のサンプルが属するクラスタのインデックスを表す.

(例)複数のガウス分布を持つランダムサンプルをK-means法でクラスタリングする

#include "cxcore.h"
#include "highgui.h"

void main( int argc, char** argv )
{
    #define MAX_CLUSTERS 5
    CvScalar color_tab[MAX_CLUSTERS];
    IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );
    CvRNG rng = cvRNG(0xffffffff);
    
    color_tab[0] = CV_RGB(255,0,0);
    color_tab[1] = CV_RGB(0,255,0);
    color_tab[2] = CV_RGB(100,100,255);
    color_tab[3] = CV_RGB(255,0,255);
    color_tab[4] = CV_RGB(255,255,0);

    cvNamedWindow( "clusters", 1 );

    for(;;)
    {
        int k, cluster_count = cvRandInt(&rng)%MAX_CLUSTERS + 1;
        int i, sample_count = cvRandInt(&rng)%1000 + 1;
        CvMat* points = cvCreateMat( sample_count, 1, CV_32FC2 );
        CvMat* clusters = cvCreateMat( sample_count, 1, CV_32SC1 );

        /* 複数のガウス分布からランダムサンプルを生成する */ 
        for( k = 0; k < cluster_count; k++ )
        {
            CvPoint center;
            CvMat point_chunk;
            center.x = cvRandInt(&rng)%img->width;
            center.y = cvRandInt(&rng)%img->height;
            cvGetRows( points, &point_chunk, k*sample_count/cluster_count,
                       k == cluster_count - 1 ? sample_count : (k+1)*sample_count/cluster_count );
            cvRandArr( &rng, &point_chunk, CV_RAND_NORMAL,
                       cvScalar(center.x,center.y,0,0),
                       cvScalar(img->width/6, img->height/6,0,0) );
        }

        /* サンプルをシャッフルする */
        for( i = 0; i < sample_count/2; i++ )
        {
            CvPoint2D32f* pt1 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
            CvPoint2D32f* pt2 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count;
            CvPoint2D32f temp;
            CV_SWAP( *pt1, *pt2, temp );
        }

        cvKMeans2( points, cluster_count, clusters,
                   cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0 ));

        cvZero( img );

        for( i = 0; i < sample_count; i++ )
        {
            CvPoint2D32f pt = ((CvPoint2D32f*)points->data.fl)[i];
            int cluster_idx = clusters->data.i[i];
            cvCircle( img, cvPointFrom32f(pt), 2, color_tab[cluster_idx], CV_FILLED );
        }

        cvReleaseMat( &points );
        cvReleaseMat( &clusters );

        cvShowImage( "clusters", img );

        int key = cvWaitKey(0);
        if( key == 27 ) // 'ESC'
            break;
    }
}

SeqPartition

データシーケンスを同値類(同じクラスに属すると定義されたデータ群)に分割する

typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata);
int cvSeqPartition( const CvSeq* seq, CvMemStorage* storage, CvSeq** labels,
                    CvCmpFunc is_equal, void* userdata );

seq
分割対象のシーケンス.
storage
同値類として分割されたシーケンスの保存領域.NULLの場合は,seq->storage を使用する.
labels
出力パラメータ.入力シーケンスの各要素に割り振られた(分割結果を表す)0から始まるラベルシーケンスへのポインタのポインタ.
is_equal
2つのシーケンス要素が同じクラスである場合,関係関数は 0以外を返す. そうでなければ0を返す.分割アルゴリズムは,同値基準として関係関数の推移閉包を用いる.
userdata
関数is_equal の引数として渡すデータへのポインタ.

関数 cvSeqPartition は,集合を一つ以上の同値類に分割する2次的(計算量がO(n2))アルゴリズムを実装する. この関数は同値類の個数を返す.

(例)2次元の点の分割

#include "cxcore.h"
#include "highgui.h"
#include <stdio.h>

CvSeq* point_seq = 0;
IplImage* canvas = 0;
CvScalar* colors = 0;
int pos = 10;

int is_equal( const void* _a, const void* _b, void* userdata )
{
    CvPoint a = *(const CvPoint*)_a;
    CvPoint b = *(const CvPoint*)_b;
    double threshold = *(double*)userdata;
    return (double)(a.x - b.x)*(a.x - b.x) + (double)(a.y - b.y)*(a.y - b.y) <= threshold;
}

void on_track( int pos )
{
    CvSeq* labels = 0;
    double threshold = pos*pos;
    int i, class_count = cvSeqPartition( point_seq, 0, &labels, is_equal, &threshold );
    printf("%4d classes\n", class_count );
    cvZero( canvas );

    for( i = 0; i < labels->total; i++ )
    {
        CvPoint pt = *(CvPoint*)cvGetSeqElem( point_seq, i );
        CvScalar color = colors[*(int*)cvGetSeqElem( labels, i  )];
        cvCircle( canvas, pt, 1, color, -1 );
    }

    cvShowImage( "points", canvas );
}

int main( int argc, char** argv )
{
    CvMemStorage* storage = cvCreateMemStorage(0);
    point_seq = cvCreateSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage );
    CvRNG rng = cvRNG(0xffffffff);

    int width = 500, height = 500;
    int i, count = 1000;
    canvas = cvCreateImage( cvSize(width,height), 8, 3 );

    colors = (CvScalar*)cvAlloc( count*sizeof(colors[0]) );
    for( i = 0; i < count; i++ )
    {
        CvPoint pt;
        int icolor;
        pt.x = cvRandInt( &rng ) % width;
        pt.y = cvRandInt( &rng ) % height;
        cvSeqPush( point_seq, &pt );
        icolor = cvRandInt( &rng ) | 0x00404040;
        colors[i] = CV_RGB(icolor & 255, (icolor >> 8)&255, (icolor >> 16)&255);
    }

    cvNamedWindow( "points", 1 );
    cvCreateTrackbar( "threshold", "points", &pos, 50, on_track );
    on_track(pos);
    cvWaitKey(0);
    return 0;
}

エラーハンドリングとシステム関数(Error Handling and System Functions)


エラーハンドリング(Error Handling)

OpenCV におけるエラーハンドリングは,IPL(Image Processing Library)と似ている. エラーが発生した場合でも,関数はエラーコードを返さない. その代わり,エラーステータスをcvSetErrStatusを用いてセットし, 標準またはユーザ定義のエラーハンドラ(メッセージボックスの表示や,ログに書き込む,など. cvRedirectErrorcvNulDevReport, cvStdErrReport, cvGuiBoxReportを参照) を呼び出す関数cvErrorを呼ぶマクロCV_ERROR を用いてエラーの通知を行う. 各プログラムスレッドについて,それぞれ一つずつ,現在のエラーステータス(一つの整数値)を持つグローバル変数が存在する. このエラーステータスは,関数 cvGetErrStatus を用いて取り出すことが可能である.

エラーハンドリングには,以下の三つのモードが存在する(cvSetErrModecvGetErrMode を参照).

Leaf
プログラムはエラーハンドラを呼び出した後,途中終了する.デフォルト.エラー発生後,直ちに通知されるので,デバッグ時に有効. しかし,製品(完成版の)システムでは,他の二つのモードの使用が制御しやすいので好ましい.
Parent
プログラムは途中終了しないが,エラーハンドラが呼び出される.スタックは解放されない(C++の例外処理を用いないため). ユーザはCxCoreの関数cvGetErrStatusを呼び出し,エラーコードをチェックし,対処を行わなければならない.
Silent
Parentモードとほぼ同じだが,エラーハンドラは呼び出されない.

実際は,モードLeafParent の動作はエラーハンドラによって実装される. 上記の説明は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__; // 処理の終了.マクロの後に書く.

    // 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 occured" );
    else
        printf("Everything is OK" );
    return 0;
}

GetErrStatus

現在のエラーステータスを返す

int cvGetErrStatus( void );

関数 cvGetErrStatus は,現在のエラーステータスを返す. ステータス値は,関数cvSetErrStatus によってセットされる. Leafモードの場合は,エラー発生後,直ちにプログラムが途中終了するので,関数呼出し後も常に制御可能にしておくためには, cvSetErrModeでエラーモードをParentSilentにセットしておくべきであることに注意する.


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, cvStdErrReportcvGuiBoxReportは標準のエラーハンドリングを提供する. 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...

システム関数(System Functions)


Alloc

メモリバッファの領域を確保する

void* cvAlloc( size_t size );

size
バッファサイズ(バイト単位).

関数 cvAllocsize バイトの領域を確保し,その領域へのポインタを返す. エラーが生じた場合は,エラーを通知しNULLポインタを返す. デフォルトで cvAlloc は,mallocを呼ぶ icvAlloc の呼び出しを行うが, 関数 cvSetMemoryManager を用いて, ユーザ定義のメモリ領域確保/領域解放のための関数を定義することも可能である.


Free

メモリバッファの領域を解放する

void cvFree( void** ptr );

ptr
解放する領域へのポインタのポインタ.

関数 cvFree は,cvAllocによって確保されたメモリバッファの領域解放を行う. 関数から出る際にバッファへのポインタをクリアするため,ポインタのポインタを用いている. *ptr が既に NULL の場合,この関数は何もしない.


GetTickCount

tics数を返す

int64 cvGetTickCount( void );

関数 cvGetTickCount は,プラットフォーム依存の開始時点からのtics数(スタートアップからのCPU ticks数,1970年からのミリ秒等)を返す. この関数は,ある関数やユーザコードの実行時間を正確に計測するのに便利である. tics数から時間単位に変換するためには,cvGetTickFrequencyを用いる.


GetTickFrequency

1マイクロ秒あたりのtics数を返す

double cvGetTickFrequency( void );

関数 cvGetTickFrequency は,1マイクロ秒あたりのtics数を返す. つまり,cvGetTickCount() を cvGetTickFrequency() で割った値が,プラットフォーム依存の開始時刻からのマイクロ秒単位の時刻になる.


RegisterModule

他のモジュールを登録する

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;

int cvRegisterModule( const CvModuleInfo* module_info );

module_info
モジュールに関する情報.

関数 cvRegisterModule は,モジュールが登録されているリストに新しいモジュールを追加する. モジュールが登録されると,そのモジュールの情報は,関数cvGetModuleInfo を用いて取り出すことができるようになる. 登録されたモジュールも,CXCOREでサポートされている最適化プラグイン(IPP,MKL,...)を活用する. CXCORE 及び CV (computer vision),CVAUX (auxilary computer vision) や HIGHGUI (visualization & image/video acquisition) などはモジュールの一例である. 通常は,登録が終わってから共有ライブラリ(shared library)がロードされる. どのように登録されるかの詳細は,cxcore/src/cxswitcher.cpp と cv/src/cvswitcher.cpp を参照のこと. また,IPPとMKLがどのようにモジュールとリンクされるのかについては,cxcore/src/cxswitcher.cpp, cxcore/src/_cxipp.h を参照のこと.


GetModuleInfo

登録されたモジュールとプラグインの情報を取り出す

void cvGetModuleInfo( const char* module_name,
                       const char** version,
                       const char** loaded_addon_plugins );

module_name
対象のモジュール名,NULLの場合はすべてのモジュール.
version
出力パラメータ.モジュールについての情報(バージョンを含む).
loaded_addon_plugins
CXCOREがロード可能な最適化プラグインの名前とバージョンのリスト.

関数 cvGetModuleInfo は,登録モジュールの一つ,またはすべての情報を返す. 返された情報はライブラリ内部に保存される.そのためユーザが領域解放や返された文字列の変更を行う必要はない.


UseOptimized

最適化モード/非最適化モードを切り替える

int cvUseOptimized( int on_off );

on_off
0以外のとき最適化,0のとき非最適化.

関数 cvUseOptimized は,cxcoreや,OpenCVのほかのライブラリなどを,純粋なC言語だけで実装したモードと, 可能な部分はIPP と MKLを用いて最適化したモードとを切り替える. cvUseOptimized(0) が呼ばれたときは,最適化ライブラリはロードされない. この関数はデバッグ時,IPP&MKLのアップグレード時,処理速度を動作中に比較したい時などに有効である. 戻り値は,ロードされた最適化関数の数. デフォルトで最適化プラグインがロードされるので,プログラムの最初にcvUseOptimized(1)を呼ぶ必要はない (実際,スタートアップ時に処理時間が増えるだけ)ことに注意.


SetMemoryManager

カスタムあるいはデフォルトのメモリ管理関数を指定する

typedef void* (CV_CDECL *CvAllocFunc)(size_t size, void* userdata);
typedef int (CV_CDECL *CvFreeFunc)(void* pptr, void* userdata);

void cvSetMemoryManager( CvAllocFunc alloc_func=NULL,
                         CvFreeFunc free_func=NULL,
                         void* userdata=NULL );

alloc_func
領域確保関数(インタフェースは,コンテクストを決定するために使用されることがあるuserdata以外は, mallocと同じ).
free_func
領域解放関数(インタフェースは,freeと同じ).
userdata
カスタム関数に引数として渡すユーザデータ.

関数 cvSetMemoryManager は,cvAlloc, cvFree や 上位レベルの関数 (例えば,cvCreateImage)から呼ばれるユーザ定義のメモリ管理関数(mallocとfreeに取って代わるもの)の設定を行う. cvAllocによってデータ領域を確保するときに,この関数が呼ばれることに注意. 再帰呼び出しの無限ループを避けるため,ユーザ定義の領域確保/解放関数では cvAlloccvFreeの呼び出しを行ってはいけない.

alloc_funcfree_func へのポインタが NULLの場合は, デフォルトのメモリ管理関数が用いられる.


SetIPLAllocators

画像領域の確保と解放のための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*);

void cvSetIPLAllocators( Cv_iplCreateImageHeader create_header,
                         Cv_iplAllocateImageData allocate_data,
                         Cv_iplDeallocate deallocate,
                         Cv_iplCreateROI create_roi,
                         Cv_iplCloneImage clone_image );

#define CV_TURN_ON_IPL_COMPATIBILITY()                                  ¥
    cvSetIPLAllocators( iplCreateImageHeader, iplAllocateImage,         ¥
                        iplDeallocate, iplCreateROI, iplCloneImage )

create_header
iplCreateImageHeaderへのポインタ.
allocate_data
iplAllocateImageへのポインタ.
deallocate
iplDeallocateへのポインタ.
create_roi
iplCreateROIへのポインタ.
clone_image
iplCloneImageへのポインタ.

関数 cvSetIPLAllocatorsは,CXCOREが,画像領域の確保と解放を行うためにIPLの関数を使用するよう変更する. 利便性のために,ラッピングマクロ CV_TURN_ON_IPL_COMPATIBILITYが存在する. この関数は,IPL と CXCORE/OpenCVを同時に使っていたり,iplCreateImageHeaderなどを呼んでいたりする場合には有効である. IPLが単にデータ処理のみで,すべての領域確保や解放はCXCOREで行っている場合や, 逆にすべての領域確保や解放をIPLで,そしてデータ処理はOpenCVの関数で行っている場合は,この関数は不要である.


GetNumThreads

現在使われているスレッド数を返す

int cvGetNumThreads( void);

関数 cvGetNumThreadsは,(OpenMPを用いて)並列化されたOpenCV関数によって使用される現在のスレッド数を返す.


SetNumThreads

スレッド数をセットする

void cvSetNumThreads( int threads=0 );

threads
スレッド数.

関数 cvSetNumThreads は,並列化されたOpenCV関数によって使用されるスレッド数をセットする. 引数が0か負の場合,またプログラム開始時は,スレッド数にOpenMPランタイムの関数omp_get_num_procs() の戻り値であるシステムのプロセッサ数がセットされる.


GetThreadNum

現在のスレッドのインデックスを返す

int cvGetThreadNum( void );

関数 cvGetThreadNum は,この関数を呼んだスレッドのインデックス (0からcvGetNumThreads()-1の範囲の値)を返す. この関数は,OpenMPランタイムの関数omp_get_thread_num()のラッパーである. 取り出されたインデックスは,並列化された各コード内のローカルスレッドのデータにアクセスするために用いられる.


関数リスト(アルファベット順)


A

AbsDiff AddWeighted Avg
AbsDiffS Alloc AvgSdv
Add And
AddS AndS

B

BackProjectPCA

C

CalcCovarMatrix CloneGraph CreateGraph
CalcPCA CloneImage CreateGraphScanner
CartToPolar CloneMat CreateImage
Cbrt CloneMatND CreateImageHeader
CheckArr CloneSeq CreateMat
Circle CloneSparseMat CreateMatHeader
ClearGraph Cmp CreateMatND
ClearMemStorage CmpS CreateMatNDHeader
ClearND ConvertScale CreateMemStorage
ClearSeq ConvertScaleAbs CreateSeq
ClearSet Copy CreateSet
ClipLine CountNonZero CreateSparseMat
ClipLine CreateChildMemStorage CrossProduct
Clone CreateData CvtSeqToArray

D

DCT Det DrawContours
DFT Div
DecRefData DotProduct

E

EigenVV EllipseBox Error
Ellipse EndWriteSeq ErrorStr
Ellipse2Poly EndWriteStruct Exp

F

FastArctan FindGraphEdgeByPtr FlushSeqWriter
FillConvexPoly FindType Free
FillPoly FirstType
FindGraphEdge Flip

G

GEMM GetMat GetTickCount
Get*D GetModuleInfo GetTickFrequency
GetCol GetNextSparseNode GraphAddEdge
GetDiag GetNumThreads GraphAddEdgeByPtr
GetDims GetOptimalDFTSize GraphAddVtx
GetElemType GetRawData GraphEdgeIdx
GetErrMode GetReal*D GraphRemoveEdge
GetErrStatus GetRootFileNode GraphRemoveEdgeByPtr
GetFileNode GetRow GraphRemoveVtx
GetFileNodeByName GetSeqElem GraphRemoveVtxByPtr
GetFileNodeName GetSeqReaderPos GraphVtxDegree
GetGraphVtx GetSetElem GraphVtxDegreeByPtr
GetHashedKey GetSize GraphVtxIdx
GetImage GetSubRect GuiBoxReport
GetImageCOI GetTextSize Get
GetImageROI GetThreadNum

I

InRange InitLineIterator InsertNodeIntoTree
InRangeS InitMatHeader InvSqrt
IncRefData InitMatNDHeader Invert
InitFont InitSparseMatIterator IsInf
InitImageHeader InitTreeNodeIterator IsNaN

K

KMeans2

L

LUT Load
Line Log

M

Mahalonobis MemStorageAlloc MinS
MakeSeqHeaderForArray MemStorageAllocString MixChannels
Mat Merge Mul
Max Min MulSpectrums
MaxS MinMaxLoc MulTransposed

N

NextGraphItem Norm Not
NextTreeNode Normalize NulDevReport

O

OpenFileStorage Or OrS

P

PerspectiveTransform Pow Ptr*D
PolarToCart PrevTreeNode PutText
PolyLine ProjectPCA

R

RNG ReadRealByName ReleaseImageHeader
RandArr ReadString ReleaseMat
RandInt ReadStringByName ReleaseMatND
RandReal Rectangle ReleaseMemStorage
RandShuffle RedirectError ReleaseSparseMat
Range Reduce RemoveNodeFromTree
Read RegisterModule Repeat
ReadByName RegisterType ResetImageROI
ReadInt Release Reshape
ReadIntByName ReleaseData ReshapeMatND
ReadRawData ReleaseFileStorage RestoreMemStoragePos
ReadRawDataSlice ReleaseGraphScanner Round
ReadReal ReleaseImage

S

SVBkSb SeqSlice SetSeqReaderPos
SVD SeqSort SetZero
Save Set Solve
SaveMemStoragePos Set*D SolveCubic
ScaleAdd SetAdd Split
SeqElemIdx SetData Sqrt
SeqInsert SetErrMode StartAppendToSeq
SeqInsertSlice SetErrStatus StartNextStream
SeqInvert SetIPLAllocators StartReadRawData
SeqPartition SetIdentity StartReadSeq
SeqPop SetImageCOI StartWriteSeq
SeqPopFront SetImageROI StartWriteStruct
SeqPopMulti SetMemoryManager StdErrReport
SeqPush SetNew Sub
SeqPushFront SetNumThreads SubRS
SeqPushMulti SetReal*D SubS
SeqRemove SetRemove Sum
SeqRemoveSlice SetRemoveByPtr Set
SeqSearch SetSeqBlockSize

T

Trace Transpose TypeOf
Transform TreeToNodeSeq

U

UnregisterType UseOptimized

W

Write WriteInt WriteString
WriteComment WriteRawData
WriteFileNode WriteReal

X

Xor XorS

OpenCVリファレンス マニュアル
OpenCVリファレンス マニュアル(分割版)
OpenCVサンプルコード


CV_RGB
CV_TREE_NODE_FIELDS
CvANN_MLP
CvANN_MLP_TrainParams
CvANN_MLP::create
CvANN_MLP::train
CvArr
CvAttrList
CvBoost
CvBoostParams
CvBoostTree
CvBoost::get_weak_predictors
CvBoost::predict
CvBoost::prune
CvBoost::train
CvBox2D
CvCapture
CvConDensation
CvConnectedComp
CvConvexityDefect
CvDTree
CvDTreeNode
CvDTreeParams
CvDTreeSplit
CvDTreeTrainData
CvDTree::predict
CvDTree::train
CvEM
CvEMParams
CvEM::train
CvFileNode
CvFileStorage
CvGraph
CvGraphScanner
CvHaarClassifier
CvHaarClassifierCascade
CvHaarFeature
CvHaarStageClassifier
CvHistogram
CvKNearest
CvKNearest::find_nearest
CvKNearest_train
CvKalman
CvMat
CvMatND
CvMemBlock
CvMemStorage
CvMemStoragePos
CvNormalBayesClassifier
CvNormalBayesClassifier::predict
CvNormalBayesClassifier::train
CvPoint
CvPoint2D32f
CvPoint2D64f
CvPoint3D32f
CvPoint3D64f
CvQuadEdge2D
CvRTParams
CvRTrees
CvRTrees::get_proximity
CvRTrees::get_var_importance
CvRTrees::predict
CvRTrees::train
CvRect
CvSVM
CvSVMParams
CvSVM::get_support_vector
CvSVM::train
CvScalar
CvSeq
CvSeqBlock
CvSet
CvSize
CvSize2D32f
CvSlice
CvSparseMat
CvStatModel
CvStatModel::CvStatModel
CvStatModel::clear
CvStatModel::CvStatModel(data)
CvStatModel::~CvStatModel
CvStatModel::load
CvStatModel::predict
CvStatModel::read
CvStatModel::save
CvStatModel::train
CvStatModel::write
CvSubdiv2D
CvSubdiv2DPoint
CvTermCriteria
CvTreeNodeIterator
CvTypeInfo
IplImage
RTreesOOBerror
cv2DRotationMatrix
cvAbsDiff
cvAbsDiffS
cvAcc
cvAdaptiveThreshold
cvAdd
cvAddS
cvAddWeighted
cvAlloc
cvAnd
cvAndS
cvApproxChains
cvApproxPoly
cvArcLength
cvAvg
cvAvgSdv
cvBackProjectPCA
cvBoundingRect
cvBoxPoints
cvCalcBackProject
cvCalcBackProjectPatch
cvCalcCovarMatrix
cvCalcEMD2
cvCalcGlobalOrientation
cvCalcHist
cvCalcImageHomography
cvCalcMotionGradient
cvCalcOpticalFlowBM
cvCalcOpticalFlowHS
cvCalcOpticalFlowLK
cvCalcOpticalFlowPyrLK
cvCalcPCA
cvCalcPGH
cvCalcProbDensity
cvCalcSubdivVoronoi2D
cvCalibrateCamera2
cvCamShift
cvCanny
cvCartToPolar
cvCbrt
cvCheckArr
cvCheckContourConvexity
cvCircle
cvClearGraph
cvClearHist
cvClearMemStorage
cvClearND
cvClearSeq
cvClearSet
cvClearSubdivVoronoi2D
cvClipLine
cvClone
cvCloneGraph
cvCloneImage
cvCloneMat
cvCloneMatND
cvCloneSeq
cvCloneSparseMat
cvCmp
cvCmpS
cvCompareHist
cvComputeCorrespondEpilines
cvConDensInitSampleSet
cvConDensUpdateByTime
cvContourArea
cvContourFromContourTree
cvConvert
cvConvertImage
cvConvertPointsHomogenious
cvConvertScale
cvConvertScaleAbs
cvConvexHull2
cvConvexityDefects
cvCopy
cvCopyHist
cvCopyMakeBorder
cvCornerEigenValsAndVecs
cvCornerHarris
cvCornerMinEigenVal
cvCountNonZero
cvCreateCameraCapture
cvCreateChildMemStorage
cvCreateConDensation
cvCreateContourTree
cvCreateData
cvCreateFileCapture
cvCreateGraph
cvCreateGraphScanner
cvCreateHist
cvCreateImage
cvCreateImageHeader
cvCreateKalman
cvCreateMat
cvCreateMatHeader
cvCreateMatND
cvCreateMatNDHeader
cvCreateMemStorage
cvCreatePOSITObject
cvCreateSeq
cvCreateSet
cvCreateSparseMat
cvCreateStructuringElementEx
cvCreateSubdivDelaunay2D
cvCreateTrackbar
cvCreateVideoWriter
cvCrossProduct
cvCvtColor
cvCvtScale
cvCvtSeqToArray
cvDCT
cvDFT
cvDecRefData
cvDestroyAllWindows
cvDestroyWindow
cvDet
cvDilate
cvDistTransform
cvDiv
cvDotProduct
cvDrawChessBoardCorners
cvDrawContours
cvEigenVV
cvEllipse
cvEllipse2Poly
cvEllipseBox
cvEndFindContours
cvEndWriteSeq
cvEndWriteStruct
cvEqualizeHist
cvErode
cvError
cvErrorStr
cvExp
cvFastArctan
cvFillConvexPoly
cvFillPoly
cvFilter2D
cvFindChessboardCorners
cvFindContours
cvFindCornerSubPix
cvFindExtrinsicCameraParams2
cvFindFundamentalMat
cvFindGraphEdge
cvFindGraphEdgeByPtr
cvFindHomography
cvFindNearestPoint2D
cvFindNextContour
cvFindType
cvFirstType
cvFitEllipse2
cvFitLine2D
cvFlip
cvFloodFill
cvFlushSeqWriter
cvFree
cvGEMM
cvGet1D
cvGet2D
cvGet3D
cvGetND
cvGetAffineTransform
cvGetCaptureProperty
cvGetCentralMoment
cvGetCol
cvGetCols
cvGetDiag
cvGetDims
cvGetElemType
cvGetErrMode
cvGetErrStatus
cvGetFileNode
cvGetFileNodeByName
cvGetFileNodeName
cvGetGraphVtx
cvGetHashedKey
cvGetHistValue_1D
cvGetHistValue_2D
cvGetHistValue_3D
cvGetHistValue_nD
cvGetHuMoments
cvGetImage
cvGetImageCOI
cvGetImageROI
cvGetMat
cvGetMinMaxHistValue
cvGetModuleInfo
cvGetNextSparseNode
cvGetNormalizedCentralMoment
cvGetNumThreads
cvGetOptimalDFTSize
cvGetPerspectiveTransform
cvGetQuadrangleSubPix
cvGetRawData
cvGetReal1D
cvGetReal2D
cvGetReal3D
cvGetRealND
cvGetRectSubPix
cvGetRootFileNode
cvGetRow
cvGetRows
cvGetSeqElem
cvGetSeqReaderPos
cvGetSetElem
cvGetSize
cvGetSpatialMoment
cvGetSubRect
cvGetTextSize
cvGetThreadNum
cvGetTickCount
cvGetTickFrequency
cvGetTrackbarPos
cvGetWindowHandle
cvGetWindowName
cvGoodFeaturesToTrack
cvGrabFrame
cvGraphAddEdge
cvGraphAddEdgeByPtr
cvGraphAddVtx
cvGraphEdgeIdx
cvGraphRemoveEdge
cvGraphRemoveEdgeByPtr
cvGraphRemoveVtx
cvGraphRemoveVtxByPtr
cvGraphVtxDegree
cvGraphVtxDegreeByPtr
cvGraphVtxIdx
cvGuiBoxReport
cvHaarDetectObjects
cvHoughCircles
cvHoughLines2
cvInRange
cvInRangeS
cvIncRefData
cvInitFont
cvInitImageHeader
cvInitLineIterator
cvInitMatHeader
cvInitMatNDHeader
cvInitSparseMatIterator
cvInitSystem
cvInitTreeNodeIterator
cvInitUndistortMap
cvInpaint
cvInsertNodeIntoTree
cvIntegral
cvInvSqrt
cvInvert
cvIsInf
cvIsNaN
cvKMeans2
cvKalmanCorrect
cvKalmanPredict
cvLUT
cvLaplace
cvLine
cvLoad
cvLoadHaarClassifierCascade
cvLoadImage
cvLog
cvLogPolar
cvMahalonobis
cvMakeHistHeaderForArray
cvMakeSeqHeaderForArray
cvMat
cvMatchContourTrees
cvMatchShapes
cvMatchTemplate
cvMax
cvMaxRect
cvMaxS
cvMeanShift
cvMemStorageAlloc
cvMemStorageAllocString
cvMerge
cvMin
cvMinAreaRect2
cvMinEnclosingCircle
cvMinMaxLoc
cvMinS
cvMixChannels
cvMoments
cvMorphologyEx
cvMoveWindow
cvMul
cvMulSpectrums
cvMulTransposed
cvMultiplyAcc
cvNamedWindow
cvNextGraphItem
cvNextTreeNode
cvNorm
cvNormalize
cvNormalizeHist
cvNot
cvNulDevReport
cvOpenFileStorage
cvOr
cvOrS
cvPOSIT
cvPerspectiveTransform
cvPointPolygonTest
cvPointSeqFromMat
cvPolarToCart
cvPolyLine
cvPow
cvPreCornerDetect
cvPrevTreeNode
cvProjectPCA
cvProjectPoints2
cvPtr1D
cvPtr2D
cvPtr3D
cvPtrND
cvPutText
cvPyrDown
cvPyrMeanShiftFiltering
cvPyrSegmentation
cvPyrUp
cvQueryFrame
cvQueryHistValue_1D
cvQueryHistValue_2D
cvQueryHistValue_3D
cvQueryHistValue_nD
cvRNG
cvRandArr
cvRandInt
cvRandReal
cvRandShuffle
cvRange
cvRead
cvReadByName
cvReadChainPoint
cvReadInt
cvReadIntByName
cvReadRawData
cvReadRawDataSlice
cvReadReal
cvReadRealByName
cvReadString
cvReadStringByName
cvRectangle
cvRedirectError
cvReduce
cvRegisterModule
cvRegisterType
cvRelease
cvReleaseCapture
cvReleaseConDensation
cvReleaseData
cvReleaseFileStorage
cvReleaseGraphScanner
cvReleaseHaarClassifierCascade
cvReleaseHist
cvReleaseImage
cvReleaseImageHeader
cvReleaseKalman
cvReleaseMat
cvReleaseMatND
cvReleaseMemStorage
cvReleasePOSITObject
cvReleaseSparseMat
cvReleaseStructuringElement
cvReleaseVideoWriter
cvRemap
cvRemoveNodeFromTree
cvRepeat
cvResetImageROI
cvReshape
cvReshapeMatND
cvResize
cvResizeWindow
cvRestoreMemStoragePos
cvRetrieveFrame
cvRodrigues2
cvRound
cvRunHaarClassifierCascade
cvRunningAvg
cvSVBkSb
cvSVD
cvSampleLine
cvSave
cvSaveImage
cvSaveMemStoragePos
cvScale
cvScaleAdd
cvSegmentMotion
cvSeqElemIdx
cvSeqInsert
cvSeqInsertSlice
cvSeqInvert
cvSeqPartition
cvSeqPop
cvSeqPopFront
cvSeqPopMulti
cvSeqPush
cvSeqPushFront
cvSeqPushMulti
cvSeqRemove
cvSeqRemoveSlice
cvSeqSearch
cvSeqSlice
cvSeqSort
cvSet
cvSet1D
cvSet2D
cvSet3D
cvSetND
cvSetAdd
cvSetCaptureProperty
cvSetData
cvSetErrMode
cvSetErrStatus
cvSetHistBinRanges
cvSetIPLAllocators
cvSetIdentity
cvSetImageCOI
cvSetImageROI
cvSetImagesForHaarClassifierCascade
cvSetMemoryManager
cvSetMouseCallback
cvSetNew
cvSetNumThreads
cvSetReal1D
cvSetReal2D
cvSetReal3D
cvSetRealND
cvSetRemove
cvSetRemoveByPtr
cvSetSeqBlockSize
cvSetSeqReaderPos
cvSetTrackbarPos
cvSetZero
cvShowImage
cvSmooth
cvSnakeImage
cvSobel
cvSolveCubic
cvSplit
cvSqrt
cvSquareAcc
cvStartAppendToSeq
cvStartFindContours
cvStartNextStream
cvStartReadChainPoints
cvStartReadRawData
cvStartReadSeq
cvStartWriteSeq
cvStartWriteStruct
cvStdErrReport
cvSub
cvSubRS
cvSubS
cvSubdiv2DEdgeDst
cvSubdiv2DEdgeOrg
cvSubdiv2DGetEdge
cvSubdiv2DLocate
cvSubdiv2DRotateEdge
cvSubdivDelaunay2DInsert
cvSubstituteContour
cvSum
cvThreshHist
cvThreshold
cvTrace
cvTransform
cvTranspose
cvTreeToNodeSeq
cvTypeOf
cvUndistort2
cvUnregisterType
cvUpdateMotionHistory
cvUseOptimized
cvWaitKey
cvWarpAffine
cvWarpPerspective
cvWatershed
cvWrite
cvWriteComment
cvWriteFileNode
cvWriteFrame
cvWriteInt
cvWriteRawData
cvWriteReal
cvWriteString
cvXor
cvXorS
cvmGet
cvmSet
error_handling_sample
error_macros