3 #include <tclap/CmdLine.h> 21 m_bSegmentationEvaluation =
true;
22 m_bAdvancedEvaluation =
false;
23 m_bSurfaceEvaluation =
true;
24 m_bLesionsDetectionEvaluation =
true;
28 m_fSensitivity = std::numeric_limits<double>::quiet_NaN();
29 m_fSpecificity = std::numeric_limits<double>::quiet_NaN();
30 m_fPPV = std::numeric_limits<double>::quiet_NaN();
31 m_fNPV = std::numeric_limits<double>::quiet_NaN();
32 m_fDice = std::numeric_limits<double>::quiet_NaN();
33 m_fJaccard = std::numeric_limits<double>::quiet_NaN();
34 m_fRVE = std::numeric_limits<double>::quiet_NaN();
38 m_fHausdorffDist = std::numeric_limits<double>::quiet_NaN();
39 m_fMeanDist = std::numeric_limits<double>::quiet_NaN();
40 m_fAverageDist = std::numeric_limits<double>::quiet_NaN();
44 m_fPPVL = std::numeric_limits<double>::quiet_NaN();
45 m_fSensL = std::numeric_limits<double>::quiet_NaN();
46 m_fF1 = std::numeric_limits<double>::quiet_NaN();
55 m_fDetectionLesionMinVolume = 3.0;
56 m_fTPLMinOverlapRatio = 0.1;
57 m_fTPLMaxFalsePositiveRatio = 0.7;
58 m_fTPLMaxFalsePositiveRatioModerator = 0.65;
74 TCLAP::CmdLine cmd(
"Tools to analyze segmentation performances by comparison",
' ', ANIMA_VERSION);
77 TCLAP::ValueArg<std::string> oArgInputImg(
"i",
"input",
"Input image.",
true,
"",
"string", cmd);
80 TCLAP::ValueArg<std::string> oArgRefImg(
"r",
"ref",
"Reference image to compare input image.",
true,
"",
"string", cmd);
83 TCLAP::ValueArg<std::string> oArgBaseOutputName(
"o",
"outputBase",
"Base name for output files",
true,
"",
"string", cmd);
86 TCLAP::ValueArg<int> oArgNbThreads(
"t",
"threads",
"Number of threads",
false, 0,
"int", cmd);
89 TCLAP::SwitchArg oArgAbout(
"A",
"About",
"Details on output metrics", cmd,
false);
92 TCLAP::SwitchArg oArgSwitchText(
"T",
"text",
"Stores results into a text file.", cmd,
false);
95 TCLAP::SwitchArg oArgSwitchXml(
"X",
"xml",
"Stores results into a xml file.", cmd,
false);
98 TCLAP::SwitchArg oArgSwitchScreen(
"S",
"screen",
"Print results on the screen when program ended.", cmd,
false);
101 TCLAP::SwitchArg oArgSegEval(
"s",
"SegmentationEvaluationMetrics",
"Compute metrics to evaluate a segmentation.", cmd,
false);
104 TCLAP::SwitchArg oArgSwitchAdvancedEvaluation(
"a",
"advancedEvaluation",
"Compute results for each cluster (intra-lesion results)", cmd,
false);
107 TCLAP::SwitchArg oArgSwitchDetectionEval(
"l",
"LesionDetectionMetrics",
"Compute metrics to evaluate the detection of lesions along to a segmentation.", cmd,
false);
110 TCLAP::SwitchArg oArgSwitchSurfaceDist(
"d",
"SurfaceEvaluation",
"Surface distances evaluation.", cmd,
false);
113 TCLAP::ValueArg<double> oArgSwitchDetectionLesionMinVolume(
"v",
"MinLesionVolume",
"Min volume of lesion for \"Lesions detection metrics\" in mm^3 (default 3mm^3).",
false, 3.00,
"double", cmd);
116 TCLAP::ValueArg<double> oArgSwitchTPLMinOverlapRatio(
"x",
"MinOverlapRatio",
"Minimum overlap ratio to say if a lesion of the GT is detected. (default 0.10)",
false, 0.10,
"double", cmd);
119 TCLAP::ValueArg<double> oArgSwitchTPLMaxFalsePositiveRatio(
"y",
"MaxFalsePositiveRatio",
"Maximum of false positive ratio to limit the detection of a lesion in GT if a lesion in the image is too big. (default 0.7)",
false, 0.70,
"double", cmd);
122 TCLAP::ValueArg<double> oArgSwitchTPLMaxFalsePositiveRatioModerator(
"z",
"MaxFalsePositiveRatioModerator",
"Percentage of the regions overlapping the tested lesion is not too much outside of this lesion. (default 0.65)",
false, 0.65,
"double", cmd);
125 cmd.parse( argc, argv );
127 if (oArgAbout.isSet())
133 m_oStrInImage = oArgInputImg.getValue();
134 m_oStrRefImage = oArgRefImg.getValue();
135 m_oStrBaseOut = oArgBaseOutputName.getValue();
137 m_bTxt = oArgSwitchText.getValue();
138 m_bXml = oArgSwitchXml.getValue();
139 m_bScreen = oArgSwitchScreen.getValue();
141 m_iNbThreads = oArgNbThreads.getValue();
143 m_bSegmentationEvaluation = oArgSegEval.getValue();
144 m_bAdvancedEvaluation = oArgSwitchAdvancedEvaluation.getValue();
145 m_bSurfaceEvaluation = oArgSwitchSurfaceDist.getValue();
146 m_bLesionsDetectionEvaluation = oArgSwitchDetectionEval.getValue();
148 m_fDetectionLesionMinVolume = oArgSwitchDetectionLesionMinVolume.getValue();
149 m_fTPLMinOverlapRatio = oArgSwitchTPLMinOverlapRatio.getValue();
150 m_fTPLMaxFalsePositiveRatio = oArgSwitchTPLMaxFalsePositiveRatio.getValue();
151 m_fTPLMaxFalsePositiveRatioModerator = oArgSwitchTPLMaxFalsePositiveRatioModerator.getValue();
164 if(!(m_bSegmentationEvaluation || m_bAdvancedEvaluation || m_bSurfaceEvaluation || m_bLesionsDetectionEvaluation))
166 m_bSegmentationEvaluation =
true;
169 if (m_bAdvancedEvaluation && !(m_bSegmentationEvaluation || m_bSurfaceEvaluation))
171 std::cout <<
"Switch \"advancedEvaluation\" need \"SegmentationEvaluationMetrics\" or/and SurfaceEvaluation switches." << std::endl;
172 std::cout <<
"!!!\"SegmentationEvaluationMetrics\" has been enabled by default!!!" << std::endl;
173 m_bSegmentationEvaluation =
true;
176 if (m_fDetectionLesionMinVolume<0)
178 std::cout <<
"!!!!! Error on DetectionLesionMinVolume!!!!!" << std::endl;
182 if (m_fTPLMinOverlapRatio<=0 || m_fTPLMinOverlapRatio>1)
184 std::cout <<
"!!!!! Error on TPLMinOverlapRatio!!!!!" << std::endl;
188 if (m_fTPLMaxFalsePositiveRatio<=0 || m_fTPLMaxFalsePositiveRatio>1)
190 std::cout <<
"!!!!! Error on TPLMaxFalsePositiveRatio!!!!!" << std::endl;
194 if (m_fTPLMaxFalsePositiveRatioModerator<=0 || m_fTPLMaxFalsePositiveRatioModerator>1)
196 std::cout <<
"!!!!! Error on TPLMaxFalsePositiveRatioModerator!!!!!" << std::endl;
202 std::cout <<
"*** 0 < DetectionLesionMinVolume ***" << std::endl;
203 std::cout <<
"*** 0 < TPLMinOverlapRatio <= 1 ***" << std::endl;
204 std::cout <<
"*** 0 < TPLMaxFalsePositiveRatio <= 1 ***" << std::endl;
205 std::cout <<
"*** 0 < TPLMaxFalsePositiveRatioModerator <= 1 ***" << std::endl;
217 if (!(m_bTxt || m_bXml || m_bScreen))
228 if (m_oStrBaseOut.empty())
230 int iDotPos = m_oStrInImage.rfind(
'.');
232 int iSlashPos = m_oStrInImage.rfind(
'/');
233 int iBkSlashPos = m_oStrInImage.rfind(
'\\');
235 if (iSlashPos != std::string::npos && iBkSlashPos != std::string::npos)
237 iFolderPos = iSlashPos>iBkSlashPos ? iSlashPos : iBkSlashPos;
239 else if (iSlashPos != std::string::npos)
241 iFolderPos = iSlashPos;
243 else if (iBkSlashPos != std::string::npos)
245 iFolderPos = iBkSlashPos;
251 m_pchOutBase.append(m_oStrInImage.begin() + iFolderPos, m_oStrInImage.end());
253 if(iDotPos != std::string::npos)
254 m_pchOutBase[iDotPos-iFolderPos] = 0;
257 m_pchOutBase = m_oStrBaseOut;
270 throw itk::ExceptionObject(__FILE__, __LINE__,
"Orientation matrices and volumes do not match");
277 std::string sOutBase = m_pchOutBase;
278 std::string sOut = sOutBase;
287 std::stringstream outBaseTemp;
290 outBaseTemp << sOut <<
"_global";
292 outBaseTemp << sOut <<
"_cluster" << i;
294 sOut = outBaseTemp.str();
303 }
while (i < nbLabels && m_bAdvancedEvaluation);
317 if(m_bSegmentationEvaluation || m_bSurfaceEvaluation)
322 m_fPPV = pi_roAnalyzer.
getPPV();
323 m_fNPV = pi_roAnalyzer.
getNPV();
329 if(m_bSurfaceEvaluation)
338 if(m_bLesionsDetectionEvaluation)
364 if(m_bSegmentationEvaluation)
379 pi_roRes.
setRVE(m_fRVE*100);
383 if(m_bSurfaceEvaluation)
394 if(m_bLesionsDetectionEvaluation)
412 long lRes = (long) !pi_roRes.
save();
421 std::cout << std::endl;
422 std::cout <<
"********************************************************************************" << std::endl;
423 std::cout <<
"********************************************************************************" << std::endl;
424 std::cout <<
"SegPerfAnalyser (Segmentation Performance Analyzer) provides different" << std::endl;
425 std::cout <<
"marks, metrics and scores for segmentation evaluation." << std::endl;
426 std::cout << std::endl;
427 std::cout <<
"3 categories are available:" << std::endl;
428 std::cout <<
" - SEGMENTATION EVALUATION:" << std::endl;
429 std::cout <<
" Dice, the mean overlap" << std::endl;
430 std::cout <<
" Jaccard, the union overlap" << std::endl;
431 std::cout <<
" Sensitivity" << std::endl;
432 std::cout <<
" Specificity" << std::endl;
433 std::cout <<
" NPV (Negative Predictive Value)" << std::endl;
434 std::cout <<
" PPV (Positive Predictive Value)" << std::endl;
435 std::cout <<
" RVE (Relative Volume Error) in percentage" << std::endl;
436 std::cout <<
" - SURFACE DISTANCE EVALUATION:" << std::endl;
437 std::cout <<
" Hausdorff distance" << std::endl;
438 std::cout <<
" Contour mean distance" << std::endl;
439 std::cout <<
" Average surface distance" << std::endl;
440 std::cout <<
" - DETECTION LESIONS EVALUATION:" << std::endl;
441 std::cout <<
" PPVL (Positive Predictive Value for Lesions)" << std::endl;
442 std::cout <<
" SensL, Lesion detection sensitivity" << std::endl;
443 std::cout <<
" F1 Score, a F1 Score between PPVL and SensL" << std::endl;
444 std::cout << std::endl;
447 std::cout <<
"Results are provided as follows: " << std::endl;
450 std::cout << ppchNameTab[i]<<
";\t";
452 std::cout << std::endl;
453 std::cout <<
"********************************************************************************" << std::endl;
454 std::cout <<
"********************************************************************************" << std::endl;
double getPPV()
Getter of Positive predictive value.
double getDiceCoefficient()
Getter of Dice coefficient.
bool init(int argc, char *argv[])
This method set the application behavior thanks to command line arguments parsing.
void setScreen(bool pi_bEnable=true)
Enable or disable on screen results.
void setAverageSurfaceDist(double pi_fVal)
Set the result value of average surface distance measure.
double computeAverageSurfaceDistance()
Compute average surface distance.
void setDetectionThresholdBeta(double pi_fVal)
static void about()
This method display information about SegPerfAnalyzer results.
void setSensL(double pi_fVal)
Set the result value of SensL measure.
double getJaccardCoefficient()
Getter of Jaccard coefficient.
bool checkParamsCoherence()
This method check if command line arguments are coherent between us.
void setF1test(double pi_fVal)
Set the result value of F1 score of F-test.
bool save()
It saves results on text file or xml file in function of class default settings.
void computeITKMeasures()
Compute different measures with ITK to evaluate segmentation.
double computeMeanDist()
Compute mean distance.
double getNPV()
Getter of Negative predictive value.
void play()
This method execute images filter to obtain desired measures, marks and scores.
void selectCluster(unsigned int)
Select the cluster we want to use to compute evaluation results.
static char const *const *const getMeasureNameTable()
Get the list of all Measures available.
bool checkImagesMatrixAndVolumes()
Check if the 2 inputs images are compatible.
void setDice(double pi_fVal)
Set the result value of Dice measure.
void setRVE(double pi_fVal)
Set the result value of Relative volume error.
long writeStoredMetricsAndMarks(SegPerfResults &pi_roRes)
This method flush SegPerfResults class instance.
int getNumberOfClusters()
Return the number of clusters.
double getRelativeVolumeError()
Getter of Relative volume error.
void setSensibility(double pi_fVal)
Set the result value of Sensibility measure.
void setNbThreads(int pi_iNbThreads)
Set the number of threads to use for the computation of ITK.
void processAnalyze(SegPerfCAnalyzer &pi_oAnalyzer, int pi_iIndex)
This method provides computing metrics, marks and scores for desired label.
bool getDetectionMarks(double &po_fPPVL, double &po_fSensL, double &po_fF1)
Compute useful variables to get detection scores.
void setXml(bool pi_bEnable=true)
Enable or disable XML file results.
void storeMetricsAndMarks(SegPerfResults &pi_roRes)
This method store results into SegPerfResults class instance.
Class to compute various metrics to evaluate segmentation results.
void checkOutputCoherence()
This method define an output way if none are defined by command line.
void setDetectionThresholdAlpha(double pi_fVal)
double getSensitivity()
Getter of Sensibility.
void setJaccard(double pi_fVal)
Set the result value of Jaccard measure.
double getSpecificity()
Getter of Specificity.
void setMinLesionVolumeDetection(double pi_fVal)
void setPPVL(double pi_fVal)
Set the result value of PPVL measure.
double computeHausdorffDist()
Compute Haussdorf distance.
void setNPV(double pi_fVal)
Set the result value of NPV (Negative Predictive Value) measure.
void setHausdorffDist(double pi_fVal)
Set the result value of DistHausdorff measure.
void setContourMeanDist(double pi_fVal)
Set the result value of contour mean distance measure.
void prepareOutput()
This method define the base file name for output way.
Class to format and saves results.
bool activeMeasurementOutput(eMesureName pi_eVal)
It active the saving of one specific measure. If it set twice time the effect is inverted.
void setSpecificity(double pi_fVal)
Set the result value of Specificity measure.
void setPPV(double pi_fVal)
Set the result value of PPV (Positive Predictive Value) measure.
void setDetectionThresholdGamma(double pi_fVal)
void setTxt(bool pi_bEnable=true)
Enable or disable text file results.