画像ピラミッドを利用してLucas-Kanade 法を反復実行することにより,疎な特徴集合に対するオプティカルフローを求めます.
パラメタ: |
|
---|
関数 calcOpticalFlowPyrLK は,Lucas-Kanade法を利用したオプティカルフローの疎な反復バージョンの実装です.詳しくは Bouguet00 を参照してください.
Gunnar Farneback のアルゴリズムを用いて,密なオプティカルフローを求めます.
パラメタ: |
|
---|
この関数は,以下を満たすようなアルゴリズムを利用して, prevImg の各ピクセルのオプティカルフローを求めます.
動作を表すシルエット画像を用いて,モーション履歴画像を更新します.
パラメタ: |
|
---|
関数 updateMotionHistory は,モーション履歴画像を以下のように更新します:
つまり,モーションが発生した場所の MHI(モーション履歴画像)ピクセルには,現在のタイムスタンプがセットされます.また,モーションが発生からある程度以上時間が経ったピクセルの値はクリアされます.
この関数は, calcMotionGradient() や calcGlobalOrientation() と共に,モーションテンプレートの実装となっています.このテクニックについては, Davis97 と Bradski00 で述べられています. すべてのモーションテンプレート関数を実演する OpenCV のサンプル motempl.c を参照してください.
モーション履歴画像の勾配方向を求めます.
パラメタ: |
|
---|
関数 calcMotionGradient は,各ピクセル における勾配方向を次のように求めます:
(実際には,度単位で表現された計算角度が,全方位0から360までをカバーするように, fastArctan() と phase() が利用されます).また, mask は,その場所で求められた角度が有効であることを示すピクセル値で埋められます.
複数の選択領域の全体的なモーション方向を求めます.
パラメタ: |
|
---|
関数 calcGlobalOrientation は,選択領域におけるモーションの平均方向を求め,その0から360までの角度を返します.平均方向は,重み付きの方向ヒストグラムから計算されます.これは mhi に記録されているように,最近のモーションが大きな重みを持ち,以前のモーションがより小さな重みを持ちます.
物体の中心,サイズ,姿勢を求めます.
パラメタ: |
|
---|
関数 CamShift は, Bradski98 で述べられている CAMSHIFT 物体追跡アルゴリズムの実装です. まず, meanShift() を用いて物体の中心を求め,物体サイズに合わせて窓サイズを調整して,さらに最適な方向を検出します.この関数は,物体の位置,サイズ,姿勢を含む,回転した矩形を表現する構造体を返します.探索窓の次の位置は, RotatedRect::boundingRect() から得ることができます.
カラー物体を追跡する OpenCV サンプル camshiftdemo.c を参照してください.
バックプロジェクション画像上の物体中心を求めます.
パラメタ: |
|
---|
この関数は,物体の反復探索アルゴリズムの実装です.これは,物体のバックプロジェクションと初期位置を入力としてとります.バックプロジェクション画像の window 内の重心が計算され,探索窓の中心が,その重心に合うよう移動されます.この処理は,反復数が規定回数 criteria.maxCount に達するか,探索窓の移動距離が criteria.epsilon 以下になるまで繰り返されます.このアルゴリズムは, CamShift() 内部でも利用されていますが,これは CamShift() とは異なり,探索中に探索窓のサイズや姿勢は変化しません. calcBackProject() の出力を単純にこの関数に渡すことができますが,バックプロジェクションを事前にフィルタリングしてノイズを除去することで,より良い結果を得ることができます(例えば, findContours() を利用して連結成分を抽出, contourArea() を利用して小さい領域の輪郭を削除,そして残った輪郭を drawContours() によって描画します).
カルマンフィルタクラス.
class KalmanFilter
{
public:
KalmanFilter();
KalmanFilter(int dynamParams, int measureParams, int controlParams=0);
void init(int dynamParams, int measureParams, int controlParams=0);
// statePost から statePre を予測します.
const Mat& predict(const Mat& control=Mat());
// 入力された観測ベクトルに基づき statePre を更新して,
// その結果を statePost に格納します.
const Mat& correct(const Mat& measurement);
Mat statePre; // 状態の推定値 (x'(k)):
// x(k)=A*x(k-1)+B*u(k)
Mat statePost; // 更新された状態の推定値 (x(k)):
// x(k)=x'(k)+K(k)*(z(k)-H*x'(k))
Mat transitionMatrix; // システムの時間遷移に関する線形モデル (A)
Mat controlMatrix; // 制御行列 (B)
// (制御していない場合は,これは利用されません)
Mat measurementMatrix; // 観測行列 (H)
Mat processNoiseCov; // プロセスノイズ(時間遷移に関するノイズ)の共分散行列 (Q)
Mat measurementNoiseCov;// 観測ノイズの共分散行列 (R)
Mat errorCovPre; // 今の時刻の誤差行列 (P'(k)):
// P'(k)=A*P(k-1)*At + Q)*/
Mat gain; // 最適カルマンゲイン (K(k)):
// K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R)
Mat errorCovPost; // 更新された誤差の共分散行列 (P(k)):
// P(k)=(I-K(k)*H)*P'(k)
...
};
このクラスは,標準的なカルマンフィルタ http://en.wikipedia.org/wiki/Kalman_filter の実装です.しかし,ユーザは transitionMatrix , controlMatrix および measurementMatrix を変更して,拡張カルマンフィルタとして動作するようにもできます.OpenCVのサンプル kalman.c を参照してください.