从坐标列表中提取运动数据

时间:2011-05-21 16:23:10

标签: c# language-agnostic coordinates motion categorization

我有一系列带时间戳坐标的CSV文件(X,Y和Z,单位为mm)。从中提取运动数据的最简单方法是什么?

可测

我想提取的信息包括以下内容:

  1. 方向更改次数
  2. 第一次和最后一次动作的初始加速
  3. ......以及这些运动的方位(角度)
  4. 非静止时的平均速度
  5. 理想情况下,我最终希望能够对运动模式进行分类,因此任何能够提出这种方法的人都可以获得奖励积分。令我感到震惊的是,我能做到这一点的一种方法是从坐标生成动画的图片/视频,并要求人们对它们进行分类 - 我非常欢迎这样做的建议。

    噪声

    一个复杂因素是读数受到噪音的污染。为了克服这一点,每个记录前面都有至少20秒的静止,这可以作为一种“噪声分布”。我不知道如何实现这一点。

    具体细节

    如果有帮助,正在记录的动作是在简单抓取任务期间的人手。使用连接到手腕的磁性运动跟踪器生成数据。另外,我正在使用C#,但我猜数学与语言无关。

    编辑

    恩惠

    对于赏金,我真的很想看到一些(伪)代码示例。

3 个答案:

答案 0 :(得分:6)

让我们看看您的示例数据可以做些什么。

免责声明:我没有阅读您的硬件规格(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]}]

enter image description here

现在,有两点意见:

  • 你的动作开始于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]}]

enter image description here

由于曲线有足够的噪音来破坏计算,我们会用Gaussian Kernel对其进行卷积以对其进行去噪:

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];

enter image description here

所以你可以在下面看到原始和平滑的轨迹:

enter image description here

enter image description here

现在我们已准备好将衍生物用于速度和加速度。我们将使用fourth order approximants作为第一个和第二个导数。我们也将使用高斯内核来平滑它们,如前所述:

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]]

enter image description here enter image description here

现在,我们还有速度和加速度模数:

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]       

enter image description here enter image description here

和标题,作为速度的方向:

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}]]]

enter image description here

我认为这足以让你入门。如果您在计算特定参数时需要帮助,请告诉我。

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]}]

enter image description here

所以你看到5是一个合适的值。

答案 1 :(得分:1)

解决方案可以像状态机一样简单,其中每个状态代表一个方向。运动序列由方向序列表示。只有当传感器的方向相对于运动没有变化时,这种方法才有效,否则在计算方向序列之前,您需要一种将运动转换为正确方向的方法。

另一方面,你可以使用各种人工智能技术,虽然你使用的正是我的。

要获得任意两个坐标之间的速度:

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

要获得整个运动的平均速度,假设您有100个带时间戳的坐标,请使用上面的等式计算99个速度值。然后将所有速度相加,并除以速度数(99)

要获得加速度,需要三个时刻的位置,或两个时刻的速度。

Accel X = (x3 - 2*x + x1) / (t3 - t2)
Accel Y = (y3 - 2*y + y1) / (t3 - t2)
Accel Z = (z3 - 2*z + z1) / (t3 - t2)

答案 2 :(得分:0)

注意:这都假设每轴计算:我没有双轴粒子运动的经验。

如果您首先将位置测量值转换为速度测量值,则可以更轻松地完成此操作。

第一步:消除噪音。如你所说,每张录音都以20秒的静止为前提。因此,要查找实际测量值,请搜索位置不变的20秒间隔。然后,直接进行测量。

第二步:使用:(x2-x1)/(t2-t1)计算速度;坡度公式。间隔应与录制的间隔相匹配。

<强>计算:

方向改变:

加速度为零时发生方向变化。使用数字积分查找这些时间。从0积分到积分结果为零的时间。记录这一次。然后,从前一次整合,直到你再次归零。重复,直到你到达数据的末尾。

初步加速:

再次使用斜率公式找到它们,用v代替x

平均速度:

平均速度公式是斜率公式。 x1和t1应对应于第一个读数,x2和t2应对应于最终读数。