1 /*============================================================================
3 The Medical Imaging Interaction Toolkit (MITK)
5 Copyright (c) German Cancer Research Center (DKFZ)
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
11 ============================================================================*/
12 #ifndef __itkShortestPathImageFilter_txx
13 #define __itkShortestPathImageFilter_txx
15 #include "itkShortestPathImageFilter.h"
17 #include "mitkMemoryUtilities.h"
25 // Constructor (initialize standard values)
26 template <class TInputImageType, class TOutputImageType>
27 ShortestPathImageFilter<TInputImageType, TOutputImageType>::ShortestPathImageFilter()
29 m_Graph_NumberOfNodes(0),
30 m_Graph_fullNeighbors(false),
31 m_FullNeighborsMode(false),
32 m_MakeOutputImage(true),
33 m_StoreVectorOrder(false),
34 m_CalcAllDistances(false),
35 multipleEndPoints(false),
36 m_ActivateTimeOut(false),
40 m_endPointsClosed.clear();
42 if (m_MakeOutputImage)
44 this->SetNumberOfRequiredOutputs(1);
45 this->SetNthOutput(0, OutputImageType::New());
49 template <class TInputImageType, class TOutputImageType>
50 ShortestPathImageFilter<TInputImageType, TOutputImageType>::~ShortestPathImageFilter()
55 template <class TInputImageType, class TOutputImageType>
56 inline typename ShortestPathImageFilter<TInputImageType, TOutputImageType>::IndexType
57 ShortestPathImageFilter<TInputImageType, TOutputImageType>::NodeToCoord(NodeNumType node)
59 const InputImageSizeType &size = this->GetInput()->GetRequestedRegion().GetSize();
60 int dim = InputImageType::ImageDimension;
64 coord[1] = node / size[0];
65 coord[0] = node % size[0];
66 if (((unsigned long)coord[0] >= size[0]) || ((unsigned long)coord[1] >= size[1]))
74 coord[2] = node / (size[0] * size[1]);
75 coord[1] = (node % (size[0] * size[1])) / size[0];
76 coord[0] = (node % (size[0] * size[1])) % size[0];
77 if (((unsigned long)coord[0] >= size[0]) || ((unsigned long)coord[1] >= size[1]) ||
78 ((unsigned long)coord[2] >= size[2]))
89 template <class TInputImageType, class TOutputImageType>
90 inline typename itk::NodeNumType ShortestPathImageFilter<TInputImageType, TOutputImageType>::CoordToNode(
93 const InputImageSizeType &size = this->GetInput()->GetRequestedRegion().GetSize();
94 int dim = InputImageType::ImageDimension;
98 node = (coord[1] * size[0]) + coord[0];
102 node = (coord[2] * size[0] * size[1]) + (coord[1] * size[0]) + coord[0];
104 if ((m_Graph_NumberOfNodes > 0) && (node >= m_Graph_NumberOfNodes))
106 /*MITK_INFO << "WARNING! Coordinates outside image!";
107 MITK_INFO << "Coords = " << coord ;
108 MITK_INFO << "ImageDim = " << dim ;
109 MITK_INFO << "RequestedRegionSize = " << size ;*/
116 template <class TInputImageType, class TOutputImageType>
117 inline bool ShortestPathImageFilter<TInputImageType, TOutputImageType>::CoordIsInBounds(IndexType coord)
119 const InputImageSizeType &size = this->GetInput()->GetRequestedRegion().GetSize();
120 int dim = InputImageType::ImageDimension;
124 if ((coord[0] >= 0) && ((unsigned long)coord[0] < size[0]) && (coord[1] >= 0) &&
125 ((unsigned long)coord[1] < size[1]))
132 if ((coord[0] >= 0) && ((unsigned long)coord[0] < size[0]) && (coord[1] >= 0) &&
133 ((unsigned long)coord[1] < size[1]) && (coord[2] >= 0) && ((unsigned long)coord[2] < size[2]))
141 template <class TInputImageType, class TOutputImageType>
142 inline std::vector<ShortestPathNode *> ShortestPathImageFilter<TInputImageType, TOutputImageType>::GetNeighbors(
143 unsigned int nodeNum, bool FullNeighbors)
145 // returns a vector of nodepointers.. these nodes are the neighbors
146 int dim = InputImageType::ImageDimension;
147 IndexType Coord = NodeToCoord(nodeNum);
148 IndexType NeighborCoord;
149 std::vector<ShortestPathNode *> nodeList;
151 int neighborDistance = 1; // if i increase that, i might not hit the endnote
153 // maybe use itkNeighborhoodIterator here, might be faster
158 NeighborCoord[0] = Coord[0];
159 NeighborCoord[1] = Coord[1] - neighborDistance;
160 if (CoordIsInBounds(NeighborCoord))
161 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
163 NeighborCoord[0] = Coord[0] + neighborDistance;
164 NeighborCoord[1] = Coord[1];
165 if (CoordIsInBounds(NeighborCoord))
166 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
168 NeighborCoord[0] = Coord[0];
169 NeighborCoord[1] = Coord[1] + neighborDistance;
170 if (CoordIsInBounds(NeighborCoord))
171 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
173 NeighborCoord[0] = Coord[0] - neighborDistance;
174 NeighborCoord[1] = Coord[1];
175 if (CoordIsInBounds(NeighborCoord))
176 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
181 NeighborCoord[0] = Coord[0] - neighborDistance;
182 NeighborCoord[1] = Coord[1] - neighborDistance;
183 if (CoordIsInBounds(NeighborCoord))
184 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
186 NeighborCoord[0] = Coord[0] + neighborDistance;
187 NeighborCoord[1] = Coord[1] - neighborDistance;
188 if (CoordIsInBounds(NeighborCoord))
189 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
191 NeighborCoord[0] = Coord[0] - neighborDistance;
192 NeighborCoord[1] = Coord[1] + neighborDistance;
193 if (CoordIsInBounds(NeighborCoord))
194 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
196 NeighborCoord[0] = Coord[0] + neighborDistance;
197 NeighborCoord[1] = Coord[1] + neighborDistance;
198 if (CoordIsInBounds(NeighborCoord))
199 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
205 NeighborCoord[0] = Coord[0];
206 NeighborCoord[1] = Coord[1] - neighborDistance;
207 NeighborCoord[2] = Coord[2];
208 if (CoordIsInBounds(NeighborCoord))
209 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
211 NeighborCoord[0] = Coord[0] + neighborDistance;
212 NeighborCoord[1] = Coord[1];
213 NeighborCoord[2] = Coord[2];
214 if (CoordIsInBounds(NeighborCoord))
215 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
217 NeighborCoord[0] = Coord[0];
218 NeighborCoord[1] = Coord[1] + neighborDistance;
219 NeighborCoord[2] = Coord[2];
220 if (CoordIsInBounds(NeighborCoord))
221 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
223 NeighborCoord[0] = Coord[0] - neighborDistance;
224 NeighborCoord[1] = Coord[1];
225 NeighborCoord[2] = Coord[2];
226 if (CoordIsInBounds(NeighborCoord))
227 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
229 NeighborCoord[0] = Coord[0];
230 NeighborCoord[1] = Coord[1];
231 NeighborCoord[2] = Coord[2] + neighborDistance;
232 if (CoordIsInBounds(NeighborCoord))
233 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
235 NeighborCoord[0] = Coord[0];
236 NeighborCoord[1] = Coord[1];
237 NeighborCoord[2] = Coord[2] - neighborDistance;
238 if (CoordIsInBounds(NeighborCoord))
239 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
245 NeighborCoord[0] = Coord[0] - neighborDistance;
246 NeighborCoord[1] = Coord[1] - neighborDistance;
247 NeighborCoord[2] = Coord[2];
248 if (CoordIsInBounds(NeighborCoord))
249 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
251 NeighborCoord[0] = Coord[0] + neighborDistance;
252 NeighborCoord[1] = Coord[1] - neighborDistance;
253 NeighborCoord[2] = Coord[2];
254 if (CoordIsInBounds(NeighborCoord))
255 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
257 NeighborCoord[0] = Coord[0] - neighborDistance;
258 NeighborCoord[1] = Coord[1] + neighborDistance;
259 NeighborCoord[2] = Coord[2];
260 if (CoordIsInBounds(NeighborCoord))
261 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
263 NeighborCoord[0] = Coord[0] + neighborDistance;
264 NeighborCoord[1] = Coord[1] + neighborDistance;
265 NeighborCoord[2] = Coord[2];
266 if (CoordIsInBounds(NeighborCoord))
267 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
269 // BackSlice (Diagonal)
270 NeighborCoord[0] = Coord[0] - neighborDistance;
271 NeighborCoord[1] = Coord[1] - neighborDistance;
272 NeighborCoord[2] = Coord[2] - neighborDistance;
273 if (CoordIsInBounds(NeighborCoord))
274 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
276 NeighborCoord[0] = Coord[0] + neighborDistance;
277 NeighborCoord[1] = Coord[1] - neighborDistance;
278 NeighborCoord[2] = Coord[2] - neighborDistance;
279 if (CoordIsInBounds(NeighborCoord))
280 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
282 NeighborCoord[0] = Coord[0] - neighborDistance;
283 NeighborCoord[1] = Coord[1] + neighborDistance;
284 NeighborCoord[2] = Coord[2] - neighborDistance;
285 if (CoordIsInBounds(NeighborCoord))
286 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
288 NeighborCoord[0] = Coord[0] + neighborDistance;
289 NeighborCoord[1] = Coord[1] + neighborDistance;
290 NeighborCoord[2] = Coord[2] - neighborDistance;
291 if (CoordIsInBounds(NeighborCoord))
292 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
294 // BackSlice (Non-Diag)
295 NeighborCoord[0] = Coord[0];
296 NeighborCoord[1] = Coord[1] - neighborDistance;
297 NeighborCoord[2] = Coord[2] - neighborDistance;
298 if (CoordIsInBounds(NeighborCoord))
299 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
301 NeighborCoord[0] = Coord[0] + neighborDistance;
302 NeighborCoord[1] = Coord[1];
303 NeighborCoord[2] = Coord[2] - neighborDistance;
304 if (CoordIsInBounds(NeighborCoord))
305 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
307 NeighborCoord[0] = Coord[0];
308 NeighborCoord[1] = Coord[1] + neighborDistance;
309 NeighborCoord[2] = Coord[2] - neighborDistance;
310 if (CoordIsInBounds(NeighborCoord))
311 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
313 NeighborCoord[0] = Coord[0] - neighborDistance;
314 NeighborCoord[1] = Coord[1];
315 NeighborCoord[2] = Coord[2] - neighborDistance;
316 if (CoordIsInBounds(NeighborCoord))
317 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
319 // FrontSlice (Diagonal)
320 NeighborCoord[0] = Coord[0] - neighborDistance;
321 NeighborCoord[1] = Coord[1] - neighborDistance;
322 NeighborCoord[2] = Coord[2] + neighborDistance;
323 if (CoordIsInBounds(NeighborCoord))
324 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
326 NeighborCoord[0] = Coord[0] + neighborDistance;
327 NeighborCoord[1] = Coord[1] - neighborDistance;
328 NeighborCoord[2] = Coord[2] + neighborDistance;
329 if (CoordIsInBounds(NeighborCoord))
330 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
332 NeighborCoord[0] = Coord[0] - neighborDistance;
333 NeighborCoord[1] = Coord[1] + neighborDistance;
334 NeighborCoord[2] = Coord[2] + neighborDistance;
335 if (CoordIsInBounds(NeighborCoord))
336 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
338 NeighborCoord[0] = Coord[0] + neighborDistance;
339 NeighborCoord[1] = Coord[1] + neighborDistance;
340 NeighborCoord[2] = Coord[2] + neighborDistance;
341 if (CoordIsInBounds(NeighborCoord))
342 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
344 // FrontSlice(Non-Diag)
345 NeighborCoord[0] = Coord[0];
346 NeighborCoord[1] = Coord[1] - neighborDistance;
347 NeighborCoord[2] = Coord[2] + neighborDistance;
348 if (CoordIsInBounds(NeighborCoord))
349 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
351 NeighborCoord[0] = Coord[0] + neighborDistance;
352 NeighborCoord[1] = Coord[1];
353 NeighborCoord[2] = Coord[2] + neighborDistance;
354 if (CoordIsInBounds(NeighborCoord))
355 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
357 NeighborCoord[0] = Coord[0];
358 NeighborCoord[1] = Coord[1] + neighborDistance;
359 NeighborCoord[2] = Coord[2] + neighborDistance;
360 if (CoordIsInBounds(NeighborCoord))
361 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
363 NeighborCoord[0] = Coord[0] - neighborDistance;
364 NeighborCoord[1] = Coord[1];
365 NeighborCoord[2] = Coord[2] + neighborDistance;
366 if (CoordIsInBounds(NeighborCoord))
367 nodeList.push_back(&m_Nodes[CoordToNode(NeighborCoord)]);
373 template <class TInputImageType, class TOutputImageType>
374 void ShortestPathImageFilter<TInputImageType, TOutputImageType>::SetStartIndex(
375 const typename TInputImageType::IndexType &StartIndex)
377 for (unsigned int i = 0; i < TInputImageType::ImageDimension; ++i)
379 m_StartIndex[i] = StartIndex[i];
381 m_Graph_StartNode = CoordToNode(m_StartIndex);
382 // MITK_INFO << "StartIndex = " << StartIndex;
383 // MITK_INFO << "StartNode = " << m_Graph_StartNode;
384 m_Initialized = false;
387 template <class TInputImageType, class TOutputImageType>
388 void ShortestPathImageFilter<TInputImageType, TOutputImageType>::SetEndIndex(
389 const typename TInputImageType::IndexType &EndIndex)
391 for (unsigned int i = 0; i < TInputImageType::ImageDimension; ++i)
393 m_EndIndex[i] = EndIndex[i];
395 m_Graph_EndNode = CoordToNode(m_EndIndex);
396 // MITK_INFO << "EndNode = " << m_Graph_EndNode;
399 template <class TInputImageType, class TOutputImageType>
400 void ShortestPathImageFilter<TInputImageType, TOutputImageType>::AddEndIndex(
401 const typename TInputImageType::IndexType &index)
403 // ONLY FOR MULTIPLE END POINTS SEARCH
404 IndexType newEndIndex;
405 for (unsigned int i = 0; i < TInputImageType::ImageDimension; ++i)
407 newEndIndex[i] = index[i];
409 m_endPoints.push_back(newEndIndex);
410 SetEndIndex(m_endPoints[0]);
411 multipleEndPoints = true;
414 template <class TInputImageType, class TOutputImageType>
415 inline double ShortestPathImageFilter<TInputImageType, TOutputImageType>::getEstimatedCostsToTarget(
416 const typename TInputImageType::IndexType &a)
418 // Returns the minimal possible costs for a path from "a" to targetnode.
419 itk::Vector<float, 3> v;
420 v[0] = m_EndIndex[0] - a[0];
421 v[1] = m_EndIndex[1] - a[1];
422 v[2] = m_EndIndex[2] - a[2];
424 return m_CostFunction->GetMinCost() * v.GetNorm();
427 template <class TInputImageType, class TOutputImageType>
428 void ShortestPathImageFilter<TInputImageType, TOutputImageType>::InitGraph()
432 // Clean up previous stuff
435 // Calc Number of nodes
436 auto imageDimensions = TInputImageType::ImageDimension;
437 const InputImageSizeType &size = this->GetInput()->GetRequestedRegion().GetSize();
438 m_Graph_NumberOfNodes = 1;
439 for (NodeNumType i = 0; i < imageDimensions; ++i)
440 m_Graph_NumberOfNodes = m_Graph_NumberOfNodes * size[i];
442 // Initialize mainNodeList with that number
443 m_Nodes = new ShortestPathNode[m_Graph_NumberOfNodes];
445 // Initialize each node in nodelist
446 for (NodeNumType i = 0; i < m_Graph_NumberOfNodes; i++)
448 m_Nodes[i].distAndEst = -1;
449 m_Nodes[i].distance = -1;
450 m_Nodes[i].prevNode = -1;
451 m_Nodes[i].mainListIndex = i;
452 m_Nodes[i].closed = false;
455 m_Initialized = true;
458 // In the beginning, the Startnode needs a distance of 0
459 m_Nodes[m_Graph_StartNode].distance = 0;
460 m_Nodes[m_Graph_StartNode].distAndEst = 0;
462 // initalize cost function
463 m_CostFunction->Initialize();
466 template <class TInputImageType, class TOutputImageType>
467 void ShortestPathImageFilter<TInputImageType, TOutputImageType>::StartShortestPathSearch()
470 clock_t startAll = clock();
471 clock_t stopAll = clock();
474 double durationAll = 0;
475 bool timeout = false;
476 NodeNumType mainNodeListIndex = 0;
477 DistanceType curNodeDistance = 0;
478 NodeNumType numberOfNodesChecked = 0;
480 // Create Multimap (tree structure for fast searching)
481 std::multimap<double, ShortestPathNode *> myMap;
482 std::pair<std::multimap<double, ShortestPathNode *>::iterator, std::multimap<double, ShortestPathNode *>::iterator>
484 std::multimap<double, ShortestPathNode *>::iterator it;
486 // At first, only startNote is discovered.
488 std::pair<double, ShortestPathNode *>(m_Nodes[m_Graph_StartNode].distAndEst, &m_Nodes[m_Graph_StartNode]));
490 // While there are discovered Nodes, pick the one with lowest distance,
491 // update its neighbors and eventually delete it from the discovered Nodes list.
492 while (!myMap.empty())
494 numberOfNodesChecked++;
495 /*if ( (numberOfNodesChecked % (m_Graph_NumberOfNodes/100)) == 0)
497 MITK_INFO << "Checked " << ( numberOfNodesChecked / (m_Graph_NumberOfNodes/100) ) << "% List: " << myMap.size()
501 // Get element with lowest score
502 mainNodeListIndex = myMap.begin()->second->mainListIndex;
503 curNodeDistance = myMap.begin()->second->distance;
504 myMap.begin()->second->closed = true; // close it
507 // MITK_INFO << "INFO: size " << myMap.size();
509 for (it = myMap.begin(); it != myMap.end(); ++it)
511 MITK_INFO << "(1) " << it->first << "|" << it->second->distAndEst << "|"<<it->second->mainListIndex;
515 // Kicks out element with lowest score
516 myMap.erase(myMap.begin());
518 // if wanted, store vector order
519 if (m_StoreVectorOrder)
521 m_VectorOrder.push_back(mainNodeListIndex);
525 std::vector<ShortestPathNode *> neighborNodes = GetNeighbors(mainNodeListIndex, m_Graph_fullNeighbors);
526 for (NodeNumType i = 0; i < neighborNodes.size(); i++)
528 if (neighborNodes[i]->closed)
529 continue; // this nodes is already closed, go to next neighbor
531 IndexType coordCurNode = NodeToCoord(mainNodeListIndex);
532 IndexType coordNeighborNode = NodeToCoord(neighborNodes[i]->mainListIndex);
534 // calculate the new Distance to the current neighbor
535 double newDistance = curNodeDistance + (m_CostFunction->GetCost(coordCurNode, coordNeighborNode));
537 // if it is shorter than any yet known path to this neighbor, than the current path is better. Save that!
538 if ((newDistance < neighborNodes[i]->distance) || (neighborNodes[i]->distance == -1))
540 // if that neighbornode is not in discoverednodeList yet, Push it there and update
541 if (neighborNodes[i]->distance == -1)
543 neighborNodes[i]->distance = newDistance;
544 neighborNodes[i]->distAndEst = newDistance + getEstimatedCostsToTarget(coordNeighborNode);
545 neighborNodes[i]->prevNode = mainNodeListIndex;
546 myMap.insert(std::pair<double, ShortestPathNode *>(m_Nodes[neighborNodes[i]->mainListIndex].distAndEst,
547 &m_Nodes[neighborNodes[i]->mainListIndex]));
549 MITK_INFO << "Inserted: " << m_Nodes[neighborNodes[i]->mainListIndex].distAndEst << "|" <<
550 m_Nodes[neighborNodes[i]->mainListIndex].mainListIndex;
551 MITK_INFO << "INFO: size " << myMap.size();
552 for (it = myMap.begin(); it != myMap.end(); ++it)
554 MITK_INFO << "(1) " << it->first << "|" << it->second->distAndEst << "|"<<it->second->mainListIndex;
558 // or if is already in discoverednodelist, update
562 it = myMap.find(neighborNodes[i]->distAndEst);
563 if (it == myMap.end() )
565 MITK_INFO << "Nothing!";
567 for (it = myMap.begin(); it != myMap.end(); ++it)
569 if ((*it).second->mainListIndex == lookForId)
571 MITK_INFO << "But it is there!!!";
572 MITK_INFO << "Searched for: " << lookFor << " but had: " << (*it).second->distAndEst;
579 // 1st : find and delete old element
581 ret = myMap.equal_range(neighborNodes[i]->distAndEst);
583 if ((ret.first == ret.second))
585 /*+++++++++++++ no exact match +++++++++++++*/
586 // MITK_INFO << "No exact match!"; // if this happens, you are screwed
588 MITK_INFO << "Was looking for: " << lookFor << " ID: " << lookForId;
589 if (ret.first != myMap.end() )
592 MITK_INFO << "Found: " << it->first << " ID: " << it->second->mainListIndex;
594 MITK_INFO << "Found: " << it->first << " ID: " << it->second->mainListIndex;
597 MITK_INFO << "Found: " << it->first << " ID: " << it->second->mainListIndex;
600 // look if that ID is found in the map
601 for (it = myMap.begin(); it != myMap.end(); ++it)
603 if ((*it).second->mainListIndex == lookForId)
605 MITK_INFO << "But it is there!!!";
606 MITK_INFO << "Searched dist: " << lookFor << " found dist: " << (*it).second->distAndEst;
614 for (it = ret.first; it != ret.second; ++it)
616 if (it->second->mainListIndex == neighborNodes[i]->mainListIndex)
621 MITK_INFO << "INFO: size " << myMap.size();
622 MITK_INFO << "Erase: " << it->first << "|" << it->second->mainListIndex;
624 MITK_INFO << "INFO: size " << myMap.size();
625 for (it = myMap.begin(); it != myMap.end(); ++it)
627 MITK_INFO << "(1) " << it->first << "|" << it->second->distAndEst << "|"<<it->second->mainListIndex;
637 // MITK_INFO << "Could not find it! :(";
641 // 2nd: update and insert new element
642 neighborNodes[i]->distance = newDistance;
643 neighborNodes[i]->distAndEst = newDistance + getEstimatedCostsToTarget(coordNeighborNode);
644 neighborNodes[i]->prevNode = mainNodeListIndex;
645 // myMap.insert( std::pair<double,ShortestPathNode*> (neighborNodes[i]->distAndEst, neighborNodes[i]));
646 myMap.insert(std::pair<double, ShortestPathNode *>(m_Nodes[neighborNodes[i]->mainListIndex].distAndEst,
647 &m_Nodes[neighborNodes[i]->mainListIndex]));
649 // MITK_INFO << "Re-Inserted: " << m_Nodes[neighborNodes[i]->mainListIndex].distAndEst << "|" <<
650 // m_Nodes[neighborNodes[i]->mainListIndex].mainListIndex;
651 // MITK_INFO << "INFO: size " << myMap.size();
652 /*for (it = myMap.begin(); it != myMap.end(); ++it)
654 MITK_INFO << "(1) " << it->first << "|" << it->second->distAndEst << "|"<<it->second->mainListIndex;
659 // finished with checking all neighbors.
661 // Check Timeout, if activated
662 if (m_ActivateTimeOut)
665 durationAll = (double)(stopAll - startAll) / CLOCKS_PER_SEC;
666 if (durationAll >= 30)
668 // MITK_INFO << "TIMEOUT!! Search took over 30 seconds";
673 // Check end criteria:
674 // For multiple points
675 if (multipleEndPoints)
677 // super slow, make it faster
678 for (unsigned int i = 0; i < m_endPoints.size(); i++)
680 if (CoordToNode(m_endPoints[i]) == mainNodeListIndex)
682 m_endPointsClosed.push_back(NodeToCoord(mainNodeListIndex));
683 m_endPoints.erase(m_endPoints.begin() + i);
684 if (m_endPoints.empty())
689 if (m_Graph_EndNode == mainNodeListIndex)
692 SetEndIndex(m_endPoints[0]);
697 // if single end point, then end, if this one is reached or timeout happened.
698 else if ((mainNodeListIndex == m_Graph_EndNode || timeout) && !m_CalcAllDistances)
700 /*if (m_StoreVectorOrder)
701 MITK_INFO << "Number of Nodes checked: " << m_VectorOrder.size() ;*/
707 template <class TInputImageType, class TOutputImageType>
708 void ShortestPathImageFilter<TInputImageType, TOutputImageType>::MakeOutputs()
710 // MITK_INFO << "Make Output";
712 if (m_MakeOutputImage)
714 OutputImagePointer output0 = this->GetOutput(0);
715 output0->SetRegions(this->GetInput()->GetLargestPossibleRegion());
717 OutputImageIteratorType shortestPathImageIt(output0, output0->GetRequestedRegion());
718 // Create ShortestPathImage (Output 0)
719 for (shortestPathImageIt.GoToBegin(); !shortestPathImageIt.IsAtEnd(); ++shortestPathImageIt)
721 // First intialize with background color
722 shortestPathImageIt.Set(BACKGROUND);
725 if (!multipleEndPoints) // Only one path was calculated
727 for (unsigned int i = 0; i < m_VectorPath.size(); i++)
729 shortestPathImageIt.SetIndex(m_VectorPath[i]);
730 shortestPathImageIt.Set(FOREGROUND);
733 else // multiple pathes has been calculated, draw all
735 for (unsigned int i = 0; i < m_MultipleVectorPaths.size(); i++)
737 for (unsigned int j = 0; j < m_MultipleVectorPaths[i].size(); j++)
739 shortestPathImageIt.SetIndex(m_MultipleVectorPaths[i][j]);
740 shortestPathImageIt.Set(FOREGROUND);
747 template <class TInputImageType, class TOutputImageType>
748 typename ShortestPathImageFilter<TInputImageType, TOutputImageType>::OutputImagePointer
749 ShortestPathImageFilter<TInputImageType, TOutputImageType>::GetVectorOrderImage()
751 // Create Vector Order Image
754 OutputImagePointer image = OutputImageType::New();
755 image->SetRegions(this->GetInput()->GetLargestPossibleRegion());
757 OutputImageIteratorType vectorOrderImageIt(image, image->GetRequestedRegion());
759 // MITK_INFO << "GetVectorOrderImage";
760 for (vectorOrderImageIt.GoToBegin(); !vectorOrderImageIt.IsAtEnd(); ++vectorOrderImageIt)
762 // First intialize with background color
763 vectorOrderImageIt.Value() = BACKGROUND;
765 for (int i = 0; i < m_VectorOrder.size(); i++)
767 vectorOrderImageIt.SetIndex(NodeToCoord(m_VectorOrder[i]));
768 vectorOrderImageIt.Set(BACKGROUND + i);
773 template <class TInputImageType, class TOutputImageType>
774 typename ShortestPathImageFilter<TInputImageType, TOutputImageType>::OutputImagePointer
775 ShortestPathImageFilter<TInputImageType, TOutputImageType>::GetDistanceImage()
777 // Create Distance Image
780 OutputImagePointer image = OutputImageType::New();
781 image->SetRegions(this->GetInput()->GetLargestPossibleRegion());
784 OutputImageIteratorType distanceImageIt(image, image->GetRequestedRegion());
785 // Create Distance Image (Output 1)
786 NodeNumType myNodeNum;
787 for (distanceImageIt.GoToBegin(); !distanceImageIt.IsAtEnd(); ++distanceImageIt)
789 IndexType index = distanceImageIt.GetIndex();
790 myNodeNum = CoordToNode(index);
791 double newVal = m_Nodes[myNodeNum].distance;
792 distanceImageIt.Set(newVal);
796 template <class TInputImageType, class TOutputImageType>
797 std::vector<typename ShortestPathImageFilter<TInputImageType, TOutputImageType>::IndexType>
798 ShortestPathImageFilter<TInputImageType, TOutputImageType>::GetVectorPath()
803 template <class TInputImageType, class TOutputImageType>
804 std::vector<std::vector<typename ShortestPathImageFilter<TInputImageType, TOutputImageType>::IndexType>>
805 ShortestPathImageFilter<TInputImageType, TOutputImageType>::GetMultipleVectorPaths()
807 return m_MultipleVectorPaths;
810 template <class TInputImageType, class TOutputImageType>
811 void ShortestPathImageFilter<TInputImageType, TOutputImageType>::MakeShortestPathVector()
813 // MITK_INFO << "Make ShortestPath Vec";
816 if (!multipleEndPoints)
818 // fill m_VectorPath with the Shortest Path
819 m_VectorPath.clear();
821 // Go backwards from endnote to startnode
822 NodeNumType prevNode = m_Graph_EndNode;
823 while (prevNode != m_Graph_StartNode)
825 m_VectorPath.push_back(NodeToCoord(prevNode));
826 prevNode = m_Nodes[prevNode].prevNode;
828 m_VectorPath.push_back(NodeToCoord(prevNode));
830 std::reverse(m_VectorPath.begin(), m_VectorPath.end());
832 // Multiple end end points and pathes
835 for (unsigned int i = 0; i < m_endPointsClosed.size(); i++)
837 m_VectorPath.clear();
838 // Go backwards from endnote to startnode
839 NodeNumType prevNode = CoordToNode(m_endPointsClosed[i]);
840 while (prevNode != m_Graph_StartNode)
842 m_VectorPath.push_back(NodeToCoord(prevNode));
843 prevNode = m_Nodes[prevNode].prevNode;
845 m_VectorPath.push_back(NodeToCoord(prevNode));
848 std::reverse(m_VectorPath.begin(), m_VectorPath.end());
850 m_MultipleVectorPaths.push_back(m_VectorPath);
855 template <class TInputImageType, class TOutputImageType>
856 void ShortestPathImageFilter<TInputImageType, TOutputImageType>::CleanUp()
858 m_VectorOrder.clear();
859 m_VectorPath.clear();
860 // TODO: if multiple Path, clear all multiple Paths
866 template <class TInputImageType, class TOutputImageType>
867 void ShortestPathImageFilter<TInputImageType, TOutputImageType>::GenerateData()
872 // Calc Shortest Parth
873 StartShortestPathSearch();
875 // Fill Shortest Path
876 MakeShortestPathVector();
882 template <class TInputImageType, class TOutputImageType>
883 void ShortestPathImageFilter<TInputImageType, TOutputImageType>::PrintSelf(std::ostream &os, Indent indent) const
885 Superclass::PrintSelf(os, indent);
888 } /* end namespace itk */
890 #endif // __itkShortestPathImageFilter_txx