Retrait des doublons et appariement des squelettes
This commit is contained in:
parent
cef4a611d9
commit
b862eaf766
|
@ -5,7 +5,7 @@
|
|||
#include "VectorFunctions.hpp"
|
||||
#include "FreeFlyCamera.hpp"
|
||||
|
||||
FreeFlyCamera::FreeFlyCamera() : speed(0.1), sensitivity(0.001), theta(0), phi(0)
|
||||
FreeFlyCamera::FreeFlyCamera() : speed(10), sensitivity(0.001), theta(0), phi(0)
|
||||
{
|
||||
vectorsFromAngles();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ SOURCES = Box.cpp Skeleton.cpp FreeFlyCamera.cpp main.cpp
|
|||
|
||||
OBJECTS = $(SOURCES:.cpp=.o)
|
||||
TARGET = main
|
||||
LIBS = -lsfml-graphics -lsfml-window -lsfml-system -lsfml-audio -lGL -lGLU -lglut
|
||||
LIBS = -lsfml-graphics -lsfml-window -lsfml-system -lsfml-audio -lGL -lGLU
|
||||
CXX = g++
|
||||
|
||||
%.o: %.cpp
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <GL/gl.h>
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
#include "Skeleton.hpp"
|
||||
#include "Box.hpp"
|
||||
|
||||
|
@ -12,6 +13,11 @@ Skeleton::Skeleton() : m_vertices{}, m_edges{}, m_neighbourgs_counters{}, m_junc
|
|||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \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
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Skeleton::loadFromFile(std::string const& path)
|
||||
{
|
||||
std::ifstream file{path};
|
||||
|
@ -33,9 +39,9 @@ void Skeleton::loadFromFile(std::string const& path)
|
|||
case 'v':
|
||||
float x;
|
||||
float y;
|
||||
float r;
|
||||
stream >> x >> y >> r;
|
||||
m_vertices.push_back(Vertex{x,y,r});
|
||||
float z;
|
||||
stream >> x >> y >> z;
|
||||
m_vertices.push_back(Vertex{x,y,z});
|
||||
break;
|
||||
|
||||
case 'e':
|
||||
|
@ -51,6 +57,15 @@ void Skeleton::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 Skeleton::loadFromVectors(std::vector<Vertex> const& vertices, std::vector<unsigned int> const& path)
|
||||
{
|
||||
m_vertices = vertices;
|
||||
|
@ -60,6 +75,23 @@ void Skeleton::loadFromVectors(std::vector<Vertex> const& vertices, std::vector<
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief countNeighbourgs : 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 :
|
||||
///
|
||||
///
|
||||
/// 3 6
|
||||
/// | |
|
||||
/// 1-2-4-5-8-9
|
||||
/// |
|
||||
/// 7
|
||||
///
|
||||
/// It would compute : m_neighbors_counters = [1,3,1,2,4,1,1,2,1]
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Skeleton::countNeighbourgs()
|
||||
{
|
||||
m_neighbourgs_counters.reserve(m_vertices.size());
|
||||
|
@ -75,6 +107,10 @@ void Skeleton::countNeighbourgs()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief draw : draw the skeleton with OpenGL
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Skeleton::draw() const
|
||||
{
|
||||
|
||||
|
@ -84,6 +120,9 @@ void Skeleton::draw() const
|
|||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief computeJunctions : compute the junctions
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Skeleton::computeJunctions()
|
||||
{
|
||||
countNeighbourgs();
|
||||
|
@ -112,10 +151,14 @@ void Skeleton::computeJunctions()
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief split : split the whole skeletons into branches of skeletons
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
std::vector<Skeleton> Skeleton::split()
|
||||
{
|
||||
std::vector<Skeleton> branches;
|
||||
std::vector<std::vector<bool>> connections;
|
||||
std::vector<std::vector<unsigned int>> paths;
|
||||
|
||||
if (m_junctions.size() == 0)
|
||||
computeJunctions();
|
||||
|
@ -152,7 +195,6 @@ std::vector<Skeleton> Skeleton::split()
|
|||
path.push_back(pathNumber);
|
||||
auto j = 0u;
|
||||
unsigned int k;
|
||||
// auto counter = 0u;
|
||||
|
||||
do
|
||||
{
|
||||
|
@ -161,18 +203,44 @@ std::vector<Skeleton> Skeleton::split()
|
|||
k = path[path.size()-1];
|
||||
} while (m_neighbourgs_counters[k] == 2);
|
||||
|
||||
bool toBeAdded = true;
|
||||
|
||||
for (unsigned int j = 0; j < paths.size(); j++)
|
||||
{
|
||||
auto const& branche_path = paths[j];
|
||||
auto const& sizeBranche = branche_path.size();
|
||||
bool samePathOfSize2 = (path.size() == 2 && path.size() == sizeBranche && (path[0] == branche_path[1] && path[1] == branche_path[0]));
|
||||
bool samePath = (path.size() > 2 && path.size() == sizeBranche && (path[0] == branche_path[sizeBranche-1] && path[path.size()-1] == branche_path[0] && path[1] == branche_path[sizeBranche-2]));
|
||||
if (samePathOfSize2||samePath)
|
||||
{
|
||||
toBeAdded = false;
|
||||
}
|
||||
}
|
||||
if (toBeAdded)
|
||||
{
|
||||
paths.push_back(path);
|
||||
branches.push_back(Skeleton{});
|
||||
branches[branches.size()-1].loadFromVectors(m_vertices, path);
|
||||
branches[branches.size()-1].m_bounding_box = m_bounding_box;
|
||||
numberOfBranchesFound++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
std::cout << std::endl;
|
||||
std::cout << "Nombre de branches de squelettes trouvées : " << branches.size() << std::endl;
|
||||
|
||||
return branches;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief addNextPoint : add a point to a branche
|
||||
///
|
||||
/// \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 Skeleton::addNextPoint(std::vector<std::vector<bool>> const& connections, std::vector<unsigned int>& path) const
|
||||
{
|
||||
auto lastPoint = path[path.size()-1];
|
||||
|
@ -194,6 +262,14 @@ void Skeleton::addNextPoint(std::vector<std::vector<bool>> const& connections, s
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief findOnes : return a vector containing the column containing a 1 in a triangular matrix
|
||||
/// given a certain line
|
||||
///
|
||||
/// \param connections Inferior triangular matrix containing 1 in (i,j) if the vertex i is connected
|
||||
/// to the vertex j
|
||||
/// \param lineNumber Index i of the line of connections where the algorithm looks for 1
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
std::vector<unsigned int> Skeleton::findOnes(std::vector<std::vector<bool>> const& connections, unsigned int lineNumber) const
|
||||
{
|
||||
std::vector<unsigned int> onesPosition;
|
||||
|
@ -214,6 +290,9 @@ std::vector<unsigned int> Skeleton::findOnes(std::vector<std::vector<bool>> cons
|
|||
return onesPosition;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief computeBoundingBox : computes the bounding box of the skeleton
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void Skeleton::computeBoundingBox()
|
||||
{
|
||||
m_bounding_box.m_x_min = m_vertices[0].x;
|
||||
|
@ -229,17 +308,195 @@ void Skeleton::computeBoundingBox()
|
|||
m_bounding_box.m_y_max = std::max(m_bounding_box.m_y_max,vertex.y);
|
||||
}
|
||||
|
||||
std::cout << "Affichage de la bounding box : " << std::endl;
|
||||
std::cout << "[" << m_bounding_box.m_x_min << "," << m_bounding_box.m_x_max << "] "
|
||||
<< "[" << m_bounding_box.m_y_min << "," << m_bounding_box.m_y_max << "]"
|
||||
<< std::endl;
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// \brief branchesMatching : match branches of two skeletons together
|
||||
///
|
||||
/// On considère que les deux squelettes que l'on cherche à apparier ont le même nombre de points
|
||||
/// We use the copy parameters to avoid side effects
|
||||
///
|
||||
/// \param keypoints
|
||||
/// \param branches1
|
||||
/// \param branches2
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
std::vector<std::pair<unsigned int,unsigned int>> branchesMatching(std::vector<std::pair<cv::KeyPoint,cv::KeyPoint>> keypoints, std::vector<Skeleton> branches1, std::vector<Skeleton> branches2)
|
||||
{
|
||||
std::vector<std::pair<unsigned int,unsigned int>> matchingBranches;
|
||||
|
||||
// We verify that skeletons both have as many branches
|
||||
if (branches1.size() != branches2.size())
|
||||
{
|
||||
std::cout << "Le premier squelette dispose de " << branches1.size() << " branches, tandis que le second en dispose de " << branches2.size() << "." << std::endl;
|
||||
}
|
||||
|
||||
// We divide the x and y coordinates of each vertex by the z-coordinate for both skeletons
|
||||
for (unsigned int i = 0; i < branches1.size() ; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < branches1[i].m_vertices.size(); j++)
|
||||
{
|
||||
branches1[i].m_vertices[j].x /= branches1[i].m_vertices[j].z;
|
||||
branches1[i].m_vertices[j].y /= branches1[i].m_vertices[j].z;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < branches2.size() ; i++)
|
||||
{
|
||||
for (unsigned int j = 0; j < branches2[i].m_vertices.size(); j++)
|
||||
{
|
||||
branches2[i].m_vertices[j].x /= branches2[i].m_vertices[j].z;
|
||||
branches2[i].m_vertices[j].y /= branches2[i].m_vertices[j].z;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<unsigned int> correspondingBranches1;
|
||||
std::vector<unsigned int> correspondingBranches2;
|
||||
|
||||
// Matching between key points of the first image and branches of the first skeleton
|
||||
for (unsigned int i = 0; i < keypoints.size(); i++)
|
||||
{
|
||||
auto const& keypoint = keypoints[i].first;
|
||||
unsigned int nearest_branche_index;
|
||||
nearest_branche_index = searchNearestBrancheIndex(keypoint, branches1);
|
||||
correspondingBranches1.push_back(nearest_branche_index);
|
||||
}
|
||||
|
||||
// Matching between key points of the second image and branches of the second skeleton
|
||||
for (unsigned int i = 0; i < keypoints.size(); i++)
|
||||
{
|
||||
auto const& keypoint = keypoints[i].second;
|
||||
unsigned int nearest_branche_index;
|
||||
nearest_branche_index = searchNearestBrancheIndex(keypoint, branches2);
|
||||
correspondingBranches2.push_back(nearest_branche_index);
|
||||
}
|
||||
|
||||
// Initialisation of a 2D matching matrix couting the number of times that each branche of the first skeleton is associated to another branche of the second skeleton as their respective associated keypoints are paired
|
||||
unsigned int matchingMatrix[branches1.size()][branches2.size()];
|
||||
for (auto i = 0u; i < 6; i++)
|
||||
{
|
||||
for (auto j = 0u; j < 6; j++)
|
||||
matchingMatrix[i][j] = 0;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < correspondingBranches1.size() ; i++)
|
||||
{
|
||||
std::cout << "Le morceau du premier squelette d'indice " << correspondingBranches1[i] << " semble correspondre au morceau du second squelette d'indice " << correspondingBranches2[i] << "." << std::endl;
|
||||
matchingMatrix[correspondingBranches1[i]][correspondingBranches2[i]]++;
|
||||
}
|
||||
|
||||
std::cout << "--------Matrix is--------------" << std::endl;
|
||||
for (auto i = 0u; i < 6; i++)
|
||||
{
|
||||
for (auto j = 0u; j < 6; j++)
|
||||
std::cout << matchingMatrix[i][j] << " ";
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
std::cout << "----------------------------------" << std::endl;
|
||||
|
||||
for (unsigned int i = 0; i < branches1.size(); i++)
|
||||
{
|
||||
unsigned int maximumMatchingScore = 0;
|
||||
unsigned int maximumMatchingScoreIndex = 0;
|
||||
|
||||
for (unsigned int j = 0; j < branches1.size(); j++)
|
||||
{
|
||||
if (matchingMatrix[i][j] > maximumMatchingScore)
|
||||
{
|
||||
maximumMatchingScore = matchingMatrix[i][j];
|
||||
maximumMatchingScoreIndex = j;
|
||||
}
|
||||
}
|
||||
std::pair<unsigned int, unsigned int> pairOfBranches(i,maximumMatchingScoreIndex);
|
||||
matchingBranches.push_back(pairOfBranches);
|
||||
}
|
||||
|
||||
return matchingBranches;
|
||||
}
|
||||
|
||||
unsigned int searchNearestBrancheIndex(cv::KeyPoint const& keypoint, std::vector<Skeleton> branches)
|
||||
{
|
||||
unsigned int nearest_branche_index = 0;
|
||||
float shortest_distance;
|
||||
for (unsigned int j = 0 ; j < branches.size() ; j++)
|
||||
{
|
||||
auto const& branche = branches[j];
|
||||
|
||||
for (unsigned int k = 0 ; k < branche.m_edges.size() ; k++)
|
||||
{
|
||||
auto const& edge = branche.m_edges[k];
|
||||
|
||||
// We compute the coordinates of the projection of the keypoint on each edge
|
||||
float d_keypoint_edge;
|
||||
|
||||
float xK = keypoint.pt.x;
|
||||
float yK = keypoint.pt.y;
|
||||
|
||||
float xv1 = branche.m_vertices[edge.v1].x;
|
||||
float yv1 = branche.m_vertices[edge.v1].y;
|
||||
float xv2 = branche.m_vertices[edge.v2].x;
|
||||
float yv2 = branche.m_vertices[edge.v2].y;
|
||||
|
||||
float xv1v2 = xv2 - xv1;
|
||||
float yv1v2 = yv2 - yv1;
|
||||
|
||||
float a = yv1v2;
|
||||
float b = -xv1v2;
|
||||
float c = -a*xv1 - b*yv1;
|
||||
|
||||
float na1 = xv1v2;
|
||||
float nb1 = yv1v2;
|
||||
float nc1 = -na1*xv1 - nb1*yv1;
|
||||
float nc2 = -na1*xv2 - nb1*yv2;
|
||||
|
||||
float yH1 = (na1/(na1*na1+nb1*nb1))*(na1*yK-nb1*nc1/na1-nb1*xK);
|
||||
float xH1 = -(nb1*yH1+nc1)/na1;
|
||||
float yH2 = (na1/(na1*na1+nb1*nb1))*(na1*yK-nb1*nc2/na1-nb1*xK);
|
||||
float xH2 = -(nb1*yH2+nc2)/na1;
|
||||
|
||||
float d_v1_v2 = std::sqrt((xv1-xv2)*(xv1-xv2)+(yv1-yv2)*(yv1-yv2));
|
||||
float d_K_H1 = std::sqrt((xK-xH1)*(xK-xH1)+(yK-yH1)*(yK-yH1));
|
||||
float d_K_H2 = std::sqrt((xK-xH2)*(xK-xH2)+(yK-yH2)*(yK-yH2));
|
||||
|
||||
if (d_K_H1 + d_K_H2 <= d_v1_v2)
|
||||
{
|
||||
float yH = (a/(a*a+b*b))*(a*yK-b*c/a-b*xK);
|
||||
float xH = -(b*yH+c)/a;
|
||||
float d_K_H = std::sqrt((xK-xH)*(xK-xH)+(yK-yH)*(yK-yH));
|
||||
d_keypoint_edge = d_K_H;
|
||||
}
|
||||
else
|
||||
{
|
||||
float d_K_v1 = std::sqrt((xK-xv1)*(xK-xv1)+(yK-yv1)*(yK-yv1));
|
||||
float d_K_v2 = std::sqrt((xK-xv2)*(xK-xv2)+(yK-yv2)*(yK-yv2));
|
||||
d_keypoint_edge = std::min(d_K_v1,d_K_v2);
|
||||
}
|
||||
|
||||
if (j+k == 0)
|
||||
{
|
||||
shortest_distance = d_keypoint_edge;
|
||||
}
|
||||
if (d_keypoint_edge < shortest_distance)
|
||||
{
|
||||
shortest_distance = d_keypoint_edge;
|
||||
nearest_branche_index = j;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return nearest_branche_index;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, Skeleton const& s)
|
||||
{
|
||||
for (auto const& vertex : s.m_vertices)
|
||||
{
|
||||
out << "v " << vertex.x << " " << vertex.y << " " << vertex.r << "\n";
|
||||
out << "v " << vertex.x << " " << vertex.y << " " << vertex.z << "\n";
|
||||
}
|
||||
|
||||
out << "\n";
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include "opencv2/features2d/features2d.hpp"
|
||||
#include "Box.hpp"
|
||||
|
||||
class Vertex
|
||||
|
@ -11,7 +12,7 @@ class Vertex
|
|||
public:
|
||||
float x;
|
||||
float y;
|
||||
float r;
|
||||
float z;
|
||||
};
|
||||
|
||||
class Edge
|
||||
|
@ -41,11 +42,12 @@ class Skeleton
|
|||
std::vector<Skeleton> split();
|
||||
friend std::ostream& operator<<(std::ostream& out, Skeleton const& s);
|
||||
void computeBoundingBox();
|
||||
friend std::vector<std::pair<unsigned int,unsigned int>> branchesMatching(std::vector<std::pair<cv::KeyPoint,cv::KeyPoint>> keypoints, std::vector<Skeleton> branches1, std::vector<Skeleton> branches2);
|
||||
|
||||
private:
|
||||
void addNextPoint(std::vector<std::vector<bool>> const& connections, std::vector<unsigned int>& path) const;
|
||||
std::vector<unsigned int> findOnes(std::vector<std::vector<bool>> const& connections, unsigned int lineNumber) const;
|
||||
|
||||
friend unsigned int searchNearestBrancheIndex(cv::KeyPoint const& keypoint, std::vector<Skeleton> branches);
|
||||
std::vector<Vertex> m_vertices;
|
||||
std::vector<Edge> m_edges;
|
||||
std::vector<unsigned int> m_neighbourgs_counters;
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
v 30 2 10
|
||||
v 25 0 9
|
||||
v 20 2 8
|
||||
v 17 5 9
|
||||
v 16 9 7
|
||||
v 16 13 8
|
||||
v 17 16 7
|
||||
v 21 15 6
|
||||
v 25 14 6
|
||||
v 29 13 6
|
||||
v 33 12 5
|
||||
v 13 7 6
|
||||
v 10 5 6
|
||||
v 7 8 5
|
||||
v 4 11 4
|
||||
v 2 15 3
|
||||
v 17 20 8
|
||||
v 17 24 9
|
||||
v 18 28 8
|
||||
v 21 30 7
|
||||
v 25 32 6
|
||||
v 29 33 5
|
||||
v 33 34 4
|
||||
v 14 30 7
|
||||
v 10 33 6
|
||||
v 6 35 5
|
||||
|
||||
e 1 2
|
||||
e 2 3
|
||||
e 3 4
|
||||
e 4 5
|
||||
e 5 6
|
||||
e 6 7
|
||||
e 7 8
|
||||
e 8 9
|
||||
e 9 10
|
||||
e 10 11
|
||||
e 7 12
|
||||
e 12 13
|
||||
e 13 14
|
||||
e 14 15
|
||||
e 15 16
|
||||
e 7 17
|
||||
e 17 18
|
||||
e 18 19
|
||||
e 19 20
|
||||
e 20 21
|
||||
e 21 22
|
||||
e 22 23
|
||||
e 19 24
|
||||
e 24 25
|
||||
e 25 26
|
|
@ -0,0 +1,33 @@
|
|||
std::vector<std::pair<cv::KeyPoint,cv::KeyPoint>> keypoints1 = {
|
||||
// Pairs of keypoints supposed to be matched with branche[0]
|
||||
{cv::KeyPoint{cv::Point{100,400},0}, cv::KeyPoint{cv::Point{400,400},0}},
|
||||
{cv::KeyPoint{cv::Point{200,200},0}, cv::KeyPoint{cv::Point{400,300},0}},
|
||||
{cv::KeyPoint{cv::Point{400,400},0}, cv::KeyPoint{cv::Point{500,300},0}},
|
||||
{cv::KeyPoint{cv::Point{300,600},0}, cv::KeyPoint{cv::Point{500,600},0}},
|
||||
{cv::KeyPoint{cv::Point{100,400},0}, cv::KeyPoint{cv::Point{500,300},0}},
|
||||
// Pairs of keypoints supposed to be matched with branches[1]
|
||||
{cv::KeyPoint{cv::Point{700,300},0}, cv::KeyPoint{cv::Point{650,400},0}},
|
||||
{cv::KeyPoint{cv::Point{900,200},0}, cv::KeyPoint{cv::Point{700,200},0}},
|
||||
{cv::KeyPoint{cv::Point{1100,400},0}, cv::KeyPoint{cv::Point{900,300},0}},
|
||||
{cv::KeyPoint{cv::Point{1000,600},0}, cv::KeyPoint{cv::Point{800,500},0}},
|
||||
{cv::KeyPoint{cv::Point{800,600},0}, cv::KeyPoint{cv::Point{700,600},0}},
|
||||
// Pairs of keypoints supposed to be matched with branches[2]
|
||||
{cv::KeyPoint{cv::Point{400,800},0}, cv::KeyPoint{cv::Point{500,800},0}},
|
||||
{cv::KeyPoint{cv::Point{600,700},0}, cv::KeyPoint{cv::Point{700,700},0}},
|
||||
{cv::KeyPoint{cv::Point{700,900},0}, cv::KeyPoint{cv::Point{750,900},0}},
|
||||
// Pairs of keypoints supposed to be matched with branches[3]
|
||||
{cv::KeyPoint{cv::Point{300,1000},0}, cv::KeyPoint{cv::Point{400,1000},0}},
|
||||
{cv::KeyPoint{cv::Point{100,1100},0}, cv::KeyPoint{cv::Point{300,1100},0}},
|
||||
{cv::KeyPoint{cv::Point{300,1200},0}, cv::KeyPoint{cv::Point{500,1100},0}},
|
||||
// Pairs of keypoints supposed to be matched with branches[4]
|
||||
{cv::KeyPoint{cv::Point{1000,1100},0}, cv::KeyPoint{cv::Point{900,1100},0}},
|
||||
{cv::KeyPoint{cv::Point{1100,1300},0}, cv::KeyPoint{cv::Point{1000,1300},0}},
|
||||
{cv::KeyPoint{cv::Point{900,1400},0}, cv::KeyPoint{cv::Point{900,1400},0}},
|
||||
// {cv::KeyPoint{cv::Point{800,1200},0}, cv::KeyPoint{cv::Point{800,1200},0}},
|
||||
{cv::KeyPoint{cv::Point{800,1200},0}, cv::KeyPoint{cv::Point{670,1200},0}},
|
||||
// Pairs of keypoints supposed to be matched with branches[5]
|
||||
{cv::KeyPoint{cv::Point{500,1100},0}, cv::KeyPoint{cv::Point{600,1100},0}},
|
||||
{cv::KeyPoint{cv::Point{400,1300},0}, cv::KeyPoint{cv::Point{500,1300},0}},
|
||||
{cv::KeyPoint{cv::Point{600,1400},0}, cv::KeyPoint{cv::Point{700,1400},0}},
|
||||
{cv::KeyPoint{cv::Point{400,1500},0}, cv::KeyPoint{cv::Point{500,1500},0}}
|
||||
};
|
|
@ -15,7 +15,7 @@
|
|||
constexpr auto WIDTH = 1920;
|
||||
constexpr auto HEIGHT = 1080;
|
||||
|
||||
void drawScene(FreeFlyCamera const& camera, std::vector<Skeleton> const& s, std::vector<std::array<float,3>> const& colors);
|
||||
void drawScene(FreeFlyCamera const& camera, std::vector<Skeleton> const& s, std::vector<Skeleton> const& s2, std::vector<std::pair<unsigned int, unsigned int>> const& matching, std::vector<std::array<float,3>> const& colors);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
|
@ -40,7 +40,7 @@ int main(int argc, char *argv[])
|
|||
//Initialisation du mode 3D
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
gluPerspective(70,(double)WIDTH/HEIGHT,0.2,1000);
|
||||
gluPerspective(70,(double)WIDTH/HEIGHT,0.2,10000);
|
||||
|
||||
// Initialisation de Z-Buffer
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
@ -61,10 +61,28 @@ int main(int argc, char *argv[])
|
|||
glFlush();
|
||||
|
||||
// Init mesh
|
||||
Skeleton s;
|
||||
Skeleton s, s2;
|
||||
s.loadFromFile(std::string{argv[1]});
|
||||
s.computeJunctions();
|
||||
std::vector<std::pair<unsigned int, unsigned int>> matching;
|
||||
std::vector<Skeleton> split = s.split();
|
||||
std::vector<Skeleton> split2;
|
||||
#include "init.cxx"
|
||||
|
||||
if (argc > 2)
|
||||
{
|
||||
s2.loadFromFile(std::string{argv[2]});
|
||||
s2.computeJunctions();
|
||||
split2 = s2.split();
|
||||
std::swap(split2[1], split2[2]);
|
||||
matching = branchesMatching(keypoints1, split, split2);
|
||||
|
||||
std::cout << "-------------------------------------------" << std::endl;
|
||||
|
||||
for (auto const& pair : matching)
|
||||
std::cout << pair.first << " -> " << pair.second << std::endl;
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::array<float,3>> colors;
|
||||
|
||||
|
@ -121,7 +139,7 @@ int main(int argc, char *argv[])
|
|||
sf::Mouse::setPosition(sf::Vector2i{WIDTH/2, HEIGHT/2});
|
||||
|
||||
// Dessin de la scene
|
||||
drawScene(camera, split, colors);
|
||||
drawScene(camera, split, split2, matching, colors);
|
||||
glScalef(0.01, 0.01, 1);
|
||||
|
||||
if (captureRequired)
|
||||
|
@ -139,7 +157,7 @@ int main(int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
void drawScene(FreeFlyCamera const& camera, std::vector<Skeleton> const& split, std::vector<std::array<float,3>> const& colors)
|
||||
void drawScene(FreeFlyCamera const& camera, std::vector<Skeleton> const& split, std::vector<Skeleton> const& split2, std::vector<std::pair<unsigned int, unsigned int>> const& matching, std::vector<std::array<float,3>> const& colors)
|
||||
{
|
||||
// Initialisation
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
@ -149,11 +167,23 @@ void drawScene(FreeFlyCamera const& camera, std::vector<Skeleton> const& split,
|
|||
// Position Camera gluLookAt(positionCamera, positionCible, vecteurVertical)
|
||||
camera.look();
|
||||
|
||||
for (auto i = 0u; i < split.size(); i++)
|
||||
for (auto i = 0u; i < matching.size(); i++)
|
||||
{
|
||||
// Find random color
|
||||
glColor3f(colors[i][0], colors[i][1], colors[i][2]);
|
||||
split[i].draw();
|
||||
glPushMatrix();
|
||||
glTranslatef(1000,0,0);
|
||||
split2[i].draw();
|
||||
glPopMatrix();
|
||||
glPushMatrix();
|
||||
glTranslatef(0,-1500,0);
|
||||
split[matching[i].first].draw();
|
||||
glPushMatrix();
|
||||
glTranslatef(1000,0,0);
|
||||
split2[matching[i].second].draw();
|
||||
glPopMatrix();
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
// MAJ de l'écran
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,34 @@
|
|||
v 200 300 1
|
||||
v 300 400 1
|
||||
v 300 500 1
|
||||
v 500 600 1
|
||||
v 600 500 1
|
||||
v 800 400 1
|
||||
v 900 300 1
|
||||
v 500 800 1
|
||||
v 600 900 1
|
||||
v 600 1000 1
|
||||
v 400 1000 1
|
||||
v 200 1100 1
|
||||
v 800 1100 1
|
||||
v 900 1300 1
|
||||
v 500 1200 1
|
||||
v 500 1300 1
|
||||
v 400 1400 1
|
||||
|
||||
e 1 2
|
||||
e 2 3
|
||||
e 3 4
|
||||
e 4 5
|
||||
e 5 6
|
||||
e 6 7
|
||||
e 4 8
|
||||
e 8 9
|
||||
e 9 10
|
||||
e 10 11
|
||||
e 11 12
|
||||
e 10 13
|
||||
e 13 14
|
||||
e 10 15
|
||||
e 15 16
|
||||
e 16 17
|
|
@ -0,0 +1,36 @@
|
|||
v 450 325 1
|
||||
v 500 400 1
|
||||
v 500 500 1
|
||||
v 600 600 1
|
||||
v 650 500 1
|
||||
v 750 400 1
|
||||
v 800 275 1
|
||||
v 600 800 1
|
||||
v 675 900 1
|
||||
v 675 1000 1
|
||||
v 500 1000 1
|
||||
v 400 1100 1
|
||||
v 800 1100 1
|
||||
v 875 1250 1
|
||||
v 625 1200 1
|
||||
v 625 1300 1
|
||||
v 550 1450 1
|
||||
v 540 1470 1
|
||||
|
||||
e 4 5
|
||||
e 5 6
|
||||
e 6 7
|
||||
e 8 4
|
||||
e 8 9
|
||||
e 9 10
|
||||
e 1 2
|
||||
e 2 3
|
||||
e 3 4
|
||||
e 10 11
|
||||
e 11 12
|
||||
e 10 13
|
||||
e 13 14
|
||||
e 15 10
|
||||
e 15 16
|
||||
e 17 16
|
||||
e 17 18
|
Loading…
Reference in New Issue