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は,現在の状態から次の確率モデル状態を推定する.
