モーション解析と物体追跡 ==================================== .. highlight:: python .. index:: CalcGlobalOrientation .. _CalcGlobalOrientation: CalcGlobalOrientation --------------------- `id=0.201798908966 Comments from the Wiki `__ .. function:: CalcGlobalOrientation(orientation,mask,mhi,timestamp,duration)-> float 複数の選択領域の全体的なモーション方向を求めます. :param orientation: モーション勾配方向画像.関数 :ref:`CalcMotionGradient` によって計算されます. :type orientation: :class:`CvArr` :param mask: マスク画像. :ref:`CalcMotionGradient` で求められた有効勾配のマスクと,方向を計算する必要がある領域を示すマスクの論理積. :type mask: :class:`CvArr` :param mhi: モーション履歴画像. :type mhi: :class:`CvArr` :param timestamp: ミリ秒単位,あるいは別の単位で表される現在時間.大きな画像に対して :ref:`UpdateMotionHistory` や :ref:`CalcMotionGradient` を実行すると時間がかかる可能性があるので,事前に :ref:`UpdateMotionHistory` に渡す時間値を保存しておき,ここでそれを再利用する方が良いでしょう. :type timestamp: float :param duration: ミリ秒単位で表される,モーションの最大持続時間. :ref:`UpdateMotionHistory` のものと同じです. :type duration: float この関数は,選択領域における全体的なモーション方向を求め,0から360度の間の角度を返します.これはまず,方向ヒストグラムを作成し,ヒストグラムが最大値を取る方向を基本方向とします.次に,全方向ベクトル(相対角度)の重み付き和を求め,基本方向からのズレを計算します:最近の動作ベクトルであるほど,より大きな重みを持ちます.結果として得られる角度は,基本方向とこのズレ量の和になります. .. index:: CalcMotionGradient .. _CalcMotionGradient: CalcMotionGradient ------------------ `id=0.477006631655 Comments from the Wiki `__ .. function:: CalcMotionGradient(mhi,mask,orientation,delta1,delta2,apertureSize=3)-> None モーション履歴画像の勾配方向を求めます. :param mhi: モーション履歴画像. :type mhi: :class:`CvArr` :param mask: マスク画像.モーション勾配データが有効なピクセルがマークされます.出力パラメータです. :type mask: :class:`CvArr` :param orientation: モーション勾配方向画像.0~360 度の角度. :type orientation: :class:`CvArr` :param delta1: 以下を参照してください. :type delta1: float :param delta2: 以下を参照してください. :type delta2: float :param apertureSize: この関数で利用される微分オペレータのアパーチャサイズ:CV _ SCHARR, 1, 3, 5, 7( :ref:`Sobel` を参照してください). :type apertureSize: int この関数は, ``mhi`` の微分 :math:`Dx` と :math:`Dy` を求め,勾配方向を次のように計算します: .. math:: \texttt{orientation} (x,y)= \arctan{\frac{Dy(x,y)}{Dx(x,y)}} ここでは,(関数 :ref:`CartToPolar` と同様に) :math:`Dx(x,y)` と :math:`Dy(x,y)` の両方の符号が考慮されます.その後,勾配方向が有効である箇所を示すために ``mask`` が埋められます. この関数は,各ピクセル :math:`(x,y)` の近傍において,最小( :math:`m(x,y)` ) と最大( :math:`M(x,y)` )の mhi 値を求め,以下の条件を満たす場合のみ有効な勾配であるとします. .. math:: \min ( \texttt{delta1} , \texttt{delta2} ) \le M(x,y)-m(x,y) \le \max ( \texttt{delta1} , \texttt{delta2} ). .. index:: CalcOpticalFlowBM .. _CalcOpticalFlowBM: CalcOpticalFlowBM ----------------- `id=0.0897900941945 Comments from the Wiki `__ .. function:: CalcOpticalFlowBM(prev,curr,blockSize,shiftSize,max_range,usePrevious,velx,vely)-> None ブロックマッチング法を用いて,2つの画像に対するオプティカルフローを求めます. :param prev: 1番目の画像.8ビット,シングルチャンネル. :type prev: :class:`CvArr` :param curr: 2番目の画像.8ビット,シングルチャンネル. :type curr: :class:`CvArr` :param blockSize: 比較される基本ブロックのサイズ. :type blockSize: :class:`CvSize` :param shiftSize: ブロック座標の増加量. :type shiftSize: :class:`CvSize` :param max_range: ピクセル単位で表される,ブロック周辺の探索範囲サイズ. :type max_range: :class:`CvSize` :param usePrevious: 前回のフレームの速度場を,今回の計算の初期値として利用します. :type usePrevious: int :param velx: オプティカルフローの水平成分.32ビット,浮動小数点型,シングルチャンネルで,サイズは次のようになります. .. math:: \left \lfloor \frac{\texttt{prev->width} - \texttt{blockSize.width}}{\texttt{shiftSize.width}} \right \rfloor \times \left \lfloor \frac{\texttt{prev->height} - \texttt{blockSize.height}}{\texttt{shiftSize.height}} \right \rfloor :type velx: :class:`CvArr` :param vely: オプティカルフローの垂直成分. ``velx`` と同じサイズ,32ビット,浮動小数点型,シングルチャンネル. :type vely: :class:`CvArr` この関数は,重なり合った :math:`\texttt{blockSize.width} \times \texttt{blockSize.height}` ピクセルのブロック毎にオプティカルフローを計算します.したがって,速度場のサイズは元の画像よりも小さくなります.この関数は, ``prev`` の各ブロックに対して, ``curr`` からそれに似たブロックを探そうとします.その探索範囲は,元のブロックの近傍,あるいは,( ``use_previous=1`` の場合)前回の関数呼び出しで計算された速度分 (velx(x0,y0),vely(x0,y0)) だけ移動したブロックの近傍です. .. index:: CalcOpticalFlowHS .. _CalcOpticalFlowHS: CalcOpticalFlowHS ----------------- `id=0.732101616943 Comments from the Wiki `__ .. function:: CalcOpticalFlowHS(prev,curr,usePrevious,velx,vely,lambda,criteria)-> None 2つの画像に対するオプティカルフローを求めます. :param prev: 1番目の画像.8ビット,シングルチャンネル. :type prev: :class:`CvArr` :param curr: 2番目の画像.8ビット,シングルチャンネル. :type curr: :class:`CvArr` :param usePrevious: 前回のフレームの速度場を,今回の計算の初期値として利用します. :type usePrevious: int :param velx: オプティカルフローの水平成分.入力画像と同じサイズ,32ビット,浮動小数点型,シングルチャンネル. :type velx: :class:`CvArr` :param vely: オプティカルフローの垂直成分.入力画像と同じサイズ,32ビット,浮動小数点型,シングルチャンネル. :type vely: :class:`CvArr` :param lambda: ラグランジュ乗数. :type lambda: float :param criteria: 速度計算の停止基準. :type criteria: :class:`CvTermCriteria` この関数は,Horn-Schunck のアルゴリズム Horn81 を用いて,1番目の画像の各ピクセルに対するフローを計算します. .. index:: CalcOpticalFlowLK .. _CalcOpticalFlowLK: CalcOpticalFlowLK ----------------- `id=0.917095271969 Comments from the Wiki `__ .. function:: CalcOpticalFlowLK(prev,curr,winSize,velx,vely)-> None 2つの画像に対するオプティカルフローを求めます. :param prev: 1番目の画像.8ビット,シングルチャンネル. :type prev: :class:`CvArr` :param curr: 2番目の画像.8ビット,シングルチャンネル. :type curr: :class:`CvArr` :param winSize: ピクセルをグループ化するための平均化窓のサイズ. :type winSize: :class:`CvSize` :param velx: オプティカルフローの水平成分.入力画像と同じサイズ,32ビット,浮動小数点型,シングルチャンネル. :type velx: :class:`CvArr` :param vely: オプティカルフローの垂直成分.入力画像と同じサイズ,32ビット,浮動小数点型,シングルチャンネル. :type vely: :class:`CvArr` この関数は,Lucas-Kanade のアルゴリズム Lucas81 を用いて,1番目の画像の各ピクセルに対するフローを計算します. .. index:: CalcOpticalFlowPyrLK .. _CalcOpticalFlowPyrLK: CalcOpticalFlowPyrLK -------------------- `id=0.529042636377 Comments from the Wiki `__ .. function:: CalcOpticalFlowPyrLK( prev, curr, prevPyr, currPyr, prevFeatures, winSize, level, criteria, flags, guesses = None) -> (currFeatures, status, track_error) Lucas-Kanade法を画像ピラミッドを利用して反復実行することにより,疎な特徴集合に対するオプティカルフローを求めます. :param prev: 時間 ``t`` における1番目のフレーム. :type prev: :class:`CvArr` :param curr: 時間 ``t + dt`` における2番目のフレーム. :type curr: :class:`CvArr` :param prevPyr: 1番目のフレームに対する画像ピラミッドのバッファ.このポインタが ``NULL`` ではない場合,バッファは,レベル ``1`` から ``level`` までの画像ピラミッドを格納するのに十分なサイズでなければいけません.合計 ``(image_width+8)*image_height/3`` バイトが十分なサイズといえます. :type prevPyr: :class:`CvArr` :param curr_pyr: ``prevPyr`` と同様.こちらは2番目のフレームに対して利用されます. :param prevFeatures: フローを検出するのに必要な(特徴)点の配列. :type prevFeatures: :class:`CvPoint2D32f` :param currFeatures: 2次元座標点の配列.入力特徴の2番目のフレームにおける新しい位置が求められ,ここに格納されます. :type currFeatures: :class:`CvPoint2D32f` :param winSize: 画像ピラミッドの各レベルにおける探索窓のサイズ. :type winSize: :class:`CvSize` :param level: 画像ピラミッドの最大レベル数.これが ``0`` ならば,画像ピラミッドは利用されません(1レベル). ``1`` ならば,2レベルまでの画像ピラミッドが利用されます.以降同様. :type level: int :param status: 配列.特徴点のフローが検出できた場合は,それに対応する要素が ``1`` にセットされ,そうでない場合は ``0`` にセットされます. :type status: str :param track_error: オプション.移動前の特徴点の周辺領域と,移動後の特徴点の周辺領域との差を含む配列. ``NULL`` でも構いません. :type track_error: float :param criteria: 各レベルの画像ピラミッドの各特徴点に対するフローを求める反復計算の停止基準. :type criteria: :class:`CvTermCriteria` :param flags: 雑多なフラグ: * **CV_LKFLOWPyr_A_READY** 1番目のフレームに対する画像ピラミッドが事前(この関数の呼び出し前)に計算されています. * **CV_LKFLOWPyr_B_READY** 2番目のフレームに対する画像ピラミッドが事前(この関数の呼び出し前)に計算されています. :type flags: int :param guesses: オプション.2番目のフレームにおける特徴点座標の推定値(初期値)の配列. ``prevFeatures`` と同じ長さです. :type guesses: :class:`CvPoint2D32f` この関数は,Lucas-Kanade法を利用したオプティカルフロー計算を,画像ピラミッドを利用して数回反復するバージョンの実装です Bouguet00 .以前のビデオフレームの特徴点座標が与えられると,現在のフレームでの座標が計算されます.また,この関数は,サブピクセル精度で座標を検出します. パラメータ ``prevPyr`` と ``currPyr`` は,どちらも以下の規則に従います:画像ポインタが0の場合,この関数は内部にバッファを確保後,画像ピラミッドを計算します.そして,処理が終わるとそのバッファは解放されます.画像ポインタが0ではない場合,画像ピラミッドを計算し,指定のバッファにそれを格納します.ただし,フラグ ``CV_LKFLOWPyr_A[B]_READY`` が指定されている場合を除きます.また,これらの画像は,ガウシアンピラミッドのデータが入るのに十分な大きさが必要です.関数呼び出し後,両方の画像ピラミッドが計算され,次の関数呼び出しに備えて対応画像の準備完了フラグがセットされます(つまり,通常は,一番最初の関数呼び出し以外は, ``CV_LKFLOWPyr_A_READY`` が指定されています). .. index:: CamShift .. _CamShift: CamShift -------- `id=0.201791734751 Comments from the Wiki `__ .. function:: CamShift(prob_image,window,criteria)-> (int, comp, box) 物体の中心,サイズ,姿勢を求めます. :param prob_image: 物体のヒストグラムのバックプロジェクション( :ref:`CalcBackProject` を参照). :type prob_image: :class:`CvArr` :param window: 探索窓の初期状態. :type window: :class:`CvRect` :param criteria: 探索の停止基準. :type criteria: :class:`CvTermCriteria` :param comp: 結果として得られる構造体.最終的に収束した探索窓の座標(フィールド ``comp->rect`` ),および窓内の全ピクセル値の合計(フィールド ``comp->area`` )を含みます. :type comp: :class:`CvConnectedComp` :param box: オブジェクトに外接する矩形 :type box: :class:`CvBox2D` この関数は,CAMSHIFT 物体追跡アルゴリズム Bradski98 の実装です.まず, :ref:`MeanShift` を用いて物体中心を求め,次に,物体のサイズと姿勢を計算します.この関数は, :ref:`MeanShift` 内における反復数を返します. cv.hpp で宣言されている ``CamShiftTracker`` クラスは,この関数を利用したカラー物体追跡器の実装です. .. index:: CvKalman .. _CvKalman: CvKalman -------- `id=0.000962177013167 Comments from the Wiki `__ .. class:: CvKalman カルマンフィルタの状態構造体. .. attribute:: MP 観測ベクトルの次元数. .. attribute:: DP 状態ベクトルの次元数. .. attribute:: CP 制御ベクトルの次元数. .. attribute:: state_pre 状態の推定値 (x'(k)):x(k)=A*x(k-1)+B*u(k). .. attribute:: state_post 更新された状態の推定値 (x(k)): x(k)=x'(k)+K(k)*(z(k)-H*x'(k)). .. attribute:: transition_matrix システムの時間遷移に関する線形モデル (A). .. attribute:: control_matrix 制御行列 (B)(制御していない場合は,これは利用されません). .. attribute:: measurement_matrix 観測行列 (H). .. attribute:: process_noise_cov プロセスノイズ(時間遷移に関するノイズ)の共分散行列 (Q). .. attribute:: measurement_noise_cov 観測ノイズの共分散行列 (R). .. attribute:: error_cov_pre 今の時刻の誤差行列 (P'(k)): P'(k)=A*P(k-1)*At + Q. .. attribute:: gain 最適カルマンゲイン (K(k)): K(k)=P'(k)*Ht*inv(H*P'(k)*Ht+R). .. attribute:: error_cov_post 更新された誤差の共分散行列 (P(k)): P(k)=(I-K(k)*H)*P'(k). 構造体 ``CvKalman`` は,カルマンフィルタの状態を記憶しておくために利用されます.これは,関数 :ref:`CreateKalman` によって作成,関数 :ref:`KalmanPredict` と :ref:`KalmanCorrect` によって更新され ます.通常,この構造体は標準カルマンフィルタで利用されます(以下の表記法と式は,優れたカルマンフィルタのチュートリアルである :ref:`Welch95` から引用しました) .. math:: \begin{array}{l} x_k=A \cdot x_{k-1}+B \cdot u_k+w_k \\ z_k=H \cdot x_k+v_k \end{array} ここで, :math:`x_k (x_{k-1})` : 時刻 :math:`\emph{k} (\emph{k-1})` におけるシステムの状態, :math:`z_k` : 時刻 :math:`\emph{k}` における観測値, :math:`u_k` : 時刻 :math:`\emph{k}` における制御入力,を表します. また, :math:`w_k` と :math:`v_k` はそれぞれ,正規分布に従うプロセスノイズ,および観測ノイズです: .. math:: \begin{array}{l} p(w) \sim N(0,Q) \\ p(v) \sim N(0,R) \end{array} つまり, :math:`Q` プロセスノイズの共分散行列,定数あるいは変数, :math:`R` 観測ノイズの共分散行列,定数あるいは変数 標準カルマンフィルタの場合,全ての行列:A, B, H, Q, R は, :ref:`CreateKalman` によって構造体 :ref:`CvKalman` が確保された後で1度だけ初期化されます.しかし,拡張カルマンフィルタの式を現在のシステム状態周辺において線形化することで,拡張カルマンフィルタをシミュレートするために,同じ構造体と同じ関数が利用されることがあります.この場合,A, B, H (おそらく,Q と R も)毎ステップ更新されます. .. index:: CreateKalman .. _CreateKalman: CreateKalman ------------ `id=0.945207044614 Comments from the Wiki `__ .. function:: CreateKalman(dynam_params, measure_params, control_params=0) -> CvKalman カルマンフィルタの構造の領域を確保します. :param dynam_params: 状態ベクトルの次元数. :type dynam_params: int :param measure_params: 観測ベクトルの次元数. :type measure_params: int :param control_params: 制御ベクトルの次元数. :type control_params: int この関数は,構造体 :ref:`CvKalman` と,そのメンバであるすべての行列の領域を確保し,何らかの方法で初期化します. .. index:: KalmanCorrect .. _KalmanCorrect: KalmanCorrect ------------- `id=0.213196521493 Comments from the Wiki `__ .. function:: KalmanCorrect(kalman, measurement) -> cvmat モデルの状態を更新します. :param kalman: :ref:`CreateKalman` によって返されるカルマンフィルタオブジェクト. :type kalman: :class:`CvKalman` :param measurement: 観測ベクトルを含む CvMat. :type measurement: :class:`CvMat` この関数は,モデル状態に対する観測ベクトルが与えられると,それに基づき確率モデル状態を更新します: .. math:: \begin{array}{l} K_k=P'_k \cdot H^T \cdot (H \cdot P'_k \cdot H^T+R)^{-1} \\ x_k=x'_k+K_k \cdot (z_k-H \cdot x'_k) \\ P_k=(I-K_k \cdot H) \cdot P'_k \end{array} ここで .. table:: =========== ========================================================= :math:`z_k` 与えられた観測 ( ``mesurement`` パラメータ) \ =========== ========================================================= :math:`K_k` カルマン「ゲイン」行列 \ =========== ========================================================= です. この関数は,更新された状態を ``kalman->state_post`` に格納し,そのポインタを返します. .. index:: KalmanPredict .. _KalmanPredict: KalmanPredict ------------- `id=0.136651958243 Comments from the Wiki `__ .. function:: KalmanPredict(kalman, control=None) -> cvmat 次のモデル状態を推定します. :param kalman: :ref:`CreateKalman` によって返されるカルマンフィルタオブジェクト. :type kalman: :class:`CvKalman` :param control: 制御ベクトル :math:`u_k` , 制御入力が存在しない場合( ``control_params`` =0 )のみ NULL. :type control: :class:`CvMat` この関数は,現在の状態から次の確率モデル状態を推定し, ``kalman->state_pre`` に格納します: .. math:: \begin{array}{l} x'_k=A x_{k-1} + B u_k \\ P'_k=A P_{k-1} A^T + Q \end{array} ここで .. table:: =============== ========================================================================================================================================================================== :math:`x'_k` 状態の推定値 ``kalman->state_pre`` , \ =============== ========================================================================================================================================================================== :math:`x_{k-1}` 前回の更新された状態の推定値 ``kalman->state_post`` (最初は何らかの方法で初期化される,デフォルトではゼロベクトル), \ :math:`u_k` 制御入力 ( ``control`` パラメータ), \ :math:`P'_k` 今の時刻の誤差の共分散行列 ``kalman->error_cov_pre`` \ :math:`P_{k-1}` 前回の更新された誤差の共分散行列 ``kalman->error_cov_post`` (最初は何らかの方法で初期化される,デフォルトでは単位行列), =============== ========================================================================================================================================================================== この関数は,状態の推定値を返します. KalmanUpdateByMeasurement ------------------------- :ref:`KalmanCorrect` と同義 KalmanUpdateByTime ------------------ :ref:`KalmanPredict` と同義 .. index:: MeanShift .. _MeanShift: MeanShift --------- `id=0.274833303314 Comments from the Wiki `__ .. function:: MeanShift(prob_image,window,criteria)-> comp バックプロジェクション上の物体中心を求めます. :param prob_image: 物体のヒストグラムのバックプロジェクション( :ref:`CalcBackProject` を参照してください). :type prob_image: :class:`CvArr` :param window: 探索窓の初期状態. :type window: :class:`CvRect` :param criteria: 探索の停止基準. :type criteria: :class:`CvTermCriteria` :param comp: 結果として得られる構造体.最終的に収束した探索窓の座標(フィールド ``comp->rect`` ),および窓内の全ピクセル値の合計(フィールド ``comp->area`` )を含みます. :type comp: :class:`CvConnectedComp` この関数は,物体のバック工プロジェクションと探索窓の初期位置が与えられると,その物体の中心を求めるための反復計算を行います.反復計算は,探索窓中心の移動量が与えられた閾値より小さくなるか,あるいは関数の反復数が最大値に達するまで続けられます.また,この関数は,その反復数を返します. .. index:: SegmentMotion .. _SegmentMotion: SegmentMotion ------------- `id=0.885370428773 Comments from the Wiki `__ .. function:: SegmentMotion(mhi,seg_mask,storage,timestamp,seg_thresh)-> None モーション全体を個別のモーションに分解します. :param mhi: モーション履歴画像. :type mhi: :class:`CvArr` :param seg_mask: 検出されたマスクが保存される画像.シングルチャンネル,32ビット,浮動小数点型. :type seg_mask: :class:`CvArr` :param storage: モーション連結成分のシーケンスが保存されるメモリストレージ. :type storage: :class:`CvMemStorage` :param timestamp: ミリ秒単位,あるいは別の単位で表される現在時間. :type timestamp: float :param seg_thresh: 分割の閾値.モーション履歴の間隔と同じか,それよりも大きい値の方が良いでしょう. :type seg_thresh: float この関数は,すべてのモーション成分を検出し,それぞれ個別の値を用いて ``seg_mask`` にマークします.これは,各モーション成分毎に,構造体 :ref:`CvConnectedComp` のシーケンスを返します.その後,特定の成分を抽出するマスク :ref:`Cmp` を利用し, :ref:`CalcGlobalOrientation` によって全てのモーション成分のモーション方向が計算されます. .. index:: SnakeImage .. _SnakeImage: SnakeImage ---------- `id=0.502434420144 Comments from the Wiki `__ .. function:: SnakeImage(image,points,alpha,beta,gamma,win,criteria,calc_gradient=1)-> new_points そのエネルギーが最小となるように輪郭位置を変更します. :param image: 入力画像,あるいは外部エネルギー場. :type image: :class:`IplImage` :param points: 輪郭点 (snake). :type points: :class:`CvPoints` :param alpha: 連続エネルギーの重み.1つの浮動小数点数,あるいは浮動小数点数リスト.後者の場合,1つの要素が1つの輪郭点に対応します. :type alpha: sequence of float :param beta: 曲率エネルギーの重み. ``alpha`` と同様. :type beta: sequence of float :param gamma: 画像エネルギーの重み. ``alpha`` と同様. :type gamma: sequence of float :param win: 最小値探索に用いられる各輪郭点の近傍領域サイズ. ``win.width`` および ``win.height`` は奇数でなければいけません. :type win: :class:`CvSize` :param criteria: 停止基準. :type criteria: :class:`CvTermCriteria` :param calc_gradient: 勾配フラグ.0以外の場合,この関数は,各画像ピクセルに対する勾配の強さを計算し,それをエネルギー場として扱います.そうでない場合,入力画像はそのまま扱われます. :type calc_gradient: int この関数は,内部エネルギーと外部エネルギーの総和が最小になるように輪郭点を更新します.内部エネルギーは,輪郭形状に依存します(滑らかな輪郭ほど,内部エネルギーが小さくなります).また,外部エネルギーはエネルギー場に依存し,画像勾配を用いる場合は,画像エッジのようにエネルギーが極小値をとる場所において最小になります. パラメータ ``criteria.epsilon`` は,1回の計算で最低何個の輪郭点が移動すれば反復計算が継続されるか,を規定します. ある試行において,移動する輪郭点の個数が ``criteria.epsilon`` よりも少ないか,あるいは,関数の反復計算回数が  ``criteria.max_iter`` に達した場合,この関数は終了します. この関数は更新された輪郭点のリストを返します. .. index:: UpdateMotionHistory .. _UpdateMotionHistory: UpdateMotionHistory ------------------- `id=0.686499522406 Comments from the Wiki `__ .. function:: UpdateMotionHistory(silhouette,mhi,timestamp,duration)-> None 動作を表すシルエット画像を用いて,モーション履歴画像を更新します. :param silhouette: モーションが発生した場所が 0 以外のピクセル値をもつシルエットマスク. :type silhouette: :class:`CvArr` :param mhi: この関数によって更新される,モーション履歴画像(シングルチャンネル,32ビット浮動小数点型). :type mhi: :class:`CvArr` :param timestamp: ミリ秒単位,あるいは別の単位で表される現在時間. :type timestamp: float :param duration: ``timestamp`` と同じ単位で表される,モーションの最大持続時間. :type duration: float この関数は,モーション履歴画像を以下のように更新します: .. math:: \texttt{mhi} (x,y)= \forkthree{\texttt{timestamp}}{if $\texttt{silhouette}(x,y) \ne 0$}{0}{if $\texttt{silhouette}(x,y) = 0$ and $\texttt{mhi} < (\texttt{timestamp} - \texttt{duration})$}{\texttt{mhi}(x,y)}{otherwise} つまり,モーションが発生した場所のMHI(モーション履歴画像)ピクセルには,現在のタイムスタンプがセットされ,モーションが発生からある程度以上時間が経ったピクセルの値はクリアされます.