From 4039631386ae84abbf476263b28c92d91ac23b81 Mon Sep 17 00:00:00 2001 From: Stéphane Lenclud Date: Wed, 24 Apr 2019 23:34:36 +0200 Subject: Adding support for four points model. Can't get it to work correctly though. --- tracker-easy/lang/nl_NL.ts | 40 +++--- tracker-easy/lang/ru_RU.ts | 41 +++--- tracker-easy/lang/stub.ts | 40 +++--- tracker-easy/lang/zh_CN.ts | 40 +++--- tracker-easy/point-extractor.cpp | 4 +- tracker-easy/point-extractor.h | 5 +- tracker-easy/preview.cpp | 10 +- tracker-easy/preview.h | 2 +- tracker-easy/settings.h | 6 +- tracker-easy/tracker-easy-dialog.cpp | 20 ++- tracker-easy/tracker-easy-settings.ui | 261 +++++++++++++++++++++++++++------- tracker-easy/tracker-easy.cpp | 116 ++++++++++++--- tracker-easy/tracker-easy.h | 8 ++ 13 files changed, 437 insertions(+), 156 deletions(-) diff --git a/tracker-easy/lang/nl_NL.ts b/tracker-easy/lang/nl_NL.ts index 22a99106..f084f93f 100644 --- a/tracker-easy/lang/nl_NL.ts +++ b/tracker-easy/lang/nl_NL.ts @@ -141,10 +141,6 @@ Cap - - Custom - - z: @@ -153,22 +149,10 @@ x: - - <html><head/><body><p>Location of the two remaining model points<br/>with respect to the reference point in default pose</p><p>Use any units you want, not necessarily centimeters.</p></body></html> - - y: - - <html><head/><body><p><span style=" font-size:16pt;">P</span><span style=" font-size:16pt; vertical-align:sub;">3</span></p></body></html> - - - - <html><head/><body><p><span style=" font-size:16pt;">P</span><span style=" font-size:16pt; vertical-align:sub;">2</span></p></body></html> - - Model position @@ -254,5 +238,29 @@ Don't roll or change position. Settings + + Four + + + + Model vertices + + + + <html><head/><body><p><span style=" font-size:16pt;">Top</span></p></body></html> + + + + <html><head/><body><p><span style=" font-size:16pt;">Left</span></p></body></html> + + + + <html><head/><body><p><span style=" font-size:16pt;">Right</span></p></body></html> + + + + <html><head/><body><p><span style=" font-size:16pt;">Center</span></p></body></html> + + diff --git a/tracker-easy/lang/ru_RU.ts b/tracker-easy/lang/ru_RU.ts index d45c89d1..e05e58f3 100644 --- a/tracker-easy/lang/ru_RU.ts +++ b/tracker-easy/lang/ru_RU.ts @@ -141,10 +141,6 @@ Cap Кепка - - Custom - Свой - z: @@ -153,23 +149,10 @@ x: - - <html><head/><body><p>Location of the two remaining model points<br/>with respect to the reference point in default pose</p><p>Use any units you want, not necessarily centimeters.</p></body></html> - Расположение двух оставшихся точек модели относительно опорной точки в стандартной позе. Возможно исп-ть любые единицы измерения, не обязательно сантиметры. - <html><head/><body><p> Расположение двух оставшихся точек модели<br/>относительно опорной точки в стандартной позе. </p><p>Возможно использовать любые единицы измерения.</p></body></html - y: - - <html><head/><body><p><span style=" font-size:16pt;">P</span><span style=" font-size:16pt; vertical-align:sub;">3</span></p></body></html> - - - - <html><head/><body><p><span style=" font-size:16pt;">P</span><span style=" font-size:16pt; vertical-align:sub;">2</span></p></body></html> - - Model position Положение модели @@ -259,5 +242,29 @@ ROLL или X/Y-смещения. Settings + + Four + + + + Model vertices + + + + <html><head/><body><p><span style=" font-size:16pt;">Top</span></p></body></html> + + + + <html><head/><body><p><span style=" font-size:16pt;">Left</span></p></body></html> + + + + <html><head/><body><p><span style=" font-size:16pt;">Right</span></p></body></html> + + + + <html><head/><body><p><span style=" font-size:16pt;">Center</span></p></body></html> + + diff --git a/tracker-easy/lang/stub.ts b/tracker-easy/lang/stub.ts index 1b58a8f4..89c6d087 100644 --- a/tracker-easy/lang/stub.ts +++ b/tracker-easy/lang/stub.ts @@ -141,10 +141,6 @@ Cap - - Custom - - z: @@ -153,22 +149,10 @@ x: - - <html><head/><body><p>Location of the two remaining model points<br/>with respect to the reference point in default pose</p><p>Use any units you want, not necessarily centimeters.</p></body></html> - - y: - - <html><head/><body><p><span style=" font-size:16pt;">P</span><span style=" font-size:16pt; vertical-align:sub;">3</span></p></body></html> - - - - <html><head/><body><p><span style=" font-size:16pt;">P</span><span style=" font-size:16pt; vertical-align:sub;">2</span></p></body></html> - - Model position @@ -254,5 +238,29 @@ Don't roll or change position. Settings + + Four + + + + Model vertices + + + + <html><head/><body><p><span style=" font-size:16pt;">Top</span></p></body></html> + + + + <html><head/><body><p><span style=" font-size:16pt;">Left</span></p></body></html> + + + + <html><head/><body><p><span style=" font-size:16pt;">Right</span></p></body></html> + + + + <html><head/><body><p><span style=" font-size:16pt;">Center</span></p></body></html> + + diff --git a/tracker-easy/lang/zh_CN.ts b/tracker-easy/lang/zh_CN.ts index d524aaed..417de26a 100644 --- a/tracker-easy/lang/zh_CN.ts +++ b/tracker-easy/lang/zh_CN.ts @@ -141,10 +141,6 @@ Cap 帽子式 - - Custom - 自定义模式 - z: Z: @@ -153,22 +149,10 @@ x: X: - - <html><head/><body><p>Location of the two remaining model points<br/>with respect to the reference point in default pose</p><p>Use any units you want, not necessarily centimeters.</p></body></html> - <html><head/><body><p>三点中的两点位置是相对第一个点的</p><p>单位不一定要用厘米</p></body></html> - y: Y: - - <html><head/><body><p><span style=" font-size:16pt;">P</span><span style=" font-size:16pt; vertical-align:sub;">3</span></p></body></html> - <html><head/><body><p><span style=" font-size:16pt;">P</span><span style=" font-size:16pt; vertical-align:sub;">3</span></p></body></html> - - - <html><head/><body><p><span style=" font-size:16pt;">P</span><span style=" font-size:16pt; vertical-align:sub;">2</span></p></body></html> - <html><head/><body><p><span style=" font-size:16pt;">P</span><span style=" font-size:16pt; vertical-align:sub;">2</span></p></body></html> - Model position 姿态空间位置 @@ -254,5 +238,29 @@ Don't roll or change position. Settings + + Four + + + + Model vertices + + + + <html><head/><body><p><span style=" font-size:16pt;">Top</span></p></body></html> + + + + <html><head/><body><p><span style=" font-size:16pt;">Left</span></p></body></html> + + + + <html><head/><body><p><span style=" font-size:16pt;">Right</span></p></body></html> + + + + <html><head/><body><p><span style=" font-size:16pt;">Center</span></p></body></html> + + diff --git a/tracker-easy/point-extractor.cpp b/tracker-easy/point-extractor.cpp index 61175a57..0a5ca81d 100644 --- a/tracker-easy/point-extractor.cpp +++ b/tracker-easy/point-extractor.cpp @@ -35,7 +35,7 @@ namespace EasyTracker } - void PointExtractor::ExtractPoints(const cv::Mat& aFrame, cv::Mat* aPreview, std::vector& aPoints) + void PointExtractor::ExtractPoints(const cv::Mat& aFrame, cv::Mat* aPreview, int aNeededPointCount, std::vector& aPoints) { //TODO: Assert if channel size is neither one nor two // Make sure our frame channel is 8 bit @@ -133,7 +133,7 @@ namespace EasyTracker // Typically noise comming from zippers and metal parts on your clothing. // With a cap tracker it also successfully discards noise from glasses. // However it may not work as good with a clip user wearing glasses. - while (aPoints.size() > KPointCount) // Until we have no more than three points + while (aPoints.size() > aNeededPointCount) // Until we have no more than three points { int maxY = 0; size_t index = -1; diff --git a/tracker-easy/point-extractor.h b/tracker-easy/point-extractor.h index 3c65b193..b037eed6 100644 --- a/tracker-easy/point-extractor.h +++ b/tracker-easy/point-extractor.h @@ -17,16 +17,13 @@ namespace EasyTracker { - - const int KPointCount = 3; - class PointExtractor { public: PointExtractor(); // 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, std::vector& aPoints); + void ExtractPoints(const cv::Mat& aFrame, cv::Mat* aPreview, int aNeededPointCount, std::vector& aPoints); // Settings Settings s; diff --git a/tracker-easy/preview.cpp b/tracker-easy/preview.cpp index 4d6b7c61..218fca43 100644 --- a/tracker-easy/preview.cpp +++ b/tracker-easy/preview.cpp @@ -105,19 +105,17 @@ namespace EasyTracker cv::putText(iFrameRgb, aString, cv::Point(4,iFrameRgb.size().height-4), cv::FONT_HERSHEY_PLAIN, 2, cv::Scalar(0, 255, 0),2); } - void Preview::DrawCross(cv::Point aPoint) + void Preview::DrawCross(const cv::Point& aPoint, const cv::Scalar& aColor) { - constexpr int len = 9; - - static const cv::Scalar color(0, 255, 255); + constexpr int len = 9; cv::line(iFrameRgb, cv::Point(aPoint.x - len, aPoint.y), cv::Point(aPoint.x + len, aPoint.y), - color, 2); + aColor, 2); cv::line(iFrameRgb, cv::Point(aPoint.x, aPoint.y - len), cv::Point(aPoint.x, aPoint.y + len), - color, 2); + aColor, 2); } void Preview::ensure_size(cv::Mat& frame, int w, int h, int type) diff --git a/tracker-easy/preview.h b/tracker-easy/preview.h index 74ef89aa..d5cc8c30 100644 --- a/tracker-easy/preview.h +++ b/tracker-easy/preview.h @@ -21,7 +21,7 @@ namespace EasyTracker Preview& operator=(const cv::Mat& frame); QImage get_bitmap(); - void DrawCross(cv::Point aPoint); + void DrawCross(const cv::Point& aPoint, const cv::Scalar& aColor); void DrawInfo(const std::string& aString); operator cv::Mat&() { return iFrameResized; } diff --git a/tracker-easy/settings.h b/tracker-easy/settings.h index b4c14967..8c6a2b3e 100644 --- a/tracker-easy/settings.h +++ b/tracker-easy/settings.h @@ -27,8 +27,10 @@ namespace EasyTracker { max_point_size{ b, "max-point-size", 50 }; value DeadzoneRectHalfEdgeSize { b, "deadzone-rect-half-edge-size", 1 }; - value m01_x{ b, "m_01-x", 0 }, m01_y{ b, "m_01-y", 0 }, m01_z{ b, "m_01-z", 0 }; - value m02_x{ b, "m_02-x", 0 }, m02_y{ b, "m_02-y", 0 }, m02_z{ b, "m_02-z", 0 }; + value iFourPointsTopX{ b, "iFourPointsTopX", 0 }, iFourPointsTopY{ b, "iFourPointsTopY", 0 }, iFourPointsTopZ{ b, "iFourPointsTopZ", 0 }; + value iFourPointsLeftX{ b, "iFourPointsLeftX", 0 }, iFourPointsLeftY{ b, "iFourPointsLeftY", 0 }, iFourPointsLeftZ{ b, "iFourPointsLeftZ", 0 }; + value iFourPointsRightX{ b, "iFourPointsRightX", 0 }, iFourPointsRightY{ b, "iFourPointsRightY", 0 }, iFourPointsRightZ{ b, "iFourPointsRightZ", 0 }; + value iFourPointsCenterX{ b, "iFourPointsCenterX", 0 }, iFourPointsCenterY{ b, "iFourPointsCenterY", 0 }, iFourPointsCenterZ{ b, "iFourPointsCenterZ", 0 }; value t_MH_x{ b, "model-centroid-x", 0 }, t_MH_y{ b, "model-centroid-y", 0 }, diff --git a/tracker-easy/tracker-easy-dialog.cpp b/tracker-easy/tracker-easy-dialog.cpp index fe0091c5..ce100b48 100644 --- a/tracker-easy/tracker-easy-dialog.cpp +++ b/tracker-easy/tracker-easy-dialog.cpp @@ -55,13 +55,21 @@ namespace EasyTracker tie_setting(s.cap_y, ui.cap_height_spin); tie_setting(s.cap_z, ui.cap_length_spin); - tie_setting(s.m01_x, ui.m1x_spin); - tie_setting(s.m01_y, ui.m1y_spin); - tie_setting(s.m01_z, ui.m1z_spin); + tie_setting(s.iFourPointsTopX, ui.iSpinFourTopX); + tie_setting(s.iFourPointsTopY, ui.iSpinFourTopY); + tie_setting(s.iFourPointsTopZ, ui.iSpinFourTopZ); - tie_setting(s.m02_x, ui.m2x_spin); - tie_setting(s.m02_y, ui.m2y_spin); - tie_setting(s.m02_z, ui.m2z_spin); + tie_setting(s.iFourPointsLeftX, ui.iSpinFourLeftX); + tie_setting(s.iFourPointsLeftY, ui.iSpinFourLeftY); + tie_setting(s.iFourPointsLeftZ, ui.iSpinFourLeftZ); + + tie_setting(s.iFourPointsRightX, ui.iSpinFourRightX); + tie_setting(s.iFourPointsRightY, ui.iSpinFourRightY); + tie_setting(s.iFourPointsRightZ, ui.iSpinFourRightZ); + + tie_setting(s.iFourPointsCenterX, ui.iSpinFourCenterX); + tie_setting(s.iFourPointsCenterY, ui.iSpinFourCenterY); + tie_setting(s.iFourPointsCenterZ, ui.iSpinFourCenterZ); tie_setting(s.t_MH_x, ui.tx_spin); tie_setting(s.t_MH_y, ui.ty_spin); diff --git a/tracker-easy/tracker-easy-settings.ui b/tracker-easy/tracker-easy-settings.ui index 2ec56a04..9b9c67a8 100644 --- a/tracker-easy/tracker-easy-settings.ui +++ b/tracker-easy/tracker-easy-settings.ui @@ -9,7 +9,7 @@ 0 0 - 418 + 422 724 @@ -115,7 +115,7 @@ - 0 + 1 @@ -871,22 +871,35 @@ - + - false + true - Custom + Four - Model Dimensions + Model vertices - - + + + + mm + + + -65535 + + + 65535 + + + + + 0 @@ -894,12 +907,25 @@ - z: + x: - - + + + + + 0 + 0 + + + + y: + + + + + mm @@ -911,8 +937,8 @@ - - + + 0 @@ -920,12 +946,25 @@ - x: + z: - - + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-size:16pt;">Top</span></p></body></html> + + + + + mm @@ -937,8 +976,8 @@ - - + + mm @@ -950,8 +989,8 @@ - - + + mm @@ -963,8 +1002,8 @@ - - + + mm @@ -976,21 +1015,73 @@ - - + + - + + 0 + 0 + + + + <html><head/><body><p><span style=" font-size:16pt;">Left</span></p></body></html> + + + + + + + + 0 + 0 + + + + y: + + + + + + + 0 0 - <html><head/><body><p>Location of the two remaining model points<br/>with respect to the reference point in default pose</p><p>Use any units you want, not necessarily centimeters.</p></body></html> + z: + + + + + + + + 0 + 0 + + + + x: + + + + + + + + 0 + 0 + + + + <html><head/><body><p><span style=" font-size:16pt;">Right</span></p></body></html> - + mm @@ -1002,8 +1093,21 @@ - - + + + + + 0 + 0 + + + + x: + + + + + 0 @@ -1015,8 +1119,21 @@ - - + + + + mm + + + -65535 + + + 65535 + + + + + 0 @@ -1024,11 +1141,24 @@ - x: + z: - + + + + mm + + + -65535 + + + 65535 + + + + @@ -1037,12 +1167,12 @@ - <html><head/><body><p><span style=" font-size:16pt;">P</span><span style=" font-size:16pt; vertical-align:sub;">3</span></p></body></html> + <html><head/><body><p><span style=" font-size:16pt;">Center</span></p></body></html> - - + + 0 @@ -1050,12 +1180,25 @@ - <html><head/><body><p><span style=" font-size:16pt;">P</span><span style=" font-size:16pt; vertical-align:sub;">2</span></p></body></html> + x: - - + + + + mm + + + -65535 + + + 65535 + + + + + 0 @@ -1063,12 +1206,25 @@ - z: + y: - - + + + + mm + + + -65535 + + + 65535 + + + + + 0 @@ -1076,7 +1232,20 @@ - y: + z: + + + + + + + mm + + + -65535 + + + 65535 @@ -1318,12 +1487,6 @@ Don't roll or change position. cap_length_spin cap_height_spin cap_width_spin - m1x_spin - m1y_spin - m1z_spin - m2x_spin - m2y_spin - m2z_spin tx_spin ty_spin tz_spin diff --git a/tracker-easy/tracker-easy.cpp b/tracker-easy/tracker-easy.cpp index ebc6e128..971127d4 100644 --- a/tracker-easy/tracker-easy.cpp +++ b/tracker-easy/tracker-easy.cpp @@ -77,7 +77,6 @@ namespace EasyTracker // Compute Euler angles from rotation matrix void getEulerAngles(cv::Mat &rotCamerMatrix, cv::Vec3d &eulerAngles) { - cv::Mat cameraMatrix, rotMatrix, transVect, rotMatrixX, rotMatrixY, rotMatrixZ; double* _r = rotCamerMatrix.ptr(); double projMatrix[12] = { _r[0],_r[1],_r[2],0, @@ -100,11 +99,20 @@ namespace EasyTracker // 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. - // s.active_model_panel != PointModel::Clip iModel.clear(); - iModel.push_back(cv::Point3f(iSettings.cap_x / 10.0, iSettings.cap_z / 10.0, -iSettings.cap_y / 10.0)); // Right - iModel.push_back(cv::Point3f(-iSettings.cap_x / 10.0, iSettings.cap_z / 10.0, -iSettings.cap_y / 10.0)); // Left - iModel.push_back(cv::Point3f(0, 0, 0)); // Top + 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 + } + 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 + iModel.push_back(cv::Point3f(-iSettings.cap_x / 10.0, iSettings.cap_z / 10.0, -iSettings.cap_y / 10.0)); // Left + } } /// @@ -149,11 +157,14 @@ namespace EasyTracker } iPoints.clear(); - iPointExtractor.ExtractPoints(iMatFrame, (doPreview ? &iPreview.iFrameRgb : nullptr), iPoints); + iPointExtractor.ExtractPoints(iMatFrame, (doPreview ? &iPreview.iFrameRgb : nullptr), iModel.size(), iPoints); - const bool success = iPoints.size() >= KPointCount; + const bool success = iPoints.size() >= iModel.size(); int topPointIndex = -1; + int rightPointIndex = -1; + int leftPointIndex = -1; + int centerPointIndex = -1; { QMutexLocker l(¢er_lock); @@ -167,7 +178,7 @@ namespace EasyTracker // 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::max(); - for (int i = 0; i < 3; i++) + for (int i = 0; i < iPoints.size(); i++) { if (iPoints[i].y < minY) { @@ -176,11 +187,11 @@ namespace EasyTracker } } - int rightPointIndex = -1; + int maxX = 0; // Find right most point - for (int i = 0; i < 3; i++) + for (int i = 0; i < iPoints.size(); i++) { // Excluding top most point if (i != topPointIndex && iPoints[i].x > maxX) @@ -191,21 +202,38 @@ namespace EasyTracker } // Find left most point - int leftPointIndex = -1; - for (int i = 0; i < 3; i++) + + int minX = std::numeric_limits::max();; + for (int i = 0; i < iPoints.size(); i++) { - // Excluding top most point - if (i != topPointIndex && i != rightPointIndex) + // Excluding top most point and right most point + if (i != topPointIndex && i != rightPointIndex && iPoints[i].x < minX) { leftPointIndex = i; - break; + minX = iPoints[i].x; } } - // + // 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) + { + centerPointIndex = i; + } + } + + // Order matters + iTrackedPoints.push_back(iPoints[topPointIndex]); iTrackedPoints.push_back(iPoints[rightPointIndex]); iTrackedPoints.push_back(iPoints[leftPointIndex]); - iTrackedPoints.push_back(iPoints[topPointIndex]); + if (iModel.size() > iTrackedPoints.size()) + { + // We are tracking more than 3 points + iTrackedPoints.push_back(iPoints[centerPointIndex]); + } + bool movedEnough = true; // Check if we moved enough since last time we were here @@ -243,7 +271,32 @@ namespace EasyTracker iAngles.clear(); iBestSolutionIndex = -1; // Solve P3P problem with OpenCV - int solutionCount = cv::solveP3P(iModel, iTrackedPoints, iCameraMatrix, iDistCoeffsMatrix, iRotations, iTranslations, iSolver); + int solutionCount = 0; + if (iModel.size() == 3) + { + solutionCount = cv::solveP3P(iModel, iTrackedPoints, iCameraMatrix, iDistCoeffsMatrix, iRotations, iTranslations, iSolver); + } + else + { + //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) + { + solutionCount = 1; + iRotations.push_back(rotation); + iTranslations.push_back(translation); + } + } + if (solutionCount > 0) { @@ -306,13 +359,34 @@ namespace EasyTracker ss << "FPS: " << iFps << "/" << iSkippedFps; iPreview.DrawInfo(ss.str()); - // + //Color is BGR if (topPointIndex != -1) { // Render a cross to indicate which point is the head - iPreview.DrawCross(iPoints[topPointIndex]); + static const cv::Scalar color(0, 255, 255); // Yellow + iPreview.DrawCross(iPoints[topPointIndex],color); + } + + if (rightPointIndex != -1) + { + static const cv::Scalar color(255, 0, 255); // Pink + iPreview.DrawCross(iPoints[rightPointIndex], color); } + if (leftPointIndex != -1) + { + static const cv::Scalar color(255, 0, 0); // Blue + iPreview.DrawCross(iPoints[leftPointIndex], color); + } + + if (centerPointIndex != -1) + { + static const cv::Scalar color(0, 255, 0); // Green + iPreview.DrawCross(iPoints[centerPointIndex], color); + } + + + // Render our deadzone rects for (const cv::Rect& rect : iTrackedRects) { @@ -462,7 +536,7 @@ namespace EasyTracker module_status Tracker::start_tracker(QFrame* video_frame) { // Check that we support that solver - if (iSolver!=cv::SOLVEPNP_P3P && iSolver != cv::SOLVEPNP_AP3P) + if (iSolver!=cv::SOLVEPNP_P3P && iSolver != cv::SOLVEPNP_AP3P && iModel.size()==3) { return module_status("Error: Solver not supported use either P3P or AP3P."); } diff --git a/tracker-easy/tracker-easy.h b/tracker-easy/tracker-easy.h index 41226d23..37337087 100644 --- a/tracker-easy/tracker-easy.h +++ b/tracker-easy/tracker-easy.h @@ -33,6 +33,14 @@ namespace EasyTracker { + // Order matters, it must match the order of the UI tabs + enum ModelType + { + Clip, + Cap, + FourPoints + }; + static const QString KModuleName = "tracker-easy"; class Dialog; -- cgit v1.2.3 From 518becf76bb5313949c76e9fa02d1ada2c25242d Mon Sep 17 00:00:00 2001 From: Stéphane Lenclud Date: Sat, 27 Apr 2019 18:06:06 +0200 Subject: Easy Tracker: Auto center when user removes her hat. --- tracker-easy/tracker-easy.cpp | 100 +++++++++++++++++++++++++++--------------- tracker-easy/tracker-easy.h | 8 +++- 2 files changed, 71 insertions(+), 37 deletions(-) diff --git a/tracker-easy/tracker-easy.cpp b/tracker-easy/tracker-easy.cpp index 971127d4..adffa33d 100644 --- a/tracker-easy/tracker-easy.cpp +++ b/tracker-easy/tracker-easy.cpp @@ -167,12 +167,10 @@ namespace EasyTracker int centerPointIndex = -1; { - QMutexLocker l(¢er_lock); + QMutexLocker l(&iProcessLock); if (success) { - ever_success.store(true, std::memory_order_relaxed); - //Bitmap origin is top left iTrackedPoints.clear(); // Tracked points must match the order of the object model points. @@ -252,7 +250,14 @@ namespace EasyTracker } } - if (movedEnough) + 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(); @@ -296,7 +301,9 @@ namespace EasyTracker iTranslations.push_back(translation); } } - + + // Reset best solution index + iBestSolutionIndex = -1; if (solutionCount > 0) { @@ -331,26 +338,28 @@ namespace EasyTracker dbgout << "\n"; } - } - } - - - 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]); - - // Send solution data back to main thread - QMutexLocker l2(&data_lock); - iBestAngles = angles; - iBestTranslation = translation; - } + 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(); + } + } + } } if (doPreview) @@ -518,7 +527,7 @@ namespace EasyTracker void Tracker::UpdateDeadzones(int aHalfEdgeSize) { - QMutexLocker l(¢er_lock); + QMutexLocker l(&iProcessLock); iDeadzoneHalfEdge = aHalfEdgeSize; iDeadzoneEdge = iDeadzoneHalfEdge * 2; iTrackedRects.clear(); @@ -527,7 +536,7 @@ namespace EasyTracker void Tracker::UpdateSolver(int aSolver) { - QMutexLocker l(¢er_lock); + QMutexLocker l(&iProcessLock); iSolver = aSolver; } @@ -568,29 +577,48 @@ namespace EasyTracker return {}; } + // + void FeedData(double* aData, const cv::Vec3d& aAngles, const cv::Vec3d& aTranslation) + { + aData[Yaw] = aAngles[1]; + aData[Pitch] = aAngles[0]; + aData[Roll] = aAngles[2]; + aData[TX] = aTranslation[0]; + aData[TY] = aTranslation[1]; + aData[TZ] = aTranslation[2]; + } + // // That's called around 250 times per second. // Therefore we better not do anything here other than provide current data. // - void Tracker::data(double *data) + void Tracker::data(double* aData) { if (ever_success.load(std::memory_order_relaxed)) { // Get data back from tracker thread - QMutexLocker l(&data_lock); - data[Yaw] = iBestAngles[1]; - data[Pitch] = iBestAngles[0]; - data[Roll] = iBestAngles[2]; - data[TX] = iBestTranslation[0]; - data[TY] = iBestTranslation[1]; - data[TZ] = iBestTranslation[2]; + 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. + if (iBestTime.elapsed_seconds() > 1) + { + // Reset to center until we get new data + FeedData(aData, iCenterAngles, iCenterTranslation); + } + else + { + // We got valid data, provide it + FeedData(aData, iBestAngles, iBestTranslation); + } } } bool Tracker::center() { - QMutexLocker l(¢er_lock); - //TODO: Do we need to do anything there? + QMutexLocker l(&iDataLock); + iCenterTranslation = iBestTranslation; + iCenterAngles = iBestAngles; + // Returning false tells the pipeline we want to use the default center behaviour return false; } diff --git a/tracker-easy/tracker-easy.h b/tracker-easy/tracker-easy.h index 37337087..65b777bf 100644 --- a/tracker-easy/tracker-easy.h +++ b/tracker-easy/tracker-easy.h @@ -101,7 +101,7 @@ namespace EasyTracker Preview iPreview; std::atomic ever_success = false; - mutable QMutex center_lock, data_lock; + mutable QMutex iProcessLock, iDataLock; // Deadzone int iDeadzoneEdge=0; @@ -144,6 +144,12 @@ namespace EasyTracker cv::Vec3d iBestTranslation; // Best angles cv::Vec3d iBestAngles; + // Time at which we found our last best solution + Timer iBestTime; + // Center translation + cv::Vec3d iCenterTranslation = {0,0,0}; + // Center angles + cv::Vec3d iCenterAngles = { 0,0,0 }; }; } -- cgit v1.2.3 From 3e56f47a9cef709d4a099a0ac6ff43e361fe4a43 Mon Sep 17 00:00:00 2001 From: Stéphane Lenclud Date: Sun, 28 Apr 2019 00:03:24 +0200 Subject: 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. --- options/tie.cpp | 7 + options/tie.hpp | 2 + tracker-easy/lang/nl_NL.ts | 89 ++--- tracker-easy/lang/ru_RU.ts | 93 ++--- tracker-easy/lang/stub.ts | 89 ++--- tracker-easy/lang/zh_CN.ts | 89 ++--- tracker-easy/point-extractor.cpp | 19 +- tracker-easy/point-extractor.h | 10 +- tracker-easy/settings.h | 23 +- tracker-easy/tracker-easy-dialog.cpp | 126 +++--- tracker-easy/tracker-easy-dialog.h | 7 +- tracker-easy/tracker-easy-settings.ui | 702 ++++++++++++---------------------- tracker-easy/tracker-easy.cpp | 391 ++++++++++--------- tracker-easy/tracker-easy.h | 11 +- 14 files changed, 716 insertions(+), 942 deletions(-) diff --git a/options/tie.cpp b/options/tie.cpp index 671a72c2..8220854d 100644 --- a/options/tie.cpp +++ b/options/tie.cpp @@ -72,6 +72,13 @@ void tie_setting(value& v, QComboBox* cb) // XXX TODO need variant with setEnabled based on lambda retval -- sh 20170524 +void tie_setting(value& v, QRadioButton* cb) +{ + cb->setChecked(v); + value_::connect(cb, SIGNAL(toggled(bool)), &v, SLOT(setValue(bool)), v.DIRECT_CONNTYPE); + value_::connect(&v, SIGNAL(valueChanged(bool)), cb, SLOT(setChecked(bool)), v.SAFE_CONNTYPE); +} + void tie_setting(value& v, QCheckBox* cb) { cb->setChecked(v); diff --git a/options/tie.hpp b/options/tie.hpp index c2607a6c..2ac27d64 100644 --- a/options/tie.hpp +++ b/options/tie.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include @@ -97,6 +98,7 @@ OTR_OPTIONS_EXPORT void tie_setting(value& v, QComboBox* cb); OTR_OPTIONS_EXPORT void tie_setting(value& v, QComboBox* cb); OTR_OPTIONS_EXPORT void tie_setting(value& v, QComboBox* cb); OTR_OPTIONS_EXPORT void tie_setting(value& v, QCheckBox* cb); +OTR_OPTIONS_EXPORT void tie_setting(value& v, QRadioButton* cb); OTR_OPTIONS_EXPORT void tie_setting(value& v, QDoubleSpinBox* dsb); OTR_OPTIONS_EXPORT void tie_setting(value& v, QSpinBox* sb); OTR_OPTIONS_EXPORT void tie_setting(value& v, QLineEdit* le); diff --git a/tracker-easy/lang/nl_NL.ts b/tracker-easy/lang/nl_NL.ts index f084f93f..9b7ae1dd 100644 --- a/tracker-easy/lang/nl_NL.ts +++ b/tracker-easy/lang/nl_NL.ts @@ -3,26 +3,6 @@ EasyTracker::Dialog - - %1 yaw samples. Yaw more to %2 samples for stable calibration. - - - - %1 pitch samples. Pitch more to %2 samples for stable calibration. - - - - %1 samples. Over %2, good! - - - - Stop calibration - - - - Start calibration - - Tracker offline @@ -141,31 +121,6 @@ Cap - - z: - - - - x: - - - - y: - - - - Model position - - - - Use only yaw and pitch while calibrating. -Don't roll or change position. - - - - Start calibration - - About @@ -239,27 +194,59 @@ Don't roll or change position. - Four + Custom + + + + Top Right + + + + Top + + + + Top Left + + + + Left + + + + Vertex count + + + + Three vertices + + + + Four vertices + + + + Five vertices - Model vertices + Center - <html><head/><body><p><span style=" font-size:16pt;">Top</span></p></body></html> + Right - <html><head/><body><p><span style=" font-size:16pt;">Left</span></p></body></html> + <html><head/><body><p><span style=" font-size:12pt;">X</span></p></body></html> - <html><head/><body><p><span style=" font-size:16pt;">Right</span></p></body></html> + <html><head/><body><p><span style=" font-size:12pt;">Y</span></p></body></html> - <html><head/><body><p><span style=" font-size:16pt;">Center</span></p></body></html> + <html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html> 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 @@ -3,26 +3,6 @@ EasyTracker::Dialog - - %1 yaw samples. Yaw more to %2 samples for stable calibration. - По оси YAW выполнено: %1 замер(а/ов). Для стабильного результата необходимо не меньше %2 - - - %1 pitch samples. Pitch more to %2 samples for stable calibration. - По оси Pitch выполнено: %1 замер(а/ов). Для стабильного результата необходимо не меньше %2 - - - %1 samples. Over %2, good! - Получено %1 образца(-ов). Больше %2, отлично!! - - - Stop calibration - Остановить калибровку - - - Start calibration - Начать калибровку - Tracker offline Отслеживание отключено @@ -141,35 +121,6 @@ Cap Кепка - - z: - - - - x: - - - - y: - - - - Model position - Положение модели - - - Use only yaw and pitch while calibrating. -Don't roll or change position. - Во время калибровки -используйте только оси -YAW и PITCH. -Не используйте оси -ROLL или X/Y-смещения. - - - Start calibration - Начать калибровку - About О программе @@ -243,27 +194,59 @@ ROLL или X/Y-смещения. - Four + Custom + + + + Top Right + + + + Top + + + + Top Left + + + + Left + + + + Vertex count + + + + Three vertices + + + + Four vertices + + + + Five vertices - Model vertices + Center - <html><head/><body><p><span style=" font-size:16pt;">Top</span></p></body></html> + Right - <html><head/><body><p><span style=" font-size:16pt;">Left</span></p></body></html> + <html><head/><body><p><span style=" font-size:12pt;">X</span></p></body></html> - <html><head/><body><p><span style=" font-size:16pt;">Right</span></p></body></html> + <html><head/><body><p><span style=" font-size:12pt;">Y</span></p></body></html> - <html><head/><body><p><span style=" font-size:16pt;">Center</span></p></body></html> + <html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html> 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 @@ -3,26 +3,6 @@ EasyTracker::Dialog - - %1 yaw samples. Yaw more to %2 samples for stable calibration. - - - - %1 pitch samples. Pitch more to %2 samples for stable calibration. - - - - %1 samples. Over %2, good! - - - - Stop calibration - - - - Start calibration - - Tracker offline @@ -141,31 +121,6 @@ Cap - - z: - - - - x: - - - - y: - - - - Model position - - - - Use only yaw and pitch while calibrating. -Don't roll or change position. - - - - Start calibration - - About @@ -239,27 +194,59 @@ Don't roll or change position. - Four + Custom + + + + Top Right + + + + Top + + + + Top Left + + + + Left + + + + Vertex count + + + + Three vertices + + + + Four vertices + + + + Five vertices - Model vertices + Center - <html><head/><body><p><span style=" font-size:16pt;">Top</span></p></body></html> + Right - <html><head/><body><p><span style=" font-size:16pt;">Left</span></p></body></html> + <html><head/><body><p><span style=" font-size:12pt;">X</span></p></body></html> - <html><head/><body><p><span style=" font-size:16pt;">Right</span></p></body></html> + <html><head/><body><p><span style=" font-size:12pt;">Y</span></p></body></html> - <html><head/><body><p><span style=" font-size:16pt;">Center</span></p></body></html> + <html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html> 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 @@ -3,26 +3,6 @@ EasyTracker::Dialog - - %1 yaw samples. Yaw more to %2 samples for stable calibration. - - - - %1 pitch samples. Pitch more to %2 samples for stable calibration. - - - - %1 samples. Over %2, good! - %1 样本。%2 正常 - - - Stop calibration - 停止校准 - - - Start calibration - 开始校准 - Tracker offline 跟踪器脱机 @@ -141,26 +121,6 @@ Cap 帽子式 - - z: - Z: - - - x: - X: - - - y: - Y: - - - Model position - 姿态空间位置 - - - Start calibration - 开始校准 - About 关于 @@ -177,11 +137,6 @@ Camera Info: 设备信息: - - Use only yaw and pitch while calibrating. -Don't roll or change position. - 用pitch和yaw校准。不要roll或者变换位置 - Debug (full size preview) @@ -239,27 +194,59 @@ Don't roll or change position. - Four + Custom + + + + Top Right + + + + Top + + + + Top Left + + + + Left + + + + Vertex count + + + + Three vertices + + + + Four vertices + + + + Five vertices - Model vertices + Center - <html><head/><body><p><span style=" font-size:16pt;">Top</span></p></body></html> + Right - <html><head/><body><p><span style=" font-size:16pt;">Left</span></p></body></html> + <html><head/><body><p><span style=" font-size:12pt;">X</span></p></body></html> - <html><head/><body><p><span style=" font-size:16pt;">Right</span></p></body></html> + <html><head/><body><p><span style=" font-size:12pt;">Y</span></p></body></html> - <html><head/><body><p><span style=" font-size:16pt;">Center</span></p></body></html> + <html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html> 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& 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& 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 > 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 cam_res_x{ b, "camera-res-width", 640 }, cam_res_y{ b, "camera-res-height", 480 }, cam_fps{ b, "camera-fps", 30 }; - value min_point_size{ b, "min-point-size", 2.5 }, - max_point_size{ b, "max-point-size", 50 }; + value iMinBlobSize{ b, "iMinBlobSize", 4 }, iMaxBlobSize{ b, "iMaxBlobSize", 15 }; value DeadzoneRectHalfEdgeSize { b, "deadzone-rect-half-edge-size", 1 }; - value iFourPointsTopX{ b, "iFourPointsTopX", 0 }, iFourPointsTopY{ b, "iFourPointsTopY", 0 }, iFourPointsTopZ{ b, "iFourPointsTopZ", 0 }; - value iFourPointsLeftX{ b, "iFourPointsLeftX", 0 }, iFourPointsLeftY{ b, "iFourPointsLeftY", 0 }, iFourPointsLeftZ{ b, "iFourPointsLeftZ", 0 }; - value iFourPointsRightX{ b, "iFourPointsRightX", 0 }, iFourPointsRightY{ b, "iFourPointsRightY", 0 }, iFourPointsRightZ{ b, "iFourPointsRightZ", 0 }; - value iFourPointsCenterX{ b, "iFourPointsCenterX", 0 }, iFourPointsCenterY{ b, "iFourPointsCenterY", 0 }, iFourPointsCenterZ{ b, "iFourPointsCenterZ", 0 }; + // Type of custom model + value iCustomModelThree{ b, "iCustomModelThree", true }; + value iCustomModelFour{ b, "iCustomModelFour", false }; + value iCustomModelFive{ b, "iCustomModelFive", false }; + + // Custom model vertices + value iVertexTopX{ b, "iVertexTopX", 0 }, iVertexTopY{ b, "iVertexTopY", 0 }, iVertexTopZ{ b, "iVertexTopZ", 0 }; + value iVertexRightX{ b, "iVertexRightX", 0 }, iVertexRightY{ b, "iVertexRightY", 0 }, iVertexRightZ{ b, "iVertexRightZ", 0 }; + value iVertexLeftX{ b, "iVertexLeftX", 0 }, iVertexLeftY{ b, "iVertexLeftY", 0 }, iVertexLeftZ{ b, "iVertexLeftZ", 0 }; + value iVertexCenterX{ b, "iVertexCenterX", 0 }, iVertexCenterY{ b, "iVertexCenterY", 0 }, iVertexCenterZ{ b, "iVertexCenterZ", 0 }; + value iVertexTopRightX{ b, "iVertexTopRightX", 0 }, iVertexTopRightY{ b, "iVertexTopRightY", 0 }, iVertexTopRightZ{ b, "iVertexTopRightZ", 0 }; + value iVertexTopLeftX{ b, "iVertexTopLeftX", 0 }, iVertexTopLeftY{ b, "iVertexTopLeftY", 0 }, iVertexTopLeftZ{ b, "iVertexTopLeftZ", 0 }; - value 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 clip_ty{ b, "clip-ty", 40 }, clip_tz{ b, "clip-tz", 30 }, @@ -50,6 +54,7 @@ namespace EasyTracker { value debug{ b, "debug", false }; + value 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(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 @@ 0 0 - 422 - 724 + 465 + 764 @@ -36,71 +36,17 @@ QLayout::SetFixedSize - - + + 0 0 - - Status + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - 0 - 0 - - - - Extracted Points: - - - - - - - - 0 - 0 - - - - Camera Info: - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - - - - - @@ -115,7 +61,7 @@ - 1 + 0 @@ -387,9 +333,6 @@ Max size - - maxdiam_spin - @@ -477,8 +420,8 @@ - - + + 0 @@ -486,21 +429,15 @@ - Minimum point diameter + Size in pixels of half the edge defining deadzone squares around tracked points px - - 1 - - - 0.100000000000000 - - + 0 @@ -513,16 +450,10 @@ px - - 1 - - - 0.100000000000000 - - - + + 0 @@ -530,7 +461,7 @@ - Size in pixels of half the edge defining deadzone squares around tracked points + Minimum point diameter px @@ -871,61 +802,55 @@ - + true - Four + Custom - - + + - Model vertices + - - - - - mm - - - -65535 - - - 65535 + + false + + + + + + <html><head/><body><p><span style=" font-size:12pt;">X</span></p></body></html> - - - - - 0 - 0 - - + + - x: + <html><head/><body><p><span style=" font-size:12pt;">Y</span></p></body></html> - - - - - 0 - 0 - - + + - y: + <html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html> - - + + + + + + + Top Right + + + + mm @@ -937,34 +862,43 @@ - - - - - 0 - 0 - + + + + mm - - z: + + -65535 + + + 65535 - - - - - 0 - 0 - + + + + mm - - <html><head/><body><p><span style=" font-size:16pt;">Top</span></p></body></html> + + -65535 + + + 65535 - - + + + + + + + Top Left + + + + mm @@ -976,8 +910,8 @@ - - + + mm @@ -989,8 +923,8 @@ - - + + mm @@ -1002,8 +936,17 @@ - - + + + + + + + Left + + + + mm @@ -1015,73 +958,76 @@ - - - - - 0 - 0 - + + + + mm - - <html><head/><body><p><span style=" font-size:16pt;">Left</span></p></body></html> + + -65535 + + + 65535 - - - - - 0 - 0 - + + + + mm - - y: + + -65535 + + + 65535 - - - - - 0 - 0 - - + + + + + + + Vertex count + + + + - z: + Three vertices + + + true - - - - - 0 - 0 - - + + - x: + Four vertices - - - - - 0 - 0 - - + + - <html><head/><body><p><span style=" font-size:16pt;">Right</span></p></body></html> + Five vertices - - + + + + + + + Center + + + + mm @@ -1093,34 +1039,21 @@ - - - - - 0 - 0 - - - - x: + + + + mm - - - - - - - 0 - 0 - + + -65535 - - y: + + 65535 - - + + mm @@ -1132,21 +1065,17 @@ - - - - - 0 - 0 - - - - z: - - - - - + + + + + + + Right + + + + mm @@ -1158,34 +1087,21 @@ - - - - - 0 - 0 - - - - <html><head/><body><p><span style=" font-size:16pt;">Center</span></p></body></html> + + + + mm - - - - - - - 0 - 0 - + + -65535 - - x: + + 65535 - - + + mm @@ -1197,21 +1113,20 @@ - - - - - 0 - 0 - - - - y: - - - - - + + + + + + + Top + + + + 9 + + + mm @@ -1223,21 +1138,21 @@ - - - - - 0 - 0 - + + + + mm - - z: + + -65535 + + + 65535 - - + + mm @@ -1256,169 +1171,6 @@ - - - - - 0 - 0 - - - - Model position - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - - - mm - - - -65535 - - - 65536 - - - - - - - - 0 - 0 - - - - z: - - - - - - - mm - - - -65535 - - - 65536 - - - - - - - - 0 - 0 - - - - x: - - - - - - - mm - - - -65535 - - - 65536 - - - - - - - - 0 - 0 - - - - y: - - - - - - - - - - QFrame::NoFrame - - - QFrame::Raised - - - - - - Use only yaw and pitch while calibrating. -Don't roll or change position. - - - Qt::AlignCenter - - - true - - - false - - - - - - - - 0 - 0 - - - - - - - true - - - - - - - false - - - Start calibration - - - true - - - - - - - - - @@ -1456,17 +1208,71 @@ Don't roll or change position. - - + + 0 0 - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + Status + + + + + + 0 + 0 + + + + Extracted Points: + + + + + + + + 0 + 0 + + + + Camera Info: + + + + + + + + 0 + 0 + + + + + + + + + + + + 0 + 0 + + + + + + + + @@ -1487,10 +1293,6 @@ Don't roll or change position. cap_length_spin cap_height_spin cap_width_spin - tx_spin - ty_spin - tz_spin - tcalib_button 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(), this, &Tracker::SetFps, Qt::DirectConnection); // Make sure deadzones are updated whenever the settings are changed - connect(&iSettings.DeadzoneRectHalfEdgeSize, value_::value_changed(), this, &Tracker::UpdateDeadzones, Qt::DirectConnection); - UpdateDeadzones(iSettings.DeadzoneRectHalfEdgeSize); + connect(&iSettings.DeadzoneRectHalfEdgeSize, value_::value_changed(), this, &Tracker::UpdateSettings, Qt::DirectConnection); + + // Update point extractor whenever some of the settings it needs are changed + connect(&iSettings.iMinBlobSize, value_::value_changed(), this, &Tracker::UpdateSettings, Qt::DirectConnection); + connect(&iSettings.iMaxBlobSize, value_::value_changed(), this, &Tracker::UpdateSettings, Qt::DirectConnection); // Make sure solver is updated whenever the settings are changed - connect(&iSettings.PnpSolver, value_::value_changed(), this, &Tracker::UpdateSolver, Qt::DirectConnection); - UpdateSolver(iSettings.PnpSolver); + connect(&iSettings.PnpSolver, value_::value_changed(), this, &Tracker::UpdateSettings, Qt::DirectConnection); + + // Debug + connect(&iSettings.debug, value_::value_changed(), this, &Tracker::UpdateSettings, Qt::DirectConnection); + + // Make sure model is updated whenever it is changed + connect(&iSettings.iCustomModelThree, value_::value_changed(), this, &Tracker::UpdateModel, Qt::DirectConnection); + connect(&iSettings.iCustomModelFour, value_::value_changed(), this, &Tracker::UpdateModel, Qt::DirectConnection); + connect(&iSettings.iCustomModelFive, value_::value_changed(), this, &Tracker::UpdateModel, Qt::DirectConnection); + + // Update model logic + #define UM(v) connect(&iSettings.v, value_::value_changed(), 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(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::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::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::max();; - for (int i = 0; i < iPoints.size(); i++) + // Find left most point + int minX = std::numeric_limits::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::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::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 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; -- cgit v1.2.3 From 389f77790d649a9da852ff7df3e0717b4c4dc1c3 Mon Sep 17 00:00:00 2001 From: Stéphane Lenclud Date: Sun, 28 Apr 2019 09:14:13 +0200 Subject: Easy Tracker: Adding basic bad pose filter based on pitch consistency. Working toward five vertices support. --- tracker-easy/tracker-easy.cpp | 203 ++++++++++++++++++++++++++---------------- tracker-easy/tracker-easy.h | 8 +- 2 files changed, 132 insertions(+), 79 deletions(-) diff --git a/tracker-easy/tracker-easy.cpp b/tracker-easy/tracker-easy.cpp index 68729567..220765cc 100644 --- a/tracker-easy/tracker-easy.cpp +++ b/tracker-easy/tracker-easy.cpp @@ -24,11 +24,14 @@ using namespace options; // Disable debug -#define dbgout if (true) {} else std::cout +#define dbgout if (true) {} else std::cout << "\n" <::max(); + for (int i = 0; i < iPoints.size(); i++) + { + if (iPoints[i].y < minY) + { + minY = iPoints[i].y; + aTopIndex = i; + } + } + + + int maxX = 0; + + // Find right most point + for (int i = 0; i < iPoints.size(); i++) + { + // Excluding top most point + if (i != aTopIndex && iPoints[i].x > maxX) + { + maxX = iPoints[i].x; + aRightIndex = i; + } + } + + // Find left most point + int minX = std::numeric_limits::max(); + for (int i = 0; i < iPoints.size(); i++) + { + // Excluding top most point and right most point + if (i != aTopIndex && i != aRightIndex && iPoints[i].x < minX) + { + aLeftIndex = i; + minX = iPoints[i].x; + } + } + + // Find center point, the last one + for (int i = 0; i < iPoints.size(); i++) + { + // Excluding the three points we already have + if (i != aTopIndex && i != aRightIndex && i != aLeftIndex) + { + aCenterIndex = i; + } + } + + // Order matters + iTrackedPoints.push_back(iPoints[aTopIndex]); + iTrackedPoints.push_back(iPoints[aRightIndex]); + iTrackedPoints.push_back(iPoints[aLeftIndex]); + if (iModel.size() > iTrackedPoints.size()) + { + // We are tracking more than 3 points + iTrackedPoints.push_back(iPoints[aCenterIndex]); + } + + + } + + + /// /// /// @@ -199,71 +293,13 @@ namespace EasyTracker int rightPointIndex = -1; int leftPointIndex = -1; int centerPointIndex = -1; - - + int topRightPointIndex = -1; + int topLeftPointIndex = -1; 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::max(); - for (int i = 0; i < iPoints.size(); i++) - { - if (iPoints[i].y < minY) - { - minY = iPoints[i].y; - topPointIndex = i; - } - } - - - int maxX = 0; - - // Find right most point - for (int i = 0; i < iPoints.size(); i++) - { - // Excluding top most point - if (i != topPointIndex && iPoints[i].x > maxX) - { - maxX = iPoints[i].x; - rightPointIndex = i; - } - } - - // Find left most point - int minX = std::numeric_limits::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) - { - leftPointIndex = i; - minX = iPoints[i].x; - } - } - - // 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) - { - 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]); - } - + // Lets match our 3D vertices with our image 2D points + MatchVertices(topPointIndex, rightPointIndex, leftPointIndex, centerPointIndex, topRightPointIndex, topLeftPointIndex); bool movedEnough = true; // Check if we moved enough since last time we were here @@ -381,22 +417,35 @@ namespace EasyTracker // 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); + // Check if our solution makes sense + // For now, just discard solutions with extrem pitch + if (std::abs(angles[0]) > 50) //TODO: Put that in settings + { + infout << "WARNING: discarding solution!"; + iBadSolutionCount++; + } + else + { + iGoodSolutionCount++; + // 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(); + } - // Send solution data back to main thread - QMutexLocker l2(&iDataLock); - iBestAngles = angles; - iBestTranslation = translation; - iBestTime.start(); } } } if (doPreview) { + double qualityIndex = 1 - (iGoodSolutionCount!=0?(double)iBadSolutionCount / (double)iGoodSolutionCount:0); std::ostringstream ss; - ss << "FPS: " << iFps << "/" << iSkippedFps; + ss << "FPS: " << iFps << "/" << iSkippedFps << " QI: " << qualityIndex; iPreview.DrawInfo(ss.str()); //Color is BGR @@ -425,8 +474,6 @@ namespace EasyTracker iPreview.DrawCross(iPoints[centerPointIndex], color); } - - // Render our deadzone rects for (const cv::Rect& rect : iTrackedRects) { @@ -561,7 +608,7 @@ namespace EasyTracker /// void Tracker::UpdateSettings() { - infout << std::chrono::system_clock::now().time_since_epoch().count() << ": Update Setting\n"; + infout << "Update Setting"; QMutexLocker l(&iProcessLock); iPointExtractor.UpdateSettings(); iSolver = iSettings.PnpSolver; diff --git a/tracker-easy/tracker-easy.h b/tracker-easy/tracker-easy.h index f36ea598..e1dcee55 100644 --- a/tracker-easy/tracker-easy.h +++ b/tracker-easy/tracker-easy.h @@ -68,7 +68,11 @@ namespace EasyTracker private: void UpdateModel(); void CreateCameraIntrinsicsMatrices(); - void ProcessFrame(); + void ProcessFrame(); + void MatchVertices(int& aTopIndex, int& aRightIndex, int& aLeftIndex, int& aCenterIndex, int& aTopRight, int& aTopLeft); + void MatchThreeOrFourVertices(int& aTopIndex, int& aRightIndex, int& aLeftIndex, int& aCenterIndex); + void MatchFiveVertices(int& aTopIndex, int& aRightIndex, int& aLeftIndex, int& aTopRight, int& aTopLeft); + // @@ -118,6 +122,8 @@ namespace EasyTracker int iSkippedFrameCount = 0; int iFps = 0; int iSkippedFps = 0; + uint iBadSolutionCount = 0; + uint iGoodSolutionCount = 0; // KalmanFilterPose iKf; -- cgit v1.2.3 From 6fc9a425a00e98387cdd0023a39885b463cd2d02 Mon Sep 17 00:00:00 2001 From: Stéphane Lenclud Date: Sun, 28 Apr 2019 10:27:28 +0200 Subject: Easy Track: Five points model support. Because we can! --- tracker-easy/tracker-easy.cpp | 113 ++++++++++++++++++++++++++++++++++++++++-- tracker-easy/tracker-easy.h | 28 ++++++++--- 2 files changed, 132 insertions(+), 9 deletions(-) diff --git a/tracker-easy/tracker-easy.cpp b/tracker-easy/tracker-easy.cpp index 220765cc..3f0855a0 100644 --- a/tracker-easy/tracker-easy.cpp +++ b/tracker-easy/tracker-easy.cpp @@ -129,7 +129,7 @@ namespace EasyTracker // 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 == Custom) + if (iSettings.active_model_panel == Model::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 @@ -195,6 +195,102 @@ namespace EasyTracker void Tracker::MatchFiveVertices(int& aTopIndex, int& aRightIndex, int& aLeftIndex, int& aTopRight, int& aTopLeft) { + //Bitmap origin is top left + iTrackedPoints.clear(); + + int vertexIndices[] = { -1,-1,-1,-1,-1 }; + std::vector indices = { 0,1,2,3,4 }; + + // 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::max(); + for (int i = 0; i < iPoints.size(); i++) + { + if (iPoints[i].y < minY) + { + minY = iPoints[i].y; + vertexIndices[VertexPosition::Top] = i; + } + } + indices.erase(std::find(indices.begin(), indices.end(), vertexIndices[VertexPosition::Top])); + + // Find right most point + int maxX = 0; + for (int i = 0; i < iPoints.size(); i++) + { + // Excluding top most point + if (i != vertexIndices[VertexPosition::Top] && iPoints[i].x > maxX) + { + maxX = iPoints[i].x; + vertexIndices[VertexPosition::Right] = i; + } + } + indices.erase(std::find(indices.begin(), indices.end(), vertexIndices[VertexPosition::Right])); + + // Find left most point + int minX = std::numeric_limits::max(); + for (int i = 0; i < iPoints.size(); i++) + { + // Excluding top most point and right most point + if (i != vertexIndices[VertexPosition::Top] && i != vertexIndices[VertexPosition::Right] && iPoints[i].x < minX) + { + minX = iPoints[i].x; + vertexIndices[VertexPosition::Left] = i; + } + } + indices.erase(std::find(indices.begin(), indices.end(), vertexIndices[VertexPosition::Left])); + + // Check which of our two remaining points is on the left + int leftIndex = -1; + int rightIndex = -1; + if (iPoints[indices[0]].x > iPoints[indices[1]].x) + { + leftIndex = indices[1]; + rightIndex = indices[0]; + } + else + { + leftIndex = indices[0]; + rightIndex = indices[1]; + } + + // Check which of the left points is at the top + if (iPoints[vertexIndices[VertexPosition::Left]].y < iPoints[leftIndex].y) + { + vertexIndices[VertexPosition::TopLeft] = vertexIndices[VertexPosition::Left]; + vertexIndices[VertexPosition::Left] = leftIndex; + } + else + { + vertexIndices[VertexPosition::TopLeft] = leftIndex; + } + + // Check which of the right points is at the top + if (iPoints[vertexIndices[VertexPosition::Right]].y < iPoints[rightIndex].y) + { + vertexIndices[VertexPosition::TopRight] = vertexIndices[VertexPosition::Right]; + vertexIndices[VertexPosition::Right] = rightIndex; + } + else + { + vertexIndices[VertexPosition::TopRight] = rightIndex; + } + + + // Order matters, see UpdateModel function + iTrackedPoints.push_back(iPoints[vertexIndices[VertexPosition::Top]]); + iTrackedPoints.push_back(iPoints[vertexIndices[VertexPosition::Right]]); + iTrackedPoints.push_back(iPoints[vertexIndices[VertexPosition::Left]]); + iTrackedPoints.push_back(iPoints[vertexIndices[VertexPosition::TopRight]]); + iTrackedPoints.push_back(iPoints[vertexIndices[VertexPosition::TopLeft]]); + + // + aTopIndex = vertexIndices[VertexPosition::Top]; + aRightIndex = vertexIndices[VertexPosition::Right]; + aLeftIndex = vertexIndices[VertexPosition::Left]; + aTopRight = vertexIndices[VertexPosition::TopRight]; + aTopLeft = vertexIndices[VertexPosition::TopLeft]; + } @@ -260,8 +356,6 @@ namespace EasyTracker // We are tracking more than 3 points iTrackedPoints.push_back(iPoints[aCenterIndex]); } - - } @@ -474,6 +568,19 @@ namespace EasyTracker iPreview.DrawCross(iPoints[centerPointIndex], color); } + if (topRightPointIndex != -1) + { + static const cv::Scalar color(0, 0, 255); // Red + iPreview.DrawCross(iPoints[topRightPointIndex], color); + } + + if (topLeftPointIndex != -1) + { + static const cv::Scalar color(255, 255, 0); // Cyan + iPreview.DrawCross(iPoints[topLeftPointIndex], color); + } + + // Render our deadzone rects for (const cv::Rect& rect : iTrackedRects) { diff --git a/tracker-easy/tracker-easy.h b/tracker-easy/tracker-easy.h index e1dcee55..d99d4662 100644 --- a/tracker-easy/tracker-easy.h +++ b/tracker-easy/tracker-easy.h @@ -33,13 +33,29 @@ namespace EasyTracker { - // Order matters, it must match the order of the UI tabs - enum ModelType + namespace VertexPosition { - Clip, - Cap, - Custom - }; + enum Type + { + Top = 0, + Right, + Left, + TopRight, + TopLeft, + Center + }; + } + + namespace Model + { + // Order matters, it must match the order of the UI tabs + enum Type + { + Clip, + Cap, + Custom + }; + } static const QString KModuleName = "tracker-easy"; -- cgit v1.2.3 From b3a1c327bc3d8b7547171d99d3bfcf4d2714549c Mon Sep 17 00:00:00 2001 From: Stéphane Lenclud Date: Sun, 28 Apr 2019 10:46:45 +0200 Subject: Easy Tracker: Removing support for specific models such as clip and cap. Only generic model supported from now on. Removing vestige from calibration stuff. Changing version to 1.0. --- tracker-easy/lang/nl_NL.ts | 53 +- tracker-easy/lang/ru_RU.ts | 53 +- tracker-easy/lang/stub.ts | 53 +- tracker-easy/lang/zh_CN.ts | 53 +- tracker-easy/module.cpp | 3 +- tracker-easy/settings.h | 9 - tracker-easy/tracker-easy-dialog.cpp | 51 +- tracker-easy/tracker-easy-dialog.h | 4 - tracker-easy/tracker-easy-settings.ui | 1115 +++++++++++---------------------- tracker-easy/tracker-easy.cpp | 28 +- tracker-easy/tracker-easy.h | 11 - 11 files changed, 386 insertions(+), 1047 deletions(-) diff --git a/tracker-easy/lang/nl_NL.ts b/tracker-easy/lang/nl_NL.ts index 9b7ae1dd..fe73b271 100644 --- a/tracker-easy/lang/nl_NL.ts +++ b/tracker-easy/lang/nl_NL.ts @@ -1,17 +1,10 @@ - - EasyTracker::Dialog - - Tracker offline - - - EasyTracker::Metadata - Easy Tracker 0.1 + Easy Tracker 1.0 @@ -97,46 +90,14 @@ Model - - Clip - - - - Model Dimensions - - mm - - Side - - - - Front - - - - Cap - - About - - Status - - - - Extracted Points: - - - - Camera Info: - - Debug (full size preview) @@ -145,10 +106,6 @@ Deadzone - - <html><head/><body><p><span style=" font-weight:600;">Easy Tracker<br/>Version 0.1</span></p><p><span style=" font-weight:600;">by Stéphane Lenclud</span></p><p>See <a href="https://github.com/opentrack/opentrack/wiki/Easy-Tracker"><span style=" font-weight:600; text-decoration: underline; color:#9999AA;">documentation on GitHub</span></a></p></body></html> - - Size in pixels of half the edge defining deadzone squares around tracked points @@ -193,10 +150,6 @@ Settings - - Custom - - Top Right @@ -249,5 +202,9 @@ <html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html> + + <html><head/><body><p><span style=" font-weight:600;">Easy Tracker<br/>Version 1.0</span></p><p><span style=" font-weight:600;">by Stéphane Lenclud</span></p><p>See <a href="https://github.com/opentrack/opentrack/wiki/Easy-Tracker"><span style=" font-weight:600; text-decoration: underline; color:#9999aa;">documentation on GitHub</span></a></p></body></html> + + diff --git a/tracker-easy/lang/ru_RU.ts b/tracker-easy/lang/ru_RU.ts index ba8caacb..022acd68 100644 --- a/tracker-easy/lang/ru_RU.ts +++ b/tracker-easy/lang/ru_RU.ts @@ -1,17 +1,10 @@ - - EasyTracker::Dialog - - Tracker offline - Отслеживание отключено - - EasyTracker::Metadata - Easy Tracker 0.1 + Easy Tracker 1.0 @@ -97,46 +90,14 @@ Model Модель - - Clip - Клипса - - - Model Dimensions - Размеры модели - mm мм - - Side - Сбоку - - - Front - Спереди - - - Cap - Кепка - About О программе - - Status - Статус - - - Extracted Points: - Извлечено точек: - - - Camera Info: - Параметры камеры: - Debug (full size preview) @@ -145,10 +106,6 @@ Deadzone - - <html><head/><body><p><span style=" font-weight:600;">Easy Tracker<br/>Version 0.1</span></p><p><span style=" font-weight:600;">by Stéphane Lenclud</span></p><p>See <a href="https://github.com/opentrack/opentrack/wiki/Easy-Tracker"><span style=" font-weight:600; text-decoration: underline; color:#9999AA;">documentation on GitHub</span></a></p></body></html> - - Size in pixels of half the edge defining deadzone squares around tracked points @@ -193,10 +150,6 @@ Settings - - Custom - - Top Right @@ -249,5 +202,9 @@ <html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html> + + <html><head/><body><p><span style=" font-weight:600;">Easy Tracker<br/>Version 1.0</span></p><p><span style=" font-weight:600;">by Stéphane Lenclud</span></p><p>See <a href="https://github.com/opentrack/opentrack/wiki/Easy-Tracker"><span style=" font-weight:600; text-decoration: underline; color:#9999aa;">documentation on GitHub</span></a></p></body></html> + + diff --git a/tracker-easy/lang/stub.ts b/tracker-easy/lang/stub.ts index 55a0bd46..60c84d35 100644 --- a/tracker-easy/lang/stub.ts +++ b/tracker-easy/lang/stub.ts @@ -1,17 +1,10 @@ - - EasyTracker::Dialog - - Tracker offline - - - EasyTracker::Metadata - Easy Tracker 0.1 + Easy Tracker 1.0 @@ -97,46 +90,14 @@ Model - - Clip - - - - Model Dimensions - - mm - - Side - - - - Front - - - - Cap - - About - - Status - - - - Extracted Points: - - - - Camera Info: - - Debug (full size preview) @@ -145,10 +106,6 @@ Deadzone - - <html><head/><body><p><span style=" font-weight:600;">Easy Tracker<br/>Version 0.1</span></p><p><span style=" font-weight:600;">by Stéphane Lenclud</span></p><p>See <a href="https://github.com/opentrack/opentrack/wiki/Easy-Tracker"><span style=" font-weight:600; text-decoration: underline; color:#9999AA;">documentation on GitHub</span></a></p></body></html> - - Size in pixels of half the edge defining deadzone squares around tracked points @@ -193,10 +150,6 @@ Settings - - Custom - - Top Right @@ -249,5 +202,9 @@ <html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html> + + <html><head/><body><p><span style=" font-weight:600;">Easy Tracker<br/>Version 1.0</span></p><p><span style=" font-weight:600;">by Stéphane Lenclud</span></p><p>See <a href="https://github.com/opentrack/opentrack/wiki/Easy-Tracker"><span style=" font-weight:600; text-decoration: underline; color:#9999aa;">documentation on GitHub</span></a></p></body></html> + + diff --git a/tracker-easy/lang/zh_CN.ts b/tracker-easy/lang/zh_CN.ts index 73f0f0be..ee89b5b6 100644 --- a/tracker-easy/lang/zh_CN.ts +++ b/tracker-easy/lang/zh_CN.ts @@ -1,17 +1,10 @@ - - EasyTracker::Dialog - - Tracker offline - 跟踪器脱机 - - EasyTracker::Metadata - Easy Tracker 0.1 + Easy Tracker 1.0 @@ -97,46 +90,14 @@ Model 点模式 - - Clip - 夹子式 - - - Model Dimensions - 尺寸 - mm 毫米 - - Side - 侧面 - - - Front - 正面 - - - Cap - 帽子式 - About 关于 - - Status - 状态 - - - Extracted Points: - 解析出的点: - - - Camera Info: - 设备信息: - Debug (full size preview) @@ -145,10 +106,6 @@ Deadzone - - <html><head/><body><p><span style=" font-weight:600;">Easy Tracker<br/>Version 0.1</span></p><p><span style=" font-weight:600;">by Stéphane Lenclud</span></p><p>See <a href="https://github.com/opentrack/opentrack/wiki/Easy-Tracker"><span style=" font-weight:600; text-decoration: underline; color:#9999AA;">documentation on GitHub</span></a></p></body></html> - - Size in pixels of half the edge defining deadzone squares around tracked points @@ -193,10 +150,6 @@ Settings - - Custom - - Top Right @@ -249,5 +202,9 @@ <html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html> + + <html><head/><body><p><span style=" font-weight:600;">Easy Tracker<br/>Version 1.0</span></p><p><span style=" font-weight:600;">by Stéphane Lenclud</span></p><p>See <a href="https://github.com/opentrack/opentrack/wiki/Easy-Tracker"><span style=" font-weight:600; text-decoration: underline; color:#9999aa;">documentation on GitHub</span></a></p></body></html> + + diff --git a/tracker-easy/module.cpp b/tracker-easy/module.cpp index 9f5461d5..3a9df22b 100644 --- a/tracker-easy/module.cpp +++ b/tracker-easy/module.cpp @@ -6,8 +6,7 @@ namespace EasyTracker { - - QString Metadata::name() { return tr("Easy Tracker 0.1"); } + QString Metadata::name() { return tr("Easy Tracker 1.0"); } QIcon Metadata::icon() { return QIcon(":/Resources/easy-tracker-logo.png"); } } diff --git a/tracker-easy/settings.h b/tracker-easy/settings.h index 825282d4..5a4dff84 100644 --- a/tracker-easy/settings.h +++ b/tracker-easy/settings.h @@ -40,15 +40,6 @@ namespace EasyTracker { value iVertexTopLeftX{ b, "iVertexTopLeftX", 0 }, iVertexTopLeftY{ b, "iVertexTopLeftY", 0 }, iVertexTopLeftZ{ b, "iVertexTopLeftZ", 0 }; - value clip_ty{ b, "clip-ty", 40 }, - clip_tz{ b, "clip-tz", 30 }, - clip_by{ b, "clip-by", 70 }, - clip_bz{ b, "clip-bz", 80 }; - - value active_model_panel{ b, "active-model-panel", 0 }, - cap_x{ b, "cap-x", 35 }, - cap_y{ b, "cap-y", 55 }, - cap_z{ b, "cap-z", 100 }; value fov{ b, "camera-fov", 56 }; diff --git a/tracker-easy/tracker-easy-dialog.cpp b/tracker-easy/tracker-easy-dialog.cpp index b30efed4..d1aafee1 100644 --- a/tracker-easy/tracker-easy-dialog.cpp +++ b/tracker-easy/tracker-easy-dialog.cpp @@ -26,9 +26,7 @@ namespace EasyTracker Dialog::Dialog() : s(KModuleName), - tracker(nullptr), - timer(this), - trans_calib(1, 2) + tracker(nullptr) { init_resources(); @@ -46,15 +44,6 @@ namespace EasyTracker tie_setting(s.iMaxBlobSize, ui.maxdiam_spin); tie_setting(s.DeadzoneRectHalfEdgeSize, ui.spinDeadzone); - tie_setting(s.clip_by, ui.clip_bheight_spin); - tie_setting(s.clip_bz, ui.clip_blength_spin); - tie_setting(s.clip_ty, ui.clip_theight_spin); - tie_setting(s.clip_tz, ui.clip_tlength_spin); - - tie_setting(s.cap_x, ui.cap_width_spin); - tie_setting(s.cap_y, ui.cap_height_spin); - tie_setting(s.cap_z, ui.cap_length_spin); - tie_setting(s.iVertexTopX, ui.iSpinVertexTopX); tie_setting(s.iVertexTopY, ui.iSpinVertexTopY); tie_setting(s.iVertexTopZ, ui.iSpinVertexTopZ); @@ -79,11 +68,8 @@ namespace EasyTracker tie_setting(s.iVertexTopLeftY, ui.iSpinVertexTopLeftY); tie_setting(s.iVertexTopLeftZ, ui.iSpinVertexTopLeftZ); - tie_setting(s.fov, ui.fov); - tie_setting(s.active_model_panel, ui.model_tabs); - tie_setting(s.debug, ui.debug); @@ -103,17 +89,12 @@ namespace EasyTracker 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); - - - poll_tracker_info_impl(); - - connect(this, &Dialog::poll_tracker_info, this, &Dialog::poll_tracker_info_impl, Qt::DirectConnection); - for (unsigned k = 0; k < cv::SOLVEPNP_MAX_COUNT; k++) + { ui.comboBoxSolvers->setItemData(k, k); + } + tie_setting(s.PnpSolver, ui.comboBoxSolvers); @@ -143,26 +124,6 @@ namespace EasyTracker } - void Dialog::poll_tracker_info_impl() - { - //SL: sort this out - /* - pt_camera_info info; - if (tracker && tracker->get_cam_info(info)) - { - ui.caminfo_label->setText(tr("%1x%2 @ %3 FPS").arg(info.res_x).arg(info.res_y).arg(iround(info.fps))); - - // display point info - const int n_points = tracker->get_n_points(); - ui.pointinfo_label->setText((n_points == 3 ? tr("%1 OK!") : tr("%1 BAD!")).arg(n_points)); - } - else - */ - { - ui.caminfo_label->setText(tr("Tracker offline")); - ui.pointinfo_label->setText(QString()); - } - } void Dialog::set_camera_settings_available(const QString& /* camera_name */) { @@ -200,14 +161,10 @@ namespace EasyTracker void Dialog::register_tracker(ITracker *t) { tracker = static_cast(t); - poll_tracker_info(); - timer.start(); } void Dialog::unregister_tracker() { tracker = nullptr; - poll_tracker_info(); - timer.stop(); } } diff --git a/tracker-easy/tracker-easy-dialog.h b/tracker-easy/tracker-easy-dialog.h index f63ef66f..7eb1ffb1 100644 --- a/tracker-easy/tracker-easy-dialog.h +++ b/tracker-easy/tracker-easy-dialog.h @@ -33,7 +33,6 @@ namespace EasyTracker void doOK(); void doCancel(); - void poll_tracker_info_impl(); void set_camera_settings_available(const QString& camera_name); void show_camera_settings(); signals: @@ -42,9 +41,6 @@ namespace EasyTracker Settings s; Tracker* tracker; - QTimer timer; - TranslationCalibrator trans_calib; - QMutex calibrator_mutex; Ui::UICPTClientControls ui; }; diff --git a/tracker-easy/tracker-easy-settings.ui b/tracker-easy/tracker-easy-settings.ui index 6690a3e5..c6c3fbd7 100644 --- a/tracker-easy/tracker-easy-settings.ui +++ b/tracker-easy/tracker-easy-settings.ui @@ -36,7 +36,7 @@ QLayout::SetFixedSize - + @@ -61,7 +61,7 @@ - 0 + 2 @@ -477,698 +477,362 @@ Model - - - - - true + + + + + Vertex count - - - 0 - 0 - + + + + + Three vertices + + + true + + + + + + + Four vertices + + + + + + + Five vertices + + + + + + + + + + - - QTabWidget::Rounded + + false - - 2 + + + + + <html><head/><body><p><span style=" font-size:12pt;">X</span></p></body></html> + + + + + + + <html><head/><body><p><span style=" font-size:12pt;">Y</span></p></body></html> + + + + + + + <html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html> + + + + + + + + + + Top - - false + + + 9 + + + + + mm + + + -65535 + + + 65535 + + + + + + + mm + + + -65535 + + + 65535 + + + + + + + mm + + + -65535 + + + 65535 + + + + + + + + + + Right - - false + + + + + mm + + + -65535 + + + 65535 + + + + + + + mm + + + -65535 + + + 65535 + + + + + + + mm + + + -65535 + + + 65535 + + + + + + + + + + Left - - false + + + + + mm + + + -65535 + + + 65535 + + + + + + + mm + + + -65535 + + + 65535 + + + + + + + mm + + + -65535 + + + 65535 + + + + + + + + + + Center - - - false - - - Clip - - - - - - - 0 - 0 - - - - - 331 - 208 - - - - Model Dimensions - - - - - 70 - 35 - 100 - 22 - - - - mm - - - -65535 - - - 65535 - - - - - - 150 - 130 - 100 - 22 - - - - mm - - - -65535 - - - 65535 - - - - - - 65 - 55 - 71 - 111 - - - - - - - :/Resources/clip_side.png - - - - - - 20 - 40 - 46 - 13 - - - - Side - - - - - - 50 - 160 - 100 - 22 - - - - mm - - - -65535 - - - 65535 - - - - - - 150 - 70 - 100 - 22 - - - - mm - - - -65535 - - - 65535 - - - - - - 290 - 40 - 46 - 13 - - - - Front - - - - - - 300 - 70 - 21 - 111 - - - - - - - :/Resources/clip_front.png - - - - - - - - - Cap - - - - - - - 331 - 208 - - - - Model Dimensions - - - - - 100 - 60 - 111 - 81 - - - - - - - :/Resources/cap_side.png - - - - - - 20 - 40 - 46 - 13 - - - - Side - - - - - - 90 - 40 - 101 - 22 - - - - mm - - - -65535 - - - 65535 - - - - - - 220 - 100 - 81 - 81 - - - - - - - :/Resources/cap_front.png - - - - - - 240 - 70 - 81 - 22 - - - - mm - - - -65535 - - - 65535 - - - - - - 240 - 40 - 46 - 13 - - - - Front - - - - - - 20 - 90 - 81 - 22 - - - - mm - - - -65535 - - - 65535 - - - - - - - - - true - - - Custom - - - - - - - - - false - - - - - - <html><head/><body><p><span style=" font-size:12pt;">X</span></p></body></html> - - - - - - - <html><head/><body><p><span style=" font-size:12pt;">Y</span></p></body></html> - - - - - - - <html><head/><body><p><span style=" font-size:12pt;">Z</span></p></body></html> - - - - - - - - - - Top Right - - - - - - mm - - - -65535 - - - 65535 - - - - - - - mm - - - -65535 - - - 65535 - - - - - - - mm - - - -65535 - - - 65535 - - - - - - - - - - Top Left - - - - - - mm - - - -65535 - - - 65535 - - - - - - - mm - - - -65535 - - - 65535 - - - - - - - mm - - - -65535 - - - 65535 - - - - - - - - - - Left - - - - - - mm - - - -65535 - - - 65535 - - - - - - - mm - - - -65535 - - - 65535 - - - - - - - mm - - - -65535 - - - 65535 - - - - - - - - - - Vertex count - - - - - - Three vertices - - - true - - - - - - - Four vertices - - - - - - - Five vertices - - - - - - - - - - Center - - - - - - mm - - - -65535 - - - 65535 - - - - - - - mm - - - -65535 - - - 65535 - - - - - - - mm - - - -65535 - - - 65535 - - - - - - - - - - Right - - - - - - mm - - - -65535 - - - 65535 - - - - - - - mm - - - -65535 - - - 65535 - - - - - - - mm - - - -65535 - - - 65535 - - - - - - - - - - Top - - - - 9 - - - - - mm - - - -65535 - - - 65535 - - - - - - - mm - - - -65535 - - - 65535 - - - - - - - mm - - - -65535 - - - 65535 - - - - - - - - + + + + + mm + + + -65535 + + + 65535 + + + + + + + mm + + + -65535 + + + 65535 + + + + + + + mm + + + -65535 + + + 65535 + + + + + + + + + + Top Right + + + + + + mm + + + -65535 + + + 65535 + + + + + + + mm + + + -65535 + + + 65535 + + + + + + + mm + + + -65535 + + + 65535 + + + + + + + + + + Top Left + + + + + + mm + + + -65535 + + + 65535 + + + + + + + mm + + + -65535 + + + 65535 + + + + + + + mm + + + -65535 + + + 65535 + + + + @@ -1181,7 +845,7 @@ - <html><head/><body><p><span style=" font-weight:600;">Easy Tracker<br/>Version 0.1</span></p><p><span style=" font-weight:600;">by Stéphane Lenclud</span></p><p>See <a href="https://github.com/opentrack/opentrack/wiki/Easy-Tracker"><span style=" font-weight:600; text-decoration: underline; color:#9999AA;">documentation on GitHub</span></a></p></body></html> + <html><head/><body><p><span style=" font-weight:600;">Easy Tracker<br/>Version 1.0</span></p><p><span style=" font-weight:600;">by Stéphane Lenclud</span></p><p>See <a href="https://github.com/opentrack/opentrack/wiki/Easy-Tracker"><span style=" font-weight:600; text-decoration: underline; color:#9999aa;">documentation on GitHub</span></a></p></body></html> Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop @@ -1208,73 +872,6 @@ - - - - - 0 - 0 - - - - Status - - - - - - - 0 - 0 - - - - Extracted Points: - - - - - - - - 0 - 0 - - - - Camera Info: - - - - - - - - 0 - 0 - - - - - - - - - - - - 0 - 0 - - - - - - - - - - @@ -1285,14 +882,6 @@ fps_spin fov camera_settings - model_tabs - clip_tlength_spin - clip_theight_spin - clip_bheight_spin - clip_blength_spin - cap_length_spin - cap_height_spin - cap_width_spin diff --git a/tracker-easy/tracker-easy.cpp b/tracker-easy/tracker-easy.cpp index 3f0855a0..1bb6b5e1 100644 --- a/tracker-easy/tracker-easy.cpp +++ b/tracker-easy/tracker-easy.cpp @@ -129,28 +129,18 @@ namespace EasyTracker // 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 == Model::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 + 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.iCustomModelFive) - { - iModel.push_back(cv::Point3f(iSettings.iVertexTopRightX / 10.0, iSettings.iVertexTopRightY / 10.0, iSettings.iVertexTopRightZ / 10.0)); // Top Right - iModel.push_back(cv::Point3f(iSettings.iVertexTopLeftX / 10.0, iSettings.iVertexTopLeftY / 10.0, iSettings.iVertexTopLeftZ / 10.0)); // Top Left - } + if (iSettings.iCustomModelFour) + { + iModel.push_back(cv::Point3f(iSettings.iVertexCenterX / 10.0, iSettings.iVertexCenterY / 10.0, iSettings.iVertexCenterZ / 10.0)); // Center } - // Default to Cap for now - else //if (iSettings.active_model_panel == Cap) + else if (iSettings.iCustomModelFive) { - 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 - iModel.push_back(cv::Point3f(-iSettings.cap_x / 10.0, iSettings.cap_z / 10.0, -iSettings.cap_y / 10.0)); // Left + iModel.push_back(cv::Point3f(iSettings.iVertexTopRightX / 10.0, iSettings.iVertexTopRightY / 10.0, iSettings.iVertexTopRightZ / 10.0)); // Top Right + iModel.push_back(cv::Point3f(iSettings.iVertexTopLeftX / 10.0, iSettings.iVertexTopLeftY / 10.0, iSettings.iVertexTopLeftZ / 10.0)); // Top Left } } diff --git a/tracker-easy/tracker-easy.h b/tracker-easy/tracker-easy.h index d99d4662..952f05a4 100644 --- a/tracker-easy/tracker-easy.h +++ b/tracker-easy/tracker-easy.h @@ -46,17 +46,6 @@ namespace EasyTracker }; } - namespace Model - { - // Order matters, it must match the order of the UI tabs - enum Type - { - Clip, - Cap, - Custom - }; - } - static const QString KModuleName = "tracker-easy"; class Dialog; -- cgit v1.2.3 From 5b3d825f1eace207502371427e15d8b54a237f83 Mon Sep 17 00:00:00 2001 From: Stéphane Lenclud Date: Sun, 28 Apr 2019 18:45:08 +0200 Subject: Easy Tracker: Auto center configurable from settings. --- tracker-easy/lang/nl_NL.ts | 20 ++++++ tracker-easy/lang/ru_RU.ts | 20 ++++++ tracker-easy/lang/stub.ts | 20 ++++++ tracker-easy/lang/zh_CN.ts | 20 ++++++ tracker-easy/settings.h | 2 + tracker-easy/tracker-easy-dialog.cpp | 3 + tracker-easy/tracker-easy-settings.ui | 129 ++++++++++++++++++++++++++-------- tracker-easy/tracker-easy.cpp | 58 +++++++-------- 8 files changed, 213 insertions(+), 59 deletions(-) diff --git a/tracker-easy/lang/nl_NL.ts b/tracker-easy/lang/nl_NL.ts index fe73b271..9c4e1843 100644 --- a/tracker-easy/lang/nl_NL.ts +++ b/tracker-easy/lang/nl_NL.ts @@ -206,5 +206,25 @@ <html><head/><body><p><span style=" font-weight:600;">Easy Tracker<br/>Version 1.0</span></p><p><span style=" font-weight:600;">by Stéphane Lenclud</span></p><p>See <a href="https://github.com/opentrack/opentrack/wiki/Easy-Tracker"><span style=" font-weight:600; text-decoration: underline; color:#9999aa;">documentation on GitHub</span></a></p></body></html> + + Auto center + + + + <html><head/><body><p>Use P3P or AP3P for three and four points setup. Use EPNP or ITERATIVE for five points setup. Inconsistent configuration will result in undefined behavior.</p></body></html> + + + + Auto center timeout + + + + If no valid pose can be determined after that much time the center pose will be used. + + + + ms + + diff --git a/tracker-easy/lang/ru_RU.ts b/tracker-easy/lang/ru_RU.ts index 022acd68..6499415f 100644 --- a/tracker-easy/lang/ru_RU.ts +++ b/tracker-easy/lang/ru_RU.ts @@ -206,5 +206,25 @@ <html><head/><body><p><span style=" font-weight:600;">Easy Tracker<br/>Version 1.0</span></p><p><span style=" font-weight:600;">by Stéphane Lenclud</span></p><p>See <a href="https://github.com/opentrack/opentrack/wiki/Easy-Tracker"><span style=" font-weight:600; text-decoration: underline; color:#9999aa;">documentation on GitHub</span></a></p></body></html> + + Auto center + + + + <html><head/><body><p>Use P3P or AP3P for three and four points setup. Use EPNP or ITERATIVE for five points setup. Inconsistent configuration will result in undefined behavior.</p></body></html> + + + + Auto center timeout + + + + If no valid pose can be determined after that much time the center pose will be used. + + + + ms + + diff --git a/tracker-easy/lang/stub.ts b/tracker-easy/lang/stub.ts index 60c84d35..7b6facec 100644 --- a/tracker-easy/lang/stub.ts +++ b/tracker-easy/lang/stub.ts @@ -206,5 +206,25 @@ <html><head/><body><p><span style=" font-weight:600;">Easy Tracker<br/>Version 1.0</span></p><p><span style=" font-weight:600;">by Stéphane Lenclud</span></p><p>See <a href="https://github.com/opentrack/opentrack/wiki/Easy-Tracker"><span style=" font-weight:600; text-decoration: underline; color:#9999aa;">documentation on GitHub</span></a></p></body></html> + + Auto center + + + + <html><head/><body><p>Use P3P or AP3P for three and four points setup. Use EPNP or ITERATIVE for five points setup. Inconsistent configuration will result in undefined behavior.</p></body></html> + + + + Auto center timeout + + + + If no valid pose can be determined after that much time the center pose will be used. + + + + ms + + diff --git a/tracker-easy/lang/zh_CN.ts b/tracker-easy/lang/zh_CN.ts index ee89b5b6..bbd8aff1 100644 --- a/tracker-easy/lang/zh_CN.ts +++ b/tracker-easy/lang/zh_CN.ts @@ -206,5 +206,25 @@ <html><head/><body><p><span style=" font-weight:600;">Easy Tracker<br/>Version 1.0</span></p><p><span style=" font-weight:600;">by Stéphane Lenclud</span></p><p>See <a href="https://github.com/opentrack/opentrack/wiki/Easy-Tracker"><span style=" font-weight:600; text-decoration: underline; color:#9999aa;">documentation on GitHub</span></a></p></body></html> + + Auto center + + + + <html><head/><body><p>Use P3P or AP3P for three and four points setup. Use EPNP or ITERATIVE for five points setup. Inconsistent configuration will result in undefined behavior.</p></body></html> + + + + Auto center timeout + + + + If no valid pose can be determined after that much time the center pose will be used. + + + + ms + + diff --git a/tracker-easy/settings.h b/tracker-easy/settings.h index 5a4dff84..b0f14417 100644 --- a/tracker-easy/settings.h +++ b/tracker-easy/settings.h @@ -44,6 +44,8 @@ namespace EasyTracker { value fov{ b, "camera-fov", 56 }; value debug{ b, "debug", false }; + value iAutoCenter{ b, "iAutoCenter", true }; + value iAutoCenterTimeout{ b, "iAutoCenterTimeout", 1000 }; value PnpSolver{ b, "pnp-solver", cv::SOLVEPNP_P3P }; diff --git a/tracker-easy/tracker-easy-dialog.cpp b/tracker-easy/tracker-easy-dialog.cpp index d1aafee1..8c8356d1 100644 --- a/tracker-easy/tracker-easy-dialog.cpp +++ b/tracker-easy/tracker-easy-dialog.cpp @@ -72,6 +72,9 @@ namespace EasyTracker tie_setting(s.debug, ui.debug); + tie_setting(s.iAutoCenter, ui.iCheckBoxAutoCenter); + tie_setting(s.iAutoCenterTimeout, ui.iSpinBoxAutoCenterTimeout); + connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(doOK())); connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(doCancel())); diff --git a/tracker-easy/tracker-easy-settings.ui b/tracker-easy/tracker-easy-settings.ui index c6c3fbd7..451b3e54 100644 --- a/tracker-easy/tracker-easy-settings.ui +++ b/tracker-easy/tracker-easy-settings.ui @@ -61,7 +61,7 @@ - 2 + 0 @@ -289,8 +289,21 @@ Settings - - + + + + + + 0 + 0 + + + + Debug (full size preview) + + + + @@ -306,24 +319,24 @@ - - + + 0 0 - - Deadzone + + Minimum point diameter - - maxdiam_spin + + px - - + + 0 @@ -331,12 +344,25 @@ - Max size + - - + + + + + 0 + 0 + + + + + + + + + 0 @@ -344,12 +370,12 @@ - Debug (full size preview) + Auto center - - + + 0 @@ -357,11 +383,27 @@ - + Max size - + + + + + 0 + 0 + + + + Size in pixels of half the edge defining deadzone squares around tracked points + + + px + + + + @@ -369,12 +411,15 @@ 0 + + <html><head/><body><p>Use P3P or AP3P for three and four points setup. Use EPNP or ITERATIVE for five points setup. Inconsistent configuration will result in undefined behavior.</p></body></html> + Perspective-N-Point solver - + @@ -420,23 +465,23 @@ - - + + 0 0 - - Size in pixels of half the edge defining deadzone squares around tracked points + + Deadzone - - px + + maxdiam_spin - + @@ -452,8 +497,24 @@ - - + + + + + 0 + 0 + + + + Auto center timeout + + + mindiam_spin + + + + + 0 @@ -461,10 +522,16 @@ - Minimum point diameter + If no valid pose can be determined after that much time the center pose will be used. - px + ms + + + 3600000 + + + 500 diff --git a/tracker-easy/tracker-easy.cpp b/tracker-easy/tracker-easy.cpp index 1bb6b5e1..e13bdf37 100644 --- a/tracker-easy/tracker-easy.cpp +++ b/tracker-easy/tracker-easy.cpp @@ -117,33 +117,6 @@ namespace EasyTracker eulerAngles); } - /// - /// Create our model from settings specifications - /// - void Tracker::UpdateModel() - { - infout << "Update model"; - - 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(); - 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.iCustomModelFive) - { - iModel.push_back(cv::Point3f(iSettings.iVertexTopRightX / 10.0, iSettings.iVertexTopRightY / 10.0, iSettings.iVertexTopRightZ / 10.0)); // Top Right - iModel.push_back(cv::Point3f(iSettings.iVertexTopLeftX / 10.0, iSettings.iVertexTopLeftY / 10.0, iSettings.iVertexTopLeftZ / 10.0)); // Top Left - } - } - /// void Tracker::CreateCameraIntrinsicsMatrices() { @@ -700,6 +673,34 @@ namespace EasyTracker iKf.Init(18, 6, 0, dt); } + + /// + /// Create our model from settings specifications + /// + void Tracker::UpdateModel() + { + infout << "Update model"; + + 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(); + 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.iCustomModelFive) + { + iModel.push_back(cv::Point3f(iSettings.iVertexTopRightX / 10.0, iSettings.iVertexTopRightY / 10.0, iSettings.iVertexTopRightZ / 10.0)); // Top Right + iModel.push_back(cv::Point3f(iSettings.iVertexTopLeftX / 10.0, iSettings.iVertexTopLeftY / 10.0, iSettings.iVertexTopLeftZ / 10.0)); // Top Left + } + } + /// /// Take a copy of the settings needed by our thread to avoid deadlocks /// @@ -715,6 +716,7 @@ namespace EasyTracker iDebug = iSettings.debug; } + /// module_status Tracker::start_tracker(QFrame* video_frame) { // Check that we support that solver @@ -773,7 +775,7 @@ namespace EasyTracker 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. - if (iBestTime.elapsed_seconds() > 1) + if (iSettings.iAutoCenter && iBestTime.elapsed_ms() > iSettings.iAutoCenterTimeout) { // Reset to center until we get new data FeedData(aData, iCenterAngles, iCenterTranslation); -- cgit v1.2.3