#ifndef SKELETON_HPP #define SKELETON_HPP #include #include #include #include #include #include /////////////////////////////////////////////////////////// /// \defgroup skeleton Skeleton module /// /// Module to manage 2D-skeletons /// /// This module contains two programs. /// - Skeleton /// - SkeletonDrawing /// /// \section Skeleton /// This is the main binary. it takes several arguments /// \verbatim // Allowed options: // -h [ --help ] produce help message // --img1 arg first image (for the keypoints detection) // --img2 arg second image (for the keypoints detection) // --mask1 arg binary mask of the first image (to remove useless // keypoints) // --mask2 arg binary mask of the second image // --skl1 arg first skeleton, and its branches // --skl2 arg second skeleton // -o [ --output ] arg output file /// \endverbatim /////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// /// \ingroup skeleton /// \brief Class wrapping a 2D-skeleton /////////////////////////////////////////////////////////// class Skeleton { public: // This using will be nice for the next template using couples = std::vector>; //////////////////////////////////////////////////////////////////////// /// \brief default constructor /// /// builds an empty skeleton //////////////////////////////////////////////////////////////////////// Skeleton(); //////////////////////////////////////////////////////////////////////// /// \brief computes the number of branches of the skeleton /// \return the number of branches of the skeleton //////////////////////////////////////////////////////////////////////// unsigned int numberOfBranches() const { return m_branches.size(); } //////////////////////////////////////////////////////////////////////// /// \brief read a file at format skl and extract vertices /// and edges /// /// \param path String containing the path to the file at format skl /// \return true if the skeleton was correclty loaded //////////////////////////////////////////////////////////////////////// bool loadFromFile(std::string const& path); //////////////////////////////////////////////////////////////////////// /// \brief 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 count the number of neighbors of each /// vertex /// /// \return a vector with the number of neighbors /// /// 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 the skeleton /////////////////////////////////////////////////////////////////////// void draw() const; /////////////////////////////////////////////////////////////////////// /// \brief Draw the i-th branch of the skeleton /// \param i number of the branch to draw /////////////////////////////////////////////////////////////////////// void draw(unsigned int i) const; //////////////////////////////////////////////////////////////////////// /// \brief split the whole skeletons into branches of skeletons /// /// \return a vector of branches //////////////////////////////////////////////////////////////////////// void split(); //////////////////////////////////////////////////////////////////////// /// \brief Overload of the operator<< /// \param out stream to print the skeleton /// \param s skeleton to print onthe stream /// \return a reference to out //////////////////////////////////////////////////////////////////////// friend std::ostream& operator<<(std::ostream& out, Skeleton const& s); //////////////////////////////////////////////////////////////////////// /// \ingroup skeleton /// \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; ///< vertices of the skeleton std::vector> m_edges; ///< edges of the skeleton std::vector m_branches; ///< branches of the skeleton, might be empty }; #endif // SKELETON_HPP