diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2013-12-01 12:17:43 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2013-12-01 12:17:43 +0100 |
commit | cb233e361a859bc3271cdccd701e1690af459592 (patch) | |
tree | 99070da3f49c8b20c8c7d79df8150ed7f5e48e06 /ftnoir_filter_kalman | |
parent | b2bd39a926aa338796ceb2ef606fea70b5eb0333 (diff) |
accela: implement a third-order highpass filter
Signed-off-by: Stanislaw Halik <sthalik@misaki.pl>
Diffstat (limited to 'ftnoir_filter_kalman')
-rw-r--r-- | ftnoir_filter_kalman/ftnoir_filter_kalman.h | 33 | ||||
-rw-r--r-- | ftnoir_filter_kalman/kalman.cpp | 60 |
2 files changed, 63 insertions, 30 deletions
diff --git a/ftnoir_filter_kalman/ftnoir_filter_kalman.h b/ftnoir_filter_kalman/ftnoir_filter_kalman.h index 59169612..6c2cb6a9 100644 --- a/ftnoir_filter_kalman/ftnoir_filter_kalman.h +++ b/ftnoir_filter_kalman/ftnoir_filter_kalman.h @@ -19,25 +19,29 @@ #include <QString> #include <QIcon> #include <QWidget> +#include <QElapsedTimer> #include <QObject> class FTNOIR_FILTER_BASE_EXPORT FTNoIR_Filter : public IFilter { public: FTNoIR_Filter(); - virtual ~FTNoIR_Filter() { + ~FTNoIR_Filter() virt_override { } - void Initialize(); - void FilterHeadPoseData(double *current_camera_position, - double *target_camera_position, + void Initialize() virt_override; + void FilterHeadPoseData(const double *target_camera_position, double *new_camera_position, - double *last_post_filter_values); + const double *) virt_override; cv::KalmanFilter kalman; double prev_position[6]; + double prev2_filter_pos[6]; + double prev_filter_pos[6]; + QElapsedTimer timer; + qint64 timedelta; }; -void kalman_load_settings(FTNoIR_Filter& self); -void kalman_save_settings(FTNoIR_Filter& self); +void kalman_load_settings(FTNoIR_Filter&); +void kalman_save_settings(FTNoIR_Filter&); class FTNOIR_FILTER_BASE_EXPORT FTNoIR_FilterDll : public Metadata { @@ -48,7 +52,7 @@ public: void getIcon(QIcon *icon){ *icon = QIcon(":/images/filter-16.png"); } }; -class FTNOIR_FILTER_BASE_EXPORT FilterControls: public QWidget, Ui::KalmanUICFilterControls, public IFilterDialog +class FTNOIR_FILTER_BASE_EXPORT FilterControls: public QWidget, public IFilterDialog { Q_OBJECT public: @@ -65,21 +69,24 @@ public: connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel())); show(); } - virtual ~FilterControls() {} - void showEvent ( QShowEvent * event ) { + ~FilterControls() {} + void showEvent ( QShowEvent * ) virt_override { show(); } - void Initialize(QWidget *parent, IFilter* ptr) { + void Initialize(QWidget *) virt_override { + show(); + raise(); } bool settingsDirty; Ui::KalmanUICFilterControls ui; - + virtual void registerFilter(IFilter*) virt_override {} + virtual void unregisterFilter() virt_override {} public slots: void doOK(); void doCancel(); - void settingsChanged(double unused) { + void settingsChanged(double) { settingsDirty = true; } }; diff --git a/ftnoir_filter_kalman/kalman.cpp b/ftnoir_filter_kalman/kalman.cpp index 51af35e1..5ecd417c 100644 --- a/ftnoir_filter_kalman/kalman.cpp +++ b/ftnoir_filter_kalman/kalman.cpp @@ -9,7 +9,7 @@ #include <QDebug> #include <math.h> -void kalman_load_settings(FTNoIR_Filter& self) { +void kalman_load_settings(FTNoIR_Filter&) { QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); @@ -19,7 +19,7 @@ void kalman_load_settings(FTNoIR_Filter& self) { iniFile.endGroup(); } -void kalman_save_settings(FilterControls& self) { +void kalman_save_settings(FilterControls&) { QSettings settings("Abbequerque Inc.", "FaceTrackNoIR"); // Registry settings (in HK_USER) QString currentFile = settings.value ( "SettingsFile", QCoreApplication::applicationDirPath() + "/Settings/default.ini" ).toString(); @@ -37,8 +37,8 @@ FTNoIR_Filter::FTNoIR_Filter() { // the following was written by Donovan Baarda <abo@minkirri.apana.org.au> // https://sourceforge.net/p/facetracknoir/discussion/1150909/thread/418615e1/?limit=25#af75/084b void FTNoIR_Filter::Initialize() { - const double accel_variance = 1e-4; - const double noise_variance = 1e1; + const double accel_variance = 1e-3; + const double noise_variance = 5e2; kalman.init(12, 6, 0, CV_64F); kalman.transitionMatrix = (cv::Mat_<double>(12, 12) << 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, @@ -73,13 +73,28 @@ void FTNoIR_Filter::Initialize() { cv::setIdentity(kalman.measurementNoiseCov, cv::Scalar::all(noise_variance)); cv::setIdentity(kalman.errorCovPost, cv::Scalar::all(accel_variance * 1e4)); for (int i = 0; i < 6; i++) + { prev_position[i] = 0; + prev2_filter_pos[i] = 0; + prev_filter_pos[i] = 0; + timedelta = 1; + timer.invalidate(); + } +} + +template<typename T> +static inline T clamp(const T min, const T max, const T value) +{ + if (value < min) + return min; + if (value > max) + return max; + return value; } -void FTNoIR_Filter::FilterHeadPoseData(double *current_camera_position, - double *target_camera_position, +void FTNoIR_Filter::FilterHeadPoseData(const double* target_camera_position, double *new_camera_position, - double *last_post_filter_values) + const double *) { bool new_target = false; @@ -89,23 +104,34 @@ void FTNoIR_Filter::FilterHeadPoseData(double *current_camera_position, new_target = true; break; } - - cv::Mat output = kalman.predict(); - + if (new_target) { + cv::Mat output = kalman.predict(); cv::Mat measurement(6, 1, CV_64F); for (int i = 0; i < 3; i++) { measurement.at<double>(i) = target_camera_position[i+3]; measurement.at<double>(i+3) = target_camera_position[i]; } kalman.correct(measurement); - } - - for (int i = 0; i < 3; i++) { - new_camera_position[i] = output.at<double>(i+3); - new_camera_position[i+3] = output.at<double>(i); - prev_position[i] = target_camera_position[i]; - prev_position[i+3] = target_camera_position[i+3]; + for (int i = 0; i < 6; i++) + { + prev_position[i] = target_camera_position[i]; + } + if (timer.isValid()) + timedelta = timer.elapsed(); + else + timedelta = 1; + for (int i = 0; i < 6; i++) + { + prev2_filter_pos[i] = prev_filter_pos[i]; + prev_filter_pos[i] = new_camera_position[i] = output.at<double>((i + 3) % 6); + } + timer.start(); + } else { + auto d = timer.isValid() ? timer.elapsed() : 1; + auto c = clamp(0.0, 1.0, d / (double) timedelta); + for (int i = 0; i < 6; i++) + new_camera_position[i] = prev2_filter_pos[i] + (prev_filter_pos[i] - prev2_filter_pos[i]) * c; } } |