Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkConnectomicsNetworkCreator.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
18 
19 #include <sstream>
20 #include <vector>
21 
23 #include "mitkImageAccessByItk.h"
25 #include "mitkImageCast.h"
26 
27 #include "itkImageRegionIteratorWithIndex.h"
28 
29 // VTK
30 #include <vtkPolyData.h>
31 #include <vtkPolyLine.h>
32 #include <vtkCellArray.h>
33 
35 : m_FiberBundle()
36 , m_Segmentation()
37 , m_ConNetwork( mitk::ConnectomicsNetwork::New() )
38 , idCounter(0)
39 , m_LabelToVertexMap()
40 , m_LabelToNodePropertyMap()
41 , allowLoops( false )
42 , m_UseCoMCoordinates( false )
43 , m_LabelsToCoordinatesMap()
44 , m_MappingStrategy( EndElementPositionAvoidingWhiteMatter )
45 , m_EndPointSearchRadius( 10.0 )
46 , m_ZeroLabelInvalid( true )
47 , m_AbortConnection( false )
48 {
49 }
50 
52 : m_FiberBundle(fiberBundle)
53 , m_Segmentation(segmentation)
54 , m_ConNetwork( mitk::ConnectomicsNetwork::New() )
55 , idCounter(0)
56 , m_LabelToVertexMap()
57 , m_LabelToNodePropertyMap()
58 , allowLoops( false )
59 , m_LabelsToCoordinatesMap()
60 , m_MappingStrategy( EndElementPositionAvoidingWhiteMatter )
61 , m_EndPointSearchRadius( 10.0 )
62 , m_ZeroLabelInvalid( true )
63 , m_AbortConnection( false )
64 {
65  mitk::CastToItkImage( segmentation, m_SegmentationItk );
66 }
67 
69 {
70 }
71 
73 {
74  m_FiberBundle = fiberBundle;
75 }
76 
78 {
79  m_Segmentation = segmentation;
80  mitk::CastToItkImage( segmentation, m_SegmentationItk );
81 }
82 
83 itk::Point<float, 3> mitk::ConnectomicsNetworkCreator::GetItkPoint(double point[3])
84 {
85  itk::Point<float, 3> itkPoint;
86  itkPoint[0] = point[0];
87  itkPoint[1] = point[1];
88  itkPoint[2] = point[2];
89  return itkPoint;
90 }
91 
93 {
94 
95  //empty graph
96  m_ConNetwork = mitk::ConnectomicsNetwork::New();
97  m_LabelToVertexMap.clear();
98  m_LabelToNodePropertyMap.clear();
99  idCounter = 0;
100 
101  vtkSmartPointer<vtkPolyData> fiberPolyData = m_FiberBundle->GetFiberPolyData();
102  vtkSmartPointer<vtkCellArray> vLines = fiberPolyData->GetLines();
103  vLines->InitTraversal();
104 
105  int numFibers = m_FiberBundle->GetNumFibers();
106  for( int fiberID( 0 ); fiberID < numFibers; fiberID++ )
107  {
108  vtkIdType numPointsInCell(0);
109  vtkIdType* pointsInCell(nullptr);
110  vLines->GetNextCell ( numPointsInCell, pointsInCell );
111 
112  TractType::Pointer singleTract = TractType::New();
113  for( int pointInCellID( 0 ); pointInCellID < numPointsInCell ; pointInCellID++)
114  {
115  // push back point
116  PointType point = GetItkPoint( fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] ) );
117  singleTract->InsertElement( singleTract->Size(), point );
118  }
119 
120  if ( singleTract && ( singleTract->Size() > 0 ) )
121  {
122  AddConnectionToNetwork(
123  ReturnAssociatedVertexPairForLabelPair(
124  ReturnLabelForFiberTract( singleTract, m_MappingStrategy )
125  )
126  );
127  m_AbortConnection = false;
128  }
129  }
130 
131  // Prune unconnected nodes
132  //m_ConNetwork->PruneUnconnectedSingleNodes();
133 
134  // provide network with geometry
135  m_ConNetwork->SetGeometry( dynamic_cast<mitk::BaseGeometry*>(m_Segmentation->GetGeometry()->Clone().GetPointer()) );
136  m_ConNetwork->UpdateBounds();
137  m_ConNetwork->SetIsModified( true );
138 
140 }
141 
143 {
144  if( m_AbortConnection )
145  {
146  MITK_DEBUG << "Connection aborted";
147  return;
148  }
149 
150  VertexType vertexA = newConnection.first;
151  VertexType vertexB = newConnection.second;
152 
153  // check for loops (if they are not allowed)
154  if( allowLoops || !( vertexA == vertexB ) )
155  {
156  // If the connection already exists, increment weight, else create connection
157  if ( m_ConNetwork->EdgeExists( vertexA, vertexB ) )
158  {
159  m_ConNetwork->IncreaseEdgeWeight( vertexA, vertexB );
160  }
161  else
162  {
163  m_ConNetwork->AddEdge( vertexA, vertexB );
164  }
165  }
166 }
167 
168 
170 {
171  if( m_ZeroLabelInvalid && ( label == 0 ) )
172  {
173  m_AbortConnection = true;
174  return ULONG_MAX;
175  }
176 
177  // if label is not known, create entry
178  if( ! ( m_LabelToVertexMap.count( label ) > 0 ) )
179  {
180  VertexType newVertex = m_ConNetwork->AddVertex( idCounter );
181  idCounter++;
182  SupplyVertexWithInformation(label, newVertex);
183  m_LabelToVertexMap.insert( std::pair< ImageLabelType, VertexType >( label, newVertex ) );
184  }
185 
186  //return associated vertex
187  return m_LabelToVertexMap.find( label )->second;
188 }
189 
191 {
192  //hand both labels through to the single label function
193  ConnectionType connection( ReturnAssociatedVertexForLabel(labelpair.first), ReturnAssociatedVertexForLabel(labelpair.second) );
194 
195  return connection;
196 }
197 
199 {
200  switch( strategy )
201  {
202  case EndElementPosition:
203  {
204  return EndElementPositionLabel( singleTract );
205  }
206  case JustEndPointVerticesNoLabel:
207  {
208  return JustEndPointVerticesNoLabelTest( singleTract );
209  }
210  case EndElementPositionAvoidingWhiteMatter:
211  {
212  return EndElementPositionLabelAvoidingWhiteMatter( singleTract );
213  }
214  case PrecomputeAndDistance:
215  {
216  return PrecomputeVertexLocationsBySegmentation( singleTract );
217  }
218  }
219 
220  // To remove warnings, this code should never be reached
222  ImageLabelPairType nullPair( 0,0 );
223  return nullPair;
224 }
225 
227 {
228  ImageLabelPairType labelpair;
229 
230  {// Note: .fib image tracts are safed using index coordinates
231  mitk::Point3D firstElementFiberCoord, lastElementFiberCoord;
232  mitk::Point3D firstElementSegCoord, lastElementSegCoord;
233  itk::Index<3> firstElementSegIndex, lastElementSegIndex;
234 
235  if( singleTract->front().Size() != 3 )
236  {
238  }
239  for( unsigned int index = 0; index < singleTract->front().Size(); index++ )
240  {
241  firstElementFiberCoord.SetElement( index, singleTract->front().GetElement( index ) );
242  lastElementFiberCoord.SetElement( index, singleTract->back().GetElement( index ) );
243  }
244 
245  // convert from fiber index coordinates to segmentation index coordinates
246  FiberToSegmentationCoords( firstElementFiberCoord, firstElementSegCoord );
247  FiberToSegmentationCoords( lastElementFiberCoord, lastElementSegCoord );
248 
249  for( int index = 0; index < 3; index++ )
250  {
251  firstElementSegIndex.SetElement( index, firstElementSegCoord.GetElement( index ) );
252  lastElementSegIndex.SetElement( index, lastElementSegCoord.GetElement( index ) );
253  }
254 
255  int firstLabel = m_SegmentationItk->GetPixel(firstElementSegIndex);
256  int lastLabel = m_SegmentationItk->GetPixel(lastElementSegIndex );
257 
258  labelpair.first = firstLabel;
259  labelpair.second = lastLabel;
260 
261  // Add property to property map
262  CreateNewNode( firstLabel, firstElementSegIndex, m_UseCoMCoordinates );
263  CreateNewNode( lastLabel, lastElementSegIndex, m_UseCoMCoordinates );
264  }
265 
266  return labelpair;
267 }
268 
270 {
271  ImageLabelPairType labelpair;
272 
273  return labelpair;
274 }
275 
277 {
278  ImageLabelPairType labelpair;
279 
280  {// Note: .fib image tracts are safed using index coordinates
281  mitk::Point3D firstElementFiberCoord, lastElementFiberCoord;
282  mitk::Point3D firstElementSegCoord, lastElementSegCoord;
283  itk::Index<3> firstElementSegIndex, lastElementSegIndex;
284 
285  if( singleTract->front().Size() != 3 )
286  {
288  }
289  for( unsigned int index = 0; index < singleTract->front().Size(); index++ )
290  {
291  firstElementFiberCoord.SetElement( index, singleTract->front().GetElement( index ) );
292  lastElementFiberCoord.SetElement( index, singleTract->back().GetElement( index ) );
293  }
294 
295  // convert from fiber index coordinates to segmentation index coordinates
296  FiberToSegmentationCoords( firstElementFiberCoord, firstElementSegCoord );
297  FiberToSegmentationCoords( lastElementFiberCoord, lastElementSegCoord );
298 
299  for( int index = 0; index < 3; index++ )
300  {
301  firstElementSegIndex.SetElement( index, firstElementSegCoord.GetElement( index ) );
302  lastElementSegIndex.SetElement( index, lastElementSegCoord.GetElement( index ) );
303  }
304 
305  int firstLabel = m_SegmentationItk->GetPixel(firstElementSegIndex);
306  int lastLabel = m_SegmentationItk->GetPixel(lastElementSegIndex );
307 
308  // Check whether the labels belong to the white matter (which means, that the fibers ended early)
309  bool extendFront(false), extendEnd(false), retractFront(false), retractEnd(false);
310  extendFront = !IsNonWhiteMatterLabel( firstLabel );
311  extendEnd = !IsNonWhiteMatterLabel( lastLabel );
312  retractFront = IsBackgroundLabel( firstLabel );
313  retractEnd = IsBackgroundLabel( lastLabel );
314 
315  //if( extendFront || extendEnd )
316  //{
317  //MBI_INFO << "Before Start: " << firstLabel << " at " << firstElementSegIndex[ 0 ] << " " << firstElementSegIndex[ 1 ] << " " << firstElementSegIndex[ 2 ] << " End: " << lastLabel << " at " << lastElementSegIndex[ 0 ] << " " << lastElementSegIndex[ 1 ] << " " << lastElementSegIndex[ 2 ];
318  //}
319  if ( extendFront )
320  {
321  std::vector< int > indexVectorOfPointsToUse;
322 
323  //Use first two points for direction
324  indexVectorOfPointsToUse.push_back( 1 );
325  indexVectorOfPointsToUse.push_back( 0 );
326 
327  // label and coordinate temp storage
328  int tempLabel( firstLabel );
329  itk::Index<3> tempIndex = firstElementSegIndex;
330 
331  LinearExtensionUntilGreyMatter( indexVectorOfPointsToUse, singleTract, tempLabel, tempIndex );
332 
333  firstLabel = tempLabel;
334  firstElementSegIndex = tempIndex;
335 
336  }
337 
338  if ( extendEnd )
339  {
340  std::vector< int > indexVectorOfPointsToUse;
341 
342  //Use last two points for direction
343  indexVectorOfPointsToUse.push_back( singleTract->Size() - 2 );
344  indexVectorOfPointsToUse.push_back( singleTract->Size() - 1 );
345 
346  // label and coordinate temp storage
347  int tempLabel( lastLabel );
348  itk::Index<3> tempIndex = lastElementSegIndex;
349 
350  LinearExtensionUntilGreyMatter( indexVectorOfPointsToUse, singleTract, tempLabel, tempIndex );
351 
352  lastLabel = tempLabel;
353  lastElementSegIndex = tempIndex;
354  }
355  if ( retractFront )
356  {
357  // label and coordinate temp storage
358  int tempLabel( firstLabel );
359  itk::Index<3> tempIndex = firstElementSegIndex;
360 
361  RetractionUntilBrainMatter( true, singleTract, tempLabel, tempIndex );
362 
363  firstLabel = tempLabel;
364  firstElementSegIndex = tempIndex;
365 
366  }
367 
368  if ( retractEnd )
369  {
370  // label and coordinate temp storage
371  int tempLabel( lastLabel );
372  itk::Index<3> tempIndex = lastElementSegIndex;
373 
374  RetractionUntilBrainMatter( false, singleTract, tempLabel, tempIndex );
375 
376  lastLabel = tempLabel;
377  lastElementSegIndex = tempIndex;
378  }
379  //if( extendFront || extendEnd )
380  //{
381  // MBI_INFO << "After Start: " << firstLabel << " at " << firstElementSegIndex[ 0 ] << " " << firstElementSegIndex[ 1 ] << " " << firstElementSegIndex[ 2 ] << " End: " << lastLabel << " at " << lastElementSegIndex[ 0 ] << " " << lastElementSegIndex[ 1 ] << " " << lastElementSegIndex[ 2 ];
382  //}
383 
384  labelpair.first = firstLabel;
385  labelpair.second = lastLabel;
386 
387  // Add property to property map
388  CreateNewNode( firstLabel, firstElementSegIndex, m_UseCoMCoordinates );
389  CreateNewNode( lastLabel, lastElementSegIndex, m_UseCoMCoordinates );
390  }
391 
392  return labelpair;
393 }
394 
396 {
397  ImageLabelPairType labelpair;
398 
399  {// Note: .fib image tracts are safed using index coordinates
400  mitk::Point3D firstElementFiberCoord, lastElementFiberCoord;
401  mitk::Point3D firstElementSegCoord, lastElementSegCoord;
402  itk::Index<3> firstElementSegIndex, lastElementSegIndex;
403 
404  if( singleTract->front().Size() != 3 )
405  {
407  }
408  for( unsigned int index = 0; index < singleTract->front().Size(); index++ )
409  {
410  firstElementFiberCoord.SetElement( index, singleTract->front().GetElement( index ) );
411  lastElementFiberCoord.SetElement( index, singleTract->back().GetElement( index ) );
412  }
413 
414  // convert from fiber index coordinates to segmentation index coordinates
415  FiberToSegmentationCoords( firstElementFiberCoord, firstElementSegCoord );
416  FiberToSegmentationCoords( lastElementFiberCoord, lastElementSegCoord );
417 
418  for( int index = 0; index < 3; index++ )
419  {
420  firstElementSegIndex.SetElement( index, firstElementSegCoord.GetElement( index ) );
421  lastElementSegIndex.SetElement( index, lastElementSegCoord.GetElement( index ) );
422  }
423 
424  int firstLabel = 1 * firstElementSegIndex[ 0 ] + 1000 * firstElementSegIndex[ 1 ] + 1000000 * firstElementSegIndex[ 2 ];
425  int lastLabel = 1 * firstElementSegIndex[ 0 ] + 1000 * firstElementSegIndex[ 1 ] + 1000000 * firstElementSegIndex[ 2 ];
426 
427  labelpair.first = firstLabel;
428  labelpair.second = lastLabel;
429 
430  // Add property to property map
431  CreateNewNode( firstLabel, firstElementSegIndex, m_UseCoMCoordinates );
432  CreateNewNode( lastLabel, lastElementSegIndex, m_UseCoMCoordinates );
433  }
434 
435  return labelpair;
436 }
437 
439 { // supply a vertex with the additional information belonging to the label
440 
441  // TODO: Implement additional information acquisition
442 
443  m_ConNetwork->SetLabel( vertex, m_LabelToNodePropertyMap.find( label )->second.label );
444  m_ConNetwork->SetCoordinates( vertex, m_LabelToNodePropertyMap.find( label )->second.coordinates );
445 
446 }
447 
449 {
450  int tempInt = (int) label;
451  std::stringstream ss;//create a stringstream
452  std::string tempString;
453  ss << tempInt;//add number to the stream
454  tempString = ss.str();
455  return tempString;//return a string with the contents of the stream
456 }
457 
459 {
460  return m_ConNetwork;
461 }
462 
464 {
465  mitk::Point3D tempPoint;
466 
467  // convert from fiber index coordinates to segmentation index coordinates
468  m_FiberBundle->GetGeometry()->IndexToWorld( fiberCoord, tempPoint );
469  m_Segmentation->GetGeometry()->WorldToIndex( tempPoint, segCoord );
470 }
471 
473 {
474  mitk::Point3D tempPoint;
475 
476  // convert from fiber index coordinates to segmentation index coordinates
477  m_Segmentation->GetGeometry()->IndexToWorld( segCoord, tempPoint );
478  m_FiberBundle->GetGeometry()->WorldToIndex( tempPoint, fiberCoord );
479 }
480 
482 {
483  bool isWhite( false );
484 
485  isWhite = (
486  ( labelInQuestion == freesurfer_Left_Cerebral_White_Matter ) ||
487  ( labelInQuestion == freesurfer_Left_Cerebellum_White_Matter ) ||
488  ( labelInQuestion == freesurfer_Right_Cerebral_White_Matter ) ||
489  ( labelInQuestion == freesurfer_Right_Cerebellum_White_Matter )||
490  ( labelInQuestion == freesurfer_Left_Cerebellum_Cortex ) ||
491  ( labelInQuestion == freesurfer_Right_Cerebellum_Cortex ) ||
492  ( labelInQuestion == freesurfer_Brain_Stem )
493  );
494 
495  return !isWhite;
496 }
497 
499 {
500  bool isBackground( false );
501 
502  isBackground = ( labelInQuestion == 0 );
503 
504  return isBackground;
505 }
506 
508  std::vector<int> & indexVectorOfPointsToUse,
509  TractType::Pointer singleTract,
510  int & label,
511  itk::Index<3> & mitkIndex )
512 {
513  if( indexVectorOfPointsToUse.size() > singleTract->Size() )
514  {
516  return;
517  }
518 
519  if( indexVectorOfPointsToUse.size() < 2 )
520  {
522  return;
523  }
524 
525  for( unsigned int index( 0 ); index < indexVectorOfPointsToUse.size(); index++ )
526  {
527  if( indexVectorOfPointsToUse[ index ] < 0 )
528  {
530  return;
531  }
532  if( (unsigned int)indexVectorOfPointsToUse[ index ] > singleTract->Size() )
533  {
535  return;
536  }
537  }
538 
539  mitk::Point3D startPoint, endPoint;
540  std::vector< double > differenceVector;
541  differenceVector.resize( singleTract->front().Size() );
542 
543  {
544  // which points to use, currently only last two //TODO correct using all points
545  int endPointIndex = indexVectorOfPointsToUse.size() - 1;
546  int startPointIndex = indexVectorOfPointsToUse.size() - 2;
547 
548  // convert to segmentation coords
549  mitk::Point3D startFiber, endFiber;
550  for( unsigned int index = 0; index < singleTract->front().Size(); index++ )
551  {
552  endFiber.SetElement( index, singleTract->GetElement( indexVectorOfPointsToUse[ endPointIndex ] ).GetElement( index ) );
553  startFiber.SetElement( index, singleTract->GetElement( indexVectorOfPointsToUse[ startPointIndex ] ).GetElement( index ) );
554  }
555 
556  FiberToSegmentationCoords( endFiber, endPoint );
557  FiberToSegmentationCoords( startFiber, startPoint );
558 
559  // calculate straight line
560 
561  for( unsigned int index = 0; index < singleTract->front().Size(); index++ )
562  {
563  differenceVector[ index ] = endPoint.GetElement( index ) - startPoint.GetElement( index );
564  }
565 
566  // normalizing direction vector
567 
568  double length( 0.0 );
569  double sum( 0.0 );
570 
571  for( unsigned int index = 0; index < differenceVector.size() ; index++ )
572  {
573  sum = sum + differenceVector[ index ] * differenceVector[ index ];
574  }
575 
576  length = std::sqrt( sum );
577 
578  for( unsigned int index = 0; index < differenceVector.size() ; index++ )
579  {
580  differenceVector[ index ] = differenceVector[ index ] / length;
581  }
582 
583  // follow line until first non white matter label
584  itk::Index<3> tempIndex;
585  int tempLabel( label );
586 
587  bool keepOn( true );
588 
589  itk::ImageRegion<3> itkRegion = m_SegmentationItk->GetLargestPossibleRegion();
590 
591  for( int parameter( 0 ) ; keepOn ; parameter++ )
592  {
593  if( parameter > 1000 )
594  {
596  break;
597  }
598 
599  for( int index( 0 ); index < 3; index++ )
600  {
601  tempIndex.SetElement( index, endPoint.GetElement( index ) + parameter * differenceVector[ index ] );
602  }
603 
604  if( itkRegion.IsInside( tempIndex ) )
605  {
606  tempLabel = m_SegmentationItk->GetPixel( tempIndex );
607  }
608  else
609  {
610  tempLabel = -1;
611  }
612 
613  if( IsNonWhiteMatterLabel( tempLabel ) )
614  {
615  if( tempLabel < 1 )
616  {
617  keepOn = false;
618  //MBI_WARN << mitk::ConnectomicsConstantsManager::CONNECTOMICS_WARNING_NOT_EXTEND_TO_WHITE;
619  }
620  else
621  {
622  label = tempLabel;
623  mitkIndex = tempIndex;
624  keepOn = false;
625  }
626  }
627  }
628 
629  }
630 }
631 
633  int & label, itk::Index<3> & mitkIndex )
634 {
635  int retractionStartIndex( singleTract->Size() - 1 );
636  int retractionStepIndexSize( -1 );
637  int retractionTerminationIndex( 0 );
638 
639  if( retractFront )
640  {
641  retractionStartIndex = 0;
642  retractionStepIndexSize = 1;
643  retractionTerminationIndex = singleTract->Size() - 1;
644  }
645 
646  int currentRetractionIndex = retractionStartIndex;
647 
648  bool keepRetracting( true );
649 
650  mitk::Point3D currentPoint, nextPoint;
651  std::vector< double > differenceVector;
652  differenceVector.resize( singleTract->front().Size() );
653 
654  while( keepRetracting && ( currentRetractionIndex != retractionTerminationIndex ) )
655  {
656  // convert to segmentation coords
657  mitk::Point3D currentPointFiberCoord, nextPointFiberCoord;
658  for( unsigned int index = 0; index < singleTract->front().Size(); index++ )
659  {
660  currentPointFiberCoord.SetElement( index, singleTract->GetElement( currentRetractionIndex ).GetElement( index ) );
661  nextPointFiberCoord.SetElement( index, singleTract->GetElement( currentRetractionIndex + retractionStepIndexSize ).GetElement( index ) );
662  }
663 
664  FiberToSegmentationCoords( currentPointFiberCoord, currentPoint );
665  FiberToSegmentationCoords( nextPointFiberCoord, nextPoint );
666 
667  // calculate straight line
668 
669  for( unsigned int index = 0; index < singleTract->front().Size(); index++ )
670  {
671  differenceVector[ index ] = nextPoint.GetElement( index ) - currentPoint.GetElement( index );
672  }
673 
674  // calculate length of direction vector
675 
676  double length( 0.0 );
677  double sum( 0.0 );
678 
679  for( unsigned int index = 0; index < differenceVector.size() ; index++ )
680  {
681  sum = sum + differenceVector[ index ] * differenceVector[ index ];
682  }
683 
684  length = std::sqrt( sum );
685 
686  // retract
687  itk::Index<3> tempIndex;
688  int tempLabel( label );
689 
690  for( int parameter( 0 ) ; parameter < length ; parameter++ )
691  {
692 
693  for( int index( 0 ); index < 3; index++ )
694  {
695  tempIndex.SetElement( index,
696  currentPoint.GetElement( index ) + ( 1.0 + parameter ) / ( 1.0 + length ) * differenceVector[ index ] );
697  }
698 
699  tempLabel = m_SegmentationItk->GetPixel( tempIndex );
700 
701  if( !IsBackgroundLabel( tempLabel ) )
702  {
703  // check whether result is within the search space
704  {
705  mitk::Point3D endPoint, foundPointSegmentation, foundPointFiber;
706  for( unsigned int index = 0; index < singleTract->front().Size(); index++ )
707  {
708  // this is in fiber (world) coordinates
709  endPoint.SetElement( index, singleTract->GetElement( retractionStartIndex ).GetElement( index ) );
710  }
711 
712  for( int index( 0 ); index < 3; index++ )
713  {
714  foundPointSegmentation.SetElement( index,
715  currentPoint.GetElement( index ) + ( 1.0 + parameter ) / ( 1.0 + length ) * differenceVector[ index ] );
716  }
717 
718  SegmentationToFiberCoords( foundPointSegmentation, foundPointFiber );
719 
720  std::vector< double > finalDistance;
721  finalDistance.resize( singleTract->front().Size() );
722  for( unsigned int index = 0; index < singleTract->front().Size(); index++ )
723  {
724  finalDistance[ index ] = foundPointFiber.GetElement( index ) - endPoint.GetElement( index );
725  }
726 
727  // calculate length of direction vector
728 
729  double finalLength( 0.0 );
730  double finalSum( 0.0 );
731 
732  for( unsigned int index = 0; index < finalDistance.size() ; index++ )
733  {
734  finalSum = finalSum + finalDistance[ index ] * finalDistance[ index ];
735  }
736  finalLength = std::sqrt( finalSum );
737 
738  if( finalLength > m_EndPointSearchRadius )
739  {
740  // the found point was not within the search space
741  return;
742  }
743  }
744 
745  label = tempLabel;
746  mitkIndex = tempIndex;
747  return;
748  }
749  // hit next point without finding brain matter
750  currentRetractionIndex = currentRetractionIndex + retractionStepIndexSize;
751  if( ( currentRetractionIndex < 1 ) || ( (unsigned int)currentRetractionIndex > ( singleTract->Size() - 2 ) ) )
752  {
753  keepRetracting = false;
754  }
755  }
756  }
757 }
758 
760 {
761 
762  const int dimensions = 3;
763  int max = m_Segmentation->GetStatistics()->GetScalarValueMax();
764  int min = m_Segmentation->GetStatistics()->GetScalarValueMin();
765 
766  int range = max - min +1;
767 
768  // each label owns a vector of coordinates
769  std::vector< std::vector< std::vector< double> > > coordinatesPerLabelVector;
770  coordinatesPerLabelVector.resize( range );
771 
772  itk::ImageRegionIteratorWithIndex<ITKImageType> it_itkImage( m_SegmentationItk, m_SegmentationItk->GetLargestPossibleRegion() );
773 
774  for( it_itkImage.GoToBegin(); !it_itkImage.IsAtEnd(); ++it_itkImage )
775  {
776  std::vector< double > coordinates;
777  coordinates.resize(dimensions);
778 
779  itk::Index< dimensions > index = it_itkImage.GetIndex();
780 
781  for( int loop(0); loop < dimensions; loop++)
782  {
783  coordinates.at( loop ) = index.GetElement( loop );
784  }
785 
786  // add the coordinates to the corresponding label vector
787  coordinatesPerLabelVector.at( it_itkImage.Value() - min ).push_back( coordinates );
788  }
789 
790  for(int currentIndex(0), currentLabel( min ); currentIndex < range; currentIndex++, currentLabel++ )
791  {
792  std::vector< double > currentCoordinates;
793  currentCoordinates.resize(dimensions);
794 
795  int numberOfPoints = coordinatesPerLabelVector.at( currentIndex ).size();
796 
797  std::vector< double > sumCoords;
798  sumCoords.resize( dimensions );
799 
800  for( int loop(0); loop < numberOfPoints; loop++ )
801  {
802  for( int loopDimension( 0 ); loopDimension < dimensions; loopDimension++ )
803  {
804  sumCoords.at( loopDimension ) += coordinatesPerLabelVector.at( currentIndex ).at( loop ).at( loopDimension );
805  }
806  }
807 
808  for( int loopDimension( 0 ); loopDimension < dimensions; loopDimension++ )
809  {
810  currentCoordinates.at( loopDimension ) = sumCoords.at( loopDimension ) / numberOfPoints;
811  }
812 
813  m_LabelsToCoordinatesMap.insert( std::pair< int, std::vector<double> >( currentLabel, currentCoordinates ) );
814  }
815 
816  //can now use center of mass coordinates
817  m_UseCoMCoordinates = true;
818 }
819 
820 std::vector< double > mitk::ConnectomicsNetworkCreator::GetCenterOfMass( int label )
821 {
822  // if label is not known, warn
823  if( ! ( m_LabelsToCoordinatesMap.count( label ) > 0 ) )
824  {
825  MITK_ERROR << "Label " << label << " not found. Could not return coordinates.";
826  std::vector< double > nullVector;
827  nullVector.resize(3);
828  return nullVector;
829  }
830 
831  //return associated coordinates
832  return m_LabelsToCoordinatesMap.find( label )->second;
833 }
834 
836 {
837  // Only create node if it does not exist yet
838 
839  if( ! ( m_LabelToNodePropertyMap.count( label ) > 0 ) )
840  {
841  NetworkNode newNode;
842 
843  newNode.coordinates.resize( 3 );
844  if( !useCoM )
845  {
846  for( unsigned int loop = 0; loop < newNode.coordinates.size() ; loop++ )
847  {
848  newNode.coordinates[ loop ] = index[ loop ] ;
849  }
850  }
851  else
852  {
853  std::vector<double> labelCoords = GetCenterOfMass( label );
854  for( unsigned int loop = 0; loop < newNode.coordinates.size() ; loop++ )
855  {
856  newNode.coordinates[ loop ] = labelCoords.at( loop ) ;
857  }
858  }
859 
860  newNode.label = LabelToString( label );
861 
862  m_LabelToNodePropertyMap.insert( std::pair< ImageLabelType, NetworkNode >( label, newNode ) );
863  }
864 }
itk::SmartPointer< Self > Pointer
ImageLabelPairType EndElementPositionLabel(TractType::Pointer singleTract)
ImageLabelPairType PrecomputeVertexLocationsBySegmentation(TractType::Pointer singleTract)
void SetFiberBundle(mitk::FiberBundle::Pointer fiberBundle)
#define MITK_ERROR
Definition: mitkLogMacros.h:24
std::pair< ImageLabelType, ImageLabelType > ImageLabelPairType
std::vector< double > GetCenterOfMass(int label)
Get the location of the center of mass for a specific label This can throw an exception if the label ...
std::string LabelToString(ImageLabelType &label)
void SetSegmentation(mitk::Image::Pointer segmentation)
#define MITK_DEBUG
Definition: mitkLogMacros.h:26
mitk::ConnectomicsNetwork::Pointer GetNetwork()
DataCollection - Class to facilitate loading/accessing structured data.
void SupplyVertexWithInformation(ImageLabelType &label, VertexType &vertex)
VertexType ReturnAssociatedVertexForLabel(ImageLabelType label)
static Pointer New()
ImageLabelPairType JustEndPointVerticesNoLabelTest(TractType::Pointer singleTract)
void CalculateCenterOfMass()
Calculate the locations of vertices.
#define MBI_INFO
Macros for different message levels. Creates an instance of class PseudoStream with the corresponding...
Definition: mbilog.h:221
std::pair< VertexType, VertexType > ConnectionType
void CreateNewNode(int label, itk::Index< 3 >, bool useIndex)
Creates a new node.
mitk::ConnectomicsNetwork::VertexDescriptorType VertexType
void FiberToSegmentationCoords(mitk::Point3D &fiberCoord, mitk::Point3D &segCoord)
static T max(T x, T y)
Definition: svm.cpp:70
ImageLabelPairType ReturnLabelForFiberTract(TractType::Pointer singleTract, MappingStrategy strategy)
void AddConnectionToNetwork(ConnectionType newConnection)
ImageLabelPairType EndElementPositionLabelAvoidingWhiteMatter(TractType::Pointer singleTract)
static T min(T x, T y)
Definition: svm.cpp:67
void SegmentationToFiberCoords(mitk::Point3D &segCoord, mitk::Point3D &fiberCoord)
itk::Point< float, 3 > GetItkPoint(double point[3])
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
ConnectionType ReturnAssociatedVertexPairForLabelPair(ImageLabelPairType labelpair)
void LinearExtensionUntilGreyMatter(std::vector< int > &indexVectorOfPointsToUse, TractType::Pointer singleTract, int &label, itk::Index< 3 > &mitkIndex)
Connectomics Network Class.
void RetractionUntilBrainMatter(bool retractFront, TractType::Pointer singleTract, int &label, itk::Index< 3 > &mitkIndex)
itk::SmartPointer< Self > Pointer
Definition: mitkBaseData.h:42
#define MBI_ERROR
Definition: mbilog.h:223
#define MBI_WARN
Definition: mbilog.h:222
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.