1 #include <tclap/CmdLine.h> 7 #include <vtkSmartPointer.h> 9 #include <vtkPointData.h> 10 #include <vtkPolyData.h> 11 #include <vtkCleanPolyData.h> 12 #include <vtkGenericCell.h> 14 #include <itkNearestNeighborInterpolateImageFunction.h> 15 #include <itkPoolMultiThreader.h> 17 void FilterTracks(vtkPolyData *tracks,
unsigned int startIndex,
unsigned int endIndex,
18 itk::NearestNeighborInterpolateImageFunction < itk::Image <unsigned short, 3> > * interpolator,
19 const std::vector <unsigned int> &touchLabels,
const std::vector <unsigned int> &endingsLabels,
20 const std::vector <unsigned int> &forbiddenLabels)
22 std::vector <unsigned int> seenLabels;
23 std::vector <unsigned int> seenEndingsLabels;
24 double pointPositionVTK[3];
25 itk::ContinuousIndex<double, 3> currentIndex;
26 typedef itk::Image <unsigned short, 3>::PointType PointType;
27 PointType pointPosition;
29 vtkSmartPointer <vtkGenericCell> cell = vtkGenericCell::New();
30 for (
unsigned int i = startIndex;i < endIndex;++i)
33 tracks->GetCell(i,cell);
34 vtkPoints *cellPts = cell->GetPoints();
35 vtkIdType numCellPts = cellPts->GetNumberOfPoints();
40 seenEndingsLabels.clear();
41 for (
unsigned int j = 0;j < numCellPts;j += numCellPts - 1)
43 cellPts->GetPoint(j, pointPositionVTK);
44 for (
unsigned int k = 0; k < 3; ++k)
45 pointPosition[k] = pointPositionVTK[k];
46 interpolator->GetInputImage()->TransformPhysicalPointToContinuousIndex(pointPosition,currentIndex);
47 if (interpolator->IsInsideBuffer(currentIndex))
49 unsigned int value = static_cast <
unsigned int> (std::round(interpolator->EvaluateAtContinuousIndex(currentIndex)));
50 for (
unsigned int k = 0;k < endingsLabels.size();++k)
52 if (value == endingsLabels[k])
54 bool alreadyIn =
false;
55 for (
unsigned int l = 0;l < seenEndingsLabels.size();++l)
57 if (seenEndingsLabels[l] == value)
65 seenEndingsLabels.push_back(value);
73 if (seenEndingsLabels.size() != endingsLabels.size())
79 for (
unsigned int j = 0;j < numCellPts;++j)
81 cellPts->GetPoint(j, pointPositionVTK);
82 for (
unsigned int k = 0; k < 3; ++k)
83 pointPosition[k] = pointPositionVTK[k];
85 interpolator->GetInputImage()->TransformPhysicalPointToContinuousIndex(pointPosition,currentIndex);
87 if (!interpolator->IsInsideBuffer(currentIndex))
90 unsigned int value = static_cast <
unsigned int> (std::round(interpolator->EvaluateAtContinuousIndex(currentIndex)));
92 for (
unsigned int k = 0;k < forbiddenLabels.size();++k)
94 if (value == forbiddenLabels[k])
104 for (
unsigned int k = 0;k < touchLabels.size();++k)
106 if (value == touchLabels[k])
108 bool alreadyIn =
false;
109 for (
unsigned int l = 0;l < seenLabels.size();++l)
111 if (seenLabels[l] == value)
119 seenLabels.push_back(value);
127 if (!lineOk || (seenLabels.size() != touchLabels.size()))
128 tracks->DeleteCell(i);
135 itk::NearestNeighborInterpolateImageFunction < itk::Image <unsigned short, 3> > *
interpolator;
143 itk::MultiThreaderBase::WorkUnitInfo *threadArgs = (itk::MultiThreaderBase::WorkUnitInfo *)arg;
144 unsigned int nbThread = threadArgs->WorkUnitID;
145 unsigned int numTotalThread = threadArgs->NumberOfWorkUnits;
148 unsigned int nbTotalCells = tmpArg->
tracks->GetNumberOfCells();
150 unsigned int step = nbTotalCells / numTotalThread;
151 unsigned int startIndex = nbThread * step;
152 unsigned int endIndex = (nbThread + 1) * step;
154 if (nbThread == numTotalThread - 1)
155 endIndex = nbTotalCells;
159 return ITK_THREAD_RETURN_DEFAULT_VALUE;
162 int main(
int argc,
char **argv)
164 TCLAP::CmdLine cmd(
"Filters fibers from a vtp file using a label image and specifying with several -t and -f which labels should be touched or are forbidden for each fiber. INRIA / IRISA - VisAGeS/Empenn Team",
' ',ANIMA_VERSION);
166 TCLAP::ValueArg<std::string> inArg(
"i",
"input",
"input tracks file",
true,
"",
"input tracks",cmd);
167 TCLAP::ValueArg<std::string> roiArg(
"r",
"roi",
"input ROI label image",
true,
"",
"ROI image",cmd);
168 TCLAP::ValueArg<std::string> outArg(
"o",
"output",
"output tracks name",
true,
"",
"output tracks",cmd);
170 TCLAP::MultiArg<unsigned int> touchArg(
"t",
"touch",
"Labels that have to be touched",
false,
"touched labels",cmd);
171 TCLAP::MultiArg<unsigned int> endingsArg(
"e",
"endings",
"Labels that have to be touched by the endings of the fibers",
false,
"endings labels",cmd);
172 TCLAP::MultiArg<unsigned int> forbiddenArg(
"f",
"forbid",
"Labels that must not to be touched",
false,
"forbidden labels",cmd);
174 TCLAP::ValueArg<unsigned int> nbThreadsArg(
"T",
"nb-threads",
"Number of threads to run on (default: all available)",
false,itk::MultiThreaderBase::GetGlobalDefaultNumberOfThreads(),
"number of threads",cmd);
177 cmd.parse(argc,argv);
179 catch (TCLAP::ArgException& e)
181 std::cerr <<
"Error: " << e.error() <<
"for argument " << e.argId() << std::endl;
185 typedef itk::Image <unsigned short, 3> ROIImageType;
186 ROIImageType::Pointer roiImage = anima::readImage <ROIImageType> (roiArg.getValue());
188 typedef itk::NearestNeighborInterpolateImageFunction <ROIImageType> InterpolatorType;
189 InterpolatorType::Pointer interpolator = InterpolatorType::New();
190 interpolator->SetInputImage(roiImage);
196 vtkSmartPointer <vtkPolyData> tracks = trackReader.
GetOutput();
199 vtkSmartPointer <vtkGenericCell> dummyCell = vtkGenericCell::New();
200 tracks->GetCell(0,dummyCell);
202 std::vector <unsigned int> touchLabels = touchArg.getValue();
203 std::vector <unsigned int> endingsLabels = endingsArg.getValue();
204 std::vector <unsigned int> forbiddenLabels = forbiddenArg.getValue();
206 if (endingsLabels.size() > 2)
207 std::cerr <<
"Endings consider only the two ending points of each fiber. Having more than two labels will lead to empty bundles" << std::endl;
216 itk::PoolMultiThreader::Pointer mThreader = itk::PoolMultiThreader::New();
217 mThreader->SetNumberOfWorkUnits(nbThreadsArg.getValue());
219 mThreader->SingleMethodExecute();
222 tracks->RemoveDeletedCells();
225 vtkSmartPointer <vtkCleanPolyData> vtkCleaner = vtkSmartPointer <vtkCleanPolyData>::New();
226 vtkCleaner->SetInputData(tracks);
227 vtkCleaner->Update();
228 tracks->ShallowCopy(vtkCleaner->GetOutput());
230 std::cout <<
"Kept " << tracks->GetNumberOfCells() <<
" after filtering" << std::endl;
235 std::cout <<
"Writing tracks: " << outArg.getValue() << std::endl;
std::vector< unsigned int > endingsLabels
void SetInputData(vtkPolyData *data)
void FilterTracks(vtkPolyData *tracks, unsigned int startIndex, unsigned int endIndex, itk::NearestNeighborInterpolateImageFunction< itk::Image< unsigned short, 3 > > *interpolator, const std::vector< unsigned int > &touchLabels, const std::vector< unsigned int > &endingsLabels, const std::vector< unsigned int > &forbiddenLabels)
int main(int argc, char **argv)
std::vector< unsigned int > touchLabels
void SetFileName(std::string &name)
ITK_THREAD_RETURN_FUNCTION_CALL_CONVENTION ThreadFilterer(void *arg)
itk::NearestNeighborInterpolateImageFunction< itk::Image< unsigned short, 3 > > * interpolator
vtkPolyData * GetOutput()
std::vector< unsigned int > forbiddenLabels
void SetFileName(std::string &name)