Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ImageGraph.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
27 #include "ImageGraph.h"
28 #include <queue>
29 
30 namespace HuginGraph
31 {
32 /* build adjacency list for all images in pano */
33 ImageGraph::ImageGraph(const HuginBase::PanoramaData& pano, bool ignoreLinkedPosition)
34 {
35  if (pano.getNrOfImages() > 0)
36  {
37  m_graph.resize(pano.getNrOfImages());
38  if (!ignoreLinkedPosition)
39  {
40  // handle all linked positions
41  for (size_t i = 0; i < pano.getNrOfImages(); ++i)
42  {
43  const HuginBase::SrcPanoImage& image = pano.getImage(i);
44  if (image.YawisLinked())
45  {
46  for (size_t j = i + 1; j < pano.getNrOfImages(); ++j)
47  {
48  if (image.YawisLinkedWith(pano.getImage(j)))
49  {
50  m_graph[i].insert(j);
51  m_graph[j].insert(i);
52  };
53  };
54  };
55  };
56  };
57  // and now all control points
58  const HuginBase::CPVector& cps = pano.getCtrlPoints();
59  for (size_t i = 0; i < cps.size(); ++i)
60  {
61  if (cps[i].mode == HuginBase::ControlPoint::X_Y && cps[i].image1Nr != cps[i].image2Nr)
62  {
63  m_graph[cps[i].image1Nr].insert(cps[i].image2Nr);
64  m_graph[cps[i].image2Nr].insert(cps[i].image1Nr);
65  }
66  }
67  };
68 };
69 
71 {
72  const unsigned int nrImages = overlap.getNrOfImages();
73  m_graph.resize(nrImages);
74  // and now all control points
75  for (size_t i = 0; i < nrImages-1; ++i)
76  {
77  for (size_t j = i + 1; j < nrImages; ++j)
78  {
79  if (overlap.getOverlap(i, j)>0.001)
80  {
81  m_graph[i].insert(j);
82  m_graph[j].insert(i);
83  }
84  };
85  };
86 };
87 
88 template<typename VALUETYPE>
89 void DepthFirstSearch(const ImageGraph::GraphList& graph, std::vector<VALUETYPE>& marks, const size_t vertex, const VALUETYPE setType, const VALUETYPE unvisitedType)
90 {
91  marks[vertex] = setType;
92  for (HuginBase::UIntSet::const_iterator it = graph[vertex].begin(); it != graph[vertex].end(); ++it)
93  {
94  if (marks[*it] == unvisitedType)
95  {
96  DepthFirstSearch(graph, marks, *it, setType, unvisitedType);
97  };
98  };
99 };
100 
102 {
104  if (m_graph.empty())
105  {
106  return comp;
107  };
108  // and now the depth first search algorithm
109  std::vector<size_t> marks(m_graph.size(), 0);
110  size_t counter = 0;
111  for (size_t i = 0; i < m_graph.size(); ++i)
112  {
113  if (marks[i] == 0)
114  {
115  counter++;
116  DepthFirstSearch<size_t>(m_graph, marks, i, counter, 0);
117  };
118  };
119  // now create the connected components as vector<UIntSet>
120  comp.resize(counter);
121  for (size_t imgNr = 0; imgNr < marks.size(); ++imgNr)
122  {
123  comp[marks[imgNr] - 1].insert(imgNr);
124  }
125  return comp;
126 };
127 
129 {
130  if (m_graph.empty())
131  {
132  return false;
133  };
134  // and now the depth first search algorithm
135  std::vector<bool> visited(m_graph.size(), false);
136  DepthFirstSearch(m_graph, visited, 0, true, false);
137  for (std::vector<bool>::const_iterator it = visited.begin(); it != visited.end(); ++it)
138  {
139  if (!(*it))
140  {
141  return false;
142  }
143  }
144  return true;
145 };
146 
148  std::queue<size_t>& queue, std::vector<bool>& visited, BreadthFirstSearchVisitor* visitor)
149 {
150  while (!queue.empty())
151  {
152  const size_t vertex = queue.front();
153  queue.pop();
154  if (!visited[vertex])
155  {
156  visited[vertex] = true;
157  HuginBase::UIntSet visitedNeighbors;
158  HuginBase::UIntSet unvisitedNeighbors;
159  for (HuginBase::UIntSet::const_iterator it = graph[vertex].begin(); it != graph[vertex].end(); ++it)
160  {
161  if (visited[*it])
162  {
163  visitedNeighbors.insert(*it);
164  }
165  else
166  {
167  unvisitedNeighbors.insert(*it);
168  queue.push(*it);
169  };
170  };
171  visitor->Visit(vertex, visitedNeighbors, unvisitedNeighbors);
172  };
173  };
174 }
175 
176 void ImageGraph::VisitAllImages(const size_t startImg, bool forceAllComponents, BreadthFirstSearchVisitor* visitor)
177 {
178  if (m_graph.empty())
179  {
180  return;
181  }
182  // range checking, just in case
183  const size_t realStartImg = (startImg >= m_graph.size()) ? 0 : startImg;
184  std::vector<bool> visited(m_graph.size(), false);
185  std::queue<size_t> queue;
186  // go down the graph starting from the startImg
187  queue.push(realStartImg);
188  BreadthFirstSearchVisit(m_graph, queue, visited, visitor);
189  if (forceAllComponents)
190  {
191  // if the graph contains several components
192  // we have not yet visited all images, so
193  // restart the breadth first algorithm from the new component start
194  for (size_t i = 0; i < m_graph.size(); ++i)
195  {
196  if (!visited[i])
197  {
198  queue.push(i);
199  BreadthFirstSearchVisit(m_graph, queue, visited, visitor);
200  };
201  };
202  };
203 };
204 
205 } // namespace HuginGraph
double getOverlap(unsigned int i, unsigned int j) const
returns the overlap for 2 images with number i and j
bool IsConnected()
check if all images are connected
Definition: ImageGraph.cpp:128
std::vector< HuginBase::UIntSet > Components
stores the components of the graph
Definition: ImageGraph.h:50
ImageGraph(const HuginBase::PanoramaData &pano, bool ignoreLinkedPosition=false)
constructor, build internal representation of graph
Definition: ImageGraph.cpp:33
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
void VisitAllImages(const size_t startImg, bool forceAllComponents, BreadthFirstSearchVisitor *visitor)
visit all images via a breadth first search algorithm for each visited images, the functor visitor is...
Definition: ImageGraph.cpp:176
std::vector< HuginBase::UIntSet > GraphList
stores adjacency list for graph
Definition: ImageGraph.h:48
void BreadthFirstSearchVisit(const ImageGraph::GraphList &graph, std::queue< size_t > &queue, std::vector< bool > &visited, BreadthFirstSearchVisitor *visitor)
Definition: ImageGraph.cpp:147
Model for a panorama.
Definition: PanoramaData.h:81
virtual const SrcPanoImage & getImage(std::size_t nr) const =0
get a panorama image, counting starts with 0
void DepthFirstSearch(const ImageGraph::GraphList &graph, std::vector< VALUETYPE > &marks, const size_t vertex, const VALUETYPE setType, const VALUETYPE unvisitedType)
Definition: ImageGraph.cpp:89
virtual const CPVector & getCtrlPoints() const =0
get all control point of this Panorama
Components GetComponents()
find all connected components
Definition: ImageGraph.cpp:101
std::vector< ControlPoint > CPVector
Definition: ControlPoint.h:99
unsigned int getNrOfImages() const
return number of images in underlying pano
class for calculating overlap of images
virtual std::size_t getNrOfImages() const =0
number of images.
All variables of a source image.
Definition: SrcPanoImage.h:194
virtual void Visit(const size_t vertex, const HuginBase::UIntSet &visitedNeighbors, const HuginBase::UIntSet &unvisitedNeighbors)=0
abstract base functor for breadth first search in ImageGraph
Definition: ImageGraph.h:35