diff options
author | Stéphane Lenclud <github@lenclud.com> | 2019-04-28 00:03:24 +0200 |
---|---|---|
committer | Stéphane Lenclud <github@lenclud.com> | 2019-04-28 00:03:24 +0200 |
commit | 3e56f47a9cef709d4a099a0ac6ff43e361fe4a43 (patch) | |
tree | a8968cb73e7568902c83bb2275982ac23261a2f7 | |
parent | 518becf76bb5313949c76e9fa02d1ada2c25242d (diff) |
Easy Tracker: UI rework for custom model with three, four or five vertices.
More settings can be changed live without have to restart the tracker.
Fixing a few deadlock issues.
-rw-r--r-- | options/tie.cpp | 7 | ||||
-rw-r--r-- | options/tie.hpp | 2 | ||||
-rw-r--r-- | tracker-easy/lang/nl_NL.ts | 89 | ||||
-rw-r--r-- | tracker-easy/lang/ru_RU.ts | 93 | ||||
-rw-r--r-- | tracker-easy/lang/stub.ts | 89 | ||||
-rw-r--r-- | tracker-easy/lang/zh_CN.ts | 89 | ||||
-rw-r--r-- | tracker-easy/point-extractor.cpp | 19 | ||||
-rw-r--r-- | tracker-easy/point-extractor.h | 10 | ||||
-rw-r--r-- | tracker-easy/settings.h | 23 | ||||
-rw-r--r-- | tracker-easy/tracker-easy-dialog.cpp | 126 | ||||
-rw-r--r-- | tracker-easy/tracker-easy-dialog.h | 7 | ||||
-rw-r--r-- | tracker-easy/tracker-easy-settings.ui | 702 | ||||
-rw-r--r-- | tracker-easy/tracker-easy.cpp | 391 | ||||
-rw-r--r-- | tracker-easy/tracker-easy.h | 11 |
14 files changed, 716 insertions, 942 deletions
diff --git a/options/tie.cpp b/options/tie.cpp index 671a72c2..8220854d 100644 --- a/options/tie.cpp +++ b/options/tie.cpp @@ -72,6 +72,13 @@ void tie_setting(value<QVariant>& v, QComboBox* cb) // XXX TODO need variant with setEnabled based on lambda retval -- sh 20170524 +void tie_setting(value<bool>& v, QRadioButton* cb) +{ + cb->setChecked(v); + value_::connect(cb, SIGNAL(toggled(bool)), &v, SLOT(setValue(bool)), v.DIRECT_CONNTYPE); + value_::connect(&v, SIGNAL(valueChanged(bool)), cb, SLOT(setChecked(bool)), v.SAFE_CONNTYPE); +} + void tie_setting(value<bool>& v, QCheckBox* cb) { cb->setChecked(v); diff --git a/options/tie.hpp b/options/tie.hpp index c2607a6c..2ac27d64 100644 --- a/options/tie.hpp +++ b/options/tie.hpp @@ -20,6 +20,7 @@ #include <QLineEdit> #include <QLabel> #include <QTabWidget> +#include <QRadioButton> #include <cmath> @@ -97,6 +98,7 @@ OTR_OPTIONS_EXPORT void tie_setting(value<int>& v, QComboBox* cb); OTR_OPTIONS_EXPORT void tie_setting(value<QString>& v, QComboBox* cb); OTR_OPTIONS_EXPORT void tie_setting(value<QVariant>& v, QComboBox* cb); OTR_OPTIONS_EXPORT void tie_setting(value<bool>& v, QCheckBox* cb); +OTR_OPTIONS_EXPORT void tie_setting(value<bool>& v, QRadioButton* cb); OTR_OPTIONS_EXPORT void tie_setting(value<double>& v, QDoubleSpinBox* dsb); OTR_OPTIONS_EXPORT void tie_setting(value<int>& v, QSpinBox* sb); OTR_OPTIONS_EXPORT void tie_setting(value<QString>& v, QLineEdit* le); diff --git a/tracker-easy/lang/nl_NL.ts b/tracker-easy/lang/nl_NL.ts index f084f93f..9b7ae1dd 100644 --- a/tracker-easy/lang/nl_NL.ts +++ b/tracker-easy/lang/nl_NL.ts @@ -4,26 +4,6 @@ <context> <name>EasyTracker::Dialog</name> <message> - <source>%1 yaw samples. Yaw more to %2 samples for stable calibration.</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>%1 pitch samples. Pitch more to %2 samples for stable calibration.</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>%1 samples. Over %2, good!</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>Stop calibration</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>Start calibration</source> - <translation type="unfinished"></translation> - </message> - <message> <source>Tracker offline</source> <translation type="unfinished"></translation> </message> @@ -142,31 +122,6 @@ <translation type="unfinished"></translation> </message> <message> - <source>z:</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>x:</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>y:</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>Model position</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>Use only yaw and pitch while calibrating. -Don't roll or change position.</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>Start calibration</source> - <translation type="unfinished"></translation> - </message> - <message> <source>About</source> <translation type="unfinished"></translation> </message> @@ -239,27 +194,59 @@ Don't roll or change position.</source> <translation type="unfinished"></translation> </message> <message> - <source>Four</source> + <source>Custom</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Top Right</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Top</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Top Left</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Left</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Vertex count</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Three vertices</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Four vertices</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Five vertices</source> <translation type="unfinished"></translation> </message> <message> - <source>Model vertices</source> + <source>Center</source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Top</span></p></body></html></source> + <source>Right</source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Left</span></p></body></html></source> + <source><html><head/><body><p><span style=" font-size:12pt;">X</span></p></body></html></source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Right</span></p></body></html></source> + <source><html><head/><body><p><span style=" font-size:12pt;">Y</span></p></body></html></source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Center</span></p></body></html></source> + <source><html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html></source> <translation type="unfinished"></translation> </message> </context> diff --git a/tracker-easy/lang/ru_RU.ts b/tracker-easy/lang/ru_RU.ts index e05e58f3..ba8caacb 100644 --- a/tracker-easy/lang/ru_RU.ts +++ b/tracker-easy/lang/ru_RU.ts @@ -4,26 +4,6 @@ <context> <name>EasyTracker::Dialog</name> <message> - <source>%1 yaw samples. Yaw more to %2 samples for stable calibration.</source> - <translation type="unfinished">По оси YAW выполнено: %1 замер(а/ов). Для стабильного результата необходимо не меньше %2</translation> - </message> - <message> - <source>%1 pitch samples. Pitch more to %2 samples for stable calibration.</source> - <translation type="unfinished">По оси Pitch выполнено: %1 замер(а/ов). Для стабильного результата необходимо не меньше %2</translation> - </message> - <message> - <source>%1 samples. Over %2, good!</source> - <translation type="unfinished">Получено %1 образца(-ов). Больше %2, отлично!!</translation> - </message> - <message> - <source>Stop calibration</source> - <translation type="unfinished">Остановить калибровку</translation> - </message> - <message> - <source>Start calibration</source> - <translation type="unfinished">Начать калибровку</translation> - </message> - <message> <source>Tracker offline</source> <translation type="unfinished">Отслеживание отключено</translation> </message> @@ -142,35 +122,6 @@ <translation>Кепка</translation> </message> <message> - <source>z:</source> - <translation></translation> - </message> - <message> - <source>x:</source> - <translation></translation> - </message> - <message> - <source>y:</source> - <translation></translation> - </message> - <message> - <source>Model position</source> - <translation>Положение модели</translation> - </message> - <message> - <source>Use only yaw and pitch while calibrating. -Don't roll or change position.</source> - <translation>Во время калибровки -используйте только оси -YAW и PITCH. -Не используйте оси -ROLL или X/Y-смещения.</translation> - </message> - <message> - <source>Start calibration</source> - <translation>Начать калибровку</translation> - </message> - <message> <source>About</source> <translation>О программе</translation> </message> @@ -243,27 +194,59 @@ ROLL или X/Y-смещения.</translation> <translation type="unfinished"></translation> </message> <message> - <source>Four</source> + <source>Custom</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Top Right</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Top</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Top Left</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Left</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Vertex count</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Three vertices</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Four vertices</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Five vertices</source> <translation type="unfinished"></translation> </message> <message> - <source>Model vertices</source> + <source>Center</source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Top</span></p></body></html></source> + <source>Right</source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Left</span></p></body></html></source> + <source><html><head/><body><p><span style=" font-size:12pt;">X</span></p></body></html></source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Right</span></p></body></html></source> + <source><html><head/><body><p><span style=" font-size:12pt;">Y</span></p></body></html></source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Center</span></p></body></html></source> + <source><html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html></source> <translation type="unfinished"></translation> </message> </context> diff --git a/tracker-easy/lang/stub.ts b/tracker-easy/lang/stub.ts index 89c6d087..55a0bd46 100644 --- a/tracker-easy/lang/stub.ts +++ b/tracker-easy/lang/stub.ts @@ -4,26 +4,6 @@ <context> <name>EasyTracker::Dialog</name> <message> - <source>%1 yaw samples. Yaw more to %2 samples for stable calibration.</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>%1 pitch samples. Pitch more to %2 samples for stable calibration.</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>%1 samples. Over %2, good!</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>Stop calibration</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>Start calibration</source> - <translation type="unfinished"></translation> - </message> - <message> <source>Tracker offline</source> <translation type="unfinished"></translation> </message> @@ -142,31 +122,6 @@ <translation type="unfinished"></translation> </message> <message> - <source>z:</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>x:</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>y:</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>Model position</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>Use only yaw and pitch while calibrating. -Don't roll or change position.</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>Start calibration</source> - <translation type="unfinished"></translation> - </message> - <message> <source>About</source> <translation type="unfinished"></translation> </message> @@ -239,27 +194,59 @@ Don't roll or change position.</source> <translation type="unfinished"></translation> </message> <message> - <source>Four</source> + <source>Custom</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Top Right</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Top</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Top Left</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Left</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Vertex count</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Three vertices</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Four vertices</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Five vertices</source> <translation type="unfinished"></translation> </message> <message> - <source>Model vertices</source> + <source>Center</source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Top</span></p></body></html></source> + <source>Right</source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Left</span></p></body></html></source> + <source><html><head/><body><p><span style=" font-size:12pt;">X</span></p></body></html></source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Right</span></p></body></html></source> + <source><html><head/><body><p><span style=" font-size:12pt;">Y</span></p></body></html></source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Center</span></p></body></html></source> + <source><html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html></source> <translation type="unfinished"></translation> </message> </context> diff --git a/tracker-easy/lang/zh_CN.ts b/tracker-easy/lang/zh_CN.ts index 417de26a..73f0f0be 100644 --- a/tracker-easy/lang/zh_CN.ts +++ b/tracker-easy/lang/zh_CN.ts @@ -4,26 +4,6 @@ <context> <name>EasyTracker::Dialog</name> <message> - <source>%1 yaw samples. Yaw more to %2 samples for stable calibration.</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>%1 pitch samples. Pitch more to %2 samples for stable calibration.</source> - <translation type="unfinished"></translation> - </message> - <message> - <source>%1 samples. Over %2, good!</source> - <translation type="unfinished">%1 样本。%2 正常</translation> - </message> - <message> - <source>Stop calibration</source> - <translation type="unfinished">停止校准</translation> - </message> - <message> - <source>Start calibration</source> - <translation type="unfinished">开始校准</translation> - </message> - <message> <source>Tracker offline</source> <translation type="unfinished">跟踪器脱机</translation> </message> @@ -142,26 +122,6 @@ <translation>帽子式</translation> </message> <message> - <source>z:</source> - <translation>Z:</translation> - </message> - <message> - <source>x:</source> - <translation>X:</translation> - </message> - <message> - <source>y:</source> - <translation>Y:</translation> - </message> - <message> - <source>Model position</source> - <translation>姿态空间位置</translation> - </message> - <message> - <source>Start calibration</source> - <translation>开始校准</translation> - </message> - <message> <source>About</source> <translation>关于</translation> </message> @@ -178,11 +138,6 @@ <translation>设备信息:</translation> </message> <message> - <source>Use only yaw and pitch while calibrating. -Don't roll or change position.</source> - <translation>用pitch和yaw校准。不要roll或者变换位置</translation> - </message> - <message> <source>Debug (full size preview)</source> <translation type="unfinished"></translation> </message> @@ -239,27 +194,59 @@ Don't roll or change position.</source> <translation type="unfinished"></translation> </message> <message> - <source>Four</source> + <source>Custom</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Top Right</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Top</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Top Left</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Left</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Vertex count</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Three vertices</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Four vertices</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Five vertices</source> <translation type="unfinished"></translation> </message> <message> - <source>Model vertices</source> + <source>Center</source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Top</span></p></body></html></source> + <source>Right</source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Left</span></p></body></html></source> + <source><html><head/><body><p><span style=" font-size:12pt;">X</span></p></body></html></source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Right</span></p></body></html></source> + <source><html><head/><body><p><span style=" font-size:12pt;">Y</span></p></body></html></source> <translation type="unfinished"></translation> </message> <message> - <source><html><head/><body><p><span style=" font-size:16pt;">Center</span></p></body></html></source> + <source><html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html></source> <translation type="unfinished"></translation> </message> </context> diff --git a/tracker-easy/point-extractor.cpp b/tracker-easy/point-extractor.cpp index 0a5ca81d..b7cf7356 100644 --- a/tracker-easy/point-extractor.cpp +++ b/tracker-easy/point-extractor.cpp @@ -29,12 +29,19 @@ using namespace numeric_types; namespace EasyTracker { - PointExtractor::PointExtractor() : s(KModuleName) + PointExtractor::PointExtractor() : iSettings(KModuleName) { - + UpdateSettings(); } + /// + void PointExtractor::UpdateSettings() + { + iMinPointSize = iSettings.iMinBlobSize; + iMaxPointSize = iSettings.iMaxBlobSize; + } + /// void PointExtractor::ExtractPoints(const cv::Mat& aFrame, cv::Mat* aPreview, int aNeededPointCount, std::vector<cv::Point>& aPoints) { //TODO: Assert if channel size is neither one nor two @@ -108,10 +115,10 @@ namespace EasyTracker bBox = cv::boundingRect(iContours[i]); // Make sure bounding box matches our criteria - if (bBox.width >= s.min_point_size - && bBox.height >= s.min_point_size - && bBox.width <= s.max_point_size - && bBox.height <= s.max_point_size) + if (bBox.width >= iMinPointSize + && bBox.height >= iMinPointSize + && bBox.width <= iMaxPointSize + && bBox.height <= iMaxPointSize) { // Do a mean shift or cam shift, it's not bringing much though //cv::CamShift(iFrameGray, bBox, cv::TermCriteria(cv::TermCriteria::EPS + cv::TermCriteria::MAX_ITER, 10, 1)); diff --git a/tracker-easy/point-extractor.h b/tracker-easy/point-extractor.h index b037eed6..f275769d 100644 --- a/tracker-easy/point-extractor.h +++ b/tracker-easy/point-extractor.h @@ -24,9 +24,11 @@ namespace EasyTracker // extracts points from frame and draws some processing info into frame, if draw_output is set // dt: time since last call in seconds void ExtractPoints(const cv::Mat& aFrame, cv::Mat* aPreview, int aNeededPointCount, std::vector<cv::Point>& aPoints); - + + void UpdateSettings(); + // Settings - Settings s; + Settings iSettings; // Our frame with a channel size of 8 bits cv::Mat iFrameChannelSizeOne; // Our frame with a single 8 bits channel @@ -34,6 +36,10 @@ namespace EasyTracker // std::vector<std::vector<cv::Point> > iContours; + // Take a copy of settings to avoid dead lock + int iMinPointSize; + int iMaxPointSize; + }; } diff --git a/tracker-easy/settings.h b/tracker-easy/settings.h index 8c6a2b3e..825282d4 100644 --- a/tracker-easy/settings.h +++ b/tracker-easy/settings.h @@ -23,18 +23,22 @@ namespace EasyTracker { value<int> cam_res_x{ b, "camera-res-width", 640 }, cam_res_y{ b, "camera-res-height", 480 }, cam_fps{ b, "camera-fps", 30 }; - value<double> min_point_size{ b, "min-point-size", 2.5 }, - max_point_size{ b, "max-point-size", 50 }; + value<int> iMinBlobSize{ b, "iMinBlobSize", 4 }, iMaxBlobSize{ b, "iMaxBlobSize", 15 }; value<int> DeadzoneRectHalfEdgeSize { b, "deadzone-rect-half-edge-size", 1 }; - value<int> iFourPointsTopX{ b, "iFourPointsTopX", 0 }, iFourPointsTopY{ b, "iFourPointsTopY", 0 }, iFourPointsTopZ{ b, "iFourPointsTopZ", 0 }; - value<int> iFourPointsLeftX{ b, "iFourPointsLeftX", 0 }, iFourPointsLeftY{ b, "iFourPointsLeftY", 0 }, iFourPointsLeftZ{ b, "iFourPointsLeftZ", 0 }; - value<int> iFourPointsRightX{ b, "iFourPointsRightX", 0 }, iFourPointsRightY{ b, "iFourPointsRightY", 0 }, iFourPointsRightZ{ b, "iFourPointsRightZ", 0 }; - value<int> iFourPointsCenterX{ b, "iFourPointsCenterX", 0 }, iFourPointsCenterY{ b, "iFourPointsCenterY", 0 }, iFourPointsCenterZ{ b, "iFourPointsCenterZ", 0 }; + // Type of custom model + value<bool> iCustomModelThree{ b, "iCustomModelThree", true }; + value<bool> iCustomModelFour{ b, "iCustomModelFour", false }; + value<bool> iCustomModelFive{ b, "iCustomModelFive", false }; + + // Custom model vertices + value<int> iVertexTopX{ b, "iVertexTopX", 0 }, iVertexTopY{ b, "iVertexTopY", 0 }, iVertexTopZ{ b, "iVertexTopZ", 0 }; + value<int> iVertexRightX{ b, "iVertexRightX", 0 }, iVertexRightY{ b, "iVertexRightY", 0 }, iVertexRightZ{ b, "iVertexRightZ", 0 }; + value<int> iVertexLeftX{ b, "iVertexLeftX", 0 }, iVertexLeftY{ b, "iVertexLeftY", 0 }, iVertexLeftZ{ b, "iVertexLeftZ", 0 }; + value<int> iVertexCenterX{ b, "iVertexCenterX", 0 }, iVertexCenterY{ b, "iVertexCenterY", 0 }, iVertexCenterZ{ b, "iVertexCenterZ", 0 }; + value<int> iVertexTopRightX{ b, "iVertexTopRightX", 0 }, iVertexTopRightY{ b, "iVertexTopRightY", 0 }, iVertexTopRightZ{ b, "iVertexTopRightZ", 0 }; + value<int> iVertexTopLeftX{ b, "iVertexTopLeftX", 0 }, iVertexTopLeftY{ b, "iVertexTopLeftY", 0 }, iVertexTopLeftZ{ b, "iVertexTopLeftZ", 0 }; - value<int> t_MH_x{ b, "model-centroid-x", 0 }, - t_MH_y{ b, "model-centroid-y", 0 }, - t_MH_z{ b, "model-centroid-z", 0 }; value<int> clip_ty{ b, "clip-ty", 40 }, clip_tz{ b, "clip-tz", 30 }, @@ -50,6 +54,7 @@ namespace EasyTracker { value<bool> debug{ b, "debug", false }; + value<int> PnpSolver{ b, "pnp-solver", cv::SOLVEPNP_P3P }; diff --git a/tracker-easy/tracker-easy-dialog.cpp b/tracker-easy/tracker-easy-dialog.cpp index ce100b48..b30efed4 100644 --- a/tracker-easy/tracker-easy-dialog.cpp +++ b/tracker-easy/tracker-easy-dialog.cpp @@ -42,8 +42,8 @@ namespace EasyTracker tie_setting(s.cam_res_y, ui.res_y_spin); tie_setting(s.cam_fps, ui.fps_spin); - tie_setting(s.min_point_size, ui.mindiam_spin); - tie_setting(s.max_point_size, ui.maxdiam_spin); + tie_setting(s.iMinBlobSize, ui.mindiam_spin); + tie_setting(s.iMaxBlobSize, ui.maxdiam_spin); tie_setting(s.DeadzoneRectHalfEdgeSize, ui.spinDeadzone); tie_setting(s.clip_by, ui.clip_bheight_spin); @@ -55,25 +55,30 @@ namespace EasyTracker tie_setting(s.cap_y, ui.cap_height_spin); tie_setting(s.cap_z, ui.cap_length_spin); - tie_setting(s.iFourPointsTopX, ui.iSpinFourTopX); - tie_setting(s.iFourPointsTopY, ui.iSpinFourTopY); - tie_setting(s.iFourPointsTopZ, ui.iSpinFourTopZ); + tie_setting(s.iVertexTopX, ui.iSpinVertexTopX); + tie_setting(s.iVertexTopY, ui.iSpinVertexTopY); + tie_setting(s.iVertexTopZ, ui.iSpinVertexTopZ); - tie_setting(s.iFourPointsLeftX, ui.iSpinFourLeftX); - tie_setting(s.iFourPointsLeftY, ui.iSpinFourLeftY); - tie_setting(s.iFourPointsLeftZ, ui.iSpinFourLeftZ); + tie_setting(s.iVertexRightX, ui.iSpinVertexRightX); + tie_setting(s.iVertexRightY, ui.iSpinVertexRightY); + tie_setting(s.iVertexRightZ, ui.iSpinVertexRightZ); - tie_setting(s.iFourPointsRightX, ui.iSpinFourRightX); - tie_setting(s.iFourPointsRightY, ui.iSpinFourRightY); - tie_setting(s.iFourPointsRightZ, ui.iSpinFourRightZ); + tie_setting(s.iVertexLeftX, ui.iSpinVertexLeftX); + tie_setting(s.iVertexLeftY, ui.iSpinVertexLeftY); + tie_setting(s.iVertexLeftZ, ui.iSpinVertexLeftZ); - tie_setting(s.iFourPointsCenterX, ui.iSpinFourCenterX); - tie_setting(s.iFourPointsCenterY, ui.iSpinFourCenterY); - tie_setting(s.iFourPointsCenterZ, ui.iSpinFourCenterZ); + tie_setting(s.iVertexCenterX, ui.iSpinVertexCenterX); + tie_setting(s.iVertexCenterY, ui.iSpinVertexCenterY); + tie_setting(s.iVertexCenterZ, ui.iSpinVertexCenterZ); + + tie_setting(s.iVertexTopRightX, ui.iSpinVertexTopRightX); + tie_setting(s.iVertexTopRightY, ui.iSpinVertexTopRightY); + tie_setting(s.iVertexTopRightZ, ui.iSpinVertexTopRightZ); + + tie_setting(s.iVertexTopLeftX, ui.iSpinVertexTopLeftX); + tie_setting(s.iVertexTopLeftY, ui.iSpinVertexTopLeftY); + tie_setting(s.iVertexTopLeftZ, ui.iSpinVertexTopLeftZ); - tie_setting(s.t_MH_x, ui.tx_spin); - tie_setting(s.t_MH_y, ui.ty_spin); - tie_setting(s.t_MH_z, ui.tz_spin); tie_setting(s.fov, ui.fov); @@ -82,8 +87,6 @@ namespace EasyTracker tie_setting(s.debug, ui.debug); - connect(ui.tcalib_button, SIGNAL(toggled(bool)), this, SLOT(startstop_trans_calib(bool))); - connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); @@ -91,11 +94,18 @@ namespace EasyTracker set_camera_settings_available(ui.camdevice_combo->currentText()); connect(ui.camera_settings, &QPushButton::clicked, this, &Dialog::show_camera_settings); + // Radio Button + connect(ui.iRadioButtonCustomModelThree, &QRadioButton::clicked, this, &Dialog::UpdateCustomModelControls); + connect(ui.iRadioButtonCustomModelFour, &QRadioButton::clicked, this, &Dialog::UpdateCustomModelControls); + connect(ui.iRadioButtonCustomModelFive, &QRadioButton::clicked, this, &Dialog::UpdateCustomModelControls); + + tie_setting(s.iCustomModelThree, ui.iRadioButtonCustomModelThree); + tie_setting(s.iCustomModelFour, ui.iRadioButtonCustomModelFour); + tie_setting(s.iCustomModelFive, ui.iRadioButtonCustomModelFive); + connect(&timer, &QTimer::timeout, this, &Dialog::poll_tracker_info_impl); timer.setInterval(250); - connect(&calib_timer, &QTimer::timeout, this, &Dialog::trans_calib_step); - calib_timer.setInterval(35); poll_tracker_info_impl(); @@ -107,63 +117,30 @@ namespace EasyTracker tie_setting(s.PnpSolver, ui.comboBoxSolvers); + UpdateCustomModelControls(); } - - void Dialog::startstop_trans_calib(bool start) + void Dialog::UpdateCustomModelControls() { - QMutexLocker l(&calibrator_mutex); - - if (start) + if (ui.iRadioButtonCustomModelThree->isChecked()) { - qDebug() << "pt: starting translation calibration"; - calib_timer.start(); - trans_calib.reset(); - s.t_MH_x = 0; - s.t_MH_y = 0; - s.t_MH_z = 0; - - ui.sample_count_display->setText(QString()); + ui.iGroupBoxCenter->hide(); + ui.iGroupBoxTopRight->hide(); + ui.iGroupBoxTopLeft->hide(); } - else + else if (ui.iRadioButtonCustomModelFour->isChecked()) { - calib_timer.stop(); - qDebug() << "pt: stopping translation calibration"; - { - auto[tmp, nsamples] = trans_calib.get_estimate(); - s.t_MH_x = int(tmp[0]); - s.t_MH_y = int(tmp[1]); - s.t_MH_z = int(tmp[2]); - - constexpr int min_yaw_samples = 15; - constexpr int min_pitch_samples = 15; - constexpr int min_samples = min_yaw_samples + min_pitch_samples; - - // Don't bother counting roll samples. Roll calibration is hard enough - // that it's a hidden unsupported feature anyway. - - QString sample_feedback; - if (nsamples[0] < min_yaw_samples) - sample_feedback = tr("%1 yaw samples. Yaw more to %2 samples for stable calibration.").arg(nsamples[0]).arg(min_yaw_samples); - else if (nsamples[1] < min_pitch_samples) - sample_feedback = tr("%1 pitch samples. Pitch more to %2 samples for stable calibration.").arg(nsamples[1]).arg(min_pitch_samples); - else - { - const int nsamples_total = nsamples[0] + nsamples[1]; - sample_feedback = tr("%1 samples. Over %2, good!").arg(nsamples_total).arg(min_samples); - } - - ui.sample_count_display->setText(sample_feedback); - } + ui.iGroupBoxCenter->show(); + ui.iGroupBoxTopRight->hide(); + ui.iGroupBoxTopLeft->hide(); + } + else if (ui.iRadioButtonCustomModelFive->isChecked()) + { + ui.iGroupBoxCenter->hide(); + ui.iGroupBoxTopRight->show(); + ui.iGroupBoxTopLeft->show(); } - ui.tx_spin->setEnabled(!start); - ui.ty_spin->setEnabled(!start); - ui.tz_spin->setEnabled(!start); - if (start) - ui.tcalib_button->setText(tr("Stop calibration")); - else - ui.tcalib_button->setText(tr("Start calibration")); } void Dialog::poll_tracker_info_impl() @@ -203,12 +180,7 @@ namespace EasyTracker (void)video::show_dialog(s.camera_name); } - void Dialog::trans_calib_step() - { - QMutexLocker l(&calibrator_mutex); - // TODO: Do we still need that function - } - + void Dialog::save() { s.b->save(); @@ -228,7 +200,6 @@ namespace EasyTracker void Dialog::register_tracker(ITracker *t) { tracker = static_cast<Tracker*>(t); - ui.tcalib_button->setEnabled(true); poll_tracker_info(); timer.start(); } @@ -236,7 +207,6 @@ namespace EasyTracker void Dialog::unregister_tracker() { tracker = nullptr; - ui.tcalib_button->setEnabled(false); poll_tracker_info(); timer.stop(); } diff --git a/tracker-easy/tracker-easy-dialog.h b/tracker-easy/tracker-easy-dialog.h index 768eaa21..f63ef66f 100644 --- a/tracker-easy/tracker-easy-dialog.h +++ b/tracker-easy/tracker-easy-dialog.h @@ -26,12 +26,13 @@ namespace EasyTracker void register_tracker(ITracker *tracker) override; void unregister_tracker() override; void save(); + private: + void UpdateCustomModelControls(); + public slots: void doOK(); void doCancel(); - void startstop_trans_calib(bool start); - void trans_calib_step(); void poll_tracker_info_impl(); void set_camera_settings_available(const QString& camera_name); void show_camera_settings(); @@ -41,7 +42,7 @@ namespace EasyTracker Settings s; Tracker* tracker; - QTimer timer, calib_timer; + QTimer timer; TranslationCalibrator trans_calib; QMutex calibrator_mutex; diff --git a/tracker-easy/tracker-easy-settings.ui b/tracker-easy/tracker-easy-settings.ui index 9b9c67a8..6690a3e5 100644 --- a/tracker-easy/tracker-easy-settings.ui +++ b/tracker-easy/tracker-easy-settings.ui @@ -9,8 +9,8 @@ <rect> <x>0</x> <y>0</y> - <width>422</width> - <height>724</height> + <width>465</width> + <height>764</height> </rect> </property> <property name="sizePolicy"> @@ -36,71 +36,17 @@ <property name="sizeConstraint"> <enum>QLayout::SetFixedSize</enum> </property> - <item row="1" column="0" alignment="Qt::AlignVCenter"> - <widget class="QGroupBox" name="groupBox_5"> + <item row="8" column="0"> + <widget class="QDialogButtonBox" name="buttonBox"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="title"> - <string>Status</string> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> </property> - <layout class="QGridLayout" name="gridLayout_10"> - <item row="1" column="0"> - <widget class="QLabel" name="label_3"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Extracted Points:</string> - </property> - </widget> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="label_38"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>Camera Info:</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLabel" name="pointinfo_label"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Maximum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLabel" name="caminfo_label"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Maximum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string/> - </property> - </widget> - </item> - </layout> </widget> </item> <item row="0" column="0"> @@ -115,7 +61,7 @@ <locale language="English" country="UnitedStates"/> </property> <property name="currentIndex"> - <number>1</number> + <number>0</number> </property> <widget class="QWidget" name="tabTracker"> <attribute name="title"> @@ -387,9 +333,6 @@ <property name="text"> <string>Max size</string> </property> - <property name="buddy"> - <cstring>maxdiam_spin</cstring> - </property> </widget> </item> <item row="0" column="0"> @@ -477,8 +420,8 @@ </item> </widget> </item> - <item row="2" column="1"> - <widget class="QDoubleSpinBox" name="mindiam_spin"> + <item row="5" column="1"> + <widget class="QSpinBox" name="spinDeadzone"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> <horstretch>0</horstretch> @@ -486,21 +429,15 @@ </sizepolicy> </property> <property name="toolTip"> - <string>Minimum point diameter</string> + <string>Size in pixels of half the edge defining deadzone squares around tracked points</string> </property> <property name="suffix"> <string> px</string> </property> - <property name="decimals"> - <number>1</number> - </property> - <property name="singleStep"> - <double>0.100000000000000</double> - </property> </widget> </item> <item row="3" column="1"> - <widget class="QDoubleSpinBox" name="maxdiam_spin"> + <widget class="QSpinBox" name="maxdiam_spin"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> <horstretch>0</horstretch> @@ -513,16 +450,10 @@ <property name="suffix"> <string> px</string> </property> - <property name="decimals"> - <number>1</number> - </property> - <property name="singleStep"> - <double>0.100000000000000</double> - </property> </widget> </item> - <item row="5" column="1"> - <widget class="QSpinBox" name="spinDeadzone"> + <item row="2" column="1"> + <widget class="QSpinBox" name="mindiam_spin"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> <horstretch>0</horstretch> @@ -530,7 +461,7 @@ </sizepolicy> </property> <property name="toolTip"> - <string>Size in pixels of half the edge defining deadzone squares around tracked points</string> + <string>Minimum point diameter</string> </property> <property name="suffix"> <string> px</string> @@ -871,61 +802,55 @@ </item> </layout> </widget> - <widget class="QWidget" name="tabModelFourPoints"> + <widget class="QWidget" name="tabModelCustom"> <property name="enabled"> <bool>true</bool> </property> <attribute name="title"> - <string>Four</string> + <string>Custom</string> </attribute> <layout class="QGridLayout" name="gridLayout"> - <item row="0" column="0"> - <widget class="QGroupBox" name="groupBox_7"> + <item row="1" column="0"> + <widget class="QGroupBox" name="groupBox"> <property name="title"> - <string>Model vertices</string> + <string/> </property> - <layout class="QGridLayout" name="gridLayout_5"> - <item row="0" column="6"> - <widget class="QSpinBox" name="iSpinFourTopZ"> - <property name="suffix"> - <string> mm</string> - </property> - <property name="minimum"> - <number>-65535</number> - </property> - <property name="maximum"> - <number>65535</number> + <property name="flat"> + <bool>false</bool> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_8"> + <item> + <widget class="QLabel" name="label"> + <property name="text"> + <string><html><head/><body><p><span style=" font-size:12pt;">X</span></p></body></html></string> </property> </widget> </item> - <item row="0" column="1"> - <widget class="QLabel" name="label_68"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> + <item> + <widget class="QLabel" name="label_6"> <property name="text"> - <string>x:</string> + <string><html><head/><body><p><span style=" font-size:12pt;">Y</span></p></body></html></string> </property> </widget> </item> - <item row="0" column="3"> - <widget class="QLabel" name="label_76"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> + <item> + <widget class="QLabel" name="label_11"> <property name="text"> - <string>y:</string> + <string><html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html></string> </property> </widget> </item> - <item row="0" column="2"> - <widget class="QSpinBox" name="iSpinFourTopX"> + </layout> + </widget> + </item> + <item row="7" column="0"> + <widget class="QGroupBox" name="iGroupBoxTopRight"> + <property name="title"> + <string>Top Right</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_6"> + <item> + <widget class="QSpinBox" name="iSpinVertexTopRightX"> <property name="suffix"> <string> mm</string> </property> @@ -937,34 +862,43 @@ </property> </widget> </item> - <item row="0" column="5"> - <widget class="QLabel" name="label_65"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <item> + <widget class="QSpinBox" name="iSpinVertexTopRightY"> + <property name="suffix"> + <string> mm</string> </property> - <property name="text"> - <string>z:</string> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> </property> </widget> </item> - <item row="0" column="0"> - <widget class="QLabel" name="label_75"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <item> + <widget class="QSpinBox" name="iSpinVertexTopRightZ"> + <property name="suffix"> + <string> mm</string> </property> - <property name="text"> - <string><html><head/><body><p><span style=" font-size:16pt;">Top</span></p></body></html></string> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> </property> </widget> </item> - <item row="0" column="4"> - <widget class="QSpinBox" name="iSpinFourTopY"> + </layout> + </widget> + </item> + <item row="8" column="0"> + <widget class="QGroupBox" name="iGroupBoxTopLeft"> + <property name="title"> + <string>Top Left</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_7"> + <item> + <widget class="QSpinBox" name="iSpinVertexTopLeftX"> <property name="suffix"> <string> mm</string> </property> @@ -976,8 +910,8 @@ </property> </widget> </item> - <item row="2" column="6"> - <widget class="QSpinBox" name="iSpinFourLeftZ"> + <item> + <widget class="QSpinBox" name="iSpinVertexTopLeftY"> <property name="suffix"> <string> mm</string> </property> @@ -989,8 +923,8 @@ </property> </widget> </item> - <item row="2" column="2"> - <widget class="QSpinBox" name="iSpinFourLeftX"> + <item> + <widget class="QSpinBox" name="iSpinVertexTopLeftZ"> <property name="suffix"> <string> mm</string> </property> @@ -1002,8 +936,17 @@ </property> </widget> </item> - <item row="2" column="4"> - <widget class="QSpinBox" name="iSpinFourLeftY"> + </layout> + </widget> + </item> + <item row="5" column="0"> + <widget class="QGroupBox" name="iGroupBoxLeft"> + <property name="title"> + <string>Left</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_4"> + <item> + <widget class="QSpinBox" name="iSpinVertexLeftX"> <property name="suffix"> <string> mm</string> </property> @@ -1015,73 +958,76 @@ </property> </widget> </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_74"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <item> + <widget class="QSpinBox" name="iSpinVertexLeftY"> + <property name="suffix"> + <string> mm</string> </property> - <property name="text"> - <string><html><head/><body><p><span style=" font-size:16pt;">Left</span></p></body></html></string> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> </property> </widget> </item> - <item row="2" column="3"> - <widget class="QLabel" name="label_72"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <item> + <widget class="QSpinBox" name="iSpinVertexLeftZ"> + <property name="suffix"> + <string> mm</string> </property> - <property name="text"> - <string>y:</string> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> </property> </widget> </item> - <item row="2" column="5"> - <widget class="QLabel" name="label_73"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> + </layout> + </widget> + </item> + <item row="0" column="0"> + <widget class="QGroupBox" name="groupBoxCustomModelType"> + <property name="title"> + <string>Vertex count</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QRadioButton" name="iRadioButtonCustomModelThree"> <property name="text"> - <string>z:</string> + <string>Three vertices</string> + </property> + <property name="checked"> + <bool>true</bool> </property> </widget> </item> - <item row="2" column="1"> - <widget class="QLabel" name="label_71"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> + <item> + <widget class="QRadioButton" name="iRadioButtonCustomModelFour"> <property name="text"> - <string>x:</string> + <string>Four vertices</string> </property> </widget> </item> - <item row="3" column="0"> - <widget class="QLabel" name="label_60"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> + <item> + <widget class="QRadioButton" name="iRadioButtonCustomModelFive"> <property name="text"> - <string><html><head/><body><p><span style=" font-size:16pt;">Right</span></p></body></html></string> + <string>Five vertices</string> </property> </widget> </item> - <item row="3" column="2"> - <widget class="QSpinBox" name="iSpinFourRightX"> + </layout> + </widget> + </item> + <item row="6" column="0"> + <widget class="QGroupBox" name="iGroupBoxCenter"> + <property name="title"> + <string>Center</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_5"> + <item> + <widget class="QSpinBox" name="iSpinVertexCenterX"> <property name="suffix"> <string> mm</string> </property> @@ -1093,34 +1039,21 @@ </property> </widget> </item> - <item row="3" column="1"> - <widget class="QLabel" name="label_63"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>x:</string> + <item> + <widget class="QSpinBox" name="iSpinVertexCenterY"> + <property name="suffix"> + <string> mm</string> </property> - </widget> - </item> - <item row="3" column="3"> - <widget class="QLabel" name="label_58"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <property name="minimum"> + <number>-65535</number> </property> - <property name="text"> - <string>y:</string> + <property name="maximum"> + <number>65535</number> </property> </widget> </item> - <item row="3" column="4"> - <widget class="QSpinBox" name="iSpinFourRightY"> + <item> + <widget class="QSpinBox" name="iSpinVertexCenterZ"> <property name="suffix"> <string> mm</string> </property> @@ -1132,21 +1065,17 @@ </property> </widget> </item> - <item row="3" column="5"> - <widget class="QLabel" name="label_57"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>z:</string> - </property> - </widget> - </item> - <item row="3" column="6"> - <widget class="QSpinBox" name="iSpinFourRightZ"> + </layout> + </widget> + </item> + <item row="3" column="0"> + <widget class="QGroupBox" name="iGroupBoxRight"> + <property name="title"> + <string>Right</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <item> + <widget class="QSpinBox" name="iSpinVertexRightX"> <property name="suffix"> <string> mm</string> </property> @@ -1158,34 +1087,21 @@ </property> </widget> </item> - <item row="5" column="0"> - <widget class="QLabel" name="label_64"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string><html><head/><body><p><span style=" font-size:16pt;">Center</span></p></body></html></string> + <item> + <widget class="QSpinBox" name="iSpinVertexRightY"> + <property name="suffix"> + <string> mm</string> </property> - </widget> - </item> - <item row="5" column="1"> - <widget class="QLabel" name="label_67"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <property name="minimum"> + <number>-65535</number> </property> - <property name="text"> - <string>x:</string> + <property name="maximum"> + <number>65535</number> </property> </widget> </item> - <item row="5" column="2"> - <widget class="QSpinBox" name="iSpinFourCenterX"> + <item> + <widget class="QSpinBox" name="iSpinVertexRightZ"> <property name="suffix"> <string> mm</string> </property> @@ -1197,21 +1113,20 @@ </property> </widget> </item> - <item row="5" column="3"> - <widget class="QLabel" name="label_70"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>y:</string> - </property> - </widget> - </item> - <item row="5" column="4"> - <widget class="QSpinBox" name="iSpinFourCenterY"> + </layout> + </widget> + </item> + <item row="2" column="0"> + <widget class="QGroupBox" name="iGroupBoxTop"> + <property name="title"> + <string>Top</string> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <property name="topMargin"> + <number>9</number> + </property> + <item> + <widget class="QSpinBox" name="iSpinVertexTopX"> <property name="suffix"> <string> mm</string> </property> @@ -1223,21 +1138,21 @@ </property> </widget> </item> - <item row="5" column="5"> - <widget class="QLabel" name="label_69"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <item> + <widget class="QSpinBox" name="iSpinVertexTopY"> + <property name="suffix"> + <string> mm</string> </property> - <property name="text"> - <string>z:</string> + <property name="minimum"> + <number>-65535</number> + </property> + <property name="maximum"> + <number>65535</number> </property> </widget> </item> - <item row="5" column="6"> - <widget class="QSpinBox" name="iSpinFourCenterZ"> + <item> + <widget class="QSpinBox" name="iSpinVertexTopZ"> <property name="suffix"> <string> mm</string> </property> @@ -1256,169 +1171,6 @@ </widget> </widget> </item> - <item row="1" column="0"> - <widget class="QGroupBox" name="groupBox_10"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="title"> - <string>Model position</string> - </property> - <layout class="QGridLayout" name="gridLayout_4"> - <item row="0" column="0"> - <widget class="QFrame" name="frame_2"> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Raised</enum> - </property> - <layout class="QGridLayout" name="gridLayout_11"> - <item row="1" column="1"> - <widget class="QSpinBox" name="ty_spin"> - <property name="suffix"> - <string> mm</string> - </property> - <property name="minimum"> - <number>-65535</number> - </property> - <property name="maximum"> - <number>65536</number> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_66"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>z:</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QSpinBox" name="tz_spin"> - <property name="suffix"> - <string> mm</string> - </property> - <property name="minimum"> - <number>-65535</number> - </property> - <property name="maximum"> - <number>65536</number> - </property> - </widget> - </item> - <item row="0" column="0"> - <widget class="QLabel" name="label_61"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>x:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QSpinBox" name="tx_spin"> - <property name="suffix"> - <string> mm</string> - </property> - <property name="minimum"> - <number>-65535</number> - </property> - <property name="maximum"> - <number>65536</number> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_62"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string>y:</string> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item row="0" column="1"> - <widget class="QFrame" name="frame"> - <property name="frameShape"> - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Raised</enum> - </property> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <item> - <widget class="QLabel" name="label_59"> - <property name="text"> - <string>Use only yaw and pitch while calibrating. -Don't roll or change position.</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - <property name="openExternalLinks"> - <bool>false</bool> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="sample_count_display"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Minimum" vsizetype="Maximum"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="text"> - <string/> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="tcalib_button"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="text"> - <string>Start calibration</string> - </property> - <property name="checkable"> - <bool>true</bool> - </property> - </widget> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - </item> </layout> </widget> <widget class="QWidget" name="tab_3"> @@ -1456,17 +1208,71 @@ Don't roll or change position.</string> </widget> </widget> </item> - <item row="2" column="0"> - <widget class="QDialogButtonBox" name="buttonBox"> + <item row="7" column="0" alignment="Qt::AlignVCenter"> + <widget class="QGroupBox" name="groupBox_5"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + <property name="title"> + <string>Status</string> </property> + <layout class="QGridLayout" name="gridLayout_10"> + <item row="1" column="0"> + <widget class="QLabel" name="label_3"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Extracted Points:</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QLabel" name="label_38"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>Camera Info:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="pointinfo_label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="caminfo_label"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Maximum"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string/> + </property> + </widget> + </item> + </layout> </widget> </item> </layout> @@ -1487,10 +1293,6 @@ Don't roll or change position.</string> <tabstop>cap_length_spin</tabstop> <tabstop>cap_height_spin</tabstop> <tabstop>cap_width_spin</tabstop> - <tabstop>tx_spin</tabstop> - <tabstop>ty_spin</tabstop> - <tabstop>tz_spin</tabstop> - <tabstop>tcalib_button</tabstop> </tabstops> <resources> <include location="tracker_easy.qrc"/> diff --git a/tracker-easy/tracker-easy.cpp b/tracker-easy/tracker-easy.cpp index adffa33d..68729567 100644 --- a/tracker-easy/tracker-easy.cpp +++ b/tracker-easy/tracker-easy.cpp @@ -49,14 +49,35 @@ namespace EasyTracker //connect(&iSettings.cam_fps, value_::value_changed<int>(), this, &Tracker::SetFps, Qt::DirectConnection); // Make sure deadzones are updated whenever the settings are changed - connect(&iSettings.DeadzoneRectHalfEdgeSize, value_::value_changed<int>(), this, &Tracker::UpdateDeadzones, Qt::DirectConnection); - UpdateDeadzones(iSettings.DeadzoneRectHalfEdgeSize); + connect(&iSettings.DeadzoneRectHalfEdgeSize, value_::value_changed<int>(), this, &Tracker::UpdateSettings, Qt::DirectConnection); + + // Update point extractor whenever some of the settings it needs are changed + connect(&iSettings.iMinBlobSize, value_::value_changed<int>(), this, &Tracker::UpdateSettings, Qt::DirectConnection); + connect(&iSettings.iMaxBlobSize, value_::value_changed<int>(), this, &Tracker::UpdateSettings, Qt::DirectConnection); // Make sure solver is updated whenever the settings are changed - connect(&iSettings.PnpSolver, value_::value_changed<int>(), this, &Tracker::UpdateSolver, Qt::DirectConnection); - UpdateSolver(iSettings.PnpSolver); + connect(&iSettings.PnpSolver, value_::value_changed<int>(), this, &Tracker::UpdateSettings, Qt::DirectConnection); + + // Debug + connect(&iSettings.debug, value_::value_changed<bool>(), this, &Tracker::UpdateSettings, Qt::DirectConnection); + + // Make sure model is updated whenever it is changed + connect(&iSettings.iCustomModelThree, value_::value_changed<bool>(), this, &Tracker::UpdateModel, Qt::DirectConnection); + connect(&iSettings.iCustomModelFour, value_::value_changed<bool>(), this, &Tracker::UpdateModel, Qt::DirectConnection); + connect(&iSettings.iCustomModelFive, value_::value_changed<bool>(), this, &Tracker::UpdateModel, Qt::DirectConnection); + + // Update model logic + #define UM(v) connect(&iSettings.v, value_::value_changed<int>(), this, &Tracker::UpdateModel, Qt::DirectConnection) + UM(iVertexTopX); UM(iVertexTopY); UM(iVertexTopZ); + UM(iVertexTopRightX); UM(iVertexTopRightY); UM(iVertexTopRightZ); + UM(iVertexTopLeftX); UM(iVertexTopLeftY); UM(iVertexTopLeftZ); + UM(iVertexRightX); UM(iVertexRightY); UM(iVertexRightZ); + UM(iVertexLeftX); UM(iVertexLeftY); UM(iVertexLeftZ); + UM(iVertexCenterX); UM(iVertexCenterY); UM(iVertexCenterZ); + + UpdateModel(); - CreateModelFromSettings(); + UpdateSettings(); } Tracker::~Tracker() @@ -94,20 +115,29 @@ namespace EasyTracker } /// - void Tracker::CreateModelFromSettings() + void Tracker::UpdateModel() { + infout << std::chrono::system_clock::now().time_since_epoch().count() << ": Update model\n"; + + QMutexLocker lock(&iProcessLock); // Construct the points defining the object we want to detect based on settings. // We are converting them from millimeters to centimeters. // TODO: Need to support clip too. That's cap only for now. iModel.clear(); - if (iSettings.active_model_panel == FourPoints) - { - iModel.push_back(cv::Point3f(iSettings.iFourPointsTopX / 10.0, iSettings.iFourPointsTopY / 10.0, iSettings.iFourPointsTopZ / 10.0)); // Top - iModel.push_back(cv::Point3f(iSettings.iFourPointsRightX / 10.0, iSettings.iFourPointsRightY / 10.0, iSettings.iFourPointsRightZ / 10.0)); // Right - iModel.push_back(cv::Point3f(iSettings.iFourPointsLeftX / 10.0, iSettings.iFourPointsLeftY / 10.0, iSettings.iFourPointsLeftZ / 10.0)); // Left - iModel.push_back(cv::Point3f(iSettings.iFourPointsCenterX / 10.0, iSettings.iFourPointsCenterY / 10.0, iSettings.iFourPointsCenterZ / 10.0)); // Center + if (iSettings.active_model_panel == Custom) + { + iModel.push_back(cv::Point3f(iSettings.iVertexTopX / 10.0, iSettings.iVertexTopY / 10.0, iSettings.iVertexTopZ / 10.0)); // Top + iModel.push_back(cv::Point3f(iSettings.iVertexRightX / 10.0, iSettings.iVertexRightY / 10.0, iSettings.iVertexRightZ / 10.0)); // Right + iModel.push_back(cv::Point3f(iSettings.iVertexLeftX / 10.0, iSettings.iVertexLeftY / 10.0, iSettings.iVertexLeftZ / 10.0)); // Left + + if (iSettings.iCustomModelFour) + { + iModel.push_back(cv::Point3f(iSettings.iVertexCenterX / 10.0, iSettings.iVertexCenterY / 10.0, iSettings.iVertexCenterZ / 10.0)); // Center + } + } - else if (iSettings.active_model_panel == Cap) + // Default to Cap for now + else //if (iSettings.active_model_panel == Cap) { iModel.push_back(cv::Point3f(0, 0, 0)); // Top iModel.push_back(cv::Point3f(iSettings.cap_x / 10.0, iSettings.cap_z / 10.0, -iSettings.cap_y / 10.0)); // Right @@ -140,11 +170,15 @@ namespace EasyTracker iDistCoeffsMatrix.at<double>(7, 0) = iCameraInfo.radialDistortionSixthOrder; // Radial sixth order } + + const int KMinVertexCount = 3; /// /// /// void Tracker::ProcessFrame() { + QMutexLocker l(&iProcessLock); + // Create OpenCV matrix from our frame // TODO: Assert channel size is one or two iMatFrame = cv::Mat(iFrame.height, iFrame.width, CV_MAKETYPE((iFrame.channelSize == 2 ? CV_16U : CV_8U), iFrame.channels), iFrame.data, iFrame.stride); @@ -159,207 +193,204 @@ namespace EasyTracker iPoints.clear(); iPointExtractor.ExtractPoints(iMatFrame, (doPreview ? &iPreview.iFrameRgb : nullptr), iModel.size(), iPoints); - const bool success = iPoints.size() >= iModel.size(); + const bool success = iPoints.size() >= iModel.size() && iModel.size() >= KMinVertexCount; int topPointIndex = -1; int rightPointIndex = -1; int leftPointIndex = -1; int centerPointIndex = -1; - { - QMutexLocker l(&iProcessLock); - if (success) + + if (success) + { + //Bitmap origin is top left + iTrackedPoints.clear(); + // Tracked points must match the order of the object model points. + // Find top most point, that's the one with min Y as we assume our guy's head is not up side down + int minY = std::numeric_limits<int>::max(); + for (int i = 0; i < iPoints.size(); i++) { - //Bitmap origin is top left - iTrackedPoints.clear(); - // Tracked points must match the order of the object model points. - // Find top most point, that's the one with min Y as we assume our guy's head is not up side down - int minY = std::numeric_limits<int>::max(); - for (int i = 0; i < iPoints.size(); i++) + if (iPoints[i].y < minY) { - if (iPoints[i].y < minY) - { - minY = iPoints[i].y; - topPointIndex = i; - } + minY = iPoints[i].y; + topPointIndex = i; } + } - int maxX = 0; + int maxX = 0; - // Find right most point - for (int i = 0; i < iPoints.size(); i++) + // Find right most point + for (int i = 0; i < iPoints.size(); i++) + { + // Excluding top most point + if (i != topPointIndex && iPoints[i].x > maxX) { - // Excluding top most point - if (i != topPointIndex && iPoints[i].x > maxX) - { - maxX = iPoints[i].x; - rightPointIndex = i; - } + maxX = iPoints[i].x; + rightPointIndex = i; } + } - // Find left most point - - int minX = std::numeric_limits<int>::max();; - for (int i = 0; i < iPoints.size(); i++) + // Find left most point + int minX = std::numeric_limits<int>::max(); + for (int i = 0; i < iPoints.size(); i++) + { + // Excluding top most point and right most point + if (i != topPointIndex && i != rightPointIndex && iPoints[i].x < minX) { - // Excluding top most point and right most point - if (i != topPointIndex && i != rightPointIndex && iPoints[i].x < minX) - { - leftPointIndex = i; - minX = iPoints[i].x; - } + leftPointIndex = i; + minX = iPoints[i].x; } + } - // Find center point, the last one - for (int i = 0; i < iPoints.size(); i++) + // Find center point, the last one + for (int i = 0; i < iPoints.size(); i++) + { + // Excluding the three points we already have + if (i != topPointIndex && i != rightPointIndex && i != leftPointIndex) { - // Excluding the three points we already have - if (i != topPointIndex && i != rightPointIndex && i != leftPointIndex) - { - centerPointIndex = i; - } + centerPointIndex = i; } + } + + // Order matters + iTrackedPoints.push_back(iPoints[topPointIndex]); + iTrackedPoints.push_back(iPoints[rightPointIndex]); + iTrackedPoints.push_back(iPoints[leftPointIndex]); + if (iModel.size() > iTrackedPoints.size()) + { + // We are tracking more than 3 points + iTrackedPoints.push_back(iPoints[centerPointIndex]); + } + - // Order matters - iTrackedPoints.push_back(iPoints[topPointIndex]); - iTrackedPoints.push_back(iPoints[rightPointIndex]); - iTrackedPoints.push_back(iPoints[leftPointIndex]); - if (iModel.size() > iTrackedPoints.size()) + bool movedEnough = true; + // Check if we moved enough since last time we were here + // This is our deadzone management + if (iDeadzoneHalfEdge != 0 // Check if deazones are enabled + && iTrackedRects.size() == iTrackedPoints.size()) + { + movedEnough = false; + for (size_t i = 0; i < iTrackedPoints.size(); i++) { - // We are tracking more than 3 points - iTrackedPoints.push_back(iPoints[centerPointIndex]); + if (!iTrackedRects[i].contains(iTrackedPoints[i])) + { + movedEnough = true; + break; + } } - + } - bool movedEnough = true; - // Check if we moved enough since last time we were here - // This is our deadzone management - if (iSettings.DeadzoneRectHalfEdgeSize != 0 // Check if deazones are enabled - && iTrackedRects.size() == iTrackedPoints.size()) + if (!movedEnough) + { + // We are in a dead zone + // However we still have tracking so make sure we don't auto center + QMutexLocker lock(&iDataLock); + iBestTime.start(); + } + else + { + // Build deadzone rectangles if needed + iTrackedRects.clear(); + if (iDeadzoneHalfEdge != 0) // Check if deazones are enabled { - movedEnough = false; - for (size_t i = 0; i < iTrackedPoints.size(); i++) + for (const cv::Point& pt : iTrackedPoints) { - if (!iTrackedRects[i].contains(iTrackedPoints[i])) - { - movedEnough = true; - break; - } + cv::Rect rect(pt - cv::Point(iDeadzoneHalfEdge, iDeadzoneHalfEdge), cv::Size(iDeadzoneEdge, iDeadzoneEdge)); + iTrackedRects.push_back(rect); } } - if (!movedEnough) + dbgout << "Object: " << iModel << "\n"; + dbgout << "Points: " << iTrackedPoints << "\n"; + + iAngles.clear(); + iBestSolutionIndex = -1; + // Solve P3P problem with OpenCV + int solutionCount = 0; + if (iModel.size() == 3) { - // We are in a dead zone - // However we still have tracking so make sure we don't auto center - QMutexLocker lock(&iDataLock); - iBestTime.start(); + solutionCount = cv::solveP3P(iModel, iTrackedPoints, iCameraMatrix, iDistCoeffsMatrix, iRotations, iTranslations, iSolver); } else { - // Build deadzone rectangles if needed - iTrackedRects.clear(); - if (iSettings.DeadzoneRectHalfEdgeSize != 0) // Check if deazones are enabled + //Guess extrinsic boolean is only for ITERATIVE method, it will be set to false for all other method + cv::Mat rotation, translation; + // Init only needed for iterative, it's also useless as it is + rotation = cv::Mat::zeros(3, 1, CV_64FC1); + translation = cv::Mat::zeros(3, 1, CV_64FC1); + rotation.setTo(cv::Scalar(0)); + translation.setTo(cv::Scalar(0)); + ///// + iRotations.clear(); + iTranslations.clear(); + bool solved = cv::solvePnP(iModel, iTrackedPoints, iCameraMatrix, iDistCoeffsMatrix, rotation, translation, true, iSolver ); + if (solved) { - for (const cv::Point& pt : iTrackedPoints) - { - cv::Rect rect(pt - cv::Point(iDeadzoneHalfEdge, iDeadzoneHalfEdge), cv::Size(iDeadzoneEdge, iDeadzoneEdge)); - iTrackedRects.push_back(rect); - } + solutionCount = 1; + iRotations.push_back(rotation); + iTranslations.push_back(translation); } + } - dbgout << "Object: " << iModel << "\n"; - dbgout << "Points: " << iTrackedPoints << "\n"; + // Reset best solution index + iBestSolutionIndex = -1; - iAngles.clear(); - iBestSolutionIndex = -1; - // Solve P3P problem with OpenCV - int solutionCount = 0; - if (iModel.size() == 3) - { - solutionCount = cv::solveP3P(iModel, iTrackedPoints, iCameraMatrix, iDistCoeffsMatrix, iRotations, iTranslations, iSolver); - } - else + if (solutionCount > 0) + { + dbgout << "Solution count: " << solutionCount << "\n"; + int minPitch = std::numeric_limits<int>::max(); + // Find the solution we want amongst all possible ones + for (int i = 0; i < solutionCount; i++) { - //Guess extrinsic boolean is only for ITERATIVE method, it will be set to false for all other method - cv::Mat rotation, translation; - // Init only needed for iterative, it's also useless as it is - rotation = cv::Mat::zeros(3, 1, CV_64FC1); - translation = cv::Mat::zeros(3, 1, CV_64FC1); - rotation.setTo(cv::Scalar(0)); - translation.setTo(cv::Scalar(0)); - ///// - iRotations.clear(); - iTranslations.clear(); - bool solved = cv::solvePnP(iModel, iTrackedPoints, iCameraMatrix, iDistCoeffsMatrix, rotation, translation, true, iSolver ); - if (solved) + dbgout << "Translation:\n"; + dbgout << iTranslations.at(i); + dbgout << "\n"; + dbgout << "Rotation:\n"; + //dbgout << rvecs.at(i); + cv::Mat rotationCameraMatrix; + cv::Rodrigues(iRotations[i], rotationCameraMatrix); + cv::Vec3d angles; + getEulerAngles(rotationCameraMatrix, angles); + iAngles.push_back(angles); + + // Check if pitch is closest to zero + int absolutePitch = std::abs(angles[0]); + if (minPitch > absolutePitch) { - solutionCount = 1; - iRotations.push_back(rotation); - iTranslations.push_back(translation); + // The solution with pitch closest to zero is the one we want + minPitch = absolutePitch; + iBestSolutionIndex = i; } + + dbgout << angles; + dbgout << "\n"; } - // Reset best solution index - iBestSolutionIndex = -1; + dbgout << "\n"; + } - if (solutionCount > 0) - { - dbgout << "Solution count: " << solutionCount << "\n"; - int minPitch = std::numeric_limits<int>::max(); - // Find the solution we want amongst all possible ones - for (int i = 0; i < solutionCount; i++) - { - dbgout << "Translation:\n"; - dbgout << iTranslations.at(i); - dbgout << "\n"; - dbgout << "Rotation:\n"; - //dbgout << rvecs.at(i); - cv::Mat rotationCameraMatrix; - cv::Rodrigues(iRotations[i], rotationCameraMatrix); - cv::Vec3d angles; - getEulerAngles(rotationCameraMatrix, angles); - iAngles.push_back(angles); - - // Check if pitch is closest to zero - int absolutePitch = std::abs(angles[0]); - if (minPitch > absolutePitch) - { - // The solution with pitch closest to zero is the one we want - minPitch = absolutePitch; - iBestSolutionIndex = i; - } - - dbgout << angles; - dbgout << "\n"; - } + if (iBestSolutionIndex != -1) + { + // Best translation + cv::Vec3d translation = iTranslations[iBestSolutionIndex]; + // Best angles + cv::Vec3d angles = iAngles[iBestSolutionIndex]; - dbgout << "\n"; - } + // Pass solution through our kalman filter + iKf.Update(translation[0], translation[1], translation[2], angles[2], angles[0], angles[1]); - if (iBestSolutionIndex != -1) - { - // Best translation - cv::Vec3d translation = iTranslations[iBestSolutionIndex]; - // Best angles - cv::Vec3d angles = iAngles[iBestSolutionIndex]; - - // Pass solution through our kalman filter - iKf.Update(translation[0], translation[1], translation[2], angles[2], angles[0], angles[1]); - - // We succeded in finding a solution to our PNP problem - ever_success.store(true, std::memory_order_relaxed); - - // Send solution data back to main thread - QMutexLocker l2(&iDataLock); - iBestAngles = angles; - iBestTranslation = translation; - iBestTime.start(); - } + // We succeded in finding a solution to our PNP problem + ever_success.store(true, std::memory_order_relaxed); + + // Send solution data back to main thread + QMutexLocker l2(&iDataLock); + iBestAngles = angles; + iBestTranslation = translation; + iBestTime.start(); } - } + } } if (doPreview) @@ -403,7 +434,7 @@ namespace EasyTracker } // Show full size preview pop-up - if (iSettings.debug) + if (iDebug) { cv::imshow("Preview", iPreview.iFrameRgb); cv::waitKey(1); @@ -423,7 +454,7 @@ namespace EasyTracker else { // No preview, destroy preview pop-up - if (iSettings.debug) + if (iDebug) { cv::destroyWindow("Preview"); } @@ -525,23 +556,21 @@ namespace EasyTracker iKf.Init(18, 6, 0, dt); } - void Tracker::UpdateDeadzones(int aHalfEdgeSize) + /// + /// Take a copy of the settings needed by our thread to avoid deadlocks + /// + void Tracker::UpdateSettings() { + infout << std::chrono::system_clock::now().time_since_epoch().count() << ": Update Setting\n"; QMutexLocker l(&iProcessLock); - iDeadzoneHalfEdge = aHalfEdgeSize; + iPointExtractor.UpdateSettings(); + iSolver = iSettings.PnpSolver; + iDeadzoneHalfEdge = iSettings.DeadzoneRectHalfEdgeSize; iDeadzoneEdge = iDeadzoneHalfEdge * 2; iTrackedRects.clear(); + iDebug = iSettings.debug; } - - void Tracker::UpdateSolver(int aSolver) - { - QMutexLocker l(&iProcessLock); - iSolver = aSolver; - } - - - module_status Tracker::start_tracker(QFrame* video_frame) { // Check that we support that solver @@ -599,7 +628,7 @@ namespace EasyTracker // Get data back from tracker thread QMutexLocker l(&iDataLock); // If there was no new data recently then we provide center data. - // Basically if our user remove her hat we will go back to center position until she puts it back on. + // Basically, if our user remove her hat, we will go back to center position until she puts it back on. if (iBestTime.elapsed_seconds() > 1) { // Reset to center until we get new data diff --git a/tracker-easy/tracker-easy.h b/tracker-easy/tracker-easy.h index 65b777bf..f36ea598 100644 --- a/tracker-easy/tracker-easy.h +++ b/tracker-easy/tracker-easy.h @@ -38,7 +38,7 @@ namespace EasyTracker { Clip, Cap, - FourPoints + Custom }; static const QString KModuleName = "tracker-easy"; @@ -66,7 +66,7 @@ namespace EasyTracker private: - void CreateModelFromSettings(); + void UpdateModel(); void CreateCameraIntrinsicsMatrices(); void ProcessFrame(); @@ -76,8 +76,7 @@ namespace EasyTracker void set_fov(int value); void SetFps(int aFps); void DoSetFps(int aFps); - void UpdateDeadzones(int aHalfEdgeSize); - void UpdateSolver(int aSolver); + void UpdateSettings(); QMutex camera_mtx; QThread iThread; @@ -103,12 +102,14 @@ namespace EasyTracker std::atomic<bool> ever_success = false; mutable QMutex iProcessLock, iDataLock; + //// Copy the settings need by our thread to avoid dead locks // Deadzone int iDeadzoneEdge=0; int iDeadzoneHalfEdge=0; - // Solver int iSolver = cv::SOLVEPNP_P3P; + bool iDebug = false; + //// // Statistics Timer iTimer; |