21 #include <metaCommand.h>
25 #include <itkImageFileWriter.h>
27 #include <boost/lexical_cast.hpp>
30 #include <itksys/SystemTools.hxx>
33 #define _USE_MATH_DEFINES
41 int main(
int argc,
char* argv[])
45 parser.
setTitle(
"Tractometer Metrics");
46 parser.
setCategory(
"Fiber Tracking and Processing Methods");
47 parser.
setDescription(
"Calculates the Tractometer evaluation metrics for tractograms (http://www.tractometer.org/)");
58 map<string, us::Any> parsedArgs = parser.
parseArguments(argc, argv);
59 if (parsedArgs.size()==0)
64 string fibFile =
us::any_cast<
string>(parsedArgs[
"input"]);
65 string labelImageFile =
us::any_cast<
string>(parsedArgs[
"labelimage"]);
67 string outRoot =
us::any_cast<
string>(parsedArgs[
"out"]);
70 if (parsedArgs.count(
"fileID"))
71 fileID = us::any_cast<string>(parsedArgs[
"fileID"]);
74 if (parsedArgs.count(
"verbose"))
75 verbose = us::any_cast<bool>(parsedArgs[
"verbose"]);
79 typedef itk::Image<short, 3> ItkShortImgType;
80 typedef itk::Image<unsigned char, 3> ItkUcharImgType;
88 caster->SetInput(img);
92 string path = itksys::SystemTools::GetFilenamePath(labelImageFile);
94 std::vector< bool > detected;
95 std::vector< std::pair< int, int > > labelsvector;
96 std::vector< ItkUcharImgType::Pointer > bundleMasks;
97 std::vector< ItkUcharImgType::Pointer > bundleMasksCoverage;
99 for (
unsigned int i=0; i<labelpairs.size()-1; i+=2)
101 std::pair< short, short > l;
102 l.first = boost::lexical_cast<
short>(labelpairs.at(i));
103 l.second = boost::lexical_cast<
short>(labelpairs.at(i+1));
104 std::cout << labelpairs.at(i);
105 std::cout << labelpairs.at(i+1);
111 labelsvector.push_back(l);
112 detected.push_back(
false);
118 caster->SetInput(img);
121 bundleMasks.push_back(bundle);
128 caster->SetInput(img);
131 bundleMasksCoverage.push_back(bundle);
134 vnl_matrix< unsigned char > matrix; matrix.set_size(max, max); matrix.fill(0);
136 vtkSmartPointer<vtkPolyData> polyData = inputTractogram->GetFiberPolyData();
138 int validConnections = 0;
139 int noConnection = 0;
140 int validBundles = 0;
141 int invalidBundles = 0;
142 int invalidConnections = 0;
145 coverage->SetSpacing(labelImage->GetSpacing());
146 coverage->SetOrigin(labelImage->GetOrigin());
147 coverage->SetDirection(labelImage->GetDirection());
148 coverage->SetLargestPossibleRegion(labelImage->GetLargestPossibleRegion());
149 coverage->SetBufferedRegion( labelImage->GetLargestPossibleRegion() );
150 coverage->SetRequestedRegion( labelImage->GetLargestPossibleRegion() );
151 coverage->Allocate();
152 coverage->FillBuffer(0);
163 boost::progress_display disp(inputTractogram->GetNumFibers());
164 for (
int i=0; i<inputTractogram->GetNumFibers(); i++)
168 vtkCell* cell = polyData->GetCell(i);
169 int numPoints = cell->GetNumberOfPoints();
170 vtkPoints* points = cell->GetPoints();
175 double* start = points->GetPoint(0);
176 itk::Point<float, 3> itkStart;
177 itkStart[0] = start[0]; itkStart[1] = start[1]; itkStart[2] = start[2];
179 labelImage->TransformPhysicalPointToIndex(itkStart, idxStart);
181 double* end = points->GetPoint(numPoints-1);
182 itk::Point<float, 3> itkEnd;
183 itkEnd[0] = end[0]; itkEnd[1] = end[1]; itkEnd[2] = end[2];
185 labelImage->TransformPhysicalPointToIndex(itkEnd, idxEnd);
188 if ( labelImage->GetPixel(idxStart)==0 || labelImage->GetPixel(idxEnd)==0 )
195 for (
int j=0; j<numPoints; j++)
197 double* p = points->GetPoint(j);
198 vtkIdType
id = noConnPoints->InsertNextPoint(p);
199 container->GetPointIds()->InsertNextId(
id);
201 noConnCells->InsertNextCell(container);
207 for (
unsigned int i=0; i<labelsvector.size(); i++)
209 bool outside =
false;
211 std::pair< short, short > l = labelsvector.at(i);
212 if ( (labelImage->GetPixel(idxStart)==l.first && labelImage->GetPixel(idxEnd)==l.second) ||
213 (labelImage->GetPixel(idxStart)==l.second && labelImage->GetPixel(idxEnd)==l.first) )
215 for (
int j=0; j<numPoints; j++)
217 double* p = points->GetPoint(j);
219 itk::Point<float, 3> itkP;
220 itkP[0] = p[0]; itkP[1] = p[1]; itkP[2] = p[2];
222 bundle->TransformPhysicalPointToIndex(itkP, idx);
224 if ( !bundle->GetPixel(idx)>0 && bundle->GetLargestPossibleRegion().IsInside(idx) )
233 if (detected.at(i)==
false)
235 detected.at(i) =
true;
240 for (
int j=0; j<numPoints; j++)
242 double* p = points->GetPoint(j);
243 vtkIdType
id = validPoints->InsertNextPoint(p);
244 container->GetPointIds()->InsertNextId(
id);
246 itk::Point<float, 3> itkP;
247 itkP[0] = p[0]; itkP[1] = p[1]; itkP[2] = p[2];
249 coverage->TransformPhysicalPointToIndex(itkP, idx);
250 if ( coverage->GetLargestPossibleRegion().IsInside(idx) )
251 coverage->SetPixel(idx, 1);
253 validCells->InsertNextCell(container);
260 invalidConnections++;
261 int x = labelImage->GetPixel(idxStart)-1;
262 int y = labelImage->GetPixel(idxEnd)-1;
263 if (x>=0 && y>0 && x<matrix.cols() && y<matrix.rows() && (matrix[x][y]==0 || matrix[y][x]==0) )
273 for (
int j=0; j<numPoints; j++)
275 double* p = points->GetPoint(j);
276 vtkIdType
id = invalidPoints->InsertNextPoint(p);
277 container->GetPointIds()->InsertNextId(
id);
279 invalidCells->InsertNextCell(container);
290 noConnPolyData->SetPoints(noConnPoints);
291 noConnPolyData->SetLines(noConnCells);
294 string ncfilename = outRoot;
295 ncfilename.append(
"_NC.fib");
300 invalidPolyData->SetPoints(invalidPoints);
301 invalidPolyData->SetLines(invalidCells);
304 string icfilename = outRoot;
305 icfilename.append(
"_IC.fib");
310 validPolyData->SetPoints(validPoints);
311 validPolyData->SetLines(validCells);
314 string vcfilename = outRoot;
315 vcfilename.append(
"_VC.fib");
320 typedef itk::ImageFileWriter< ItkUcharImgType > WriterType;
322 writer->SetFileName(outRoot+
"_ABC.nrrd");
323 writer->SetInput(coverage);
330 int coveredVoxels = 0;
331 itk::ImageRegionIterator<ItkUcharImgType> it (coverage, coverage->GetLargestPossibleRegion());
335 for (
unsigned int i=0; i<bundleMasksCoverage.size(); i++)
338 if (bundle->GetPixel(it.GetIndex())>0)
345 if (wm && it.Get()>0)
350 int numFibers = inputTractogram->GetNumFibers();
351 double nc = (double)noConnection/numFibers;
352 double vc = (double)validConnections/numFibers;
353 double ic = (double)invalidConnections/numFibers;
360 int vb = validBundles;
361 int ib = invalidBundles;
362 double abc = (double)coveredVoxels/wmVoxels;
364 std::cout <<
"NC: " << nc;
365 std::cout <<
"VC: " << vc;
366 std::cout <<
"IC: " << ic;
367 std::cout <<
"VB: " << vb;
368 std::cout <<
"IB: " << ib;
369 std::cout <<
"ABC: " << abc;
372 logFile.append(
"_TRACTOMETER.csv");
374 file.open (logFile.c_str());
376 string sens = itksys::SystemTools::GetFilenameWithoutLastExtension(fibFile);
381 sens.append(boost::lexical_cast<string>(nc));
384 sens.append(boost::lexical_cast<string>(vc));
387 sens.append(boost::lexical_cast<string>(ic));
390 sens.append(boost::lexical_cast<string>(validBundles));
393 sens.append(boost::lexical_cast<string>(invalidBundles));
396 sens.append(boost::lexical_cast<string>(abc));
402 catch (itk::ExceptionObject e)
407 catch (std::exception e)
409 std::cout << e.what();
414 std::cout <<
"ERROR!?!";
itk::SmartPointer< Self > Pointer
static Pointer GetInstance()
void setContributor(std::string contributor)
ValueType * any_cast(Any *operand)
int main(int argc, char *argv[])
Calculates the Tractometer evaluation metrics for tractograms (http://www.tractometer.org/)
std::map< std::string, us::Any > parseArguments(const StringContainerType &arguments, bool *ok=nullptr)
static bool SaveBaseData(mitk::BaseData *data, const std::string &path)
SaveBaseData Convenience method to save arbitrary baseData.
void addArgument(const std::string &longarg, const std::string &shortarg, Type type, const std::string &argLabel, const std::string &argHelp=std::string(), const us::Any &defaultValue=us::Any(), bool optional=true, bool ignoreRest=false, bool deprecated=false)
Image class for storing images.
static std::ofstream * logFile
Base Class for Fiber Bundles;.
void setCategory(std::string category)
static mitk::DataNode::Pointer LoadDataNode(const std::string &path)
LoadDataNode Method to load an arbitrary DataNode.
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
std::vector< std::string > StringContainerType
void setTitle(std::string title)
void setDescription(std::string description)
std::list< mitk::FileWriterWithInformation::Pointer > FileWriterList
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.