diff options
-rw-r--r-- | 3rdparty-notices/HEADTRACKER-LICENSE.txt (renamed from bin/tracker-ht/license.txt) | 0 | ||||
-rw-r--r-- | CMakeLists.txt | 8 | ||||
-rw-r--r-- | bin/camera/Logitech HD Webcam C525.yml | 22 | ||||
-rw-r--r-- | bin/camera/PS3Eye Camera.yml | 22 | ||||
-rw-r--r-- | bin/tracker-ht/cleye.config | 4 | ||||
-rw-r--r-- | bin/tracker-ht/thanks.txt | 5 | ||||
-rw-r--r-- | ftnoir_filter_accela/ftnoir_filter_accela.cpp | 10 | ||||
-rw-r--r-- | ftnoir_filter_accela/ftnoir_filter_accela.h | 5 | ||||
-rwxr-xr-x | ftnoir_filter_kalman/ftnoir_filter_kalman.h | 25 | ||||
-rw-r--r-- | ftnoir_filter_kalman/ftnoir_kalman_filtercontrols.ui | 85 | ||||
-rw-r--r-- | ftnoir_filter_kalman/kalman.cpp | 11 | ||||
-rw-r--r-- | ftnoir_tracker_aruco/aruco-trackercontrols.ui | 4 | ||||
-rw-r--r-- | ftnoir_tracker_aruco/ftnoir_tracker_aruco.cpp | 33 | ||||
-rw-r--r-- | ftnoir_tracker_ht/ftnoir_tracker_ht.cpp | 10 | ||||
-rw-r--r-- | ftnoir_tracker_ht/ht-trackercontrols.ui | 2 | ||||
-rw-r--r-- | ftnoir_tracker_pt/camera.cpp | 74 | ||||
-rw-r--r-- | ftnoir_tracker_pt/ftnoir_tracker_pt.cpp | 10 | ||||
-rw-r--r-- | opentrack/opencv-calibration.hpp | 26 |
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; +} |