構造解析と形状ディスクリプタ

cv::ApproxChains

CvSeq* cvApproxChains(CvSeq* src_seq, CvMemStorage* storage, int method=CV_CHAIN_APPROX_SIMPLE, double parameter=0, int minimal_perimeter=0, int recursive=0)

フリーマンチェーンを,折れ線で近似します.

パラメタ:
  • src_seq – 他のチェーンを参照できるチェーンへのポインタ
  • storage – 結果として得られる折れ線を保存するストレージ
  • method – 近似手法(関数 FindContours の説明を参照してください)
  • parameter – 近似手法のパラメータ(現在は利用されていません)
  • minimal_perimeterminimal_perimeter 以上の周囲長をもつ輪郭のみを近似します.その他のチェーンは,結果の構造体から削除されます
  • recursive – これが0ではない場合, src_seq から h_nextv_next links によって辿ることができる全てのチェーンが近似されます.0の場合は,1つのチェーンのみが近似されます

これは,単独動作可能な近似ルーチンです.関数 cvApproxChains は,これに相当する近似フラグを引数として与えた場合の FindContours と全く同じように動作します.この関数は,結果として得られる最初の輪郭へのポインタを返します.もしその他の近似輪郭が存在するならば,返された構造体のフィールド v_nexth_next を辿って取得できます.

cv::ApproxPoly

CvSeq* cvApproxPoly(const void* src_seq, int header_size, CvMemStorage* storage, int method, double parameter, int parameter2=0)

折れ線(カーブ)を指定された精度で近似します.

パラメタ:
  • src_seq – 座標点配列のシーケンス
  • header_size – 近似された折れ線のヘッダサイズ
  • storage – 似された折れ線を保存するストレージ.これがNULLの場合,入力シーケンスのストレージが利用されます
  • method – 近似手法.Douglas-Peuckerアルゴリズムに相当する CV_POLY_APPROX_DP のみがサポートされます
  • parameter – 近似手法のパラメータ. CV_POLY_APPROX_DP の場合は,要求する近似精度を意味します
  • parameter2src_seq がシーケンスの場合,この値は,1つ のシーケンスを近似するのか, src_seq と同レベル,およびそれより下のレベルに存在する全てのシーケンスを近似するのか,を決定します(階層的輪郭構造体については FindContours の説明を参照してください).また, src_seq が 点座標の配列 CvMat* である場合,この値は折れ線が閉じている( parameter2 !=0 )か,開いている( parameter2 =0 ),を決定します

この関数は,1つあるいは複数の折れ線(カーブ)を近似し,その近似結果を返します.折れ線が複数の場合,結果の木構造は入力のそれと同じ構造になります(1対1に対応します).

cv::ArcLength

double cvArcLength(const void* curve, CvSlice slice=CV_WHOLE_SEQ, int isClosed=-1)

輪郭線の周囲長,あるいは曲線の長さを求めます.

パラメタ:
  • curve – 曲線を表す座標点のシーケンス,または配列
  • slice – 曲線の始点と終点.デフォルトでは,曲線全体の長さが求められます
  • isClosed

    閉曲線か否かを表します.以下の3通りが考えられる:

    • \texttt{is\_closed} =0 曲線は開いていると見なされます.
    • \texttt{is\_closed}>0 曲線は閉じている見なされます.
    • \texttt{is\_closed}<0 曲線がシーケンスの場合, ((CvSeq*)curve)->flags のフラグが CV_SEQ_FLAG_CLOSED であるか否かによって,曲線が閉じているか否かが決まります.シーケンスではない(頂点の配列 CvMat* で表されている場合)場合は,曲線は開いていると見なされます.

この関数は,曲線上の連続する2点間の線分距離の総和として,曲線の長さを求めます.

cv::BoundingRect

CvRect cvBoundingRect(CvArr* points, int update=0)

点群を包含する傾いていない矩形を求めます.

パラメタ:
  • points – 2次元点の集合.点座標のシーケンスあるいはベクトル( CvMat
  • update – 更新フラグ.以下を参照してください

この関数は,2次元点の集合に対する傾いていないバウンディングボックスを返します. 以下に,取り得る points の種類とフラグの組み合わせを示します:

update points action
0 CvContour* バウンディングボックスを計算せず,輪郭ヘッダのフィールド rect から取得します.
1 CvContour* バウンディングボックスを計算し,輪郭ヘッダのフィールド rect に書き込みます.
0 CvSeq* or CvMat* バウンディングボックスが計算され,それが返されます.
1 CvSeq* or CvMat* ランタイムエラーが発生します.

cv::BoxPoints

void cvBoxPoints(CvBox2D box, CvPoint2D32f pt[4])

箱形状の頂点を求めます.

パラメタ:
  • box – 箱形状
  • points – 頂点の配列

この関数は,入力された2次元の箱形状の頂点を求めます.

以下は,この関数のコードです:

void cvBoxPoints( CvBox2D box, CvPoint2D32f pt[4] )
{
    float a = (float)cos(box.angle)*0.5f;
    float b = (float)sin(box.angle)*0.5f;

    pt[0].x = box.center.x - a*box.size.height - b*box.size.width;
    pt[0].y = box.center.y + b*box.size.height - a*box.size.width;
    pt[1].x = box.center.x + a*box.size.height - b*box.size.width;
    pt[1].y = box.center.y - b*box.size.height - a*box.size.width;
    pt[2].x = 2*box.center.x - pt[0].x;
    pt[2].y = 2*box.center.y - pt[0].y;
    pt[3].x = 2*box.center.x - pt[1].x;
    pt[3].y = 2*box.center.y - pt[1].y;
}

cv::CalcPGH

void cvCalcPGH(const CvSeq* contour, CvHistogram* hist)

輪郭のペアワイズ幾何ヒストグラムを求めます.

パラメタ:
  • contour – 入力輪郭.現在は,整数値の座標のみ扱えます
  • hist – 計算されたヒストグラム.必ず2次元です

この関数は, Iivarinen97 で提唱された,輪郭に対する2次元のペアワイズ幾何ヒストグラム(PGH)を計算します.このアルゴリズムでは,輪郭を構成する辺同士の全ての組み合わせ(ペア)が考慮されます.各ペアに対して,辺同士が成す角度と,辺同士の最小/最大距離が求められます.そのために,一つ一つの辺を順番に基準辺として,それ以外の辺との関係を全て調べます.基準辺とそれ以外の辺を考える場合,基準辺ではない方の辺上にある点から,基準辺の直線までの最小距離と最大距離が選択されます.この辺同士の角度がヒストグラムの行を定義します.ヒストグラムでは,計算された最小・最大距離の範囲内に含まれる距離に対応する全てのビンが,その値を増加させます(つまり,このヒストグラムは Iivarninen97 での定義に対して,転置されています).このヒストグラムは,輪郭同士のマッチングに利用できます.

cv::CalcEMD2

float cvCalcEMD2(const CvArr* signature1, const CvArr* signature2, int distance_type, CvDistanceFunction distance_func=NULL, const CvArr* cost_matrix=NULL, CvArr* flow=NULL, float* lower_bound=NULL, void* userdata=NULL)

2つの重み付き点群間の「最小コスト」距離を求めます.

パラメタ:
  • signature1 – 1番目のシグネチャ. \texttt{size1}\times \texttt{dims}+1 の浮動小数点型行列.各行には点の重みと座標が格納されています.ユーザ定義のコスト関数を使う場合には,この行列は,1列(重みのみ)で構いません
  • signature2 – 2番目のシグネチャ. signature1 と同じフォーマットですが,行数は異なる可能性があります.重みの総和が異なる場合は, signature1signature2 のどちらかに「ダミー」の点が追加されます
  • distance_type – 用いられる距離の種類. CV_DIST_L1, CV_DIST_L2 , および CV_DIST_C はそれぞれ,標準的な距離を表しています. CV_DIST_USER の場合は,ユーザ定義関数 distance_func ,あるいは事前に計算された cost_matrix が利用されます
  • distance_func

    ユーザ定義の距離関数.2点の座標を引数にとり,その間の距離を返します ``

    typedef float (CvDistanceFunction)(const float f1, const float* f2, void* userdata);``
  • cost_matrix – ユーザ定義の \texttt{size1}\times \texttt{size2} のコスト行列.少なくとも, cost_matrixdistance_func のどちらかは NULL でなければいけません.また,コスト行列が利用される場合は,距離関数を必要とする下限値(下記の説明を参照してください)の計算はできません
  • flow – 結果として得られる \texttt{size1} \times \texttt{size2} のフロー行列: \texttt{flow}_{i,j} は, signature1i 番目の点から signature2j 番目の点までのフローを表します
  • lower_bound – オプションである入出力パラメータ.2つのシグネチャ間の距離,つまりそれぞれの重心間同士の距離の下限値.ユーザ定義のコスト行列を利用する場合,互いの点群の重みの総和が等しくない場合,シグネチャが重みのみで構成されている場合(つまり,シグネチャが1行の行列の場合)は,この下限値は計算されません.ユーザは, 必ず *lower_bound を初期化しなければいけません.また,計算された重心間距離が *lower_bound 以上だった場合(これは,シグネチャ同士が十分に離れている事を意味します),この関数はEMDの計算を行いません.したがって,重心間距離とEMDの両方を求めたい場合は, *lower_bound を0にセットするべきです
  • userdata – オプション.ユーザ定義の距離関数に渡されるデータへのポインタ

この関数は,EMDと2つの重み付き点群間の距離の下限値のどちらか片方,あるいは両方を計算します.これの RubnerSept98 で述べられている応用例の1つが,画像抽出のための多次元ヒストグラム比較です.EMDは,修正シンプレックス法で解くことができる輸送問題なので,最悪の場合は計算量が指数関数的に増加するが,平均的には十分高速に計算できます.実際は,(線形時間アルゴリズムを利用して)下限値をより高速に求めることが可能で,2つのシグネチャが十分に離れており,同一物体に関連するものではないと判断するのに利用できます.

cv::CheckContourConvexity

int cvCheckContourConvexity(const CvArr* contour)

輪郭形状が凸であるかを調べます.

Parameter:contour – 対象となる輪郭(座標点のシーケンス,または配列)

この関数は,入力輪郭が凸であるか否かを調べます.この輪郭は,自己交差しないような単純なものでなければいけません.

CvConvexityDefect

CvConvexityDefect

1つの輪郭の凹状欠損を表す構造体.

typedef struct CvConvexityDefect
{
    CvPoint* start;       /* 輪郭の凹状欠損の始点 */
    CvPoint* end;         /* 輪郭の凹状欠損の終点 */
    CvPoint* depth_point; /* 凹状欠損の中で凸包から最も遠い点 */
    float depth;          /* 最も遠い点と凸包間の距離 */
} CvConvexityDefect;
_images/defects.png

cv::ContourArea

double cvContourArea(const CvArr* contour, CvSlice slice=CV_WHOLE_SEQ)

全輪郭,あるい輪郭の一部が囲む領域面積を求めます.

パラメタ:
  • contour – 輪郭(頂点のシーケンス,または配列)
  • slice – 輪郭の一部分を表す始点と終点.デフォルトでは,全輪郭が囲む領域面積が求められます

この関数は,全輪郭,あるい輪郭の一部が囲む領域面積を求めます.後者の場合,以下の図のように,輪郭の弧と2点を結ぶ弦によって区切られた総面積が求められます:

_images/contoursecarea.png

輪郭の姿勢によっては, 負の 値を返すことがあります.面積の絶対値を得るには,C言語の fabs() を利用してください.

cv::ContourFromContourTree

CvSeq* cvContourFromContourTree(const CvContourTree* tree, CvMemStorage* storage, CvTermCriteria criteria)

木構造から輪郭を復元します.

パラメタ:
  • tree – 輪郭を表す木
  • storage – 復元された輪郭を保存するストレージ
  • criteria – 復元を停止するための停止基準

この関数は,その二分木表現から輪郭を復元します.パラメータ criteria は,精度と復元に利用する木のレベル数のどちらか片方,あるいは両方を決めます.これにより,近似された輪郭を作成することができます.また,この関数は,復元された輪郭を返します.

cv::ConvexHull2

CvSeq* cvConvexHull2(const CvArr* input, void* storage=NULL, int orientation=CV_CLOCKWISE, int return_points=0)

点集合に対する凸包を求めます.

パラメタ:
  • points – 2次元点,あるいは3次元点のシーケンス,または配列.要素は,32ビット整数型,あるいは浮動小数点型の座標
  • storage – 凸包を保存するための出力配列(CvMat*),あるいはメモリストレージ(CvMemStorage*).配列の場合,入力配列/シーケンスと同数の要素をもつ1次元配列でなければいけません.また出力時には,配列を凸包のサイズまで切り詰めるようにヘッダが変更されます. hull_storage がNULLの場合,凸包は入力シーケンスと同じストレージに保存されます
  • orientation – 凸包を構成するデータの整列方向: CV_CLOCKWISE または CV_COUNTER_CLOCKWISE
  • return_points – これが0ならば, storage が配列の場合はインデックスが保存され, storage がメモリストレージの場合はポインタが保存されます.0以外ならば,凸包を構成する点自身が保存されます

この関数は,Sklanskyのアルゴリズムを用いて2次元点集合の凸包を求めます. storage がメモリストレージならば,この関数は,凸包を構成する点,あるいはその点へのポインタを含むシーケンスを作成します.これは return_points の値によって決まり,出力としてこのシーケンスが返されます. storage が CvMat ならば,この関数はNULLを返します.

例.点のシーケンスまたは配列に対する凸包の作成

#include "cv.h"
#include "highgui.h"
#include <stdlib.h>

#define ARRAY  0 /* 0 と 1 を書き換え,配列/シーケンスでの手法を互いに切り替えます */

void main( int argc, char** argv )
{
    IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );
    cvNamedWindow( "hull", 1 );

#if !ARRAY
        CvMemStorage* storage = cvCreateMemStorage();
#endif

    for(;;)
    {
        int i, count = rand()
        CvPoint pt0;
#if !ARRAY
        CvSeq* ptseq = cvCreateSeq( CV_SEQ_KIND_GENERIC|CV_32SC2,
                                    sizeof(CvContour),
                                    sizeof(CvPoint),
                                    storage );
        CvSeq* hull;

        for( i = 0; i < count; i++ )
        {
            pt0.x = rand()
            pt0.y = rand()
            cvSeqPush( ptseq, &pt0 );
        }
        hull = cvConvexHull2( ptseq, 0, CV_CLOCKWISE, 0 );
        hullcount = hull->total;
#else
        CvPoint* points = (CvPoint*)malloc( count * sizeof(points[0]));
        int* hull = (int*)malloc( count * sizeof(hull[0]));
        CvMat point_mat = cvMat( 1, count, CV_32SC2, points );
        CvMat hull_mat = cvMat( 1, count, CV_32SC1, hull );

        for( i = 0; i < count; i++ )
        {
            pt0.x = rand()
            pt0.y = rand()
            points[i] = pt0;
        }
        cvConvexHull2( &point_mat, &hull_mat, CV_CLOCKWISE, 0 );
        hullcount = hull_mat.cols;
#endif
        cvZero( img );
        for( i = 0; i < count; i++ )
        {
#if !ARRAY
            pt0 = *CV_GET_SEQ_ELEM( CvPoint, ptseq, i );
#else
            pt0 = points[i];
#endif
            cvCircle( img, pt0, 2, CV_RGB( 255, 0, 0 ), CV_FILLED );
        }

#if !ARRAY
        pt0 = **CV_GET_SEQ_ELEM( CvPoint*, hull, hullcount - 1 );
#else
        pt0 = points[hull[hullcount-1]];
#endif

        for( i = 0; i < hullcount; i++ )
        {
#if !ARRAY
            CvPoint pt = **CV_GET_SEQ_ELEM( CvPoint*, hull, i );
#else
            CvPoint pt = points[hull[i]];
#endif
            cvLine( img, pt0, pt, CV_RGB( 0, 255, 0 ));
            pt0 = pt;
        }

        cvShowImage( "hull", img );

        int key = cvWaitKey(0);
        if( key == 27 ) // 'ESC'
            break;

#if !ARRAY
        cvClearMemStorage( storage );
#else
        free( points );
        free( hull );
#endif
    }
}

cv::ConvexityDefects

CvSeq* cvConvexityDefects(const CvArr* contour, const CvArr* convexhull, CvMemStorage* storage=NULL)

輪郭の凹状欠損を見つけます.

パラメタ:
  • contour – 入力輪郭
  • convexhullConvexHull2 によって得られる凸包.これは,凸包を構成する点自身ではなく,輪郭点へのポインタあるいはインデックスを持ちます(関数 ConvexHull2 のパラメータ return_points が0でなければいけません)
  • storage – 凹状欠損の出力シーケンスを保存するストレージ.これがNULLの場合,輪郭あるいは凸包のストレージが(この優先順位で)使われます

この関数は,入力輪郭の全ての凹状欠損を見つけて,構造体 CvConvexityDefect のシーケンスを返します.

cv::CreateContourTree

CvContourTree* cvCreateContourTree(const CvSeq* contour, CvMemStorage* storage, double threshold)

輪郭の階層表現を作成します.

パラメタ:
  • contour – 入力輪郭
  • storage – 出力木構造を保存するストレージ
  • threshold – 近似精度

この関数は,入力輪郭 contour の二分木表現を作成し,その根へのポインタを返します.パラメータ threshold が0以下の場合,この関数は全二分木表現を作成します.また,0よりも大きい場合は,精度 threshold の表現を作成します:これは,近似線によって切り取られる元輪郭線上の頂点数が threshold よりも少なくなると,それ以上木を作成しません.また,この関数は,作成された木構造を返します.

cv::EndFindContours

CvSeq* cvEndFindContours(CvContourScanner* scanner)

スキャン処理を終了します.

Parameter:scanner – 輪郭スキャナへのポインタ

この関数は,輪郭スキャン処理を終了し,最高レベルにある最初の輪郭へのポインタを返します.

cv::FindContours

int cvFindContours(CvArr* image, CvMemStorage* storage, CvSeq** first_contour, int header_size=sizeof(CvContour), int mode=CV_RETR_LIST, int method=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0, 0))

2値画像中の輪郭を抽出します.

パラメタ:
  • image – 入力画像,8ビット,シングルチャンネル.0以外のピクセルは 1として,0のピクセルは0のまま処理されます.つまり,入力画像は 2値画像 として扱われます.グレースケールから,このような2値画像を得るには, Threshold , AdaptiveThreshold あるいは Canny などの関数を利用します.また,この関数は,入力画像の中身を書き換えます
  • storage – 抽出された輪郭を格納するストレージ
  • first_contour – 出力パラメータ.最も外側にある最初の輪郭へのポインタが保存されます
  • header_size – シーケンスヘッダのサイズ. \texttt{method} = \texttt{CV\_CHAIN\_CODE} の場合は, \ge \texttt{sizeof(CvChain)} であり,そうでなければ, \ge \texttt{sizeof(CvContour)} です
  • mode

    輪郭抽出モード

    • CV_RETR_EXTERNAL 最も外側の輪郭のみを抽出します
    • CV_RETR_LIST すべての輪郭を抽出し,それらをリストに保存します
    • CV_RETR_CCOMP すべての輪郭を抽出し,をれらを2階層構造として保存します:上のレベルには,連結成分の外側の境界線が,下のレベルには,連結成分の内側に存在する穴の境界線が属します
    • CV_RETR_TREE すべての輪郭を抽出し,入れ子構造になった輪郭を完全に表現する階層構造を構成します
  • method

    近似手法( CV_LINK_RUNS 以外の全ての手法では,組み込みの近似手法を利用しています)

    • CV_CHAIN_CODE 出力はフリーマンチェーンコード. 他の手法では,ポリゴン(頂点のシーケンス)を出力します
    • CV_CHAIN_APPROX_NONE チェーンコードの全ての点を,通常の点群に変換します
    • CV_CHAIN_APPROX_SIMPLE 水平・垂直・斜めの線分を圧縮し,それらの端点のみを残します
    • CV_CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS Teh-Chin チェーン近似アルゴリズムの1つを適用します
    • CV_LINK_RUNS 値が1のセグメントを水平方向に接続する,全く異なる輪郭抽出アルゴリズム.この手法を用いる場合は,抽出モードが CV_RETR_LIST でなければいけません
  • offset – オフセット.各輪郭はこの値ぶんだけ平行移動します.これは,ROIの中で抽出された輪郭を,画像全体に対して位置づけて解析する場合に役立ちます

この関数は, Suzuki85 のアルゴリズムを用いて,2値画像から輪郭を抽出します.その輪郭は,形状解析や物体検出,物体認識に役立ちます.

この関数は,2値画像から輪郭を抽出し,その輪郭数を返します.また,ポインタ first_contour に,結果が出力されます.これは,最も外側にある最初の輪郭へのポインタを表し,輪郭が全く抽出されなかった場合(画像が完全に真っ黒の場合)は,戻り値が NULL になります.それ以外の輪郭へは,リンクである h_nextv_next を利用して, first_contour から辿ることができます.関数 DrawContours の説明にあるサンプルは,輪郭を利用して連結成分を抽出する方法について述べています.輪郭は,形状解析や物体認識などにも用いられます - OpenCVサンプルディレクトリにある

squares.c を参照してください.

注意: 元の image は,この関数によって書き換えられます.

cv::FindNextContour

CvSeq* cvFindNextContour(CvContourScanner scanner)

画像の次の輪郭を求めます.

Parameter:scannerStartFindContours によって初期化された輪郭スキャナ

この関数は,画像中の次の輪郭を発見,抽出し,そのポインタを返します.これ以上の輪郭が存在しない場合は,この関数はNULLを返します.

cv::FitEllipse2

CvBox2D cvFitEllipse2(const CvArr* points)

2次元の点集合に楕円をフィッティングします.

Parameter:points – 座標点のシーケンス,または配列

この関数は,2次元点の集合に最もフィットする(二乗誤差が最小になる)楕円を求めます.返される構造体のフィールドは, size が,楕円軸の半分の長さではなく全長を表していることを除けば, Ellipse のそれと同様です..

cv::FitLine

void cvFitLine(const CvArr* points, int dist_type, double param, double reps, double aeps, float* line)

2次元あるいは3次元の点集合に直線をフィッティングします.

パラメタ:
  • points – 2次元点,あるいは3次元点のシーケンス,または配列.要素は,32ビット整数型,あるいは浮動小数点型の座標です
  • dist_type – フィッティングに利用される距離(説明を参照してください)
  • param – いくつかの距離で利用される数値パラメータ( C ).これが0の場合,最適な値が選択されます
  • reps – 半径(座標原点と直線との距離)に対する精度.デフォルト値の0.01 は,適切な値です
  • aeps – 角度に対する精度.デフォルト値の0.01 は,適切な値です
  • line – 出力直線パラメータ. 2次元フィッティングの場合,これは,4つの浮動小数点数 (vx, vy, x0, y0) の 配列 となります.ここで, (vx, vy) は直線に乗るように正規化された方向ベクトル, (x0, y0) は直線上の点を表します.3次元フィッティングの場合,これは,6つの浮動小数点数 (vx, vy, vz, x0, y0, z0) の 配列 となります.またここで, (vx, vy, vz) は直線に乗るように正規化された方向ベクトル, (x0, y0, z0) は直線上の点を表します

この関数は, \sum_i \rho(r_i) を最小化することで,2次元あるいは3次元の点集合に直線をフィッティングします.ここで, r_ii 番目の点と直線の距離, \rho(r) は距離関数(以下の内の1つ)を表します:

  • dist_type=CV_DIST_L2

    \rho (r) = r^2/2  \quad \text{(the simplest and the fastest least-squares method)}

  • dist_type=CV_DIST_L1

    \rho (r) = r

  • dist_type=CV_DIST_L12

    \rho (r) = 2  \cdot ( \sqrt{1 + \frac{r^2}{2}} - 1)

  • dist_type=CV_DIST_FAIR

    \rho \left (r \right ) = C^2  \cdot \left (  \frac{r}{C} -  \log{\left(1 + \frac{r}{C}\right)} \right )  \quad \text{where} \quad C=1.3998

  • dist_type=CV_DIST_WELSCH

    \rho \left (r \right ) =  \frac{C^2}{2} \cdot \left ( 1 -  \exp{\left(-\left(\frac{r}{C}\right)^2\right)} \right )  \quad \text{where} \quad C=2.9846

  • dist_type=CV_DIST_HUBER

    \rho (r) =  \fork{r^2/2}{if $r < C$}{C \cdot (r-C/2)}{otherwise} \quad \text{where} \quad C=1.345

cv::GetCentralMoment

double cvGetCentralMoment(CvMoments* moments, int x_order, int y_order)

画像モーメント構造体から,中心モーメントを取得します.

パラメタ:
  • moments – 画像モーメント構造体へのポインタ
  • x_order – 取得するモーメントのx方向の次数, \texttt{x\_order} >= 0
  • y_order – 取得するモーメントのy方向の次数, \texttt{y\_order} >= 0 および \texttt{x\_order} + \texttt{y\_order} <= 3

この関数は,中心モーメント,つまり,画像モーメントの場合は次のように定義される値,を取り出します:

\mu _{x \_ order,  \, y \_ order} =  \sum _{x,y} (I(x,y)  \cdot (x-x_c)^{x \_ order}  \cdot (y-y_c)^{y \_ order})

ここで, x_c,y_c は重心の座標です:

x_c= \frac{M_{10}}{M_{00}} , y_c= \frac{M_{01}}{M_{00}}

cv::GetHuMoments

void cvGetHuMoments(const CvMoments* moments, CvHuMoments* hu)

7つの Hu モーメント不変量を求めます.

パラメタ:
  • momentsMoments で求められた入力モーメント
  • hu – 出力される Hu モーメント不変量

この関数は,次のように定義される 7つの Hu モーメント不変量を求めます. http://en.wikipedia.org/wiki/Image_moment も参照してください.

\begin{array}{l} hu_1= \eta _{20}+ \eta _{02} \\ hu_2=( \eta _{20}- \eta _{02})^{2}+4 \eta _{11}^{2} \\ hu_3=( \eta _{30}-3 \eta _{12})^{2}+ (3 \eta _{21}- \eta _{03})^{2} \\ hu_4=( \eta _{30}+ \eta _{12})^{2}+ ( \eta _{21}+ \eta _{03})^{2} \\ hu_5=( \eta _{30}-3 \eta _{12})( \eta _{30}+ \eta _{12})[( \eta _{30}+ \eta _{12})^{2}-3( \eta _{21}+ \eta _{03})^{2}]+(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ hu_6=( \eta _{20}- \eta _{02})[( \eta _{30}+ \eta _{12})^{2}- ( \eta _{21}+ \eta _{03})^{2}]+4 \eta _{11}( \eta _{30}+ \eta _{12})( \eta _{21}+ \eta _{03}) \\ hu_7=(3 \eta _{21}- \eta _{03})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}]-( \eta _{30}-3 \eta _{12})( \eta _{21}+ \eta _{03})[3( \eta _{30}+ \eta _{12})^{2}-( \eta _{21}+ \eta _{03})^{2}] \\ \end{array}

ここで \eta_{ji} は,正規化された中心モーメントを表します.

反転によって符号が逆転してしまう7番目のHuモーメントを除いて,これらの値は,画像のスケール変化,回転,および反転に対して不変であることが分かっています.この不変量は,もちろん画像解像度が有限であるという仮定の元に成り立っています.ラスタ画像の場合は,元画像に対する Hu 不変量と変形した画像に対するものとは多少異なります.

cv::GetNormalizedCentralMoment

double cvGetNormalizedCentralMoment(CvMoments* moments, int x_order, int y_order)

画像モーメント構造体から,正規化された中心モーメントを取得します.

パラメタ:
  • moments – 画像モーメント構造体へのポインタ
  • x_order – 取得するモーメントのx方向の次数, \texttt{x\_order} >= 0
  • y_order – 取得するモーメントのy方向の次数, \texttt{y\_order} >= 0 および \texttt{x\_order} + \texttt{y\_order} <= 3

この関数は, 次のように正規化された中心モーメントを取得します:

\eta _{x \_ order,  \, y \_ order} =  \frac{\mu_{x\_order, \, y\_order}}{M_{00}^{(y\_order+x\_order)/2+1}}

cv::GetSpatialMoment

double cvGetSpatialMoment(CvMoments* moments, int x_order, int y_order)

画像モーメント構造体から,空間モーメントを取得します.

パラメタ:
  • momentsMoments によって計算される画像モーメント構造体へのポインタ
  • x_order – 取得するモーメントのx方向の次数, \texttt{x\_order} >= 0
  • y_order – 取得するモーメントのy方向の次数, \texttt{y\_order} >= 0 および \texttt{x\_order} + \texttt{y\_order} <= 3

この関数は,空間モーメント,つまり,画像モーメントの場合は次のように定義される値,を取り出します:

M_{x \_ order,  \, y \_ order} =  \sum _{x,y} (I(x,y)  \cdot x^{x \_ order}  \cdot y^{y \_ order})

ここで, I(x,y) は,ピクセル (x, y) の輝度値です.

cv::MatchContourTrees

double cvMatchContourTrees(const CvContourTree* tree1, const CvContourTree* tree2, int method, double threshold)

2つの輪郭を,その二分木表現によって比較します.

パラメタ:
  • tree1 – 1番目の木表現
  • tree2 – 2番目の木表現
  • method – 類似度. CV_CONTOUR_TREES_MATCH_I1 のみをサポートします
  • threshold – 類似度の閾値

この関数は,2つの輪郭(木)の類似度を求めます.この類似度は,二分木の根から順に,それぞれのレベル毎に計算されます.あるレベルにおいて,輪郭間の差が threshold よりも小さくなった場合,復元処理が中断され,その時点での差が返されます.

cv::MatchShapes

double cvMatchShapes(const void* object1, const void* object2, int method, double parameter=0)

2つの形状を比較します.

パラメタ:
  • object1 – 1番目の輪郭,あるいはグレースケール画像
  • object2 – 2番目の輪郭,あるいはグレースケール画像
  • method

    比較手法:

    CV_CONTOUR_MATCH_I1 , CV_CONTOURS_MATCH_I2

    あるいは

    CV_CONTOURS_MATCH_I3
  • parameter – 比較手法毎のパラメータ(現在は利用されていません)

この関数は,2つの形状を比較します.実装されている3つの手法は,いずれもHuモーメント( GetHuMoments の説明を参照してください)を利用します( Aobject1Bobject2 を表します):

  • method=CV_CONTOUR_MATCH_I1

    I_1(A,B) =  \sum _{i=1...7}  \left |  \frac{1}{m^A_i} -  \frac{1}{m^B_i} \right |

  • method=CV_CONTOUR_MATCH_I2

    I_2(A,B) =  \sum _{i=1...7}  \left | m^A_i - m^B_i  \right |

  • method=CV_CONTOUR_MATCH_I3

    I_3(A,B) =  \sum _{i=1...7}  \frac{ \left| m^A_i - m^B_i \right| }{ \left| m^A_i \right| }

ここで,

\begin{array}{l} m^A_i = sign(h^A_i)  \cdot \log{h^A_i} m^B_i = sign(h^B_i)  \cdot \log{h^B_i} \end{array}

です. また, h^A_i, h^B_i は, AB それぞれのHuモーメントを表します.

cv::MinAreaRect2

CvBox2D cvMinAreaRect2(const CvArr* points, CvMemStorage* storage=NULL)

与えられた2次元点集合を囲む最小の矩形を求めます.

パラメタ:
  • points – 座標点のシーケンス,あるいは配列
  • storage – オプション.一時的に使用されるメモリストレージ

この関数は,点集合に対する凸包を作成し,その凸包に対して rotating calipers 法を適用することにより,与えられた2次元点集合を囲む最小の矩形を求めます.

図.輪郭を囲む最小面積の矩形

_images/minareabox.png

cv::MinEnclosingCircle

int cvMinEnclosingCircle(const CvArr* points, CvPoint2D32f* center, float* radius)

与えられた2次元点集合を囲む最小の円を求めます.

パラメタ:
  • points – 座標点のシーケンス,あるいは配列
  • center – 出力パラメータ.包含円の中心座標
  • radius – 出力パラメータ.包含円の半径

この関数は,反復アルゴリズムを用いて,与えられた2次元点集合を囲む最小の円を求めます.そして,結果として得られる円が全ての入力点を囲んでいる場合は0以外の値を返し,そうでない場合(つまり,アルゴリズムが失敗した場合)は0を返します.

cv::Moments

void cvMoments(const CvArr* arr, CvMoments* moments, int binary=0)

ポリゴンあるいはラスタライズされた形状の,3次までのモーメントを求めます.

パラメタ:
  • arr – 画像(1チャンネル,またはCOIを伴う3チャンネル),あるいはポリゴン(点座標を要素にもつCvSeq,または点座標のベクトル)
  • moments – 計算されたモーメントが書き込まれる構造体へのポインタ
  • binary – (画像の場合のみ)このフラグが0ではない場合,値が0のピクセルは0のまま,その他のピクセル値は1として扱われます

この関数は,3次までの空間モーメントあるいは中心モーメントを計算し,それらを moments に書き込みます.そしてこれらのモーメントは,形状の重心,面積,主軸,そして7つのHuモーメント不変量を含む各種の形状特徴を計算するために利用されます.

cv::PointPolygonTest

double cvPointPolygonTest(const CvArr* contour, CvPoint2D32f pt, int measure_dist)

点と輪郭の位置関係を調べます.

パラメタ:
  • contour – 入力輪郭
  • pt – 輪郭との位置関係を調べる座標点
  • measure_dist – これが0以外ならば,この関数は点からそれに最も近い輪郭の辺までの距離を推定します

この関数は,与えられた点が輪郭の内側,外側,あるいは輪郭の辺上(あるいは,頂点上)のどこにあるかを判定します.そして,その結果に応じて,正,負,0のいずれかの値が返されます. \texttt{measure\_dist} =0 の場合,戻り値はそれぞれ +1,-1,0です.また, \texttt{measure\_dist} \ne 0 の場合,入力点とそれに最も近い輪郭の辺までの符号付き距離が返されます.

ここでは,この関数の出力例として,各画像ピクセルが輪郭に対してテストされる様子を示します.

_images/pointpolygon.png

cv::PointSeqFromMat

CvSeq* cvPointSeqFromMat(int seq_kind, const CvArr* mat, CvContour* contour_header, CvSeqBlock* block)

座標点のベクトルを用いて,座標点のシーケンスヘッダを初期化します.

パラメタ:
  • seq_kind – 座標点シーケンスの種類:点集合セット(0),曲線( CV_SEQ_KIND_CURVE ),閉曲線( CV_SEQ_KIND_CURVE+CV_SEQ_FLAG_CLOSED )など
  • mat – 入力行列.これは,連続した,座標点の1次元ベクトル,つまり, CV_32SC2 または CV_32FC2 でなければいけません
  • contour_header – この関数によって初期化される輪郭ヘッダ
  • block – この関数によって初期化されるシーケンスブロックヘッダ

この関数は,その要素が指定された行列内に存在する様な「仮想的な」シーケンスを作成するために,シーケンスヘッダを初期化します.そのデータはコピーされません.初期化されたシーケンスヘッダは,座標点のシーケンスを入力にとる任意の関数に渡すことができます.このシーケンスには,要素を追加することはできませんが,削除することはできます.この関数は, MakeSeqHeaderForArray の特別な形であり,これを内部的に利用しています.また,この関数は,初期化されたヘッダへのポインタを返します.輪郭の包含矩形(構造体 CvContour のフィールド rect )は,初期化されないことに注意してください.必要ならば,関数 BoundingRect を利用します.

ここでは,簡単な利用例を示します.

CvContour header;
CvSeqBlock block;
CvMat* vector = cvCreateMat( 1, 3, CV_32SC2 );

CV_MAT_ELEM( *vector, CvPoint, 0, 0 ) = cvPoint(100,100);
CV_MAT_ELEM( *vector, CvPoint, 0, 1 ) = cvPoint(100,200);
CV_MAT_ELEM( *vector, CvPoint, 0, 2 ) = cvPoint(200,100);

IplImage* img = cvCreateImage( cvSize(300,300), 8, 3 );
cvZero(img);

cvDrawContours( img,
    cvPointSeqFromMat(CV_SEQ_KIND_CURVE+CV_SEQ_FLAG_CLOSED,
                      vector,
                      &header,
                      &block),
                CV_RGB(255,0,0),
                CV_RGB(255,0,0),
                0, 3, 8, cvPoint(0,0));

cv::ReadChainPoint

CvPoint cvReadChainPoint(CvChainPtReader* reader)

次のチェーン点を取得します.

Parameter:reader – チェーンリーダ

この関数は,現在のチェーン点を返し,リーダの位置を更新します.

cv::StartFindContours

CvContourScanner cvStartFindContours(CvArr* image, CvMemStorage* storage, int header_size=sizeof(CvContour), int mode=CV_RETR_LIST, int method=CV_CHAIN_APPROX_SIMPLE, CvPoint offset=cvPoint(0, 0))

輪郭スキャン処理の初期化を行います.

パラメタ:
  • image – 入力画像.8ビット,シングルチャンネル,2値画像
  • storage – 抽出された輪郭を保存するコンテナ
  • header_size – シーケンスヘッダのサイズ. method =CV _ CHAIN _ CODE の場合は >=sizeof(CvChain) ,それ以外の場合は >=sizeof(CvContour)
  • mode – 輪郭抽出モード. FindContours を参照してください
  • method – 近似手法. FindContours の場合と同じですが,ここでは CV_LINK_RUNS を使うことはできません
  • offset – ROIオフセット. FindContours を参照してください

この関数は,輪郭スキャナを初期化し,そのポインタを返します.このスキャナは,関数 FindNextContour 内部で,残りの輪郭を抽出するために利用されます.

cv::StartReadChainPoints

void cvStartReadChainPoints(CvChain* chain, CvChainPtReader* reader)
チェーンリーダを初期化します.

この関数は,チェーンリーダの初期化を行います.

cv::SubstituteContour

void cvSubstituteContour(CvContourScanner scanner, CvSeq* new_contour)

抽出された輪郭を置換します.

パラメタ:
  • scannerStartFindContours によって初期化された輪郭スキャナ
  • new_contour – 新しく置き換える輪郭

この関数は,直前に呼び出した関数 FindNextContour によって返され,輪郭スキャナ内部に保存された抽出輪郭を,ユーザ指定の輪郭で置換します.この輪郭は,輪郭抽出時に得られる構造体(リスト,2階層構造,木構造,など抽出モードに依存した構造体)に挿入されます.ただし,パラメータ new_contourNULL の場合は,抽出された輪郭も,その後で構造体に追加されたかもしれない全ての子輪郭も,構造体には含まれなくなります.