フリーマンチェーンを,折れ線で近似します.
パラメタ: |
|
---|
これは,単独動作可能な近似ルーチンです.関数 cvApproxChains は,これに相当する近似フラグを引数として与えた場合の FindContours と全く同じように動作します.この関数は,結果として得られる最初の輪郭へのポインタを返します.もしその他の近似輪郭が存在するならば,返された構造体のフィールド v_next と h_next を辿って取得できます.
折れ線(カーブ)を指定された精度で近似します.
パラメタ: |
|
---|
この関数は,1つあるいは複数の折れ線(カーブ)を近似し,その近似結果を返します.折れ線が複数の場合,結果の木構造は入力のそれと同じ構造になります(1対1に対応します).
輪郭線の周囲長,あるいは曲線の長さを求めます.
パラメタ: |
|
---|
この関数は,曲線上の連続する2点間の線分距離の総和として,曲線の長さを求めます.
点群に外接する傾いていない矩形を求めます.
パラメタ: |
|
---|
この関数は,2次元点の集合に対する傾いていないバウンディングボックスを返します. 以下に,取り得る points の種類とフラグの組み合わせを示します:
update | points | action |
---|---|---|
0 | CvContour* | バウンディングボックスを計算せず,輪郭ヘッダのフィールド rect から取得します. |
1 | CvContour* | バウンディングボックスを計算し,輪郭ヘッダのフィールド rect に書き込みます. |
0 | CvSeq* or CvMat* | バウンディングボックスが計算され,それが返されます. |
1 | CvSeq* or CvMat* | ランタイムエラーが発生します. |
ボックス形状の頂点を求めます.
パラメタ: |
|
---|
この関数は,入力された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;
}
輪郭のペアワイズ幾何ヒストグラムを求めます.
パラメタ: |
|
---|
この関数は, Iivarinen97 で提唱された,輪郭に対する2次元のペアワイズ幾何ヒストグラム(PGH)を計算します.このアルゴリズムでは,輪郭を構成する辺同士のすべての組み合わせ(ペア)が考慮されます.各ペアに対して,辺同士が成す角度と,辺同士の最小/最大距離が求められます.そのために,ひとつひとつの辺を順番に基準辺として,それ以外の辺との関係をすべて調べます.基準辺とそれ以外の辺を考える場合,基準辺ではない方の辺上にある点から,基準辺の直線までの最小距離と最大距離が選択されます.この辺同士の角度がヒストグラムの行を定義します.ヒストグラムでは,計算された最小・最大距離の範囲内に含まれる距離に対応するすべてのビンが,その値を増加させます(つまり,このヒストグラムは Iivarninen97 での定義に対して,転置されています).このヒストグラムは,輪郭同士のマッチングに利用できます.
2つの重み付き点群間の「最小コスト」距離を求めます.
パラメタ: |
|
---|
この関数は,EMDと2つの重み付き点群間の距離の下限値のどちらか片方,あるいは両方を計算します.これの RubnerSept98 で述べられている応用例の1つが,画像抽出のための多次元ヒストグラム比較です.EMDは,修正シンプレックス法で解くことができる輸送問題なので,最悪の場合は計算量が指数関数的に増加しますが,平均的には十分高速に計算できます.実際は,(線形時間アルゴリズムを利用して)下限値をより高速に求めることが可能で,2つのシグネチャが十分に離れており,同一物体に関連するものではないと判断するのに利用できます.
輪郭形状が凸であるかを調べます.
パラメタ: |
|
---|
この関数は,入力輪郭が凸であるか否かを調べます.この輪郭は,自己交差しないような単純なものでなければいけません.
1つの輪郭の凹状欠損を表す構造体.
typedef struct CvConvexityDefect
{
CvPoint* start; /* 輪郭の凹状欠損の始点 */
CvPoint* end; /* 輪郭の凹状欠損の終点 */
CvPoint* depth_point; /* 凹状欠損の中で凸包から最も遠い点 */
float depth; /* 最も遠い点と凸包間の距離 */
} CvConvexityDefect;
全輪郭,あるい輪郭の一部が囲む領域面積を求めます.
パラメタ: |
|
---|
この関数は,全輪郭,あるい輪郭の一部が囲む領域面積を求めます.後者の場合,以下の図のように,輪郭の弧と2点を結ぶ弦によって区切られた総面積が求められます:
輪郭の姿勢によっては, 負の 値を返すことがあります.面積の絶対値を得るには,C 言語の fabs() を利用してください.
木構造から輪郭を復元します.
パラメタ: |
|
---|
この関数は,その二分木表現から輪郭を復元します.パラメータ criteria で,精度と復元に利用する木のレベル数のどちらか片方,あるいは両方を指定します.これにより,近似された輪郭を作成することができます.また,この関数は,復元された輪郭を返します.
点集合に対する凸包を求めます.
パラメタ: |
|
---|
この関数は,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
}
}
輪郭の凹状欠損を見つけます.
パラメタ: |
|
---|
この関数は,入力輪郭の全ての凹状欠損を見つけて,構造体 CvConvexityDefect のシーケンスを返します.
輪郭の階層表現を作成します.
パラメタ: |
|
---|
この関数は,入力輪郭 contour の二分木表現を作成し,その根へのポインタを返します.パラメータ threshold が0以下の場合,この関数は全二分木表現を作成します.また,0よりも大きい場合は,精度 threshold の表現を作成します:これは,近似線によって切り取られる元輪郭線上の頂点数が threshold よりも少なくなると,それ以上木を作成しません.また,この関数は,作成された木構造を返します.
この関数は,輪郭スキャン処理を終了し,最高レベルにある最初の輪郭へのポインタを返します.
2値画像中の輪郭を抽出します.
パラメタ: |
|
---|
この関数は, Suzuki85 のアルゴリズムを用いて,2値画像から輪郭を抽出します.その輪郭は,形状解析や物体検出,物体認識に役立ちます.
この関数は,2値画像から輪郭を抽出し,その輪郭数を返します.また,ポインタ first_contour に,結果が出力されます.これは,最も外側にある最初の輪郭へのポインタを表し,輪郭が全く抽出されなかった場合(画像が完全に真っ黒の場合)は,戻り値が NULL になります.それ以外の輪郭へは,リンクである h_next と v_next を利用して, first_contour から辿ることができます.関数 DrawContours の説明にあるサンプルは,輪郭を利用して連結成分を抽出する方法について述べています.輪郭は,形状解析や物体認識などにも用いられます - OpenCVサンプルディレクトリにある squares.c を参照してください.
注意: 元の image は,この関数によって書き換えられます.
画像の次の輪郭を求めます.
パラメタ: |
|
---|
この関数は,画像中の次の輪郭を発見,抽出し,そのポインタを返します.これ以上の輪郭が存在しない場合は,この関数は NULL を返します.
この関数は,2 次元点の集合に最もフィットする(二乗誤差が最小になる)楕円を求めます.返される構造体のフィールドは, size が,楕円軸の半分の長さではなく全長を表していることを除けば, Ellipse のそれと同様です.
2 次元あるいは 3 次元の点集合に直線をフィッティングします.
パラメタ: |
|
---|
この関数は, を最小化することで,2 次元あるいは 3 次元の点集合に直線をフィッティングします.ここで, は 番目の点と直線の距離, は距離関数(以下の内の1つ)を表します:
dist_type=CV_DIST_L2
dist_type=CV_DIST_L1
dist_type=CV_DIST_L12
dist_type=CV_DIST_FAIR
dist_type=CV_DIST_WELSCH
dist_type=CV_DIST_HUBER
画像モーメント構造体から,中心モーメントを取得します.
パラメタ: |
|
---|
この関数は,中心モーメント,つまり,画像モーメントの場合は次のように定義される値,を取り出します:
ここで, は重心の座標です:
7つの Hu モーメント不変量を求めます.
パラメタ: |
|
---|
この関数は,次のように定義される 7つの Hu モーメント不変量を求めます. http://en.wikipedia.org/wiki/Image_moment も参照してください.
ここで は,正規化された中心モーメントを表します.
反転によって符号が逆転してしまう7番目のHuモーメントを除いて,これらの値は,画像のスケール変化,回転,および反転に対して不変であることが分かっています.この不変量は,もちろん画像解像度が無限であるという仮定の元に成り立っています.ラスタ画像の場合は,元画像に対する Hu 不変量と変形した画像に対するものとは多少異なります.
画像モーメント構造体から,正規化された中心モーメントを取得します.
パラメタ: |
|
---|
この関数は, 次のように正規化された中心モーメントを取得します:
画像モーメント構造体から,空間モーメントを取得します.
パラメタ: |
|
---|
この関数は,空間モーメント,つまり,画像モーメントの場合は次のように定義される値,を取り出します:
ここで, は,ピクセル の輝度値です.
2 つの輪郭を,その二分木表現によって比較します.
パラメタ: |
|
---|
この関数は,2つの輪郭(木)の類似度を求めます.この類似度は,二分木の根から順に,それぞれのレベル毎に計算されます.あるレベルにおいて,輪郭間の差が threshold よりも小さくなった場合,復元処理が中断され,その時点での差が返されます.
2 つの形状を比較します.
パラメタ: |
|
---|
この関数は,2 つの形状を比較します.実装されている 3 つの手法は,いずれもHuモーメント( GetHuMoments の説明を参照してください)を利用します( は object1 , は object2 を表します):
method=CV_CONTOUR_MATCH_I1
method=CV_CONTOUR_MATCH_I2
method=CV_CONTOUR_MATCH_I3
ここで,
です. また, は, と それぞれのHuモーメントを表します.
与えられた2次元点集合を囲む最小の矩形を求めます.
パラメタ: |
|
---|
この関数は,点集合に対する凸包を作成し,その凸包に対して rotating calipers 法を適用することにより,与えられた2次元点集合を囲む最小の矩形を求めます.
図.輪郭を囲む最小面積の矩形
与えられた2次元点集合を囲む最小の円を求めます.
パラメタ: |
|
---|
この関数は,反復アルゴリズムを用いて,与えられた2次元点集合を囲む最小の円を求めます.そして,結果として得られる円がすべての入力点を囲んでいる場合は0以外の値を返し,そうでない場合(つまり,アルゴリズムが失敗した場合)は0を返します.
ポリゴンあるいはラスタライズされた形状の,3 次までのモーメントを求めます.
パラメタ: |
|
---|
この関数は,3次までの空間モーメントあるいは中心モーメントを計算し,それらを moments に書き込みます.そしてこれらのモーメントは,形状の重心,面積,主軸,そして7つのHuモーメント不変量を含む各種の形状特徴を計算するために利用されます.
点と輪郭の位置関係を調べます.
パラメタ: |
|
---|
この関数は,与えられた点が輪郭の内側,外側,あるいは輪郭の辺上(あるいは,頂点上)のどこにあるかを判定します.そして,その結果に応じて,正,負,0のいずれかの値が返されます. の場合,戻り値はそれぞれ +1,-1,0です.また, の場合,入力点とそれに最も近い輪郭の辺までの符号付き距離が返されます.
ここでは,この関数の出力例として,各画像ピクセルが輪郭に対してテストされる様子を示します.
座標点のベクトルを用いて,座標点のシーケンスヘッダを初期化します.
パラメタ: |
|
---|
この関数は,その要素が指定された行列内に存在する様な「仮想的な」シーケンスを作成するために,シーケンスヘッダを初期化します.そのデータはコピーされません.初期化されたシーケンスヘッダは,座標点のシーケンスを入力にとる任意の関数に渡すことができます.このシーケンスには,要素を追加することはできませんが,削除することはできます.この関数は, 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));
この関数は,現在のチェーン点を返し,リーダの位置を更新します.
輪郭スキャン処理の初期化を行います.
パラメタ: |
|
---|
この関数は,輪郭スキャナを初期化し,そのポインタを返します.このスキャナは,関数 FindNextContour 内部で,残りの輪郭を抽出するために利用されます.
チェーンリーダを初期化します.
この関数は,チェーンリーダの初期化を行います.
抽出された輪郭を置換します.
パラメタ: |
|
---|
この関数は,直前に呼び出した関数 FindNextContour によって返され,輪郭スキャナ内部に保存された抽出輪郭を,ユーザ指定の輪郭で置換します.この輪郭は,輪郭抽出時に得られる構造体(リスト,2階層構造,木構造,など抽出モードに依存した構造体)に挿入されます.ただし,パラメータ new_contour が NULL の場合は,抽出された輪郭も,その後で構造体に追加されたかもしれないすべての子輪郭も,構造体には含まれなくなります.