7 #include <itkConnectedComponentImageFilter.h> 8 #include <itkRelabelComponentImageFilter.h> 9 #include <itkImageIterator.h> 10 #include <itkMultiThreaderBase.h> 11 #include <itkImageDuplicator.h> 23 SegPerfCAnalyzer::SegPerfCAnalyzer(std::string &pi_pchImageTestName, std::string &pi_pchImageRefName,
bool bAdvancedEvaluation)
25 m_ThreadNb = itk::MultiThreaderBase::GetGlobalDefaultNumberOfThreads();
27 m_dfDetectionThresholdAlpha = 0.05;
28 m_dfDetectionThresholdBeta = 0.50;
29 m_dfDetectionThresholdGamma = 0.50;
30 m_dfMinLesionVolumeDetection = 3.0;
34 ImageReaderType::Pointer imageTestReader = ImageReaderType::New();
35 imageTestReader->SetFileName(pi_pchImageTestName);
39 imageTestReader->Update();
42 catch (itk::ExceptionObject& e)
44 std::cerr <<
"exception in file reader " << std::endl;
45 std::cerr << e << std::endl;
49 m_imageTest = imageTestReader->GetOutput();
51 ImageReaderType::Pointer imageRefReader = ImageReaderType::New();
52 imageRefReader->SetFileName(pi_pchImageRefName);
56 imageRefReader->Update();
59 catch (itk::ExceptionObject& e)
61 std::cerr <<
"exception in file reader " << std::endl;
62 std::cerr << e << std::endl;
66 m_imageRef = imageRefReader->GetOutput();
69 throw std::runtime_error(
"Images are incompatible");
73 if(bAdvancedEvaluation && m_uiNbLabels > 2)
76 typedef itk::ImageDuplicator< ImageType > DuplicatorType;
77 DuplicatorType::Pointer duplicator = DuplicatorType::New();
78 duplicator->SetInputImage(m_imageRef);
80 m_imageRefDuplicated = ImageType::New();
81 m_imageRefDuplicated = duplicator->GetOutput();
83 duplicator->SetInputImage(m_imageTest);
85 m_imageTestDuplicated = ImageType::New();
86 m_imageTestDuplicated = duplicator->GetOutput();
89 m_bValuesComputed =
false;
90 m_bContourDetected =
false;
101 unsigned int uiTestedImageDimension = m_imageTest->GetImageDimension();
102 const itk::Vector<ImageType::SpacingValueType, ImageType::ImageDimension> oVectSpacingTested = m_imageTest->GetSpacing();
103 const itk::Size<ImageType::ImageDimension> oSizeTested = m_imageTest->GetLargestPossibleRegion().GetSize();
104 const itk::Point<ImageType::IndexValueType, ImageType::ImageDimension> oPointOriginTested = m_imageTest->GetOrigin();
106 unsigned int uiRefImageDimension = m_imageRef->GetImageDimension();
107 const itk::Vector<ImageType::SpacingValueType, ImageType::ImageDimension> oVectSpacingRef = m_imageRef->GetSpacing();
108 const itk::Size<ImageType::ImageDimension> oSizeRef = m_imageRef->GetLargestPossibleRegion().GetSize();
109 const itk::Point<ImageType::IndexValueType, ImageType::ImageDimension> oPointOriginRef = m_imageRef->GetOrigin();
111 bRes = uiTestedImageDimension == uiRefImageDimension;
116 for (
int i = 0; i < uiTestedImageDimension; ++i)
118 if (oSizeTested[i] != oSizeRef[i])
121 std::cerr <<
"Different image dimensions " << i <<
" Tested size : " << oSizeTested[i] <<
" Reference size : " << oSizeRef[i] << std::endl;
126 for (
int i = 0; i < uiTestedImageDimension; ++i)
128 if (oPointOriginTested[i] != oPointOriginRef[i])
131 std::cerr <<
"Different image origin " << i <<
" Tested origin : " << oPointOriginTested[i] <<
" Reference origin : " << oPointOriginRef[i] << std::endl;
136 for (
int i = 0; i < uiTestedImageDimension; ++i)
138 for (
int j = 0; j < uiTestedImageDimension; ++j)
140 double dDiff = m_imageTest->GetDirection().GetVnlMatrix().get(i, j) - m_imageRef->GetDirection().GetVnlMatrix().get(i, j);
143 if ((dDiff > 0.000001) || (dDiff < -0.000001))
146 std::cerr <<
"Different image direction " << i <<
" - " << j << std::endl;
147 std::cerr <<
"Diff = " << dDiff <<
" Tested direction : " << m_imageTest->GetDirection().GetVnlMatrix().get(i, j) <<
" Reference direction : " << m_imageRef->GetDirection().GetVnlMatrix().get(i, j) << std::endl;
154 std::cerr <<
"Different image dimensions." << std::endl <<
"Tested is in : " << uiTestedImageDimension <<
"D and Ref is in :" << uiRefImageDimension <<
"D" << std::endl;
170 return this->m_uiNbLabels;
182 typedef itk::ImageDuplicator< ImageType > DuplicatorType;
183 DuplicatorType::Pointer duplicator = DuplicatorType::New();
184 duplicator->SetInputImage(m_imageRefDuplicated);
185 duplicator->Update();
186 m_imageRef = duplicator->GetOutput();
188 duplicator->SetInputImage(m_imageTestDuplicated);
189 duplicator->Update();
190 m_imageTest = duplicator->GetOutput();
192 unsigned int dimX = m_imageRef->GetLargestPossibleRegion().GetSize()[0];
193 unsigned int dimY = m_imageRef->GetLargestPossibleRegion().GetSize()[1];
194 unsigned int dimZ = m_imageRef->GetLargestPossibleRegion().GetSize()[2];
196 ImageType::IndexType index;
198 for(
int z=0; z<dimZ; z++)
200 for(
int y=0; y<dimY; y++)
202 for(
int x=0; x<dimX; x++)
208 int valueRef = m_imageRef->GetPixel(index);
209 int valueTest = m_imageTest->GetPixel(index);
211 if(valueRef != iCluster)
212 m_imageRef->SetPixel(index, 0);
214 m_imageRef->SetPixel(index, 1);
216 if(valueTest != iCluster)
217 m_imageTest->SetPixel(index, 0);
219 m_imageTest->SetPixel(index, 1);
223 this->m_uiNbLabels = 2;
236 if(this->m_uiNbLabels == 2)
238 typedef itk::BinaryContourImageFilter< ImageType, ImageType >
FilterType;
240 filter->SetInput( m_imageTest );
241 filter->SetFullyConnected( 0 );
242 filter->SetForegroundValue( 1 );
243 filter->SetBackgroundValue( 0 );
247 m_imageTestContour = ImageType::New();
248 m_imageTestContour = filter->GetOutput();
251 filter2->SetInput( m_imageRef );
252 filter2->SetFullyConnected( 0 );
253 filter2->SetForegroundValue( 1 );
254 filter2->SetBackgroundValue( 0 );
257 m_imageRefContour = ImageType::New();
258 m_imageRefContour = filter2->GetOutput();
263 typedef itk::LabelContourImageFilter< ImageType, ImageType >
FilterType;
265 filter->SetInput( m_imageTest );
266 filter->SetFullyConnected( 0 );
267 filter->SetBackgroundValue( 0 );
270 m_imageTestContour = ImageType::New();
271 m_imageTestContour = filter->GetOutput();
274 filter2->SetInput( m_imageRef );
275 filter2->SetFullyConnected( 0 );
276 filter2->SetBackgroundValue( 0 );
279 m_imageRefContour = ImageType::New();
280 m_imageRefContour = filter2->GetOutput();
282 m_bContourDetected =
true;
292 m_oFilter->SetNumberOfWorkUnits(m_ThreadNb);
293 m_oFilter->SetSourceImage( m_imageTest);
294 m_oFilter->SetTargetImage( m_imageRef );
300 catch( itk::ExceptionObject& excp )
302 std::cerr << excp << std::endl;
313 return m_oFilter->getUnionOverlap();
322 return m_oFilter->getMeanOverlap();
331 return m_oFilter->getSensitivity();
340 return m_oFilter->getSpecificity();
349 return m_oFilter->getPPV();
358 return m_oFilter->getNPV();
367 return m_oFilter->GetDiceCoefficient();
376 return m_oFilter->GetJaccardCoefficient();
385 return m_oFilter->getRelativeVolumeError();
393 if(iNbLabelsImageTest<=1)
396 std::cerr <<
"ERROR : Number of labels in input image is 0 !" << std::endl;
400 if(iNbLabelsImageRef<=1)
403 std::cerr <<
"ERROR : Number of labels in ground truth is 0 !"<< std::endl;
407 if (iNbLabelsImageTest == iNbLabelsImageRef)
409 m_uiNbLabels = iNbLabelsImageTest;
413 if(iNbLabelsImageTest > 2)
416 unsigned int dimX = m_imageTest->GetLargestPossibleRegion().GetSize()[0];
417 unsigned int dimY = m_imageTest->GetLargestPossibleRegion().GetSize()[1];
418 unsigned int dimZ = m_imageTest->GetLargestPossibleRegion().GetSize()[2];
420 ImageType::IndexType index;
422 for(
int z=0; z<dimZ; z++)
424 for(
int y=0; y<dimY; y++)
426 for(
int x=0; x<dimX; x++)
432 if( m_imageTest->GetPixel(index) != 0 )
433 m_imageTest->SetPixel(index, 1);
439 std::cout <<
"WARNING : Segmented image have not the same number of labels as ground truth, it have been binarized for segmentation evaluation" << std::endl;
442 if(iNbLabelsImageRef > 2)
446 unsigned int dimX = m_imageRef->GetLargestPossibleRegion().GetSize()[0];
447 unsigned int dimY = m_imageRef->GetLargestPossibleRegion().GetSize()[1];
448 unsigned int dimZ = m_imageRef->GetLargestPossibleRegion().GetSize()[2];
450 ImageType::IndexType index;
452 for(
int z=0; z<dimZ; z++)
454 for(
int y=0; y<dimY; y++)
456 for(
int x=0; x<dimX; x++)
462 if( m_imageRef->GetPixel(index) != 0 )
463 m_imageRef->SetPixel(index, 1);
469 std::cout <<
"WARNING : Ground truth have not the same number of labels as segmented image, both images have been binarized for segmentation evaluation" << std::endl;
479 ImageIteratorType refIt (m_imageTest, m_imageTest->GetLargestPossibleRegion());
481 std::vector <unsigned int> usefulLabels;
483 while (!refIt.IsAtEnd())
485 bool isAlreadyIn =
false;
486 for (
unsigned int i = 0; i < usefulLabels.size(); ++i)
488 if (refIt.Get() == usefulLabels[i])
497 usefulLabels.push_back(refIt.Get());
503 std::sort(usefulLabels.begin(), usefulLabels.end());
505 unsigned int dimX = m_imageTest->GetLargestPossibleRegion().GetSize()[0];
506 unsigned int dimY = m_imageTest->GetLargestPossibleRegion().GetSize()[1];
507 unsigned int dimZ = m_imageTest->GetLargestPossibleRegion().GetSize()[2];
509 ImageType::IndexType index;
511 for(
int z=0; z<dimZ; z++)
513 for(
int y=0; y<dimY; y++)
515 for(
int x=0; x<dimX; x++)
521 int indexvalue = std::find(usefulLabels.begin(), usefulLabels.end(), m_imageTest->GetPixel(index))-usefulLabels.begin();
522 m_imageTest->SetPixel(index, indexvalue);
530 ImageIteratorType refItRef(m_imageRef, m_imageRef->GetLargestPossibleRegion());
532 std::vector <unsigned int> usefulLabels2;
534 while (!refItRef.IsAtEnd())
536 bool isAlreadyIn =
false;
537 for (
unsigned int i = 0; i < usefulLabels2.size(); ++i)
539 if (refItRef.Get() == usefulLabels2[i])
547 usefulLabels2.push_back(refItRef.Get());
553 std::sort(usefulLabels2.begin(), usefulLabels2.end());
557 dimX = m_imageRef->GetLargestPossibleRegion().GetSize()[0];
558 dimY = m_imageRef->GetLargestPossibleRegion().GetSize()[1];
559 dimZ = m_imageRef->GetLargestPossibleRegion().GetSize()[2];
562 for(
int z=0; z<dimZ; z++)
564 for(
int y=0; y<dimY; y++)
566 for(
int x=0; x<dimX; x++)
572 int indexvalue = std::find(usefulLabels2.begin(), usefulLabels2.end(), m_imageRef->GetPixel(index))-usefulLabels2.begin();
573 m_imageRef->SetPixel(index, indexvalue);
578 int iNbOfLabelsImageTest = usefulLabels.size();
579 int iNbOfLabelsImageRef = usefulLabels2.size();
597 typedef itk::HausdorffDistanceImageFilter<ImageType, ImageType>
FilterType;
600 filter->SetInput1(m_imageTest);
601 filter->SetInput2(m_imageRef);
607 catch (itk::ExceptionObject& e)
609 std::cerr <<
"exception in filter " << std::endl;
610 std::cerr << e << std::endl;
614 hausdorffDistance = filter->GetHausdorffDistance();
617 return hausdorffDistance;
628 if (m_uiNbLabels > 1)
630 if (!this->m_bContourDetected)
634 typedef itk::ContourMeanDistanceImageFilter<ImageType, ImageType>
FilterType;
637 filter->SetInput1(m_imageTestContour);
638 filter->SetInput2(m_imageRefContour);
645 catch (itk::ExceptionObject& e)
647 std::cerr <<
"exception in filter " << std::endl;
648 std::cerr << e << std::endl;
652 meanDistance = filter->GetMeanDistance();
664 double meanDistance = std::numeric_limits<double>::quiet_NaN();
666 if (m_uiNbLabels > 1)
668 if (!this->m_bContourDetected)
674 for (
int i = 1; i < m_uiNbLabels; i++)
676 std::vector <ImageType::PointType> coordRef;
678 ImageIteratorType refContourIt(m_imageRefContour, m_imageRefContour->GetLargestPossibleRegion());
680 while (!refContourIt.IsAtEnd())
682 if (refContourIt.Get() == i)
684 ImageType::IndexType oIndex = refContourIt.GetIndex();
685 ImageType::PointType oPoint;
686 m_imageRefContour->TransformIndexToPhysicalPoint(oIndex, oPoint);
687 coordRef.push_back(oPoint);
692 std::vector <ImageType::PointType> coordTest;
695 ImageIteratorType testContourIt(m_imageTestContour, m_imageTestContour->GetLargestPossibleRegion());
697 while (!testContourIt.IsAtEnd())
699 if (testContourIt.Get() == i)
701 ImageType::IndexType oIndex = testContourIt.GetIndex();
702 ImageType::PointType oPoint;
703 m_imageTestContour->TransformIndexToPhysicalPoint(oIndex, oPoint);
704 coordTest.push_back(oPoint);
709 std::vector <double> distance1, distance2;
710 double fDistanceTemp1 = 1000000, fDistanceTemp2 = 1000000;
711 double distanceValue = 0;
712 for (
int m = 0; m < coordRef.size(); m++)
714 for (
int n = 0; n < coordTest.size(); n++)
716 distanceValue = sqrt(pow((
double)(coordRef[m][0] - coordTest[n][0]), 2) + pow((
double)(coordRef[m][1] - coordTest[n][1]), 2) + pow((
double)(coordRef[m][2] - coordTest[n][2]), 2));
717 if (distanceValue < fDistanceTemp1)
718 fDistanceTemp1 = distanceValue;
721 distance1.push_back(fDistanceTemp1);
724 for (
int m = 0; m < coordTest.size(); m++)
726 for (
int n = 0; n < coordRef.size(); n++)
728 distanceValue = sqrt(pow((
double)(coordTest[m][0] - coordRef[n][0]), 2) + pow((
double)(coordTest[m][1] - coordRef[n][1]), 2) + pow((
double)(coordTest[m][2] - coordRef[n][2]), 2));
730 if (distanceValue < fDistanceTemp2)
731 fDistanceTemp2 = distanceValue;
734 distance2.push_back(fDistanceTemp2);
737 sum_dist = sum_dist + (double)accumulate(distance1.begin(), distance1.end(), 0.0) + (double)accumulate(distance2.begin(), distance2.end(), 0.0);
738 sum_size = sum_size + (double)distance1.size() + (double)distance2.size();
741 meanDistance = sum_dist / sum_size;
759 int iNbLabelsRef = 0;
760 int iNbLabelsTest = 0;
761 int * *ppiOverlapTab = NULL;
762 int * *ppiOverlapTabTransposed = NULL;
767 transposer(iNbLabelsRef, iNbLabelsTest, ppiOverlapTab, ppiOverlapTabTransposed);
768 if (iNbLabelsRef>1 && iNbLabelsTest>1)
774 removeOverlapTab(ppiOverlapTab, iNbLabelsRef);
775 removeOverlapTab(ppiOverlapTabTransposed, iNbLabelsTest);
778 po_fPPVL = (double)((
double)iTPLd / (double)(iNbLabelsTest-1));
779 po_fSensL = (double)((
double)iTPLgt / (double)(iNbLabelsRef-1));
781 po_fF1 = 2 * (po_fPPVL * po_fSensL) / (po_fPPVL + po_fSensL);
792 m_ThreadNb =
static_cast<itk::ThreadIdType
>(pi_iNbThreads);
803 typedef itk::ImageRegionConstIterator<ImageType> imageConstIteratorType;
804 typedef itk::ConnectedComponentImageFilter<ImageType, ImageType> connectedComponentImageFilterType;
805 typedef itk::RelabelComponentImageFilter<ImageType, ImageType> relabelComponentImageFilterType;
806 typedef itk::ImageDuplicator<ImageType> imageDuplicatorFilterType;
809 connectedComponentImageFilterType::Pointer poLesionSeparatorFilter = connectedComponentImageFilterType::New();
810 ImageType::Pointer poImageRefLesionsByLabels = ITK_NULLPTR;
811 ImageType::Pointer poImageTestLesionsByLabels = ITK_NULLPTR;
812 relabelComponentImageFilterType::Pointer poRelabelFilter = relabelComponentImageFilterType::New();
813 int&iNbLabelsRef = po_iNbLabelsRef;
814 int&iNbLabelsTest = po_iNbLabelsTest;
815 int* *&ppiOverlapTab = po_ppiOverlapTab;
821 poLesionSeparatorFilter->SetNumberOfWorkUnits(m_ThreadNb);
824 poLesionSeparatorFilter->SetInput(m_imageRef);
827 poLesionSeparatorFilter->Update();
830 ImageType::SpacingType spacing = m_imageRef->GetSpacing();
831 ImageType::SpacingValueType spacingTot = spacing[0];
832 unsigned int imageDim = ImageType::ImageDimension;
833 for (
unsigned int i = 1; i < std::min(imageDim, (
unsigned int)3); ++i)
834 spacingTot *= spacing[i];
837 double minSizeInVoxelD = m_dfMinLesionVolumeDetection / spacingTot;
838 double minSizeInVoxelD_floor = floor(minSizeInVoxelD);
839 unsigned int minSizeInVoxel =
static_cast<unsigned int>(minSizeInVoxelD_floor);
842 poRelabelFilter->SetInput( poLesionSeparatorFilter->GetOutput() );
843 poRelabelFilter->SetMinimumObjectSize(minSizeInVoxel);
844 poRelabelFilter->SetNumberOfWorkUnits(m_ThreadNb);
845 poRelabelFilter->Update();
847 iNbLabelsRef += poRelabelFilter->GetNumberOfObjects();
849 imageDuplicatorFilterType::Pointer poDuplicatorFilter = imageDuplicatorFilterType::New();
850 poDuplicatorFilter->SetInputImage(poRelabelFilter->GetOutput());
851 poDuplicatorFilter->Update();
852 poImageRefLesionsByLabels = poDuplicatorFilter->GetOutput();
855 poLesionSeparatorFilter->SetInput(m_imageTest);
856 poLesionSeparatorFilter->Update();
858 poRelabelFilter->SetInput( poLesionSeparatorFilter->GetOutput() );
859 poRelabelFilter->SetMinimumObjectSize(minSizeInVoxel);
860 poRelabelFilter->SetNumberOfWorkUnits(m_ThreadNb);
861 poRelabelFilter->Update();
863 iNbLabelsTest += poRelabelFilter->GetNumberOfObjects();
864 poImageTestLesionsByLabels = poRelabelFilter->GetOutput();
867 ppiOverlapTab =
new int*[iNbLabelsRef];
868 for(
int i=0; i<iNbLabelsRef; ++i)
870 ppiOverlapTab[i] =
new int[iNbLabelsTest];
871 memset(ppiOverlapTab[i], 0, iNbLabelsTest*
sizeof(
int));
875 imageConstIteratorType itRefLabels = imageConstIteratorType(poImageRefLesionsByLabels, poImageRefLesionsByLabels->GetLargestPossibleRegion());
876 imageConstIteratorType itTestLabels = imageConstIteratorType(poImageTestLesionsByLabels, poImageTestLesionsByLabels->GetLargestPossibleRegion());
878 while(!itRefLabels.IsAtEnd())
880 ImageType::PixelType voxelRefVal = itRefLabels.Value();
881 ImageType::PixelType voxelTestVal = itTestLabels.Value();
883 ppiOverlapTab[voxelRefVal][voxelTestVal]++;
898 int iNbLesionsDetected = 0;
900 double dfSensibility = 0;
901 int *piTPRowSumTab =
new int[pi_iNbLabelsRef];
902 int *piColumnSumTab =
new int[pi_iNbLabelsTest];
905 memset(piTPRowSumTab, 0, pi_iNbLabelsRef*
sizeof(
int));
906 memset(piColumnSumTab, 0, pi_iNbLabelsTest*
sizeof(
int));
907 for (
int i=0; i<pi_iNbLabelsRef; ++i)
909 for(
int j=0; j<pi_iNbLabelsTest; ++j)
911 piColumnSumTab[j]+=pi_ppiOverlapTab[i][j];
915 piTPRowSumTab[i] += pi_ppiOverlapTab[i][j];
921 for(
int i=1; i<pi_iNbLabelsRef; ++i)
923 int&iTP = piTPRowSumTab[i];
924 int&iFN = pi_ppiOverlapTab[i][0];
927 dfSensibility = ((double)iTP) / ((double)( iTP + iFN ));
930 if (dfSensibility>m_dfDetectionThresholdAlpha)
933 if(
falsePositiveRatioTester(i, pi_iNbLabelsTest, pi_iNbLabelsRef, pi_ppiOverlapTab, piTPRowSumTab, piColumnSumTab, m_dfDetectionThresholdBeta, m_dfDetectionThresholdGamma))
935 iNbLesionsDetected++;
940 return iNbLesionsDetected;
946 bool operator() (
const std::pair<int, int>&f,
const std::pair<int, int>&s)
948 return (f.second > s.second);
965 bool SegPerfCAnalyzer::falsePositiveRatioTester(
int pi_iLesionReference,
int pi_iNbLabelsTest,
int pi_iNbLabelsRef,
int * *pi_ppiOverlapTab,
int *pi_piTPRowSumTab,
int *pi_piColumnSumTab,
double pi_dfBeta,
double pi_dfGamma)
973 int &iSumOfTPForCurentRow = pi_piTPRowSumTab[pi_iLesionReference];
974 double dfSumWeight = 0.0;
975 double dfRatioOutsideInside = 0.0;
976 std::vector<std::pair<int, int> > oSortedCollumVector;
980 for(
int l=1; l<pi_iNbLabelsTest; ++l)
982 int iTmpValOfTP = pi_ppiOverlapTab[pi_iLesionReference][l];
983 oSortedCollumVector.push_back( std::pair<int, int>(l, iTmpValOfTP) );
989 while(dfSumWeight<pi_dfGamma && k<pi_iNbLabelsRef && !bExit)
991 dfRatioOutsideInside = (double)(pi_ppiOverlapTab[0][oSortedCollumVector[k].first])/(double)(pi_piColumnSumTab[oSortedCollumVector[k].first]);
992 bExit = dfRatioOutsideInside>pi_dfBeta;
995 dfSumWeight += (double)(oSortedCollumVector[k].second)/(double)(iSumOfTPForCurentRow);
1014 void SegPerfCAnalyzer::transposer(
int pi_iNbLabelsRef,
int pi_iNbLabelsTest,
int * *pi_ppiOverlapTab,
int* *&po_rppiOverlapTabTransposed)
1016 po_rppiOverlapTabTransposed =
new int*[pi_iNbLabelsTest+1];
1017 for(
int i=0; i<pi_iNbLabelsTest; ++i)
1019 po_rppiOverlapTabTransposed[i] =
new int[pi_iNbLabelsRef+1];
1022 for(
int i=0; i<pi_iNbLabelsRef; ++i)
1024 for(
int j=0; j<pi_iNbLabelsTest; ++j)
1026 po_rppiOverlapTabTransposed[j][i] = pi_ppiOverlapTab[i][j];
1036 void SegPerfCAnalyzer::removeOverlapTab(
int * *pi_ppiOverlapTab,
int pi_iNbLabelsRef)
1038 if (pi_ppiOverlapTab)
1040 for(
int i=0; i<pi_iNbLabelsRef; ++i)
1042 delete[] (pi_ppiOverlapTab[i]);
1044 delete[] (pi_ppiOverlapTab);
double getPPV()
Getter of Positive predictive value.
double getDiceCoefficient()
Getter of Dice coefficient.
double computeAverageSurfaceDistance()
Compute average surface distance.
bool falsePositiveRatioTester(int pi_iLessionReference, int pi_iNbLabelsTest, int pi_iNbLabelsRef, int **pi_ppiOverlapTab, int *pi_piTPRowSumTab, int *pi_piColumnSumTab, double pi_dfBeta, double pi_dfGamma)
Compute if a lesion is detected or not with beta and gamma thresholds.
struct @0 pair_decreasing_comparator
double getJaccardCoefficient()
Getter of Jaccard coefficient.
void computeITKMeasures()
Compute different measures with ITK to evaluate segmentation.
double computeMeanDist()
Compute mean distance.
itk::SmartPointer< Self > Pointer
double getNPV()
Getter of Negative predictive value.
void selectCluster(unsigned int)
Select the cluster we want to use to compute evaluation results.
double getMeanOverlap()
Getter of Mean overlap.
bool checkImagesMatrixAndVolumes()
Check if the 2 inputs images are compatible.
void contourDectection()
Extract the contour of the image to evaluate and the ground truth.
void getOverlapTab(int &po_iNbLabelsRef, int &po_iNbLabelsTest, int **&po_ppiOverlapTab)
Compute a table of lesion overlap between 2 images.
int getNumberOfClusters()
Return the number of clusters.
void formatLabels()
Format labels values for the image to evaluate and the ground truth to obtain : background pixels val...
double getRelativeVolumeError()
Getter of Relative volume error.
void setNbThreads(int pi_iNbThreads)
Set the number of threads to use for the computation of ITK.
bool getDetectionMarks(double &po_fPPVL, double &po_fSensL, double &po_fF1)
Compute useful variables to get detection scores.
double getSensitivity()
Getter of Sensibility.
int getTruePositiveLesions(int pi_iNbLabelsRef, int pi_iNbLabelsTest, int **pi_ppiOverlapTab)
Getter of True positive lesions.
double getSpecificity()
Getter of Specificity.
itk::NumericTraits< LabelType >::RealType RealType
double getUnionOverlap()
Getter of Union overlap.
double computeHausdorffDist()
Compute Haussdorf distance.
void checkNumberOfLabels(int, int)
Check if the number of labels is the same for both input images.