diff options
Diffstat (limited to 'ftnoir_filter_ewma2')
| -rw-r--r-- | ftnoir_filter_ewma2/ftnoir_ewma_filtercontrols.ui | 372 | ||||
| -rw-r--r-- | ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp | 81 | ||||
| -rw-r--r-- | ftnoir_filter_ewma2/ftnoir_filter_ewma2.h | 66 | ||||
| -rw-r--r-- | ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp | 43 |
4 files changed, 0 insertions, 562 deletions
diff --git a/ftnoir_filter_ewma2/ftnoir_ewma_filtercontrols.ui b/ftnoir_filter_ewma2/ftnoir_ewma_filtercontrols.ui deleted file mode 100644 index 9387f0d5..00000000 --- a/ftnoir_filter_ewma2/ftnoir_ewma_filtercontrols.ui +++ /dev/null @@ -1,372 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<ui version="4.0"> - <class>UICFilterControls</class> - <widget class="QWidget" name="UICFilterControls"> - <property name="windowModality"> - <enum>Qt::NonModal</enum> - </property> - <property name="geometry"> - <rect> - <x>0</x> - <y>0</y> - <width>448</width> - <height>380</height> - </rect> - </property> - <property name="windowTitle"> - <string>EWMA2 filter settings</string> - </property> - <property name="windowIcon"> - <iconset resource="ewma-filter.qrc"> - <normaloff>:/images/filter-16.png</normaloff>:/images/filter-16.png</iconset> - </property> - <property name="layoutDirection"> - <enum>Qt::LeftToRight</enum> - </property> - <property name="autoFillBackground"> - <bool>false</bool> - </property> - <property name="styleSheet"> - <string notr="true"/> - </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QFrame" name="frame"> - <layout class="QGridLayout" name="gridLayout_2"> - <property name="topMargin"> - <number>2</number> - </property> - <property name="bottomMargin"> - <number>2</number> - </property> - <item row="0" column="0"> - <widget class="QLabel" name="lblInvert1_6"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="styleSheet"> - <string notr="true"/> - </property> - <property name="text"> - <string>Min</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QSlider" name="minSmooth"> - <property name="sizePolicy"> - <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimum"> - <number>1</number> - </property> - <property name="maximum"> - <number>100</number> - </property> - <property name="pageStep"> - <number>5</number> - </property> - <property name="value"> - <number>2</number> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="tickPosition"> - <enum>QSlider::NoTicks</enum> - </property> - </widget> - </item> - <item row="0" column="2"> - <widget class="QSpinBox" name="spinMinSmooth"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="styleSheet"> - <string notr="true">background:none;</string> - </property> - <property name="readOnly"> - <bool>true</bool> - </property> - <property name="buttonSymbols"> - <enum>QAbstractSpinBox::PlusMinus</enum> - </property> - <property name="minimum"> - <number>1</number> - </property> - <property name="maximum"> - <number>120</number> - </property> - <property name="singleStep"> - <number>5</number> - </property> - <property name="value"> - <number>2</number> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="lblInvert1_7"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="styleSheet"> - <string notr="true"/> - </property> - <property name="text"> - <string>Max</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QSlider" name="maxSmooth"> - <property name="sizePolicy"> - <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimum"> - <number>1</number> - </property> - <property name="maximum"> - <number>100</number> - </property> - <property name="pageStep"> - <number>5</number> - </property> - <property name="value"> - <number>10</number> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="tickPosition"> - <enum>QSlider::NoTicks</enum> - </property> - </widget> - </item> - <item row="1" column="2"> - <widget class="QSpinBox" name="spinMaxSmooth"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="styleSheet"> - <string notr="true">background:none;</string> - </property> - <property name="readOnly"> - <bool>true</bool> - </property> - <property name="buttonSymbols"> - <enum>QAbstractSpinBox::PlusMinus</enum> - </property> - <property name="minimum"> - <number>1</number> - </property> - <property name="maximum"> - <number>120</number> - </property> - <property name="singleStep"> - <number>5</number> - </property> - <property name="value"> - <number>10</number> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="lblInvert1_8"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="styleSheet"> - <string notr="true"/> - </property> - <property name="text"> - <string>Curve</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QSlider" name="powCurve"> - <property name="sizePolicy"> - <sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimum"> - <number>1</number> - </property> - <property name="maximum"> - <number>100</number> - </property> - <property name="pageStep"> - <number>5</number> - </property> - <property name="value"> - <number>10</number> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="tickPosition"> - <enum>QSlider::NoTicks</enum> - </property> - </widget> - </item> - <item row="2" column="2"> - <widget class="QSpinBox" name="spinPowCurve"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="styleSheet"> - <string notr="true">background:none;</string> - </property> - <property name="readOnly"> - <bool>true</bool> - </property> - <property name="buttonSymbols"> - <enum>QAbstractSpinBox::PlusMinus</enum> - </property> - <property name="maximum"> - <number>100</number> - </property> - <property name="singleStep"> - <number>5</number> - </property> - <property name="value"> - <number>10</number> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QLabel" name="label_4"> - <property name="styleSheet"> - <string notr="true">background-color: rgb(214, 214, 214); -border-color: rgb(0, 0, 0);</string> - </property> - <property name="frameShape"> - <enum>QFrame::Box</enum> - </property> - <property name="text"> - <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Sans Serif'; font-size:10pt; font-weight:400; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Min:</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Defines the way the filter responds to fast movements;</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Higher value: slower response;</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Max:</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Defines the way the filter responds to slow movements;</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Higher value: slower response;</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Pow:</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Defines the filters 'readiness' to respond to speed changes;</span></p> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-family:'MS Shell Dlg 2';">Higher value = </span><span style=" font-family:'MS Shell Dlg 2'; font-weight:600;">faster</span><span style=" font-family:'MS Shell Dlg 2';"> response;</span></p> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2';"><br /></p></body></html></string> - </property> - <property name="margin"> - <number>5</number> - </property> - </widget> - </item> - <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> - </property> - </widget> - </item> - </layout> - </widget> - <resources> - <include location="ewma-filter.qrc"/> - </resources> - <connections> - <connection> - <sender>minSmooth</sender> - <signal>valueChanged(int)</signal> - <receiver>spinMinSmooth</receiver> - <slot>setValue(int)</slot> - <hints> - <hint type="sourcelabel"> - <x>303</x> - <y>33</y> - </hint> - <hint type="destinationlabel"> - <x>391</x> - <y>36</y> - </hint> - </hints> - </connection> - <connection> - <sender>maxSmooth</sender> - <signal>valueChanged(int)</signal> - <receiver>spinMaxSmooth</receiver> - <slot>setValue(int)</slot> - <hints> - <hint type="sourcelabel"> - <x>281</x> - <y>61</y> - </hint> - <hint type="destinationlabel"> - <x>390</x> - <y>74</y> - </hint> - </hints> - </connection> - <connection> - <sender>powCurve</sender> - <signal>valueChanged(int)</signal> - <receiver>spinPowCurve</receiver> - <slot>setValue(int)</slot> - <hints> - <hint type="sourcelabel"> - <x>236</x> - <y>101</y> - </hint> - <hint type="destinationlabel"> - <x>391</x> - <y>98</y> - </hint> - </hints> - </connection> - </connections> - <slots> - <slot>startEngineClicked()</slot> - <slot>stopEngineClicked()</slot> - <slot>cameraSettingsClicked()</slot> - </slots> -</ui> diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp deleted file mode 100644 index c09fb912..00000000 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright (c) 2014 Donovan Baarda <abo@minkirri.apana.org.au> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - */ -#include "ftnoir_filter_ewma2.h" -#include <cmath> -#include <QDebug> -#include <QWidget> -#include "opentrack/plugin-api.hpp" -#include <algorithm> -#include <QMutexLocker> - -// Exponentially Weighted Moving Average (EWMA) Filter with dynamic smoothing. -// -// This filter tries to adjust the amount of filtering to minimize lag when -// moving, and minimize noise when still. It uses the delta filtered over the -// last 1/60sec (16ms) compared to the delta's average noise variance over -// the last 60sec to try and detect movement vs noise. As the delta increases -// from 0 to 3 stdevs of the noise, the filtering scales down from maxSmooth -// to minSmooth at a rate controlled by the powCurve setting. - - -FTNoIR_Filter::FTNoIR_Filter() -{ - reset(); -} - -void FTNoIR_Filter::receiveSettings() -{ - s.b->reload(); -} - -void FTNoIR_Filter::reset() -{ - timer.invalidate(); -} - -void FTNoIR_Filter::filter(const double *input, double *output) -{ - // Start the timer and initialise filter state if it's not running. - if (!timer.isValid()) { - timer.start(); - for (int i=0;i<6;i++) { - last_output[i] = input[i]; - last_delta[i] = 0.0; - last_noise[i] = 0.0; - } - } - // Get the time in seconds since last run and restart the timer. - auto dt = timer.restart() / 1000.0f; - // Calculate delta_alpha and noise_alpha from dt. - double delta_alpha = dt/(dt + delta_RC); - double noise_alpha = dt/(dt + noise_RC); - // Calculate the new camera position. - for (int i=0;i<6;i++) { - // Calculate the current and smoothed delta. - double delta = input[i] - last_output[i]; - last_delta[i] = delta_alpha*delta + (1.0-delta_alpha)*last_delta[i]; - // Calculate the current and smoothed noise variance. - double noise = last_delta[i]*last_delta[i]; - last_noise[i] = noise_alpha*noise + (1.0-noise_alpha)*last_noise[i]; - // Normalise the noise between 0->1 for 0->9 variances (0->3 stddevs). - double norm_noise = std::min<double>(noise/(9.0*last_noise[i]), 1.0); - if (std::isnan(norm_noise)) - norm_noise = 0; - // Calculate the smoothing 0.0->1.0 from the normalized noise. - // TODO(abo): change kSmoothingScaleCurve to a float where 1.0 is sqrt(norm_noise). - double smoothing = 1.0 - pow(norm_noise, s.kSmoothingScaleCurve/20.0); - // Currently min/max smoothing are ints 0->100. We want 0.0->3.0 seconds. - // TODO(abo): Change kMinSmoothing, kMaxSmoothing to floats 0.0->3.0 seconds RC. - double RC = 3.0*(s.kMinSmoothing + smoothing*(s.kMaxSmoothing - s.kMinSmoothing))/100.0; - // Calculate the dynamic alpha. - double alpha = dt/(dt + RC); - // Calculate the new output position. - output[i] = last_output[i] = alpha*input[i] + (1.0-alpha)*last_output[i]; - } -} - -OPENTRACK_DECLARE_FILTER(FTNoIR_Filter, FilterControls, FTNoIR_FilterDll) diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h b/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h deleted file mode 100644 index bf4e83ad..00000000 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2.h +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include "opentrack/plugin-api.hpp" -#include "ui_ftnoir_ewma_filtercontrols.h" -#include <QElapsedTimer> -#include <QWidget> -#include <QMutex> -#include "opentrack/options.hpp" -using namespace options; - -struct settings : opts { - // these are sadly sliders for now due to int/double mismatch -sh - value<int> kMinSmoothing, kMaxSmoothing, kSmoothingScaleCurve; - settings() : - opts("ewma-filter"), - kMinSmoothing(b, "min-smoothing", 15), - kMaxSmoothing(b, "max-smoothing", 50), - kSmoothingScaleCurve(b, "smoothing-scale-curve", 10) - {} -}; - - -class FTNoIR_Filter : public IFilter -{ -public: - FTNoIR_Filter(); - void reset(); - void filter(const double *input, double *output); - void receiveSettings(); -private: - // Deltas are smoothed over the last 1/60sec (16ms). - const double delta_RC = 0.016; - // Noise is smoothed over the last 60sec. - const double noise_RC = 60.0; - double last_delta[6]; - double last_noise[6]; - double last_output[6]; - QElapsedTimer timer; - settings s; -}; - -class FilterControls: public IFilterDialog -{ - Q_OBJECT -public: - FilterControls(); - void register_filter(IFilter* flt); - void unregister_filter(); - -private: - Ui::UICFilterControls ui; - void save(); - settings s; - FTNoIR_Filter* pFilter; - -private slots: - void doOK(); - void doCancel(); -}; - -class FTNoIR_FilterDll : public Metadata -{ -public: - QString name() { return QString("EWMA"); } - QIcon icon() { return QIcon(":/images/filter-16.png"); } -}; diff --git a/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp b/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp deleted file mode 100644 index 30fb6003..00000000 --- a/ftnoir_filter_ewma2/ftnoir_filter_ewma2_dialog.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "ftnoir_filter_ewma2.h" -#include <cmath> -#include <QDebug> -#include "opentrack/plugin-api.hpp" -#include "ui_ftnoir_ewma_filtercontrols.h" - -FilterControls::FilterControls() : pFilter(NULL) -{ - ui.setupUi( this ); - - connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); - connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); - - tie_setting(s.kMaxSmoothing, ui.maxSmooth); - tie_setting(s.kMinSmoothing, ui.minSmooth); - tie_setting(s.kSmoothingScaleCurve, ui.powCurve); -} - -void FilterControls::register_filter(IFilter* flt) -{ - pFilter = (FTNoIR_Filter*) flt; -} - -void FilterControls::unregister_filter() -{ - pFilter = NULL; -} - -void FilterControls::doOK() { - save(); - this->close(); -} - -void FilterControls::doCancel() { - s.b->reload(); - this->close(); -} - -void FilterControls::save() { - s.b->save(); - if (pFilter) - pFilter->receiveSettings(); -} |
