реклама на сайте
подробности

 
 
> вычисление медианы массива (или произвольной моды), stm32f4 + STL
klen
сообщение Jul 28 2013, 16:50
Сообщение #1


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



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

1. Итак, была проблема со съемом сигнала с потенциометра "крутилка рукой"- заказчик не захотел энкодеры ;( . в силу независящих от меня причин оказалось на резистеоре определенное количество шума в виде импульсных выбросов. попросили их "вырезать". проц - STM32F405RGT 168MHz
2. После анализа хар-к помехи пришла мысль выдернуть ее медианным фильтром.
3. дока по быстрому вычислению мод масивом прилагается http://klen.org/Files/Dosc/math/median.pdf
4. Как всегда захотелось решить задачу в общем виде. поэтому был пременен код STL в реализации GCC 4.9.0.
был нарисован шаблонный класс который реализует фифо и вычисляет текущую медиану, оформлено в виде заголовка С++:

CODE
/*
* moda.h
*
* Created on: 24 июля 2013 г.
* Author: klen
* URL: klen.org
*/

#ifndef __MODA_H__
#define __MODA_H__


#include <vector>
#include <algorithm>

//---------------------------------------------------------------------------------------------
template <typename T> class TModaFilterContainer
{
private:
protected:
public:

std::vector<T> vals; // входная последовательность
std::vector<T> gist; // копия входной последовательности для сортировки и поиска моды

TModaFilterContainer () {};
TModaFilterContainer (size_t size) { vals.resize(size); };
~TModaFilterContainer() {};
void Add(T val) {vals.push_front(val); }
void Remove () {vals.pop_back(); }
void Clear() { vals.clear(); }
void Resize(size_t size) {vals.resize(size); }
void Update(T val) { vals.pop_back(); vals.insert(vals.begin(), val); }
};

//---------------------------------------------------------------------------
template <typename T> class TMedianFilterSort : public TModaFilterContainer<T>
{
public:
TMedianFilterSort():TModaFilterContainer<T>() {};
TMedianFilterSort(size_t size):TModaFilterContainer<T>(size) {};
~TMedianFilterSort() {};

T Find()
{
this->gist = this->vals;
div_t divresult;
divresult = div( this->gist.size() , 2 );
size_t n = divresult.quot;
sort(this->gist.begin(), this->gist.end());
if ( divresult.rem )
return this->vals[n];
else
return (this->vals[n-1] + this->vals[n]) / static_cast<T>(2);
}

};
//--------------------------------------------------------------------------
template <typename T> class TMedianFilterNth : public TModaFilterContainer<T>
{
public:
TMedianFilterNth():TModaFilterContainer<T>() {};
TMedianFilterNth(size_t size):TModaFilterContainer<T>(size) {};
~TMedianFilterNth() {};

T Find()
{
this->gist = this->vals;
size_t n = this->gist.size() / 2;
nth_element(this->gist.begin(), this->gist.begin() + n, this->gist.end());
return this->gist[n];
}
};

// EXAMPLE
#if 0

#include "median.h"

typedef TMedianFilterNth<int16_t> median_t;
volatile int16_t mediana;


median_t m(8);

mediana = m.Find();

m.Update(8);
mediana = m.Find();
m.Update(9);
mediana = m.Find();
m.Update(10);
mediana = m.Find();
m.Update(8);
mediana = m.Find();
m.Update(10);
mediana = m.Find();
m.Update(11);
mediana = m.Find();
m.Update(0);
mediana = m.Find();
m.Update(1);
mediana = m.Find();
m.Update(2);
mediana = m.Find();
m.Clear();

// результат работы:

0 0 0 0 0 0 0 0
mediana:0
8 0 0 0 0 0 0 0
mediana:0
9 8 0 0 0 0 0 0
mediana:0
10 9 8 0 0 0 0 0
mediana:0
8 10 9 8 0 0 0 0
mediana:8
10 8 10 9 8 0 0 0
mediana:8
11 10 8 10 9 8 0 0
mediana:9
0 11 10 8 10 9 8 0
mediana:9
1 0 11 10 8 10 9 8
mediana:9
2 1 0 11 10 8 10 9
mediana:9

#endif


#endif /* __MODA_H__ */



результаты по быстродействию при спецификации шаблона типом uint16_t на STM32F405RGT 168MHz :
Код
размер буфера                                    добавления элемента в фифо+ вычисление медианы(максимальное значение)
4                                                                                             4,2мкс
16                                                                                             10мкс
32                                                                                            16мкс
128                                                                                           56мкс

размер кода потянутого шаблонами и алгоритмами ( класс vector + алгоритм thh ) ~1100 байт

5. можно вектор заменить на двухсвязанную очередь deque - по идее должно работать быстрее при добавлении елемента. можно ручками чтоб ваще быстро было - но это время разработки!
6. компилял компиллером из своей сборки http://electronix.ru/forum/index.php?showt...0&start=870
7. это должно работать на любом вменяемом С++ компиллере и наличии стандартной библиотеки шаблонов STL

надюсь с пользой запостил.

Сообщение отредактировал IgorKossak - Aug 1 2013, 06:36
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- klen   вычисление медианы массива (или произвольной моды)   Jul 28 2013, 16:50
- - Xenia   Плохой алгоритм - через полную сортировку медиану ...   Jul 28 2013, 18:33
|- - klen   Цитата(Xenia @ Jul 28 2013, 22:33) Плохой...   Jul 28 2013, 21:12
||- - Xenia   Цитата(klen @ Jul 29 2013, 01:12) я сог...   Jul 28 2013, 21:36
||- - klen   Цитата(Xenia @ Jul 29 2013, 01:36) Было б...   Jul 28 2013, 22:09
||- - demiurg_spb   А вот мой боевой вариант для uint16_t данных. Кодs...   Jul 29 2013, 06:58
|- - neiver   Цитата(Xenia @ Jul 28 2013, 22:33) Плохой...   Jul 30 2013, 13:15
|- - AlexandrY   Цитата(Xenia @ Jul 28 2013, 21:33) P.P.S....   Jul 30 2013, 16:03
|- - Xenia   Цитата(AlexandrY @ Jul 30 2013, 20:03) Вы...   Jul 30 2013, 16:35
|- - demiurg_spb   Цитата(Xenia @ Jul 30 2013, 20:35) Обычно...   Jul 31 2013, 07:25
|- - Tanya   Цитата(demiurg_spb @ Jul 31 2013, 11:25) ...   Jul 31 2013, 08:41
||- - demiurg_spb   Цитата(Tanya @ Jul 31 2013, 12:41) Кроме ...   Jul 31 2013, 10:07
||- - Tanya   Цитата(demiurg_spb @ Jul 31 2013, 14:07) ...   Jul 31 2013, 10:59
||- - demiurg_spb   Цитата(Tanya @ Jul 31 2013, 14:59) Не все...   Jul 31 2013, 11:06
||- - Tanya   Цитата(demiurg_spb @ Jul 31 2013, 15:06) ...   Jul 31 2013, 12:06
||- - Axel   Цитата(Tanya @ Jul 31 2013, 15:06) Недост...   Jul 31 2013, 12:30
|- - Xenia   Цитата(demiurg_spb @ Jul 31 2013, 11:25) ...   Jul 31 2013, 11:50
- - AlexandrY   Цитата(klen @ Jul 28 2013, 19:50) результ...   Jul 28 2013, 19:01
- - Forger   Я для таких целей использую фильтр - скользящее ср...   Jul 28 2013, 19:49
|- - AlexandrY   Цитата(Forger @ Jul 28 2013, 22:49) Я для...   Jul 28 2013, 20:29
- - Golikov A.   а как насчет экспоненциального фильтра? Быстрый, б...   Jul 29 2013, 13:29
- - RabidRabbit   По моему личному представлению всяческие скользящи...   Jul 29 2013, 14:18
- - neiver   Ура мерение длинной скоростью кода!!! ...   Jul 30 2013, 07:02
- - Altemir   Добавлю свои 5 копеек. Со времён LPC2132 использую...   Jul 30 2013, 11:43
- - Axel   Мне тоже стало интересно... Попробовал фильтр Ekst...   Jul 31 2013, 05:02
- - KRS   А ведь если фильтр скользящий, на этапе добавление...   Jul 31 2013, 11:22
|- - demiurg_spb   Цитата(KRS @ Jul 31 2013, 15:22) А ведь е...   Jul 31 2013, 14:10
- - AlexandrY   Ну что, пришло время подвести некоторые итоги. ...   Jul 31 2013, 13:14
|- - KRS   Цитата(AlexandrY @ Jul 31 2013, 17:14) Ка...   Jul 31 2013, 14:19
|- - demiurg_spb   Цитата(KRS @ Jul 31 2013, 18:19) Но как в...   Jul 31 2013, 14:28
|- - Tanya   Цитата(KRS @ Jul 31 2013, 18:19) Но как в...   Jul 31 2013, 16:04
|- - AlexandrY   Цитата(Tanya @ Jul 31 2013, 19:04) ...   Aug 1 2013, 07:45
|- - Tanya   Цитата(AlexandrY @ Aug 1 2013, 11:45) Гов...   Aug 1 2013, 08:13
|- - AlexandrY   Цитата(Tanya @ Aug 1 2013, 11:13) Какой и...   Aug 1 2013, 09:09
|- - demiurg_spb   Ещё можно попробовать сортировать пузырём, но не в...   Aug 1 2013, 09:17
|- - Tanya   Цитата(AlexandrY @ Aug 1 2013, 13:09) Мы ...   Aug 1 2013, 09:44
||- - AlexandrY   Цитата(Tanya @ Aug 1 2013, 12:44) Может.....   Aug 1 2013, 10:23
|- - neiver   Цитата(AlexandrY @ Aug 1 2013, 13:09) Алг...   Aug 1 2013, 10:20
||- - AlexandrY   Цитата(neiver @ Aug 1 2013, 13:20) Кстати...   Aug 1 2013, 10:54
||- - Altemir   Цитата(AlexandrY @ Aug 1 2013, 14:54) Да,...   Aug 1 2013, 11:09
||- - AlexandrY   Цитата(Altemir @ Aug 1 2013, 14:09) Упс. ...   Aug 1 2013, 11:22
|- - Altemir   AlexandrY Могу скромно попросить на той же платфор...   Aug 1 2013, 10:36
- - Altemir   AlexandrY "Number of samplles" - это дли...   Jul 31 2013, 14:03
|- - AlexandrY   Цитата(Altemir @ Jul 31 2013, 17:03) Alex...   Jul 31 2013, 14:10
- - KRS   Для определенных измерений его еще можно улучшить,...   Jul 31 2013, 14:37
- - Altemir   AlexandrY Огромное спасибо! Как и ожидал - у м...   Aug 1 2013, 11:24
- - VAI   Я опоздал, все результаты посчитаны, да и алгоритм...   Aug 1 2013, 18:45
|- - AlexandrY   Цитата(VAI @ Aug 1 2013, 21:45) ... и выл...   Aug 5 2013, 08:18
- - VAI   Херовый у меня алгоритм.. :-(   Aug 5 2013, 11:59
- - p_v   Тема старая, но очень годная. Спасибо за тесты, оч...   Aug 1 2018, 16:07
- - p_v   https://pastebin.com/xpLbyWN6 - двухпроходный вари...   Aug 3 2018, 15:16


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 02:17
Рейтинг@Mail.ru


Страница сгенерированна за 0.01519 секунд с 7
ELECTRONIX ©2004-2016