CXCORE リファレンス マニュアル
最終変更者: 怡土順一, 最終変更リビジョン: 491, 最終変更日時: 2009-08-31 23:34:45 +0900 (月, 31 8月 2009)
- 基本構造体(Basic Structures)
- 配列操作(Operations on Arrays)
- 動的構造体(Dynamic Structures)
- 描画関数(Drawing Functions)
- データ永続性と実行時型情報(Data Persistence and RTTI)
- その他の関数(Miscellaneous Functions)
- エラーハンドリングとシステム関数(Error Handling and System Functions)
その他の関数(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-変量ガウス分布に従うランダムサンプルのクラスタリングを行う
#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; }