27 #include "itkImageRegionIteratorWithIndex.h"
30 #include <vtkPolyData.h>
31 #include <vtkPolyLine.h>
32 #include <vtkCellArray.h>
39 , m_LabelToVertexMap()
40 , m_LabelToNodePropertyMap()
42 , m_UseCoMCoordinates( false )
43 , m_LabelsToCoordinatesMap()
44 , m_MappingStrategy( EndElementPositionAvoidingWhiteMatter )
45 , m_EndPointSearchRadius( 10.0 )
46 , m_ZeroLabelInvalid( true )
47 , m_AbortConnection( false )
52 : m_FiberBundle(fiberBundle)
53 , m_Segmentation(segmentation)
56 , m_LabelToVertexMap()
57 , m_LabelToNodePropertyMap()
59 , m_LabelsToCoordinatesMap()
60 , m_MappingStrategy( EndElementPositionAvoidingWhiteMatter )
61 , m_EndPointSearchRadius( 10.0 )
62 , m_ZeroLabelInvalid( true )
63 , m_AbortConnection( false )
74 m_FiberBundle = fiberBundle;
79 m_Segmentation = segmentation;
85 itk::Point<float, 3> itkPoint;
86 itkPoint[0] = point[0];
87 itkPoint[1] = point[1];
88 itkPoint[2] = point[2];
97 m_LabelToVertexMap.clear();
98 m_LabelToNodePropertyMap.clear();
101 vtkSmartPointer<vtkPolyData> fiberPolyData = m_FiberBundle->GetFiberPolyData();
102 vtkSmartPointer<vtkCellArray> vLines = fiberPolyData->GetLines();
103 vLines->InitTraversal();
105 int numFibers = m_FiberBundle->GetNumFibers();
106 for(
int fiberID( 0 ); fiberID < numFibers; fiberID++ )
108 vtkIdType numPointsInCell(0);
109 vtkIdType* pointsInCell(
nullptr);
110 vLines->GetNextCell ( numPointsInCell, pointsInCell );
113 for(
int pointInCellID( 0 ); pointInCellID < numPointsInCell ; pointInCellID++)
116 PointType point = GetItkPoint( fiberPolyData->GetPoint( pointsInCell[ pointInCellID ] ) );
117 singleTract->InsertElement( singleTract->Size(), point );
120 if ( singleTract && ( singleTract->Size() > 0 ) )
122 AddConnectionToNetwork(
123 ReturnAssociatedVertexPairForLabelPair(
124 ReturnLabelForFiberTract( singleTract, m_MappingStrategy )
127 m_AbortConnection =
false;
135 m_ConNetwork->SetGeometry( dynamic_cast<mitk::BaseGeometry*>(m_Segmentation->GetGeometry()->Clone().GetPointer()) );
136 m_ConNetwork->UpdateBounds();
137 m_ConNetwork->SetIsModified(
true );
144 if( m_AbortConnection )
154 if( allowLoops || !( vertexA == vertexB ) )
157 if ( m_ConNetwork->EdgeExists( vertexA, vertexB ) )
159 m_ConNetwork->IncreaseEdgeWeight( vertexA, vertexB );
163 m_ConNetwork->AddEdge( vertexA, vertexB );
171 if( m_ZeroLabelInvalid && ( label == 0 ) )
173 m_AbortConnection =
true;
178 if( ! ( m_LabelToVertexMap.count( label ) > 0 ) )
180 VertexType newVertex = m_ConNetwork->AddVertex( idCounter );
182 SupplyVertexWithInformation(label, newVertex);
183 m_LabelToVertexMap.insert( std::pair< ImageLabelType, VertexType >( label, newVertex ) );
187 return m_LabelToVertexMap.find( label )->second;
193 ConnectionType connection( ReturnAssociatedVertexForLabel(labelpair.first), ReturnAssociatedVertexForLabel(labelpair.second) );
202 case EndElementPosition:
204 return EndElementPositionLabel( singleTract );
206 case JustEndPointVerticesNoLabel:
208 return JustEndPointVerticesNoLabelTest( singleTract );
210 case EndElementPositionAvoidingWhiteMatter:
212 return EndElementPositionLabelAvoidingWhiteMatter( singleTract );
214 case PrecomputeAndDistance:
216 return PrecomputeVertexLocationsBySegmentation( singleTract );
235 if( singleTract->front().Size() != 3 )
239 for(
unsigned int index = 0; index < singleTract->front().Size(); index++ )
241 firstElementFiberCoord.SetElement( index, singleTract->front().GetElement( index ) );
242 lastElementFiberCoord.SetElement( index, singleTract->back().GetElement( index ) );
246 FiberToSegmentationCoords( firstElementFiberCoord, firstElementSegCoord );
247 FiberToSegmentationCoords( lastElementFiberCoord, lastElementSegCoord );
249 for(
int index = 0; index < 3; index++ )
251 firstElementSegIndex.SetElement( index, firstElementSegCoord.GetElement( index ) );
252 lastElementSegIndex.SetElement( index, lastElementSegCoord.GetElement( index ) );
255 int firstLabel = m_SegmentationItk->GetPixel(firstElementSegIndex);
256 int lastLabel = m_SegmentationItk->GetPixel(lastElementSegIndex );
258 labelpair.first = firstLabel;
259 labelpair.second = lastLabel;
262 CreateNewNode( firstLabel, firstElementSegIndex, m_UseCoMCoordinates );
263 CreateNewNode( lastLabel, lastElementSegIndex, m_UseCoMCoordinates );
285 if( singleTract->front().Size() != 3 )
289 for(
unsigned int index = 0; index < singleTract->front().Size(); index++ )
291 firstElementFiberCoord.SetElement( index, singleTract->front().GetElement( index ) );
292 lastElementFiberCoord.SetElement( index, singleTract->back().GetElement( index ) );
296 FiberToSegmentationCoords( firstElementFiberCoord, firstElementSegCoord );
297 FiberToSegmentationCoords( lastElementFiberCoord, lastElementSegCoord );
299 for(
int index = 0; index < 3; index++ )
301 firstElementSegIndex.SetElement( index, firstElementSegCoord.GetElement( index ) );
302 lastElementSegIndex.SetElement( index, lastElementSegCoord.GetElement( index ) );
305 int firstLabel = m_SegmentationItk->GetPixel(firstElementSegIndex);
306 int lastLabel = m_SegmentationItk->GetPixel(lastElementSegIndex );
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 );
321 std::vector< int > indexVectorOfPointsToUse;
324 indexVectorOfPointsToUse.push_back( 1 );
325 indexVectorOfPointsToUse.push_back( 0 );
328 int tempLabel( firstLabel );
331 LinearExtensionUntilGreyMatter( indexVectorOfPointsToUse, singleTract, tempLabel, tempIndex );
333 firstLabel = tempLabel;
334 firstElementSegIndex = tempIndex;
340 std::vector< int > indexVectorOfPointsToUse;
343 indexVectorOfPointsToUse.push_back( singleTract->Size() - 2 );
344 indexVectorOfPointsToUse.push_back( singleTract->Size() - 1 );
347 int tempLabel( lastLabel );
350 LinearExtensionUntilGreyMatter( indexVectorOfPointsToUse, singleTract, tempLabel, tempIndex );
352 lastLabel = tempLabel;
353 lastElementSegIndex = tempIndex;
358 int tempLabel( firstLabel );
361 RetractionUntilBrainMatter(
true, singleTract, tempLabel, tempIndex );
363 firstLabel = tempLabel;
364 firstElementSegIndex = tempIndex;
371 int tempLabel( lastLabel );
374 RetractionUntilBrainMatter(
false, singleTract, tempLabel, tempIndex );
376 lastLabel = tempLabel;
377 lastElementSegIndex = tempIndex;
384 labelpair.first = firstLabel;
385 labelpair.second = lastLabel;
388 CreateNewNode( firstLabel, firstElementSegIndex, m_UseCoMCoordinates );
389 CreateNewNode( lastLabel, lastElementSegIndex, m_UseCoMCoordinates );
404 if( singleTract->front().Size() != 3 )
408 for(
unsigned int index = 0; index < singleTract->front().Size(); index++ )
410 firstElementFiberCoord.SetElement( index, singleTract->front().GetElement( index ) );
411 lastElementFiberCoord.SetElement( index, singleTract->back().GetElement( index ) );
415 FiberToSegmentationCoords( firstElementFiberCoord, firstElementSegCoord );
416 FiberToSegmentationCoords( lastElementFiberCoord, lastElementSegCoord );
418 for(
int index = 0; index < 3; index++ )
420 firstElementSegIndex.SetElement( index, firstElementSegCoord.GetElement( index ) );
421 lastElementSegIndex.SetElement( index, lastElementSegCoord.GetElement( index ) );
424 int firstLabel = 1 * firstElementSegIndex[ 0 ] + 1000 * firstElementSegIndex[ 1 ] + 1000000 * firstElementSegIndex[ 2 ];
425 int lastLabel = 1 * firstElementSegIndex[ 0 ] + 1000 * firstElementSegIndex[ 1 ] + 1000000 * firstElementSegIndex[ 2 ];
427 labelpair.first = firstLabel;
428 labelpair.second = lastLabel;
431 CreateNewNode( firstLabel, firstElementSegIndex, m_UseCoMCoordinates );
432 CreateNewNode( lastLabel, lastElementSegIndex, m_UseCoMCoordinates );
443 m_ConNetwork->SetLabel( vertex, m_LabelToNodePropertyMap.find( label )->second.label );
444 m_ConNetwork->SetCoordinates( vertex, m_LabelToNodePropertyMap.find( label )->second.coordinates );
450 int tempInt = (int) label;
451 std::stringstream ss;
452 std::string tempString;
454 tempString = ss.str();
468 m_FiberBundle->GetGeometry()->IndexToWorld( fiberCoord, tempPoint );
469 m_Segmentation->GetGeometry()->WorldToIndex( tempPoint, segCoord );
477 m_Segmentation->GetGeometry()->IndexToWorld( segCoord, tempPoint );
478 m_FiberBundle->GetGeometry()->WorldToIndex( tempPoint, fiberCoord );
483 bool isWhite(
false );
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 )
500 bool isBackground(
false );
502 isBackground = ( labelInQuestion == 0 );
508 std::vector<int> & indexVectorOfPointsToUse,
513 if( indexVectorOfPointsToUse.size() > singleTract->Size() )
519 if( indexVectorOfPointsToUse.size() < 2 )
525 for(
unsigned int index( 0 ); index < indexVectorOfPointsToUse.size(); index++ )
527 if( indexVectorOfPointsToUse[ index ] < 0 )
532 if( (
unsigned int)indexVectorOfPointsToUse[ index ] > singleTract->Size() )
540 std::vector< double > differenceVector;
541 differenceVector.resize( singleTract->front().Size() );
545 int endPointIndex = indexVectorOfPointsToUse.size() - 1;
546 int startPointIndex = indexVectorOfPointsToUse.size() - 2;
550 for(
unsigned int index = 0; index < singleTract->front().Size(); index++ )
552 endFiber.SetElement( index, singleTract->GetElement( indexVectorOfPointsToUse[ endPointIndex ] ).GetElement( index ) );
553 startFiber.SetElement( index, singleTract->GetElement( indexVectorOfPointsToUse[ startPointIndex ] ).GetElement( index ) );
556 FiberToSegmentationCoords( endFiber, endPoint );
557 FiberToSegmentationCoords( startFiber, startPoint );
561 for(
unsigned int index = 0; index < singleTract->front().Size(); index++ )
563 differenceVector[ index ] = endPoint.GetElement( index ) - startPoint.GetElement( index );
568 double length( 0.0 );
571 for(
unsigned int index = 0; index < differenceVector.size() ; index++ )
573 sum = sum + differenceVector[ index ] * differenceVector[ index ];
576 length = std::sqrt( sum );
578 for(
unsigned int index = 0; index < differenceVector.size() ; index++ )
580 differenceVector[ index ] = differenceVector[ index ] / length;
585 int tempLabel( label );
589 itk::ImageRegion<3> itkRegion = m_SegmentationItk->GetLargestPossibleRegion();
591 for(
int parameter( 0 ) ; keepOn ; parameter++ )
593 if( parameter > 1000 )
599 for(
int index( 0 ); index < 3; index++ )
601 tempIndex.SetElement( index, endPoint.GetElement( index ) + parameter * differenceVector[ index ] );
604 if( itkRegion.IsInside( tempIndex ) )
606 tempLabel = m_SegmentationItk->GetPixel( tempIndex );
613 if( IsNonWhiteMatterLabel( tempLabel ) )
623 mitkIndex = tempIndex;
635 int retractionStartIndex( singleTract->Size() - 1 );
636 int retractionStepIndexSize( -1 );
637 int retractionTerminationIndex( 0 );
641 retractionStartIndex = 0;
642 retractionStepIndexSize = 1;
643 retractionTerminationIndex = singleTract->Size() - 1;
646 int currentRetractionIndex = retractionStartIndex;
648 bool keepRetracting(
true );
651 std::vector< double > differenceVector;
652 differenceVector.resize( singleTract->front().Size() );
654 while( keepRetracting && ( currentRetractionIndex != retractionTerminationIndex ) )
658 for(
unsigned int index = 0; index < singleTract->front().Size(); index++ )
660 currentPointFiberCoord.SetElement( index, singleTract->GetElement( currentRetractionIndex ).GetElement( index ) );
661 nextPointFiberCoord.SetElement( index, singleTract->GetElement( currentRetractionIndex + retractionStepIndexSize ).GetElement( index ) );
664 FiberToSegmentationCoords( currentPointFiberCoord, currentPoint );
665 FiberToSegmentationCoords( nextPointFiberCoord, nextPoint );
669 for(
unsigned int index = 0; index < singleTract->front().Size(); index++ )
671 differenceVector[ index ] = nextPoint.GetElement( index ) - currentPoint.GetElement( index );
676 double length( 0.0 );
679 for(
unsigned int index = 0; index < differenceVector.size() ; index++ )
681 sum = sum + differenceVector[ index ] * differenceVector[ index ];
684 length = std::sqrt( sum );
688 int tempLabel( label );
690 for(
int parameter( 0 ) ; parameter < length ; parameter++ )
693 for(
int index( 0 ); index < 3; index++ )
695 tempIndex.SetElement( index,
696 currentPoint.GetElement( index ) + ( 1.0 + parameter ) / ( 1.0 + length ) * differenceVector[ index ] );
699 tempLabel = m_SegmentationItk->GetPixel( tempIndex );
701 if( !IsBackgroundLabel( tempLabel ) )
705 mitk::Point3D endPoint, foundPointSegmentation, foundPointFiber;
706 for(
unsigned int index = 0; index < singleTract->front().Size(); index++ )
709 endPoint.SetElement( index, singleTract->GetElement( retractionStartIndex ).GetElement( index ) );
712 for(
int index( 0 ); index < 3; index++ )
714 foundPointSegmentation.SetElement( index,
715 currentPoint.GetElement( index ) + ( 1.0 + parameter ) / ( 1.0 + length ) * differenceVector[ index ] );
718 SegmentationToFiberCoords( foundPointSegmentation, foundPointFiber );
720 std::vector< double > finalDistance;
721 finalDistance.resize( singleTract->front().Size() );
722 for(
unsigned int index = 0; index < singleTract->front().Size(); index++ )
724 finalDistance[ index ] = foundPointFiber.GetElement( index ) - endPoint.GetElement( index );
729 double finalLength( 0.0 );
730 double finalSum( 0.0 );
732 for(
unsigned int index = 0; index < finalDistance.size() ; index++ )
734 finalSum = finalSum + finalDistance[ index ] * finalDistance[ index ];
736 finalLength = std::sqrt( finalSum );
738 if( finalLength > m_EndPointSearchRadius )
746 mitkIndex = tempIndex;
750 currentRetractionIndex = currentRetractionIndex + retractionStepIndexSize;
751 if( ( currentRetractionIndex < 1 ) || ( (
unsigned int)currentRetractionIndex > ( singleTract->Size() - 2 ) ) )
753 keepRetracting =
false;
762 const int dimensions = 3;
763 int max = m_Segmentation->GetStatistics()->GetScalarValueMax();
764 int min = m_Segmentation->GetStatistics()->GetScalarValueMin();
766 int range = max - min +1;
769 std::vector< std::vector< std::vector< double> > > coordinatesPerLabelVector;
770 coordinatesPerLabelVector.resize( range );
772 itk::ImageRegionIteratorWithIndex<ITKImageType> it_itkImage( m_SegmentationItk, m_SegmentationItk->GetLargestPossibleRegion() );
774 for( it_itkImage.GoToBegin(); !it_itkImage.IsAtEnd(); ++it_itkImage )
776 std::vector< double > coordinates;
777 coordinates.resize(dimensions);
781 for(
int loop(0); loop < dimensions; loop++)
783 coordinates.at( loop ) = index.GetElement( loop );
787 coordinatesPerLabelVector.at( it_itkImage.Value() -
min ).push_back( coordinates );
790 for(
int currentIndex(0), currentLabel( min ); currentIndex < range; currentIndex++, currentLabel++ )
792 std::vector< double > currentCoordinates;
793 currentCoordinates.resize(dimensions);
795 int numberOfPoints = coordinatesPerLabelVector.at( currentIndex ).size();
797 std::vector< double > sumCoords;
798 sumCoords.resize( dimensions );
800 for(
int loop(0); loop < numberOfPoints; loop++ )
802 for(
int loopDimension( 0 ); loopDimension < dimensions; loopDimension++ )
804 sumCoords.at( loopDimension ) += coordinatesPerLabelVector.at( currentIndex ).at( loop ).at( loopDimension );
808 for(
int loopDimension( 0 ); loopDimension < dimensions; loopDimension++ )
810 currentCoordinates.at( loopDimension ) = sumCoords.at( loopDimension ) / numberOfPoints;
813 m_LabelsToCoordinatesMap.insert( std::pair<
int, std::vector<double> >( currentLabel, currentCoordinates ) );
817 m_UseCoMCoordinates =
true;
823 if( ! ( m_LabelsToCoordinatesMap.count( label ) > 0 ) )
825 MITK_ERROR <<
"Label " << label <<
" not found. Could not return coordinates.";
826 std::vector< double > nullVector;
827 nullVector.resize(3);
832 return m_LabelsToCoordinatesMap.find( label )->second;
839 if( ! ( m_LabelToNodePropertyMap.count( label ) > 0 ) )
846 for(
unsigned int loop = 0; loop < newNode.
coordinates.size() ; loop++ )
853 std::vector<double> labelCoords = GetCenterOfMass( label );
854 for(
unsigned int loop = 0; loop < newNode.
coordinates.size() ; loop++ )
856 newNode.
coordinates[ loop ] = labelCoords.at( loop ) ;
860 newNode.
label = LabelToString( label );
862 m_LabelToNodePropertyMap.insert( std::pair< ImageLabelType, NetworkNode >( label, newNode ) );
itk::SmartPointer< Self > Pointer
ImageLabelPairType EndElementPositionLabel(TractType::Pointer singleTract)
static const char * CONNECTOMICS_WARNING_ESTIMATING_BEYOND_END
static const char * CONNECTOMICS_WARNING_INFO_NETWORK_CREATED
ImageLabelPairType PrecomputeVertexLocationsBySegmentation(TractType::Pointer singleTract)
void SetFiberBundle(mitk::FiberBundle::Pointer fiberBundle)
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)
mitk::ConnectomicsNetwork::Pointer GetNetwork()
DataCollection - Class to facilitate loading/accessing structured data.
void SupplyVertexWithInformation(ImageLabelType &label, VertexType &vertex)
bool IsBackgroundLabel(int labelInQuestion)
~ConnectomicsNetworkCreator()
VertexType ReturnAssociatedVertexForLabel(ImageLabelType label)
static const char * CONNECTOMICS_WARNING_DID_NOT_FIND_WHITE
ImageLabelPairType JustEndPointVerticesNoLabelTest(TractType::Pointer singleTract)
void CalculateCenterOfMass()
Calculate the locations of vertices.
void CreateNetworkFromFibersAndSegmentation()
#define MBI_INFO
Macros for different message levels. Creates an instance of class PseudoStream with the corresponding...
std::vector< float > coordinates
std::pair< VertexType, VertexType > ConnectionType
ITKImageType::Pointer m_SegmentationItk
void CreateNewNode(int label, itk::Index< 3 >, bool useIndex)
Creates a new node.
itk::Point< float, 3 > PointType
static const char * CONNECTOMICS_WARNING_ESTIMATING_BEYOND_START
mitk::ConnectomicsNetwork::VertexDescriptorType VertexType
void FiberToSegmentationCoords(mitk::Point3D &fiberCoord, mitk::Point3D &segCoord)
ImageLabelPairType ReturnLabelForFiberTract(TractType::Pointer singleTract, MappingStrategy strategy)
void AddConnectionToNetwork(ConnectionType newConnection)
ConnectomicsNetworkCreator()
static const char * CONNECTOMICS_ERROR_INVALID_MAPPING
ImageLabelPairType EndElementPositionLabelAvoidingWhiteMatter(TractType::Pointer singleTract)
bool IsNonWhiteMatterLabel(int labelInQuestion)
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
static const char * CONNECTOMICS_WARNING_ESTIMATING_LESS_THAN_2
static const char * CONNECTOMICS_ERROR_INVALID_DIMENSION_NEED_3
static const char * CONNECTOMICS_WARNING_MORE_POINTS_THAN_PRESENT
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.