#ifndef SKELETON_HPP #define SKELETON_HPP #include #include #include #include #include #include /////////////////////////////////////////////////////////// /// \defgroup skeleton Skeleton module /// /// Module to manage 2D-skeletons /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// /// \ingroup skeleton /// \brief Class wrapping a 2D-skeleton /////////////////////////////////////////////////////////// class Skeleton { public: // This using will be nice for the next template using couples = std::vector>; Skeleton(); unsigned int numberOfBranches() { return m_branches.size(); } //////////////////////////////////////////////////////////////////////// /// \brief loadFromFile : read a file at format skl and extract vertices /// and edges /// /// \param path String containing the path to the file at format skl //////////////////////////////////////////////////////////////////////// bool loadFromFile(std::string const& path); //////////////////////////////////////////////////////////////////////// /// \brief loadFromVectors : create edges from a vector of vertices /// index /// /// For example, with the vector path = [1, 5, 8, 9, 12], the created /// edges are (1,5), (5,8), (8,9) and (9,12) /// /// \param vertices Vector of vertices /// \param path Vector of vertices index //////////////////////////////////////////////////////////////////////// void loadFromVectors(std::vector> const& vertices, Branch const& path ); //////////////////////////////////////////////////////////////////////// /// \brief countNeighbors : count the number of neighbors of each /// vertex /// /// Compute a vector of counters which has the same size as the number /// of vertices. The k-th element of the vector is the number of /// neighbors of the k-th vertex. /// /// For example, with the following skeleton : /// /// /// \code /// 3 6 /// | | /// 1-2-4-5-8-9 /// | /// 7 /// \endcode /// It would return neighbors_counters = [1,3,1,2,4,1,1,2,1] //////////////////////////////////////////////////////////////////////// std::vector countNeighbors(); /////////////////////////////////////////////////////////////////////// /// \brief draw : Draw the skeleton /////////////////////////////////////////////////////////////////////// void draw() const; void draw(unsigned int i) const; //////////////////////////////////////////////////////////////////////// /// \brief split : split the whole skeletons into branches of skeletons /// /// \return a vector of branches //////////////////////////////////////////////////////////////////////// void split(); friend std::ostream& operator<<(std::ostream& out, Skeleton const& s); //////////////////////////////////////////////////////////////////////// /// \brief match branches of two skeletons together /// /// We consider that both skeletons have the number of branches. /// /// \param keypoints /// \param branches1 /// \param branches2 //////////////////////////////////////////////////////////////////////// friend couples branchesMatching(couples const& keypoints, Skeleton branches1, Skeleton branches2 ); private: //////////////////////////////////////////////////////////////////////// /// \brief add a point to a branch /// /// \param connections Inferior triangular matrix (j> const& connections, Branch& path ) const; //////////////////////////////////////////////////////////////////////// /// \brief return a vector containing the column containing a /// 1 in a triangular matrix given the number of 1 to /// be found and a certain line index /// /// \param connections Inferior triangular matrix containing 1 in /// (i,j) if the vertex i is connected to the /// vertex j /// \param numberOfOnesToFind Number of ones to find in the matrix /// connections /// \param lineNumber Index i of the line of connections where /// the algorithm looks for 1 //////////////////////////////////////////////////////////////////////// std::vector findOnes(std::vector> const& connections, unsigned int numberOfOnesToFind, unsigned int lineNumber ) const; //////////////////////////////////////////////////////////////////////// /// \brief searchNearestBrancheIndex : return the index of the branche /// associated to a keypoint /// /// \param keypoint The keypoint that we want to associate to a branche /// \param branches The list of branches in which we look for the /// nearest branche to associate the keypoint //////////////////////////////////////////////////////////////////////// unsigned int searchNearestBrancheIndex(cv::KeyPoint const& keypoint, Skeleton branches ); std::vector> m_vertices; std::vector> m_edges; std::vector m_branches; static std::stringstream stream; }; #endif // SKELETON_HPP