summaryrefslogtreecommitdiffhomepage
path: root/ftnoir_filter_kalman
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2013-12-01 12:17:43 +0100
committerStanislaw Halik <sthalik@misaki.pl>2013-12-01 12:17:43 +0100
commitcb233e361a859bc3271cdccd701e1690af459592 (patch)
tree99070da3f49c8b20c8c7d79df8150ed7f5e48e06 /ftnoir_filter_kalman
parentb2bd39a926aa338796ceb2ef606fea70b5eb0333 (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.h33
-rw-r--r--ftnoir_filter_kalman/kalman.cpp60
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;
}
}