3 #include <itkImageRegionIteratorWithIndex.h>     4 #include <itkMultiThreaderBase.h>     5 #include <itkProgressReporter.h>     9 #include <vtkPointData.h>    10 #include <vtkCellData.h>    17     m_PointsToProcess.clear();
    19     m_NumberOfFibersPerPixel = 1;
    21     m_StepProgression = 1;
    22     m_MaxFiberAngle = M_PI / 2.0;
    24     m_ComputeLocalColors = 
true;
    25     m_HighestProcessedSeed = 0;
    26     m_ProgressReport = ITK_NULLPTR;
    32         delete m_ProgressReport;
    38     m_Output = vtkPolyData::New();
    41         delete m_ProgressReport;
    43     unsigned int stepData = std::min((
int)m_PointsToProcess.size(),100);
    47     unsigned int numSteps = std::floor(m_PointsToProcess.size() / (double)stepData);
    48     if (m_PointsToProcess.size() % stepData != 0)
    51     m_ProgressReport = 
new itk::ProgressReporter(
this,0,numSteps);
    53     std::vector < FiberType > resultFibers;
    57     for (
unsigned int i = 0;i < this->GetNumberOfWorkUnits();++i)
    60     this->GetMultiThreader()->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
    61     this->GetMultiThreader()->SetSingleMethod(this->
ThreadTracker,&tmpStr);
    62     this->GetMultiThreader()->SingleMethodExecute();
    64     for (
unsigned int j = 0;j < this->GetNumberOfWorkUnits();++j)
    70     std::cout << 
"\nTracked a total of " << resultFibers.size() << 
" fibers" << std::endl;
    72     std::cout << 
"Kept " << resultFibers.size() << 
" fibers after filtering" << std::endl;
    78     typedef itk::ImageRegionIteratorWithIndex <MaskImageType> MaskImageIteratorType;
    80     MaskImageIteratorType seedItr(m_SeedingImage, m_InputImage->GetLargestPossibleRegion());
    81     m_PointsToProcess.clear();
    87     m_FilteringValues.clear();
    88     double startN = -0.5 + 1.0 / (2.0 * m_NumberOfFibersPerPixel);
    89     double stepN = 1.0 / m_NumberOfFibersPerPixel;
    91     bool is2d = (m_InputImage->GetLargestPossibleRegion().GetSize()[2] <= 1);
    94     while (!seedItr.IsAtEnd())
    96         if (seedItr.Get() == 0)
   102         tmpIndex = seedItr.GetIndex();
   106             realIndex[2] = tmpIndex[2];
   107             for (
unsigned int j = 0;j < m_NumberOfFibersPerPixel;++j)
   109                 realIndex[1] = tmpIndex[1] + startN + j * stepN;
   110                 for (
unsigned int i = 0;i < m_NumberOfFibersPerPixel;++i)
   112                     realIndex[0] = tmpIndex[0] + startN + i * stepN;
   113                     m_SeedingImage->TransformContinuousIndexToPhysicalPoint(realIndex,tmpPoint);
   114                     tmpFiber[0] = tmpPoint;
   115                     m_PointsToProcess.push_back(std::pair<FiberProgressType,FiberType>(
Both,tmpFiber));
   121             for (
unsigned int k = 0;k < m_NumberOfFibersPerPixel;++k)
   123                 realIndex[2] = tmpIndex[2] + startN + k * stepN;
   124                 for (
unsigned int j = 0;j < m_NumberOfFibersPerPixel;++j)
   126                     realIndex[1] = tmpIndex[1] + startN + j * stepN;
   127                     for (
unsigned int i = 0;i < m_NumberOfFibersPerPixel;++i)
   129                         realIndex[0] = tmpIndex[0] + startN + i * stepN;
   130                         m_SeedingImage->TransformContinuousIndexToPhysicalPoint(realIndex,tmpPoint);
   131                         tmpFiber[0] = tmpPoint;
   132                         m_PointsToProcess.push_back(std::pair<FiberProgressType,FiberType>(
Both,tmpFiber));
   141     if (m_FilteringImage.IsNotNull())
   143         MaskImageIteratorType filterItr(m_FilteringImage, m_InputImage->GetLargestPossibleRegion());
   145         while (!filterItr.IsAtEnd())
   147             if (filterItr.Get() == 0)
   153             bool isAlreadyIn = 
false;
   154             for (
unsigned int i = 0;i < m_FilteringValues.size();++i)
   156                 if (m_FilteringValues[i] == filterItr.Get())
   164                 m_FilteringValues.push_back(filterItr.Get());
   170     std::cout << 
"Generated " << m_PointsToProcess.size() << 
" seed points from ROI mask" << std::endl;
   175     itk::MultiThreaderBase::WorkUnitInfo *threadArgs = (itk::MultiThreaderBase::WorkUnitInfo *)arg;
   176     unsigned int nbThread = threadArgs->WorkUnitID;
   181     return ITK_THREAD_RETURN_DEFAULT_VALUE;
   186     bool continueLoop = 
true;
   187     unsigned int highestToleratedSeedIndex = m_PointsToProcess.size();
   189     unsigned int stepData = std::min((
int)m_PointsToProcess.size(),100);
   195         m_LockHighestProcessedSeed.lock();
   197         if (m_HighestProcessedSeed >= highestToleratedSeedIndex)
   199             m_LockHighestProcessedSeed.unlock();
   200             continueLoop = 
false;
   204         unsigned int startPoint = m_HighestProcessedSeed;
   205         unsigned int endPoint = m_HighestProcessedSeed + stepData;
   206         if (endPoint > highestToleratedSeedIndex)
   207             endPoint = highestToleratedSeedIndex;
   209         m_HighestProcessedSeed = endPoint;
   211         m_LockHighestProcessedSeed.unlock();
   215         m_LockHighestProcessedSeed.lock();
   216         m_ProgressReport->CompletedPixel();
   217         m_LockHighestProcessedSeed.unlock();
   222                                                         unsigned int startSeedIndex, 
unsigned int endSeedIndex)
   225     for (
unsigned int i = startSeedIndex;i < endSeedIndex;++i)
   227         tmpFiber = m_PointsToProcess[i].second;
   228         this->
ComputeFiber(tmpFiber,m_PointsToProcess[i].first,numThread);
   230         if (tmpFiber.size() > m_MinLengthFiber / m_StepProgression)
   231             resultFibers.push_back(tmpFiber);
   235 std::vector < std::vector <BaseTractographyImageFilter::PointType> >
   238     std::vector < FiberType > resVal;
   240     if (m_FilteringValues.size() > 1)
   242         std::vector <bool> touchingLabels(m_FilteringValues.size());
   245         for (
unsigned int i = 0;i < fibers.size();++i)
   247             std::fill(touchingLabels.begin(),touchingLabels.end(),
false);
   248             for (
unsigned int j = 0;j < fibers[i].size();++j)
   250                 tmpPoint = fibers[i][j];
   251                 m_FilteringImage->TransformPhysicalPointToIndex(tmpPoint,tmpIndex);
   253                 unsigned int maskValue = m_FilteringImage->GetPixel(tmpIndex);
   256                     for (
unsigned int k = 0;k < m_FilteringValues.size();++k)
   258                         if (maskValue == m_FilteringValues[k])
   260                             touchingLabels[k] = 
true;
   267             bool keepFiber = 
true;
   268             for (
unsigned int k = 0;k < touchingLabels.size();++k)
   270                 if (!touchingLabels[k])
   278                 resVal.push_back(fibers[i]);
   289     m_Output = vtkPolyData::New();
   290     m_Output->Initialize();
   291     m_Output->Allocate();
   293     vtkSmartPointer <vtkPoints> myPoints = vtkPoints::New();    
   294     for (
unsigned int i = 0;i < filteredFibers.size();++i)
   296         unsigned int npts = filteredFibers[i].size();
   297         vtkIdType* ids = 
new vtkIdType[npts];
   299         for (
unsigned int j = 0;j < npts;++j)
   300             ids[j] = myPoints->InsertNextPoint(filteredFibers[i][j][0],filteredFibers[i][j][1],filteredFibers[i][j][2]);
   302         m_Output->InsertNextCell (VTK_POLY_LINE, npts, ids);
   306     m_Output->SetPoints (myPoints);
   307     if (m_ComputeLocalColors)
   309         std::cout << 
"Computing local colors and microstructure maps" << std::endl;
   317                                           itk::ThreadIdType threadId)
   320     bool is2d = m_InputImage->GetLargestPossibleRegion().GetSize()[2] == 1;
   324         PointType curPoint = fiber[fiber.size() - 1];
   329         bool continueLoop = 
true;
   330         m_SeedingImage->TransformPhysicalPointToContinuousIndex(curPoint,curIndex);
   331         m_SeedingImage->TransformPhysicalPointToIndex(curPoint,curNearestIndex);
   334         modelValue.SetSize(1);
   336         if (!m_CutMaskImage.IsNull())
   339                 continueLoop = 
false;
   340             else if (m_CutMaskImage->GetPixel(curNearestIndex) != 0)
   341                 continueLoop = 
false;
   344         if (!m_ForbiddenMaskImage.IsNull())
   351             if (m_ForbiddenMaskImage->GetPixel(curNearestIndex) != 0)
   360             continueLoop = 
false;
   363             continueLoop = 
false;
   367             if (fiber.size() <= 1)
   371                 for (
unsigned int i = 0;i < 3;++i)
   372                     oldDir[i] = fiber[fiber.size() - 1][i] - fiber[fiber.size() - 2][i];
   380                 continueLoop = 
false;
   387             for (
unsigned int i = 0;i < 3;++i)
   388                 curPoint[i] = fiber[fiber.size() - 1][i] + m_StepProgression * newDir[i];
   390             m_SeedingImage->TransformPhysicalPointToContinuousIndex(curPoint,curIndex);
   391             m_SeedingImage->TransformPhysicalPointToIndex(curPoint,curNearestIndex);
   393             if (!m_CutMaskImage.IsNull())
   396                     continueLoop = 
false;
   397                 else if (m_CutMaskImage->GetPixel(curNearestIndex) != 0)
   398                     continueLoop = 
false;
   401             if (!m_ForbiddenMaskImage.IsNull())
   408                 if (m_ForbiddenMaskImage->GetPixel(curNearestIndex) != 0)
   416                 continueLoop = 
false;
   422                     continueLoop = 
false;
   426                 continueLoop = 
false;
   430                 fiber.push_back(curPoint);
   432             if (fiber.size() > m_MaxLengthFiber / m_StepProgression)
   447         bool continueLoop = 
true;
   448         m_SeedingImage->TransformPhysicalPointToContinuousIndex(curPoint,curIndex);
   449         m_SeedingImage->TransformPhysicalPointToIndex(curPoint,curNearestIndex);
   452         modelValue.SetSize(1);
   454         if (!m_CutMaskImage.IsNull())
   457                 continueLoop = 
false;
   458             else if (m_CutMaskImage->GetPixel(curNearestIndex) != 0)
   459                 continueLoop = 
false;
   462         if (!m_ForbiddenMaskImage.IsNull())
   469             if (m_ForbiddenMaskImage->GetPixel(curNearestIndex) != 0)
   478             continueLoop = 
false;
   481             continueLoop = 
false;
   485             if (fiber.size() <= 1)
   488                 for (
unsigned int i = 0;i < 3;++i)
   493                 for (
unsigned int i = 0;i < 3;++i)
   494                     oldDir[i] = fiber[0][i] - fiber[1][i];
   502                 continueLoop = 
false;
   509             for (
unsigned int i = 0;i < 3;++i)
   510                 curPoint[i] = fiber[0][i] + m_StepProgression * newDir[i];
   512             m_SeedingImage->TransformPhysicalPointToContinuousIndex(curPoint,curIndex);
   513             m_SeedingImage->TransformPhysicalPointToIndex(curPoint,curNearestIndex);
   515             if (!m_CutMaskImage.IsNull())
   518                     continueLoop = 
false;
   519                 else if (m_CutMaskImage->GetPixel(curNearestIndex) != 0)
   520                     continueLoop = 
false;
   523             if (!m_ForbiddenMaskImage.IsNull())
   530                 if (m_ForbiddenMaskImage->GetPixel(curNearestIndex) != 0)
   538                 continueLoop = 
false;
   544                     continueLoop = 
false;
   548                 continueLoop = 
false;
   552                 fiber.insert(fiber.begin(),1,curPoint);
   554             if (fiber.size() > m_MaxLengthFiber / m_StepProgression)
   567     RegionType imageRegion = testImage->GetLargestPossibleRegion();
   568     for (
unsigned int i = 0;i < ImageBaseType::ImageDimension;++i)
   570         if ((index[i] < imageRegion.GetIndex()[i]) ||
   571             (index[i] >= imageRegion.GetIndex()[i] + imageRegion.GetSize()[i]))
   580     for (
unsigned int i = 0;i < value.GetSize();++i)
 void Revert(const VectorType &v, const unsigned int vSize, VectorType &resVec)
 
ModelImageType::RegionType RegionType
 
itk::ImageBase< ModelImageType::ImageDimension > ImageBaseType
 
virtual void ComputeAdditionalScalarMaps()
 
bool isZero(VectorType &value)
 
BaseTractographyImageFilter * trackerPtr
 
std::vector< std::pair< FiberProgressType, FiberType > > FiberProcessVectorType
 
virtual void GetModelValue(ContinuousIndexType &index, VectorType &modelValue)=0
Computes value of model from data. May use SNR and previous model value to perform smart interpolatio...
 
BaseTractographyImageFilter()
 
virtual bool CheckModelCompatibility(VectorType &modelValue, itk::ThreadIdType threadId)=0
 
virtual PointType GetNextDirection(PointType &previousDirection, VectorType &modelValue, bool is2d, itk::ThreadIdType threadId)=0
 
void createVTKOutput(std::vector< std::vector< PointType > > &filteredFibers)
 
MaskImageType::PointType PointType
 
FiberProcessVectorType ComputeFiber(FiberType &fiber, FiberProgressType ways, itk::ThreadIdType threadId)
 
std::vector< PointType > FiberType
 
itk::ContinuousIndex< double, 3 > ContinuousIndexType
 
void Update() ITK_OVERRIDE
 
double ComputeOrientationAngle(const VectorType &v1, const VectorType &v2)
 
static ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION ThreadTracker(void *arg)
 
ModelImageType::PixelType VectorType
 
bool CheckIndexInImageBounds(IndexType &index, ImageBaseType *testImage)
 
virtual void PrepareTractography()
 
double ComputeScalarProduct(const VectorType &v1, const VectorType &v2, const unsigned int NDimension)
 
std::vector< std::vector< FiberType > > resultFibersFromThreads
 
void ThreadTrack(unsigned int numThread, std::vector< FiberType > &resultFibers)
 
void ThreadedTrackComputer(unsigned int numThread, std::vector< FiberType > &resultFibers, unsigned int startSeedIndex, unsigned int endSeedIndex)
 
std::vector< FiberType > FilterOutputFibers(std::vector< FiberType > &fibers)
 
virtual PointType GetModelPrincipalDirection(VectorType &modelValue, bool is2d, itk::ThreadIdType threadId)=0
 
MaskImageType::IndexType IndexType
 
virtual ~BaseTractographyImageFilter()