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 /tracker-easy | |
| 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.
Diffstat (limited to 'tracker-easy')
| -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 | 
12 files changed, 707 insertions, 942 deletions
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;  | 
