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;
}
