summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--3rdparty-notices/HEADTRACKER-LICENSE.txt (renamed from bin/tracker-ht/license.txt)0
-rw-r--r--CMakeLists.txt8
-rw-r--r--bin/camera/Logitech HD Webcam C525.yml22
-rw-r--r--bin/camera/PS3Eye Camera.yml22
-rw-r--r--bin/tracker-ht/cleye.config4
-rw-r--r--bin/tracker-ht/thanks.txt5
-rw-r--r--ftnoir_filter_accela/ftnoir_filter_accela.cpp10
-rw-r--r--ftnoir_filter_accela/ftnoir_filter_accela.h5
-rwxr-xr-xftnoir_filter_kalman/ftnoir_filter_kalman.h25
-rw-r--r--ftnoir_filter_kalman/ftnoir_kalman_filtercontrols.ui85
-rw-r--r--ftnoir_filter_kalman/kalman.cpp11
-rw-r--r--ftnoir_tracker_aruco/aruco-trackercontrols.ui4
-rw-r--r--ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp33
-rw-r--r--ftnoir_tracker_ht/ftnoir_tracker_ht.cpp10
-rw-r--r--ftnoir_tracker_ht/ht-trackercontrols.ui2
-rw-r--r--ftnoir_tracker_pt/camera.cpp74
-rw-r--r--ftnoir_tracker_pt/ftnoir_tracker_pt.cpp10
-rw-r--r--opentrack/opencv-calibration.hpp26
18 files changed, 248 insertions, 108 deletions
diff --git a/bin/tracker-ht/license.txt b/3rdparty-notices/HEADTRACKER-LICENSE.txt
index a1a778e6..a1a778e6 100644
--- a/bin/tracker-ht/license.txt
+++ b/3rdparty-notices/HEADTRACKER-LICENSE.txt
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8674e907..6719f3b0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -558,3 +558,11 @@ endif()
if(WIN32)
install(FILES "${CMAKE_SOURCE_DIR}/bin/cleye.config" DESTINATION .)
endif()
+
+install(DIRECTORY "${CMAKE_SOURCE_DIR}/bin/camera" DESTINATION .)
+
+if(APPLE)
+ install(CODE "
+ execute_process(COMMAND /bin/sh \"${CMAKE_SOURCE_DIR}/install-fail-tool\" \"${CMAKE_INSTALL_PREFIX}\")
+ ")
+endif()
diff --git a/bin/camera/Logitech HD Webcam C525.yml b/bin/camera/Logitech HD Webcam C525.yml
new file mode 100644
index 00000000..ac1bc981
--- /dev/null
+++ b/bin/camera/Logitech HD Webcam C525.yml
@@ -0,0 +1,22 @@
+%YAML:1.0
+calibration_time: "07/13/15 17:32:58"
+image_width: 640
+image_height: 480
+board_width: 24
+board_height: 15
+square_size: 1.
+flags: 0
+camera_matrix: !!opencv-matrix
+ rows: 3
+ cols: 3
+ dt: d
+ data: [ 7.1195238148354849e+002, 0., 3.4210284784635138e+002, 0.,
+ 7.1302752784110055e+002, 2.2837679451205264e+002, 0., 0., 1. ]
+distortion_coefficients: !!opencv-matrix
+ rows: 5
+ cols: 1
+ dt: d
+ data: [ -1.5165615866415242e-003, 3.6806867018034255e-002,
+ -6.6432394998828278e-004, 1.7782694073348656e-003,
+ -4.9225052904494471e-001 ]
+avg_reprojection_error: 2.5310746466741296e+000
diff --git a/bin/camera/PS3Eye Camera.yml b/bin/camera/PS3Eye Camera.yml
new file mode 100644
index 00000000..6859d0fb
--- /dev/null
+++ b/bin/camera/PS3Eye Camera.yml
@@ -0,0 +1,22 @@
+%YAML:1.0
+calibration_time: "07/13/15 17:45:33"
+image_width: 640
+image_height: 480
+board_width: 24
+board_height: 15
+square_size: 1.
+flags: 0
+camera_matrix: !!opencv-matrix
+ rows: 3
+ cols: 3
+ dt: d
+ data: [ 7.5119574967224673e+002, 0., 3.2806930334341007e+002, 0.,
+ 7.5112907969240291e+002, 2.2681331450818737e+002, 0., 0., 1. ]
+distortion_coefficients: !!opencv-matrix
+ rows: 5
+ cols: 1
+ dt: d
+ data: [ -2.2741190107950382e-001, 9.4372681451250684e-001,
+ -4.0955586655475494e-003, -2.6778551080439902e-003,
+ -1.7969804313130640e+000 ]
+avg_reprojection_error: 1.9233386799903629e+000
diff --git a/bin/tracker-ht/cleye.config b/bin/tracker-ht/cleye.config
deleted file mode 100644
index bfb37b47..00000000
--- a/bin/tracker-ht/cleye.config
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<cleye>
- <item name="mode" value="advanced" />
-</cleye> \ No newline at end of file
diff --git a/bin/tracker-ht/thanks.txt b/bin/tracker-ht/thanks.txt
deleted file mode 100644
index 42612dfa..00000000
--- a/bin/tracker-ht/thanks.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-The following people deserve thanks for their work on libheadtracker:
-
-The awesome head mesh, made using a 3D scanner was made by
-Jed Frechette. I cannot thank him enough, given how much it
-helped improve the program. \ No newline at end of file
diff --git a/ftnoir_filter_accela/ftnoir_filter_accela.cpp b/ftnoir_filter_accela/ftnoir_filter_accela.cpp
index acb9e4ac..86b65e1c 100644
--- a/ftnoir_filter_accela/ftnoir_filter_accela.cpp
+++ b/ftnoir_filter_accela/ftnoir_filter_accela.cpp
@@ -69,16 +69,16 @@ void FTNoIR_Filter::filter(const double* input, double *output)
return;
}
- const double rot_t = 10. * (1+s.rot_threshold) / 100.;
- const double trans_t = 5. * (1+s.trans_threshold) / 100.;
+ const double rot_t = (1+s.rot_threshold) * s.mult_rot;
+ const double trans_t = (1+s.trans_threshold) * s.mult_trans;
const double dt = t.elapsed() * 1e-9;
t.start();
- const double RC = 2 * s.ewma / 1000.; // seconds
+ const double RC = s.mult_ewma * s.ewma / 1000.; // seconds
const double alpha = dt/(dt+RC);
- const double rot_dz = s.rot_deadzone * 2. / 100.;
- const double trans_dz = s.trans_deadzone * 1. / 100.;
+ const double rot_dz = s.rot_deadzone * s.mult_rot_dz;
+ const double trans_dz = s.trans_deadzone * s.mult_trans_dz;
for (int i = 0; i < 6; i++)
{
diff --git a/ftnoir_filter_accela/ftnoir_filter_accela.h b/ftnoir_filter_accela/ftnoir_filter_accela.h
index e2b29ee4..0116faea 100644
--- a/ftnoir_filter_accela/ftnoir_filter_accela.h
+++ b/ftnoir_filter_accela/ftnoir_filter_accela.h
@@ -11,6 +11,11 @@ using namespace options;
struct settings_accela : opts {
value<int> rot_threshold, trans_threshold, ewma, rot_deadzone, trans_deadzone;
+ static constexpr double mult_rot = 10. / 100.;
+ static constexpr double mult_trans = 5. / 100.;
+ static constexpr double mult_rot_dz = 2. / 100.;
+ static constexpr double mult_trans_dz = 1. / 100.;
+ static constexpr double mult_ewma = 2.;
settings_accela() :
opts("Accela"),
rot_threshold(b, "rotation-threshold", 30),
diff --git a/ftnoir_filter_kalman/ftnoir_filter_kalman.h b/ftnoir_filter_kalman/ftnoir_filter_kalman.h
index f6224530..e84ef347 100755
--- a/ftnoir_filter_kalman/ftnoir_filter_kalman.h
+++ b/ftnoir_filter_kalman/ftnoir_filter_kalman.h
@@ -19,19 +19,29 @@
#include "opentrack/options.hpp"
using namespace options;
+struct settings : opts {
+ value<int> noise_stddev_slider;
+ // slider for noise_stddev goes 0->(mult_noise_stddev * 100)
+ static constexpr double mult_noise_stddev = .5;
+ settings() : opts("kalman-filter"), noise_stddev_slider(b, "noise-stddev", 40)
+ {}
+};
+
class OPENTRACK_EXPORT FTNoIR_Filter : public IFilter
{
public:
FTNoIR_Filter();
void reset();
void filter(const double *input, double *output);
- // Set accel_stddev assuming moving 0.0->100.0 in dt=0.2 is 3 stddevs: (100.0*4/dt^2)/3.
- const double accel_stddev = (100.0*4/(0.2*0.2))/3.0;
- // TODO(abo): make noise_stddev a UI setting 0.0->10.0 with 0.1 resolution.
- const double noise_stddev = 1.0;
+ // Set accel_stddev assuming moving 0.0->accel in dt_ is 3 stddevs: (accel*4/dt_^2)/3.
+ static constexpr double dt_ = .4;
+ static constexpr double accel = 60.;
+ static constexpr double accel_stddev = (accel*4/(dt_*dt_))/3.0;
cv::KalmanFilter kalman;
double last_input[6];
QElapsedTimer timer;
+ settings s;
+ int prev_slider_pos;
};
class OPENTRACK_EXPORT FTNoIR_FilterDll : public Metadata
@@ -47,13 +57,14 @@ class OPENTRACK_EXPORT FilterControls: public IFilterDialog
public:
FilterControls() {
ui.setupUi(this);
- connect(ui.btnOk, SIGNAL(clicked()), this, SLOT(doOK()));
- connect(ui.btnCancel, SIGNAL(clicked()), this, SLOT(doCancel()));
- show();
+ connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK()));
+ connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel()));
+ tie_setting(s.noise_stddev_slider, ui.noise_slider);
}
Ui::KalmanUICFilterControls ui;
void register_filter(IFilter*) override {}
void unregister_filter() override {}
+ settings s;
public slots:
void doOK();
void doCancel();
diff --git a/ftnoir_filter_kalman/ftnoir_kalman_filtercontrols.ui b/ftnoir_filter_kalman/ftnoir_kalman_filtercontrols.ui
index e0c849c9..69297102 100644
--- a/ftnoir_filter_kalman/ftnoir_kalman_filtercontrols.ui
+++ b/ftnoir_filter_kalman/ftnoir_kalman_filtercontrols.ui
@@ -9,8 +9,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>334</width>
- <height>100</height>
+ <width>288</width>
+ <height>132</height>
</rect>
</property>
<property name="sizePolicy">
@@ -23,7 +23,7 @@
<string>Kalman settings</string>
</property>
<property name="windowIcon">
- <iconset resource="../ftnoir_filter_ewma2/ewma-filter.qrc">
+ <iconset resource="../facetracknoir/ui-res.qrc">
<normaloff>:/images/filter-16.png</normaloff>:/images/filter-16.png</iconset>
</property>
<property name="layoutDirection">
@@ -35,35 +35,60 @@
<property name="styleSheet">
<string notr="true"/>
</property>
- <widget class="QPushButton" name="btnOk">
- <property name="geometry">
- <rect>
- <x>173</x>
- <y>70</y>
- <width>73</width>
- <height>25</height>
- </rect>
- </property>
- <property name="text">
- <string>OK</string>
- </property>
- </widget>
- <widget class="QPushButton" name="btnCancel">
- <property name="geometry">
- <rect>
- <x>250</x>
- <y>70</y>
- <width>73</width>
- <height>25</height>
- </rect>
- </property>
- <property name="text">
- <string>Cancel</string>
- </property>
- </widget>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Noise standard deviation</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QSlider" name="noise_slider">
+ <property name="singleStep">
+ <number>1</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="tickPosition">
+ <enum>QSlider::TicksAbove</enum>
+ </property>
+ <property name="tickInterval">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Written by Donovan Baarda, 2014</string>
+ </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="../ftnoir_filter_ewma2/ewma-filter.qrc"/>
+ <include location="../facetracknoir/ui-res.qrc"/>
</resources>
<connections/>
<designerdata>
diff --git a/ftnoir_filter_kalman/kalman.cpp b/ftnoir_filter_kalman/kalman.cpp
index c5a600af..08b46f0f 100644
--- a/ftnoir_filter_kalman/kalman.cpp
+++ b/ftnoir_filter_kalman/kalman.cpp
@@ -11,6 +11,7 @@
FTNoIR_Filter::FTNoIR_Filter() {
reset();
+ prev_slider_pos = s.noise_stddev_slider;
}
// the following was written by Donovan Baarda <abo@minkirri.apana.org.au>
@@ -56,7 +57,8 @@ void FTNoIR_Filter::reset() {
0, 0, 0, 0, b, 0, 0, 0, 0, 0, a, 0,
0, 0, 0, 0, 0, b, 0, 0, 0, 0, 0, a);
cv::setIdentity(kalman.measurementMatrix);
- double noise_variance = noise_stddev * noise_stddev;
+ const double noise_stddev = (1+s.noise_stddev_slider) * s.mult_noise_stddev;
+ const double noise_variance = noise_stddev * noise_stddev;
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++) {
@@ -67,6 +69,11 @@ void FTNoIR_Filter::reset() {
void FTNoIR_Filter::filter(const double* input, double *output)
{
+ if (prev_slider_pos != s.noise_stddev_slider)
+ {
+ reset();
+ prev_slider_pos = s.noise_stddev_slider;
+ }
// Start the timer if it's not running.
if (!timer.isValid())
timer.start();
@@ -108,10 +115,12 @@ void FTNoIR_Filter::filter(const double* input, double *output)
}
void FilterControls::doOK() {
+ s.b->save();
close();
}
void FilterControls::doCancel() {
+ s.b->reload();
close();
}
diff --git a/ftnoir_tracker_aruco/aruco-trackercontrols.ui b/ftnoir_tracker_aruco/aruco-trackercontrols.ui
index 4433c47c..bc384f39 100644
--- a/ftnoir_tracker_aruco/aruco-trackercontrols.ui
+++ b/ftnoir_tracker_aruco/aruco-trackercontrols.ui
@@ -9,7 +9,7 @@
<rect>
<x>0</x>
<y>0</y>
- <width>586</width>
+ <width>485</width>
<height>202</height>
</rect>
</property>
@@ -109,7 +109,7 @@
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
- <string>Horizontal FOV</string>
+ <string>Diagonal FOV</string>
</property>
</widget>
</item>
diff --git a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp
index 70af379d..6d87503f 100644
--- a/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp
+++ b/ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp
@@ -18,6 +18,7 @@
#include <opencv2/videoio.hpp>
#include "opentrack/camera-names.hpp"
#include "opentrack/thread.hpp"
+#include "opentrack/opencv-calibration.hpp"
typedef struct {
int width;
@@ -134,6 +135,9 @@ void Tracker::run()
double failed = 0;
const double max_failed = 1.25;
cv::Vec3d rvec, tvec;
+ double last_fov = -1;
+ cv::Mat intrinsics = cv::Mat::eye(3, 3, CV_32FC1);
+ cv::Mat dist_coeffs = cv::Mat::zeros(5, 1, CV_32FC1);
while (!stop)
{
@@ -150,15 +154,28 @@ void Tracker::run()
const int scale = grayscale.cols > 480 ? 2 : 1;
detector.setThresholdParams(box_sizes[box_idx], 5);
- const float focal_length_w = 0.5 * grayscale.cols / tan(0.5 * s.fov * HT_PI / 180);
- const float focal_length_h = 0.5 * grayscale.rows / tan(0.5 * s.fov * grayscale.rows / grayscale.cols * HT_PI / 180.0);
- cv::Mat intrinsics = cv::Mat::eye(3, 3, CV_32FC1);
- intrinsics.at<float> (0, 0) = focal_length_w;
- intrinsics.at<float> (1, 1) = focal_length_h;
- intrinsics.at<float> (0, 2) = grayscale.cols/2;
- intrinsics.at<float> (1, 2) = grayscale.rows/2;
+ static constexpr double pi = 3.1415926f;
+ const int w = grayscale.cols, h = grayscale.rows;
+ const double diag = sqrt(w * w + h * h)/w, diag_fov = static_cast<int>(s.fov) * pi / 180.;
+ const double fov = 2.*atan(tan(diag_fov/2.)/sqrt(1. + diag*diag));
+ const float focal_length_w = .5 * w / tan(.5 * fov);
+ const float focal_length_h = focal_length_w;
- cv::Mat dist_coeffs = cv::Mat::zeros(5, 1, CV_32FC1);
+ if (last_fov != s.fov)
+ {
+ last_fov = s.fov;
+ if (!get_camera_calibration(static_cast<QString>(s.camera_name), intrinsics, dist_coeffs, grayscale.cols, grayscale.rows))
+ {
+ intrinsics.at<float> (0, 0) = focal_length_w;
+ intrinsics.at<float> (1, 1) = focal_length_h;
+ intrinsics.at<float> (0, 2) = grayscale.cols/2;
+ intrinsics.at<float> (1, 2) = grayscale.rows/2;
+ }
+ else
+ {
+ qDebug() << "got calibration";
+ }
+ }
std::vector< aruco::Marker > markers;
diff --git a/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp b/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp
index deb90ee5..577ae40d 100644
--- a/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp
+++ b/ftnoir_tracker_ht/ftnoir_tracker_ht.cpp
@@ -45,12 +45,12 @@ void Tracker::load_settings(ht_config_t* config)
config->classification_delay = 500;
config->field_of_view = s.fov;
config->max_keypoints = 150;
- config->keypoint_distance = 3.4;
+ config->keypoint_distance = 3.5;
config->force_fps = nframes;
config->camera_index = camera_name_to_index(s.camera_name);
- config->ransac_max_reprojection_error = 8;
- config->ransac_max_inlier_error = 8;
+ config->ransac_max_reprojection_error = 25;
+ config->ransac_max_inlier_error = config->ransac_max_reprojection_error;
config->pyrlk_pyramids = 0;
config->pyrlk_win_size_w = config->pyrlk_win_size_h = 21;
@@ -58,8 +58,8 @@ void Tracker::load_settings(ht_config_t* config)
config->ransac_max_mean_error = 999;
config->ransac_abs_max_mean_error = 999;
- config->debug = 0;
- config->ransac_min_features = 0.85;
+ config->debug = 1;
+ config->ransac_min_features = 0.95;
config->ransac_num_iters = 300;
int res = s.resolution;
diff --git a/ftnoir_tracker_ht/ht-trackercontrols.ui b/ftnoir_tracker_ht/ht-trackercontrols.ui
index dd5e57f3..29b80c8d 100644
--- a/ftnoir_tracker_ht/ht-trackercontrols.ui
+++ b/ftnoir_tracker_ht/ht-trackercontrols.ui
@@ -55,7 +55,7 @@
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
- <string>Horizontal FOV</string>
+ <string>Diagonal FOV</string>
</property>
</widget>
</item>
diff --git a/ftnoir_tracker_pt/camera.cpp b/ftnoir_tracker_pt/camera.cpp
index eaf51e17..9168a3e4 100644
--- a/ftnoir_tracker_pt/camera.cpp
+++ b/ftnoir_tracker_pt/camera.cpp
@@ -16,39 +16,39 @@ using namespace cv;
// ----------------------------------------------------------------------------
void get_camera_device_names(std::vector<std::string>& device_names)
{
- videoInput VI;
- VI.listDevices();
- std::string device_name;
- for(int index = 0; ; ++index) {
- device_name = VI.getDeviceName(index);
- if (device_name.empty()) break;
- device_names.push_back(device_name);
- }
+ videoInput VI;
+ VI.listDevices();
+ std::string device_name;
+ for(int index = 0; ; ++index) {
+ device_name = VI.getDeviceName(index);
+ if (device_name.empty()) break;
+ device_names.push_back(device_name);
+ }
}
#endif
// ----------------------------------------------------------------------------
void Camera::set_device_index(int index)
{
- if (desired_index != index)
- {
- desired_index = index;
- _set_device_index();
+ if (desired_index != index)
+ {
+ desired_index = index;
+ _set_device_index();
- // reset fps
- dt_valid = 0;
- dt_mean = 0;
- active_index = index;
- }
+ // reset fps
+ dt_valid = 0;
+ dt_mean = 0;
+ active_index = index;
+ }
}
void Camera::set_fps(int fps)
{
- if (cam_desired.fps != fps)
- {
- cam_desired.fps = fps;
- _set_fps();
- }
+ if (cam_desired.fps != fps)
+ {
+ cam_desired.fps = fps;
+ _set_fps();
+ }
}
void Camera::set_res(int x_res, int y_res)
@@ -63,17 +63,17 @@ void Camera::set_res(int x_res, int y_res)
bool Camera::get_frame(float dt, cv::Mat* frame)
{
- bool new_frame = _get_frame(frame);
- // measure fps of valid frames
- const float dt_smoothing_const = 0.9;
- dt_valid += dt;
- if (new_frame)
- {
- dt_mean = dt_smoothing_const * dt_mean + (1.0 - dt_smoothing_const) * dt_valid;
- cam_info.fps = dt_mean > 1e-3 ? 1.0 / dt_mean : 0;
- dt_valid = 0;
- }
- return new_frame;
+ bool new_frame = _get_frame(frame);
+ // measure fps of valid frames
+ const float dt_smoothing_const = 0.9;
+ dt_valid += dt;
+ if (new_frame)
+ {
+ dt_mean = dt_smoothing_const * dt_mean + (1.0 - dt_smoothing_const) * dt_valid;
+ cam_info.fps = dt_mean > 1e-3 ? 1.0 / dt_mean : 0;
+ dt_valid = 0;
+ }
+ return new_frame;
}
void CVCamera::start()
@@ -118,10 +118,10 @@ bool CVCamera::_get_frame(Mat* frame)
if (img.empty())
return false;
- *frame = img;
- cam_info.res_x = img.cols;
- cam_info.res_y = img.rows;
- return true;
+ *frame = img;
+ cam_info.res_x = img.cols;
+ cam_info.res_y = img.rows;
+ return true;
}
return false;
}
diff --git a/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp b/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp
index d48f9252..d3cf18c1 100644
--- a/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp
+++ b/ftnoir_tracker_pt/ftnoir_tracker_pt.cpp
@@ -54,7 +54,7 @@ void Tracker_PT::reset_command(Command command)
float Tracker_PT::get_focal_length()
{
- static constexpr float pi = 3.1415926f;
+ static constexpr float pi = 3.1415926;
float fov_;
switch (s.fov)
{
@@ -67,8 +67,12 @@ float Tracker_PT::get_focal_length()
break;
}
- const float fov = static_cast<int>(fov_) * pi / 180.f;
- return 0.5f / tan(0.5f * fov);
+ const float diag_fov = static_cast<int>(fov_) * pi / 180.f;
+ CamInfo info = camera.get_info();
+ const int w = info.res_x, h = info.res_y;
+ const double diag = sqrt(w * w + h * h)/w;
+ const double fov = 2.*atan(tan(diag_fov/2.0)/sqrt(1. + diag*diag));
+ return .5 / tan(.5 * fov);
}
void Tracker_PT::run()
diff --git a/opentrack/opencv-calibration.hpp b/opentrack/opencv-calibration.hpp
new file mode 100644
index 00000000..6dee9908
--- /dev/null
+++ b/opentrack/opencv-calibration.hpp
@@ -0,0 +1,26 @@
+#pragma once
+#include <QCoreApplication>
+#include <QString>
+#include <QByteArray>
+#include <string>
+#include <opencv2/core.hpp>
+
+template<typename = void>
+bool get_camera_calibration(const QString& camera_name, cv::Mat& intrinsics, cv::Mat& distortion, int w, int h)
+{
+ QString pathname_ = QCoreApplication::applicationDirPath() + "/camera/" + camera_name + ".yml";
+ std::string pathname = pathname_.toStdString();
+ cv::FileStorage fs(pathname, cv::FileStorage::READ);
+ if (!fs.isOpened())
+ return false;
+ cv::Mat intrinsics_, distortion_;
+ fs["camera_matrix"] >> intrinsics_;
+ fs["distortion_coefficients"] >> distortion_;
+ intrinsics_.at<double>(0, 0) *= w / 640.;
+ intrinsics_.at<double>(2, 0) *= w / 640.;
+ intrinsics_.at<double>(1, 1) *= h / 480.;
+ intrinsics_.at<double>(2, 1) *= h / 480.;
+ intrinsics = intrinsics_;
+ distortion = distortion_;
+ return true;
+}