/* Copyright (c) 2019 Stephane Lenclud * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. */ #pragma once #include "api/plugin-api.hpp" #include "cv/numeric.hpp" #include "video/video-widget.hpp" #include "video/camera.hpp" #include "compat/timer.hpp" #include "preview.h" #include "settings.h" #include "point-extractor.h" #include "kalman-filter-pose.h" #include #include #include #include #include #include #include #include namespace EasyTracker { namespace VertexPosition { 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"; class Dialog; using namespace numeric_types; struct Tracker : public QObject, ITracker { Q_OBJECT public: friend class Dialog; explicit Tracker(); ~Tracker() override; // From ITracker module_status start_tracker(QFrame* parent_window) override; void data(double* data) override; bool center() override; private slots: void Tick(); private: void UpdateModel(); void CreateCameraIntrinsicsMatrices(); 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); // bool maybe_reopen_camera(); void set_fov(int value); void SetFps(int aFps); void DoSetFps(int aFps); void UpdateSettings(); QMutex camera_mtx; QThread iThread; QTimer iTicker; Settings iSettings; std::unique_ptr layout; std::vector iPoints; int preview_width = 320, preview_height = 240; PointExtractor iPointExtractor; std::unique_ptr camera; video::impl::camera::info iCameraInfo; std::unique_ptr widget; video::frame iFrame; cv::Mat iMatFrame; Preview iPreview; 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; Timer iFpsTimer; int iFrameCount = 0; int iSkippedFrameCount = 0; int iFps = 0; int iSkippedFps = 0; uint iBadSolutionCount = 0; uint iGoodSolutionCount = 0; // KalmanFilterPose iKf; // Vertices defining the model we are tracking std::vector iModel; // Bitmap points corresponding to model vertices std::vector iTrackedPoints; std::vector iTrackedRects; // Intrinsics camera matrix cv::Mat iCameraMatrix; // Intrinsics distortion coefficients as a matrix cv::Mat iDistCoeffsMatrix; // Translation solutions std::vector iTranslations; // Rotation solutions std::vector iRotations; // Angle solutions, pitch, yaw, roll, in this order std::vector iAngles; // The index of our best solution in the above arrays int iBestSolutionIndex = -1; // Best translation 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 }; }; }