我是 Boost Graph Library 的新手,并且对无向图有疑问。
我的问题是,一个2D空间,其中放置了几个地标。在开始时,定义了一个Master-landmark
,目标是计算从Master-landmark
到所有其他地标的相对姿势。由于网格很大,一次看到它,我只得到本地信息,意味着两个或多个地标之间的相对连接/姿势(Master-landmark
不必在每个图像中)。鉴于这些本地信息,我需要构建一个树,以便获得从Master-landmark
到其他地标的路径。到现在为止还挺好。
由于地标观测由另一个程序完成,我构建了一个矩阵,其中有关地标关系的信息被编码(两个地标一起看?如果是,相对姿势,如果不是0)。该矩阵是大小为tag_relation_mat
的所谓N×N
矩阵。 N
定义地标的数量,矩阵的行和列代表所有N
地标以编码它们的关系。每个元素(如果两个标记之间存在连接,否则为0
)是rel_marker_pose
,包括:2D姿势(x和y值)和错误值(高值很差) 。换句话说,tag_relation_mat
是一个矩阵,它对地标之间的所有有效连接进行编码。
基于该矩阵,我想生成无向图并计算从Master-landmark
到所有其他给定最佳误差值的相对姿势。
所以我现在基本上做的(在this link的帮助下)是
dijkstra_shortest_paths
算法结果是组合权重(从主要地标到地标)和地标的父级。
根据这些信息,我通过组合N×N
矩阵给出的变换,递归地生成从每个地标到主地标的路径:
.h文件:
// Edge weight.
typedef boost::property<boost::edge_weight_t, double> EdgeWeightProperty;
typedef adjacency_list < boost::setS, boost::vecS, boost::undirectedS,
boost::no_property, EdgeWeightProperty > Graph; //graph type
typedef typename boost::graph_traits<Graph>::vertex_descriptor Vertex; //vertex descriptor
typedef typename boost::graph_traits<Graph>::edge_descriptor Edge; //edge descriptor
typedef std::pair<int, int> _edge;
class GraphTree {
public:
GraphTree(int no_of_tags) {
this->num_vertices = no_of_tags;
//generate vertices
for(int i = 0; i < no_of_tags; i++) {
Vertex v = boost::add_vertex(this->undirected_graph);
idx_to_vertex.insert({i, v});
}
}
/**
* @brief generateTree generates tree graph with tags as edges and
*/
void generateTree();
/**
* @brief solveTree thin tree based on chosen solver
*/
std::vector<rel_marker_pose> solveTree(tree_solver solver, int master_vertex_idx);
/**
* @brief getRelPosesToMaster given a master tag (either defined or automatically chosen) rel. poses to the other existing tags are computed
*/
void getRelPosesToMaster(int master_node, std::vector<Vertex> parent_vec, int start_node, rel_marker_pose* rel_m_pose);
private:
// declare a graph object
Graph undirected_graph;
std::map<int, Vertex> idx_to_vertex;
int num_vertices;// const int num_vertices = N;
int num_edges;//int num_edges = sizeof(edge_array)/sizeof(edge_array[0]);
std::vector<Edge> edge_vec;
};
.cpp文件:
void GraphTree::generateTree() {
for(int i = 0; i < this->num_vertices; ++i) { //iterate over rows (landmark_from)
for(int j = 0; j < this->num_vertices; ++j) { //iterate over columns (landmark_to)
double weight = this->tag_relation_mat.at(i).at(j).rel_pose.quality;
//check if tags have been seen together -> add only relevant edges
if(this->tag_relation_mat.at(i).at(j).landmark_from != 0 && this->tag_relation_mat.at(i).at(j).landmark_to != 0) {
boost::add_edge(this->idx_to_vertex[i], this->idx_to_vertex[j], EdgeWeightProperty(weight), this->undirected_graph);
}
}
}
}
std::vector<rel_marker_pose> GraphTree::solveTree(tree_solver solver, int master_vertex_idx) {
std::vector<rel_marker_pose> master_to_vertex_vec;
if(solver == tree_solver::Dijkstra) { //http://www.boost.org/doc/libs/1_46_1/libs/graph/example/dijkstra-example.cpp
//create vectors to store the predecessors (p) and the distances from the root (d)
std::vector<Vertex> p(boost::num_vertices(this->undirected_graph));
std::vector<double> d(boost::num_vertices(this->undirected_graph));
//create a descriptor for the source node
Vertex master_vertex = vertex(master_vertex_idx, this->undirected_graph);
//evaluate dijkstra on graph g with source s, predecessor_map p and distance_map d
boost::dijkstra_shortest_paths(this->undirected_graph, master_vertex, boost::predecessor_map(&p[0]).distance_map(&d[0]));
boost::graph_traits < Graph >::vertex_iterator vi, vend;
for (boost::tie(vi, vend) = boost::vertices(this->undirected_graph); vi != vend; ++vi) {
rel_marker_pose r_m_p;
this->getRelPosesToMaster(master_vertex_idx, p, *vi, &r_m_p);
master_to_vertex_vec.push_back(r_m_p);
}
}
return master_to_vertex_vec;
}
void GraphTree::getRelPosesToMaster(int master_node, std::vector<Vertex> parent_vec, int start_node, rel_marker_pose* rel_m_pose ) {
rel_m_pose->rel_pose.quality += this->tag_relation_mat.at(start_node).at(parent_vec[start_node]).rel_pose.quality;
// ...
// combine the transformations
// ...
rel_m_pose->landmark_from = parent_vec[start_node];
if(parent_vec[start_node] == master_node) {
return;
}
else {
this->getRelPosesToMaster(master_node, parent_vec, parent_vec[start_node], rel_m_pose);
}
}
嗯,它有效,但绝对不是最优雅的方式!我在想:
非常感谢你的帮助!