paella/Code/include/Skeleton/Skeleton.hpp

167 lines
6.8 KiB
C++
Raw Normal View History

2015-02-05 11:38:30 +01:00
#ifndef SKELETON_HPP
#define SKELETON_HPP
#include <string>
#include <vector>
#include <sstream>
#include <opencv2/features2d/features2d.hpp>
#include <Skeleton/Branch.hpp>
#include <Geometry/Vector.hpp>
2015-02-05 11:38:30 +01:00
2015-03-11 14:57:35 +01:00
///////////////////////////////////////////////////////////
/// \defgroup skeleton Skeleton module
///
/// Module to manage 2D-skeletons
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
/// \ingroup skeleton
/// \brief Class wrapping a 2D-skeleton
///////////////////////////////////////////////////////////
2015-02-05 11:38:30 +01:00
class Skeleton
{
public:
// This using will be nice for the next
template <class T>
using couples = std::vector<std::pair<T,T>>;
2015-02-05 11:38:30 +01:00
Skeleton();
2015-03-03 17:03:58 +01:00
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
////////////////////////////////////////////////////////////////////////
2015-03-03 17:03:58 +01:00
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<geo::Vector3<float>> const& vertices,
2015-03-03 17:03:58 +01:00
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<unsigned int> countNeighbors();
///////////////////////////////////////////////////////////////////////
/// \brief draw : Draw the skeleton
///////////////////////////////////////////////////////////////////////
2015-02-05 11:38:30 +01:00
void draw() const;
2015-03-03 17:03:58 +01:00
void draw(unsigned int i) const;
////////////////////////////////////////////////////////////////////////
/// \brief split : split the whole skeletons into branches of skeletons
///
2015-03-11 14:57:35 +01:00
/// \return a vector of branches
////////////////////////////////////////////////////////////////////////
2015-03-03 17:03:58 +01:00
void split();
2015-02-05 11:38:30 +01:00
friend std::ostream& operator<<(std::ostream& out, Skeleton const& s);
////////////////////////////////////////////////////////////////////////
2015-03-11 14:57:35 +01:00
/// \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<unsigned int> branchesMatching(couples<cv::KeyPoint> const& keypoints,
2015-03-03 17:03:58 +01:00
Skeleton branches1,
Skeleton branches2
);
2015-02-05 11:38:30 +01:00
private:
////////////////////////////////////////////////////////////////////////
2015-03-11 14:57:35 +01:00
/// \brief add a point to a branch
///
/// \param connections Inferior triangular matrix (j<i) wit 0 in (i,j)
/// if the i-th vertex is
/// connected to the j-th vertex
/// \param path Branche of skeleton to be added a point
////////////////////////////////////////////////////////////////////////
void addNextPoint(std::vector<std::vector<bool>> const& connections,
2015-03-03 17:03:58 +01:00
Branch& path
) const;
////////////////////////////////////////////////////////////////////////
2015-03-11 14:57:35 +01:00
/// \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<unsigned int> findOnes(std::vector<std::vector<bool>> 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
////////////////////////////////////////////////////////////////////////
2015-03-03 17:03:58 +01:00
unsigned int searchNearestBrancheIndex(cv::KeyPoint const& keypoint,
Skeleton branches
);
std::vector<geo::Vector3<float>> m_vertices;
std::vector<geo::Vector<unsigned int,2>> m_edges;
2015-03-03 17:03:58 +01:00
std::vector<Branch> m_branches;
2015-02-05 11:38:30 +01:00
static std::stringstream stream;
};
#endif // SKELETON_HPP