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()