2012-06-01 2 views
0

Я столкнулся с проблемой и хотел попросить ваши предложения.Обнаружение подъемов в массиве. (плотность значений)

Я кодирую в c/C++, и у меня есть массив, как показано ниже.

A[40]={0,0,1,0,2,7,18,45,80,85,88,91,88,65,12,3,0,1,0,2,1,2,5,45,88,89,78,79,65,12,5,2,1,0,0,1,0,0,1} 

Как вы можете видеть, есть 2 подъема, которые мы также можем назвать их кривыми. Этот массив сохраняет значение сигнала в реальном времени относительно времени. Он работает как очередь и обновляется для каждого нового значения.

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

Мой вопрос: как я могу определить эти кривые и сказать, что в массиве A есть 2 кривых?

Знаете ли вы какой-либо хороший способ их обнаружения когерентно? Или есть способ или что-то для обработки такого рода сигналов?

Мне действительно нужен ответ для продвижения по моему проекту, поэтому все ваши ответы приветствуются. Заранее спасибо.

+0

Возможно, вы захотите взглянуть на нечто вроде БПФ. Если данные чистые и простые, вы можете просто искать точки перегиба (т. Е. Изменение знака в градиенте). – Flexo

+0

вы можете сделать что-то более простое, чем БПФ - попробуйте передвигающееся окно, чтобы определить, «вы поднимаетесь» или «бросаете», сравнивая последние значения N с предыдущими значениями N или что-то в этом роде. пока капли/подъемы более или менее одно в одном направлении, вы можете легко их подсчитать. –

+0

Другая альтернатива - сглаживание кривой, а затем поиск локальных максимумов. Сглаживание поможет избежать появления локальных максимумов в виде пиков. –

ответ

2

Вы можете определить пики в вашем данном пути поиска точек, где знак переворачивает при сравнении соседних значений:

#include <vector> 
#include <algorithm> 
#include <iterator> 
#include <iostream> 

namespace { 
    int diff(const int& a, const int& b) { 
    if (b-a > 0) 
     return 1; 
    else if (b-a < 0) 
     return -1; 
    return 0; 
    } 
} 

int main() { 
    const int A[]={0,0,1,0,2,7,18,45,80,85,88,91,88,65,12,3,0,1,0,2,1,2,5,45,88,89,78,79,65,12,5,2,1,0,0,1,0,0,1}; 
    std::vector<int> delta; 
    std::transform(A, A+((sizeof A/sizeof *A) - 1), A+1, std::back_inserter(delta), diff); 
    for (std::vector<int>::const_iterator it = ++delta.begin(); it != delta.end(); ++it) { 
    if (*it < 0 && *it != *(it - 1)) 
     std::cout << "Peak at: " << A[it-delta.begin()] << "\n"; 
    } 
} 

Обратите внимание, что вы на самом деле имеете более двух пиков в ваших данных:

 
Peak at: 1 
Peak at: 91 
Peak at: 1 
Peak at: 2 
Peak at: 89 
Peak at: 79 
Peak at: 1 

Если они на самом деле не только пики (шум в данных), то вы можете исправить это в несколько способов:

  1. Квантование данных.
  2. Сглаживание - т. Е. Изменить каждое значение, чтобы как-то быть похожим на его соседей.
  3. Порог. Запишите не только знак, но и величину. Игнорировать изменения меньше определенного размера.
+1

Во-первых, спасибо за вашу работу, это так ясно. фрагмент кода, который вы написали выше, находит значения, которые больше, чем его соседи. Таким образом, может быть много пиков, хотя число кривых равно 2. (Я называю это кривой, я думаю, вы получаете то, что я хочу сказать, значительный рост и его падение). Я попробую 3. путь, порог, чтобы игнорировать небольшие капли, пока соседи поднимаются. Еще раз спасибо. – Horizon1710

Смежные вопросы