CV リファレンス マニュアル
-
画像処理(Image Processing)
- 勾配,エッジ,コーナー(Gradients, Edges and Corners)
- サンプリング,補間,幾何変換(Sampling, Interpolation and Geometrical Transforms)
- モルフォロジー演算(Morphological Operations)
- フィルタと色変換(Filters and Color Conversion)
- ピラミッドとその応用(Pyramids and the Applications)
- 画像分割,領域結合,輪郭検出(Image Segmentation, Connected Components and Contour Retrieval)
- 画像と形状のモーメント(Image and Contour Moments)
- 特殊な画像変換(Special Image Transforms)
- ヒストグラム(Histograms)
- マッチング(Matching)
- 構造解析(Structural Analysis)
- モーション解析と物体追跡(Motion Analysis and Object Tracking)
- パターン認識(Pattern Recognition)
- カメラキャリブレーションと3次元再構成(Camera Calibration and 3D Reconstruction)
- 参考文献
モーション解析と物体追跡(Motion Analysis and Object Tracking)
推定器(Estimators)
CvKalman
カルマンフィルタ状態
typedef struct CvKalman { int MP; /* 観測ベクトルの次元数 */ int DP; /* 状態ベクトルの次元数 */ int CP; /* コントロールベクトルの次元数 */ /* 後方互換性フィールド */ #if 1 float* PosterState; /* =state_pre->data.fl */ float* PriorState; /* =state_post->data.fl */ float* DynamMatr; /* =transition_matrix->data.fl */ float* MeasurementMatr; /* =measurement_matrix->data.fl */ float* MNCovariance; /* =measurement_noise_cov->data.fl */ float* PNCovariance; /* =process_noise_cov->data.fl */ float* KalmGainMatr; /* =gain->data.fl */ float* PriorErrorCovariance;/* =error_cov_pre->data.fl */ float* PosterErrorCovariance;/* =error_cov_post->data.fl */ float* Temp1; /* temp1->data.fl */ float* Temp2; /* temp2->data.fl */ #endif CvMat* state_pre; /* 予測状態 (x'(k)): x(k)=A*x(k-1)+B*u(k) */ CvMat* state_post; /* 修正後の状態 (x(k)): x(k)=x'(k)+K(k)*(z(k)-H*x'(k)) */ CvMat* transition_matrix; /* 状態遷移行列 (A) */ CvMat* control_matrix; /* コントロール行列 (B) (コントロールされない場合は,用いられない) */ CvMat* measurement_matrix; /* 観測行列 (H) */ CvMat* process_noise_cov; /* プロセスノイズ共分散行列 (Q) */ CvMat* measurement_noise_cov; /* 観測ノイズ共分散行列 (R) */ CvMat* error_cov_pre; /* 事前誤差推定共分散行列 (P'(k)): P'(k)=A*P(k-1)*At + Q)*/ CvMat* gain; /* カルマンゲイン行列 (K(k)): K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)*/ CvMat* error_cov_post; /* 事後誤差推定共分散行列 (P(k)): P(k)=(I-K(k)*H)*P'(k) */ CvMat* temp1; /* テンポラリ行列 */ CvMat* temp2; CvMat* temp3; CvMat* temp4; CvMat* temp5; } CvKalman;
構造体 CvKalman は,カルマンフィルタ状態 を保存するために用いられる. これは関 数 cvCreateKalman によって作成され, 関数 cvKalmanPredict および, cvKalmanCorrect によって更新される. また関数 cvReleaseKalman によって解放される. 通常,構造体は標準カルマンフィルタに対して用いられる (以下の表記法と式は,優れたカルマンフィルタのチュートリアルである [Welch95] から引用した):
xk=A•xk-1+B•uk+wk zk=H•xk+vk,
ここで,
xk (xk-1) - 時刻 k (k-1) におけるシステム状態 zk - 時刻 k におけるシステム状態の観測 uk - 時刻 k に適用される外部コントロール wk と vk は,それぞれ正規分布に従うプロセスノイズと観測ノイズである. p(w) ~ N(0,Q) p(v) ~ N(0,R), つまり, Q - プロセスノイズ共分散行列,定数あるいは変数, R - 観測ノイズ共分散行列,定数あるいは変数
標準的なカルマンフィルタの場合,全ての行列:A, B, H, Q, R は, cvCreateKalman によって構造体 CvKalman が確保された後に一度だけ初期化される. ただし,現在のシステム状態の近傍における,線形化された拡張カルマンフィルタの式によって,拡張カルマンフィルタをシミュレートするために,同じ構造体と同じ関数が用いられることがある. この場合,A, B, H は(おそらくQ, R も)毎回更新される.
CreateKalman
カルマンフィルタ構造体の領域確保を行う
CvKalman* cvCreateKalman( int dynam_params, int measure_params, int control_params=0 );
- dynam_params
- 状態ベクトルの次元数
- measure_params
- 観測ベクトルの次元
- control_params
- コントロールベクトルの次元
関数 cvCreateKalman は, CvKalman と,その全ての行列の領域を確保し,それらを何らかの方法で初期化する.
ReleaseKalman
カルマンフィルタ構造体を解放する
void cvReleaseKalman( CvKalman** kalman );
- kalman
- カルマンフィルタ構造体へのポインタのポインタ.
関数 cvReleaseKalman は,構造体 CvKalman および,内部的に用いられる全ての行列を解放する.
KalmanPredict
次のモデル状態を推定する
const CvMat* cvKalmanPredict( CvKalman* kalman, const CvMat* control=NULL );
#define cvKalmanUpdateByTime cvKalmanPredict
- kalman
- カルマンフィルタ状態.
- control
- コントロールベクトル (uk).外部コントロールが存在しない場合(control_params=0)に限り,NULL である.
関数 cvKalmanPredict は,現在の状態から次の確率モデルの状態を推定し,それを kalman->state_pre に保存する.
x'k=A•xk+B•uk
P'k=A•Pk-1*AT + Q,
ここで
x'kは,予測された状態(kalman->state_pre),
xk-1は,前のステップでの修正された状態(kalman->state_post)
(これは最初に何らかの形で初期化される.デフォルトでは 0 ベクトル),
ukは,外部コントロール(引数control),
P'kは,事前誤差共分散行列(kalman->error_cov_pre)
Pk-1は,前のステップでの事後誤差共分散行列(kalman->error_cov_post)
(これは最初に何らかの形で初期化される.デフォルトでは単位ベクトル),
この関数は推定された状態を返す.
KalmanCorrect
モデル状態を修正する
const CvMat* cvKalmanCorrect( CvKalman* kalman, const CvMat* measurement );
#define cvKalmanUpdateByMeasurement cvKalmanCorrect
- kalman
- 更新される構造体へのポインタ.
- measurement
- 観測ベクトルを含む構造体 CvMat へのポインタ.
関数 cvKalmanCorrect は,与えられたモデルの観測値を基準にして,次のように確率モデル状態を修正する.
Kk=P'k•HT•(H•P'k•HT+R)-1
xk=x'k+Kk•(zk-H•x'k)
Pk=(I-Kk•H)•P'k
ここで,
zk - 与えられた観測(引数mesurement)
Kk - カルマン「ゲイン」行列
この関数は修正された状態を kalman->state_post に保存し,これを出力として返す.
(例)カルマンフィルタを用いて回転する点を追跡する
#include "cv.h" #include "highgui.h" #include <math.h> int main(int argc, char** argv) { /* 行列データ */ const float A[] = { 1, 1, 0, 1 }; IplImage* img = cvCreateImage( cvSize(500,500), 8, 3 ); CvKalman* kalman = cvCreateKalman( 2, 1, 0 ); /* 状態(φ, Δφ) - 角度と角度の増加分 */ CvMat* state = cvCreateMat( 2, 1, CV_32FC1 ); CvMat* process_noise = cvCreateMat( 2, 1, CV_32FC1 ); /* φ(角度)だけが観測される */ CvMat* measurement = cvCreateMat( 1, 1, CV_32FC1 ); CvRandState rng; int code = -1; cvRandInit( &rng, 0, 1, -1, CV_RAND_UNI ); cvZero( measurement ); cvNamedWindow( "Kalman", 1 ); for(;;) { cvRandSetRange( &rng, 0, 0.1, 0 ); rng.disttype = CV_RAND_NORMAL; cvRand( &rng, state ); memcpy( kalman->transition_matrix->data.fl, A, sizeof(A)); cvSetIdentity( kalman->measurement_matrix, cvRealScalar(1) ); cvSetIdentity( kalman->process_noise_cov, cvRealScalar(1e-5) ); cvSetIdentity( kalman->measurement_noise_cov, cvRealScalar(1e-1) ); cvSetIdentity( kalman->error_cov_post, cvRealScalar(1)); /* 初期状態をランダムに選択 */ cvRand( &rng, kalman->state_post ); rng.disttype = CV_RAND_NORMAL; for(;;) { #define calc_point(angle) \ cvPoint( cvRound(img->width/2 + img->width/3*cos(angle)), \ cvRound(img->height/2 - img->width/3*sin(angle))) float state_angle = state->data.fl[0]; CvPoint state_pt = calc_point(state_angle); /* 点の位置を予測 */ const CvMat* prediction = cvKalmanPredict( kalman, 0 ); float predict_angle = prediction->data.fl[0]; CvPoint predict_pt = calc_point(predict_angle); float measurement_angle; CvPoint measurement_pt; cvRandSetRange( &rng, 0, sqrt(kalman->measurement_noise_cov->data.fl[0]), 0 ); cvRand( &rng, measurement ); /* 観測値を生成 */ cvMatMulAdd( kalman->measurement_matrix, state, measurement, measurement ); measurement_angle = measurement->data.fl[0]; measurement_pt = calc_point(measurement_angle); /* 点をプロット */ #define draw_cross( center, color, d ) \ cvLine( img, cvPoint( center.x - d, center.y - d ), \ cvPoint( center.x + d, center.y + d ), color, 1, 0 ); \ cvLine( img, cvPoint( center.x + d, center.y - d ), \ cvPoint( center.x - d, center.y + d ), color, 1, 0 ) cvZero( img ); draw_cross( state_pt, CV_RGB(255,255,255), 3 ); draw_cross( measurement_pt, CV_RGB(255,0,0), 3 ); draw_cross( predict_pt, CV_RGB(0,255,0), 3 ); cvLine( img, state_pt, predict_pt, CV_RGB(255,255,0), 3, 0 ); /* カルマンフィルタ状態を修正 */ cvKalmanCorrect( kalman, measurement ); cvRandSetRange( &rng, 0, sqrt(kalman->process_noise_cov->data.fl[0]), 0 ); cvRand( &rng, process_noise ); cvMatMulAdd( kalman->transition_matrix, state, process_noise, state ); cvShowImage( "Kalman", img ); code = cvWaitKey( 100 ); if( code > 0 ) /* キーを押すと現在のシミュレーションを中止 */ break; } if( code == 27 ) /* ESC キーで終了 */ break; } return 0; }
CvConDensation
ConDenstation 状態
typedef struct CvConDensation { int MP; // 観測ベクトルの次元 int DP; // 状態ベクトルの次元 float* DynamMatr; // 線形ダイナミクスを表す行列 float* State; // 状態ベクトル int SamplesNum; // サンプル数 float** flSamples; // サンプルベクトルの配列 float** flNewSamples; // サンプルベクトルのテンポラリ配列 float* flConfidence; // 各サンプルの確かさ float* flCumulative; // 確かさの累積値 float* Temp; // テンポラリベクトル float* RandomSample; // サンプルセットを更新するためのランダムベクトル CvRandState* RandS; // ランダムベクトルを生成するための構造体配列 } CvConDensation;
構造体 CvConDensation は,CONditional DENSity propagATION 追跡器の状態を保存する. このアルゴリズムに関する情報は, http://www.dai.ed.ac.uk/CVonline/LOCAL_COPIES/ISARD1/condensation.html で得られる.
CreateConDensation
ConDensation フィルタ構造体の領域確保を行う
CvConDensation* cvCreateConDensation( int dynam_params, int measure_params, int sample_count );
- dynam_params
- 状態ベクトルの次元.
- measure_params
- 観測ベクトルの次元.
- sample_count
- サンプル数.
関数 cvCreateConDensation は, 構造体 CvConDensation を作成し,そのポインタを返す.
ReleaseConDensation
ConDensation フィルタ構造体を解放する
void cvReleaseConDensation( CvConDensation** condens );
- condens
- 解放する構造体のポインタのポインタ.
関数 cvReleaseConDensation は, 構造体 CvConDensation (cvConDensation を参照)および, この構造体のために確保されたメモリを解放する.
ConDensInitSampleSet
ConDensation アルゴリズムのためのサンプル集合を初期化する
void cvConDensInitSampleSet( CvConDensation* condens, CvMat* lower_bound, CvMat* upper_bound );
- condens
- 初期化される構造体へのポインタ.
- lower_bound
- 各次元の下限のベクトル.
- upper_bound
- 各次元の上限のベクトル.
関数 cvConDensInitSampleSet は, 構造体 CvConDensation 内のサンプル配列を,与えられた範囲内の値で埋める.
ConDensUpdateByTime
次のモデル状態を推定する
void cvConDensUpdateByTime( CvConDensation* condens );
- condens
- 更新する構造体へのポインタ.
関数 cvConDensUpdateByTimeは,現在の状態から次の確率モデル状態を推定する.