WedX - журнал о программировании и компьютерных науках

Рассчитать BPM на основе данных сенсора Kinect

Я изо всех сил пытаюсь с Kinect для Windows SDK создать приложение для проведения (с С#).

В основном мне нужно отслеживать одну руку (обычно правую) дирижера и распознавать его скорость в направлении (BPM), чтобы отправить это значение в другое приложение через MIDI.

Я начал с того, что SkeletonFramesReadyEvent добавил JointType.HandRight с отметкой времени DateTime.Now.Ticks в историю List, которая обновляется и удаляет первую запись. Храню историю 60 кадров (2 секунды).

Я рассчитываю BPM, ища последний минимум и максимум Joint.Position.Y, а затем вычисляю разницу и делю bpm = 60*ticksPerSecond/diff. Однако результат неверный. Есть ли другой способ сделать это? Что мне не хватает?

Это то, что я использую до сих пор:

public int DetectBPM(JointType type)
{
    // we have not history yet
    if (!HasHistory()) return 0;

    // only calculate every second
    var detectTime = DateTime.Now.Second;
    if (_lastBPM != 0 && _lastBPMDectect == detectTime) return _lastBPM;

    // search last high/low boundaries
    var index = (int) type;
    var list = History[index];
    var i = list.Count - 1;

    var lastHigh = list[i];
    var lastLow = list[i];

    // shift to last peak first
    while (i > 0 && list[i].Joint.Position.Y >= list[i - 1].Joint.Position.Y) i--;

    // find last low
    while (i >= 0 && lastLow.Joint.Position.Y >= list[i].Joint.Position.Y) lastLow = list[i--];

    // find last high
    while (i >= 0 && lastHigh.Joint.Position.Y <= list[i].Joint.Position.Y) lastHigh = list[i--];

    var ticks = lastLow.Timestamp - lastHigh.Timestamp;
    var elapsedTime = new TimeSpan(ticks);

    var bpm = (int) (60000/elapsedTime.TotalMilliseconds);

    Console.WriteLine("DEBUG: BPM = " + _lastBPM + ", elapsedMS: " + elapsedTime.TotalMilliseconds);

    _lastBPMDectect = detectTime;
    _lastBPM = bpm;

    return _lastBPM;
}

  • Какой результат вы получаете и на какой результат рассчитываете? 29.06.2012
  • DEBUG: BPM = 512, elapsedMS: 328 DEBUG: BPM = 182, elapsedMS: -322 DEBUG: BPM = -186, elapsedMS: -337 DEBUG: BPM = -178, elapsedMS: 299 DEBUG: BPM = 200, elapsedMS: 683 DEBUG : BPM = 87, прошедшее MS: -378 ОТЛАДКА: BPM = -158, прошедшее MS: 92 29.06.2012
  • Во-первых, вам, вероятно, следует использовать Math.Abs() для разницы в расчете ticks (это будет учитывать отрицательные значения). Согласно документации Timestamp указывается в миллисекундах, а не в тиках, поэтому используйте TimeSpan.FromMilliseconds(ticks) вместо new TimeSpan(ticks) (возможно, также переименуйте ticks) 29.06.2012
  • Если я вычту более старую отметку времени из более молодой, отрицательное значение не должно появиться. Во-вторых, Timestamp находится в тиках — это мой собственный класс, который содержит Joint с Timestamp в тиках. Так что это не решает мою проблему. 30.06.2012
  • Приношу свои извинения за галочки, ваш вопрос помечен как kinect, поэтому предполагается, что применяются документы kinect sdk. 30.06.2012
  • Можете ли вы добавить пример графика ваших данных истории с течением времени? 05.07.2012
  • Ну, поэтому мне нужно сначала выяснить, как отображать данные с помощью С#. 05.07.2012
  • Просто выведите свои данные в файл в формате CSV и отобразите их в Excel... 05.07.2012
  • Вы находите число ударов в минуту человека с помощью жеста? 05.07.2012
  • В яблочко. В основном человек делает типичный жест вверх-вниз одной рукой. Я хочу - в самой простой версии - отслеживать время между двумя нижними точками его / ее руки, которые представляют собой удар. С разницей во времени между двумя ударами я должен быть в состоянии рассчитать BPM. 05.07.2012

Ответы:


1

Я понял, как это сделать. Я упустил момент и рассчитал BPM между пиковым и нижним положением руки, что неверно. Я должен вычислить разницу во времени между двумя последними низкими точками, чтобы получить правильный результат.

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

Принцип показан на рисунке ниже

Схема расчета BPM

И это приводит к красивому BPM, рассчитанному следующим образом:

var ticks = Math.Abs(firstLow.Ticks - secondLow.Ticks);
var elapsedTime = new TimeSpan(ticks);

var bpm = (int) (60000/elapsedTime.TotalMilliseconds);

Спасибо за участие в любом случае.

05.07.2012
  • Если ваши данные зашумлены, обнаружение минимумов будет подозрительным. Вы вполне можете получить локальные минимумы с разницей всего в один тик. Вот почему я говорю, что вам, вероятно, нужно сгладить ваши данные (возможно, Kinect сглаживает их для вас, но, не видя графика данных, трудно сказать). Также весьма вероятно, что с легким шумом то, что у вас есть, будет работать большую часть времени, а затем выйдет из строя. 06.07.2012
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]