8

タイムスタンプ付きの座標(mm単位のX、Y、Z)の一連のCSVファイルがあります。それらからモーションデータを抽出する最も簡単な方法は何でしょうか?

測定可能なもの

抽出したい情報は次のとおりです。

  1. 方向転換の数
  2. 最初と最後の動きの初期加速
  3. ...そしてこれらの動きの方位(角度)
  4. 非定常時の平均速度

理想的には、最終的には動きのパターンを分類できるようにしたいので、これを行う方法を提案できる人にはボーナスポイントがあります。私がこれを行うことができる1つの方法は、座標からモーションの写真/ビデオを生成し、それらを分類するように人間に依頼することであると私は思います-これをどのように行うかについての提案は大歓迎です。

ノイズ

厄介なのは、測定値がノイズで汚染されているという事実です。これを克服するために、各録音の前に少なくとも20秒間の静止があり、これは一種の「ノイズプロファイル」として機能します。ただし、これを実装する方法はわかりません。

詳細

それが役立つ場合、記録される動きは、単純なつかみ作業中の人の手の動きです。データは、手首に取り付けられた磁気モーショントラッカーを使用して生成されます。また、私はC#を使用していますが、数学は言語に依存しないと思います。

編集

バウンティ

賞金については、いくつかの(擬似)コード例を実際に見てみたいと思います。

4

3 に答える 3

7

サンプルデータで何ができるか見てみましょう。

免責事項:私はあなたのハードウェア仕様を読んでいませんでした(tl; dr :))

便宜上、これをMathematicaで解決します。関連するアルゴリズム(多くはありません)がリンクとして提供されます。

最初の観察は、すべての測定値が時間的に等間隔に配置されていることです。これは、アプローチとアルゴリズムを単純化するのに最も便利です。「時間」または「ティック」(測定値)は、同等であるため、便宜上表現します。

まず、軸ごとに位置をプロットして、問題が何であるかを確認しましょう。

(* This is Mathematica code, don't mind, I am posting this only for 
   future reference *)
ListPlot[Transpose@(Take[p1[[All, 2 ;; 4]]][[1 ;;]]), 
 PlotRange -> All,
 AxesLabel -> {Style["Ticks", Medium, Bold], 
               Style["Position (X,Y,Z)", Medium, Bold]}]

ここに画像の説明を入力してください

さて、2つの観察:

  • あなたの動きはダニ1000あたりから始まります
  • あなたの動きは{0,0,0}から始まりません

したがって、ゼロ位置を減算し、ティック950から開始して、データをわずかに変換します。

ListLinePlot[
 Drop[Transpose@(x - Array[Mean@(x[[1 ;; 1000]]) &, Length@x]), {}, 950], 
 PlotRange -> All,
 AxesLabel -> {Style["Ticks", Medium, Bold], 
               Style["Position (X,Y,Z)", Medium, Bold]}]

ここに画像の説明を入力してください

曲線には計算を台無しにするのに十分なノイズがあるため、ガウスカーネルで畳み込み、ノイズを除去します。

kern = Table[Exp[-n^2/100]/Sqrt[2. Pi], {n, -10, 10}];
t = Take[p1[[All, 1]]];
x = Take[p1[[All, 2 ;; 4]]];

x1 = ListConvolve[kern, #] & /@ 
   Drop[Transpose@(x - Array[Mean@(x[[1 ;; 1000]]) &, Length@x]), {}, 
    950];

ここに画像の説明を入力してください

したがって、元の滑らかな軌道の下に表示されます。

ここに画像の説明を入力してください

ここに画像の説明を入力してください

これで、速度と加速度の導関数を取得する準備が整いました。一次導関数と二次導関数には4次近似を使用します。また、以前と同様に、ガウスカーネルを使用してそれらを平滑化します。

Vel = ListConvolve[kern, #] & /@ 
   Transpose@
    Table[Table[(-x1[[axis, i + 2]] + x1[[axis, i - 2]] - 
         8 x1[[axis, i - 1]] + 
         8 x1[[axis, i + 1]])/(12 (t[[i + 1]] - t[[i]])), {axis, 1, 3}], 
    {i, 3, Length[x1[[1]]] - 2}];

Acc = ListConvolve[kern, #] & /@ 
   Transpose@
    Table[Table[(-x1[[axis, i + 2]] - x1[[axis, i - 2]] + 
         16 x1[[axis, i - 1]] + 16 x1[[axis, i + 1]] - 
         30 x1[[axis, i]])/(12 (t[[i + 1]] - t[[i]])^2), {axis, 1,  3}], 
   {i, 3, Length[x1[[1]]] - 2}];

そして、それらをプロットします。

Show[ListLinePlot[Vel,PlotRange->All,
     AxesLabel->{Style["Ticks",Medium,Bold],
                 Style["Velocity (X,Y,Z)",Medium,Bold]}],
    ListPlot[Vel,PlotRange->All]]

Show[ListLinePlot[Acc,PlotRange->All,
     AxesLabel->{Style["Ticks",Medium,Bold],
                 Style["Acceleation (X,Y,Z)",Medium,Bold]}],
     ListPlot[Acc,PlotRange->All]]

ここに画像の説明を入力してください ここに画像の説明を入力してください

これで、速度と加速係数もわかります。

ListLinePlot[Norm /@ (Transpose@Vel), 
 AxesLabel -> {Style["Ticks", Medium, Bold], 
               Style["Speed Module", Medium, Bold]}, 
 Filling -> Axis]
ListLinePlot[Norm /@ (Transpose@Acc), 
 AxesLabel -> {Style["Ticks", Medium, Bold], 
               Style["Acceleration Module", Medium, Bold]},
 Filling -> Axis]       

ここに画像の説明を入力してください ここに画像の説明を入力してください

そして、速度の方向としての見出し:

Show[Graphics3D[
 {Line@(Normalize/@(Transpose@Vel)),
 Opacity[.7],Sphere[{0,0,0},.7]},
 Epilog->Inset[Framed[Style["Heading",20],
        Background->LightYellow],{Right,Bottom},{Right,Bottom}]]]

ここに画像の説明を入力してください

始めるにはこれで十分だと思います。特定のパラメータの計算についてサポートが必要な場合はお知らせください。

HTH!

編集

例として、手が静止していないときの平均速度を計算するとします。したがって、速度がカットオフを超えるすべてのポイント、たとえば5を選択し、平均を計算します。

Mean@Select[Norm /@ (Transpose@Vel), # > 5 &]
-> 148.085

その大きさの単位は時間の単位によって異なりますが、どこにも指定されていません。

カットオフ速度は「直感的」ではないことに注意してください。平均速度とカットオフ速度をプロットすることにより、適切な値を検索できます。

ListLinePlot[
 Table[Mean@Select[Norm /@ (Transpose@Vel), # > h &], {h, 1, 30}], 
 AxesLabel -> {Style["Cutoff Speed", Medium, Bold], 
               Style["Mean Speed", Medium, Bold]}]

ここに画像の説明を入力してください

したがって、5が適切な値であることがわかります。

于 2011-05-30T00:40:47.247 に答える
1

ソリューションは、各状態が方向を表すステートマシンのように単純である可能性があります。一連の動きは、一連の方向によって表されます。このアプローチは、センサーの向きが動きに対して変化しない場合にのみ機能します。そうでない場合は、方向のシーケンスを計算する前に、動きを正しい方向に変換する方法が必要になります。

一方で、さまざまなAI技術を使用することもできますが、使用するのは私を超えています。

任意の2つの座標間の速度を取得するには:

               _________________________________
Avg Speed =   /(x2-x1)^2 + (y2-y1)^2 + (z2-z1)^2
            --------------------------------------
                 (t2-t1)

モーション全体の平均速度を取得するには、たとえば100個のタイムスタンプ付き座標がある場合、上記の式を使用して99個の速度値を計算します。次に、すべての速度を合計し、速度の数で除算します(99)

加速度を取得するには、3つの瞬間の位置、または2つの瞬間の速度が必要です。

Accel X = (x3 - 2*x + x1) / (t3 - t2)
Accel Y = (y3 - 2*y + y1) / (t3 - t2)
Accel Z = (z3 - 2*z + z1) / (t3 - t2)
于 2011-05-21T16:32:53.027 に答える
0

注:これはすべて、軸ごとの計算を前提としています。2軸の粒子運動の経験はありません。

最初に位置測定値を速度測定値に変換すると、これを使用する時間がはるかに簡単になります。

最初のステップ:ノイズを取り除きます。あなたが言ったように、各録音は20秒の静止で始まります。したがって、実際の測定値を見つけるには、位置が変わらない20秒間隔を検索します。その後、直後に測定してください。

2番目のステップ:(x2-x1)/(t2-t1);を使用して速度を計算します。勾配式。間隔は、録音の間隔と一致する必要があります。

計算:

方向転換:

加速度がゼロの場所で方向転換が発生します。これらの時間を見つけるために数値積分を使用してください。0から積分の結果がゼロになるまで積分します。今回は録音してください。次に、前回からゼロになるまで積分します。データの最後に到達するまで繰り返します。

初期加速:

これらは、の代わりvに勾配式を使用して検出されxます。

平均速度:

平均速度の式は勾配の式です。x1とt1は最初の読み取り値に対応し、x2とt2は最後の読み取り値に対応する必要があります。

于 2011-05-21T17:01:26.907 に答える