Извлечение данных движения из списка координат - PullRequest
8 голосов
/ 21 мая 2011

У меня есть серия CSV-файлов с метками времени (X, Y и Z в мм). Какой самый простой способ извлечь из них данные о движении?

Measurables

Информация, которую я хотел бы извлечь, включает следующее:

  1. Количество смен направления
  2. Начальное ускорение первого и последнего движения
  3. ... и направление (угол) этих движений
  4. Средняя скорость при нестационарном

В идеале, я бы в конечном итоге хотел бы иметь возможность классифицировать модели движения, так что бонусные баллы для тех, кто может предложить способ сделать это. Меня поражает, что один из способов, которым я мог бы это сделать, - это сгенерировать изображения / видео о движении по координатам и попросить людей классифицировать их - предложения о том, как я это сделаю, очень приветствуются.

Шум

Сложность заключается в том, что показания загрязнены шумом. Чтобы преодолеть это, каждой записи предшествует по меньшей мере 20 секунд неподвижности, которая может служить своего рода «шумовым профилем». Я не уверен, как это реализовать.

Особенности

Если это помогает, записывается движение руки человека во время простого захвата. Данные генерируются с помощью магнитного трекера, прикрепленного к запястью. Кроме того, я использую C #, но, думаю, математика не зависит от языка.

Редактирование

Bounty

Для награды я бы очень хотел увидеть некоторые (псевдо) примеры кода.

Ответы [ 3 ]

6 голосов
/ 30 мая 2011

Давайте посмотрим, что можно сделать с данными вашего примера.

Отказ от ответственности: я не читал ваши спецификации оборудования (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

Поскольку кривые имеют достаточный шум, чтобы испортить вычисления, мы свернем его с Гауссовым ядром , чтобы понизить шум:

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

Теперь мы готовы принять производные для скорости и ускорения. Мы будем использовать аппроксиманты четвертого порядка для первой и второй производных. Мы также сгладим их, используя ядро ​​Гаусса, как и раньше:

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

Я думаю, этого достаточно, чтобы вы начали. дайте мне знать, если вам нужна помощь в расчете определенного параметра.

НТН!

Редактировать

В качестве примера предположим, что вы хотите вычислить среднюю скорость, когда рука не находится в покое. Итак, мы выбираем все точки, скорость которых больше, чем отсечка, например, 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 голос
/ 21 мая 2011

е решение может быть таким же простым, как конечный автомат, где каждое состояние представляет направление.Последовательности движений представлены последовательностями направлений.Этот подход будет работать только в том случае, если ориентация датчика не изменяется относительно движений, в противном случае вам потребуется метод перевода движений в правильную ориентацию, прежде чем вычислять последовательности направлений.

Вкл.с другой стороны, вы могли бы использовать различные техники ИИ, хотя то, что вы бы использовали, мне не подходит.

Чтобы получить скорость между любыми двумя координатами:

               _________________________________
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)
0 голосов
/ 21 мая 2011

Примечание: Все это предполагает расчеты по осям: у меня нет опыта движения двухосных частиц.

Вам будет намного легче с этим, если вы сначала преобразуете свои измерения положения в измерения скорости.

Первый шаг: убрать шум. Как вы сказали, каждой записи предшествует 20 секунд неподвижности. Итак, чтобы найти фактические измерения, ищите 20-секундные интервалы, где положение не меняется. Затем выполните измерение сразу после.

Второй шаг: рассчитать скорости, используя: (x2 - x1) / (t2 - t1); формула наклона. Интервал должен соответствовать интервалу записей.

Расчеты:

Изменение направления:

Изменение направления происходит, когда ускорение равно нулю. Используйте числовую интеграцию, чтобы найти это время. Интегрируйте от 0 до того времени, когда результат интегрирования будет равен нулю. Запишите это время. Затем интегрируйте с предыдущего раза, пока не получите ноль снова. Повторяйте, пока не дойдете до конца данных.

Начальные ускорения:

Их снова можно найти по формуле наклона, заменив v на x.

Средняя скорость:

Формула средней скорости - это формула наклона. x1 и t1 должны соответствовать первому чтению, а x2 и t2 должны соответствовать окончательному чтению.

...