9 #include <itkShapedNeighborhoodIterator.h>
10 #include <itkSignedDanielssonDistanceMapImageFilter.h>
14 : m_GroundTruthValueToIndexMapper(NULL)
15 , m_TestValueToIndexMapper(NULL)
22 m_GroundTruthValueToIndexMapper = NULL;
23 m_TestValueToIndexMapper = NULL;
29 m_Collection = collection;
49 m_GroundTruthName = name;
54 return m_GroundTruthName;
69 m_GroundTruthValueToIndexMapper = mapper;
74 return m_GroundTruthValueToIndexMapper;
79 m_TestValueToIndexMapper = mapper;
84 return m_TestValueToIndexMapper;
90 for (
int i = 0; i < m_ConnectionGold.size(); ++i)
92 if (m_ConnectionGold[i] == gold && m_ConnectionTest[i] == test)
94 resultClass = m_ConnectionClass[i];
103 if (m_GroundTruthValueToIndexMapper == NULL)
105 MITK_ERROR <<
"m_GroundTruthValueToIndexMapper is NULL";
109 if (m_TestValueToIndexMapper == NULL)
111 MITK_ERROR <<
"m_TestValueToIndexMapper is NULL";
115 typedef itk::Image<unsigned char, 3>
ImageType;
125 if (m_ImageClassStatistic.size() <= imageIndex)
130 m_ImageStatistic.push_back(statData);
132 for (
int i = 0; i < m_ClassCount; ++i)
135 data.push_back(stat);
137 m_ImageClassStatistic.push_back(data);
149 unsigned char goldClass = m_GroundTruthValueToIndexMapper->operator()(goldIter.
GetVoxel());
150 unsigned char testClass = m_TestValueToIndexMapper->operator()(testIter.
GetVoxel());
151 if (goldClass == testClass)
153 m_ImageStatistic[imageIndex].m_TruePositive += 1;
154 for (
int i = 0; i < m_ClassCount; ++i)
158 m_ImageClassStatistic[imageIndex][i].m_TruePositive += 1;
161 m_ImageClassStatistic[imageIndex][i].m_TrueNegative += 1;
166 m_ImageStatistic[imageIndex].m_FalseNegative += 1;
167 m_ImageStatistic[imageIndex].m_FalsePositive += 1;
168 for (
int i = 0; i < m_ClassCount; ++i)
172 m_ImageClassStatistic[imageIndex][i].m_FalseNegative += 1;
173 }
else if ( testClass == i)
175 m_ImageClassStatistic[imageIndex][i].m_FalsePositive += 1;
178 m_ImageClassStatistic[imageIndex][i].m_TrueNegative += 1;
187 MITK_INFO <<
"Evaluated " << index <<
" points";
193 assert(m_ImageClassStatistic.size() > 0);
194 assert(m_ImageClassStatistic[0].size() == m_ClassCount);
198 sout <<
"Label;ImageName;";
199 for (
int i = 0; i < m_ClassCount; ++i)
201 sout <<
"DICE-Class-"<< i <<
";";
202 sout <<
"Jaccard-Class-"<< i <<
";";
203 sout <<
"Sensitivity-Class-"<< i <<
";";
204 sout <<
"Specificity-Class-"<< i <<
";";
205 sout <<
"TP-Class-"<< i <<
";";
206 sout <<
"TN-Class-"<< i <<
";";
207 sout <<
"FP-Class-"<< i <<
";";
208 sout <<
"FN-Class-"<< i <<
";";
210 sout <<
"DICE-MEAN"<<
";";
211 sout <<
"Jaccard-MEAN"<<
";";
212 sout <<
"Sensitivity-MEAN"<<
";";
213 sout <<
"Specificity-MEAN"<<
";";
214 sout <<
"TP-MEAN"<<
";";
215 sout <<
"TN-MEAN"<<
";";
216 sout <<
"FP-MEAN"<<
";";
217 sout <<
"FN-MEAN"<<
";";
218 sout <<
"DICE-WMEAN"<<
";";
219 sout <<
"Jaccard-WMEAN"<<
";";
220 sout <<
"Sensitivity-WMEAN"<<
";";
221 sout <<
"Specificity-WMEAN"<<
";";
222 sout <<
"TP-WMEAN"<<
";";
223 sout <<
"TN-WMEAN"<<
";";
224 sout <<
"FP-WMEAN"<<
";";
225 sout <<
"FN-WMEAN"<<
";";
226 sout <<
"COMPLETE-TRUE/FALSE"<<
";";
227 sout <<
"COMPLETE-TRUES"<<
";";
228 sout <<
"COMPLETE_FALSE"<<
";";
231 out << std::setprecision(5);
234 MITK_INFO <<
"m_ImageClassStatistic.size(): " << m_ImageClassStatistic.size();
236 for (
int i = 0; i < m_ImageClassStatistic.size(); ++i)
238 sout << label <<
";"<< m_ImageNames[i]<<
";";
241 double pointsSum = 0;
243 out <<
"======================================================== Image " << std::setw(3) << i <<
" ========================================================" << std::endl;
244 out <<
" Image ID : " << m_ImageNames[i] <<std::endl;
246 out <<
"|--------|-------------|-------------|-------------|-------------|-------------|-------------|-------------|--------------|" << std::endl;
247 out <<
"| Class | DICE | Jaccard | Sensitivity | Specificity | TP | TN | FP | FN |" << std::endl;
248 out <<
"|--------|-------------|-------------|-------------|-------------|-------------|-------------|-------------|--------------|" << std::endl;
250 for (
int j =0; j < m_ImageClassStatistic[i].size(); ++j)
279 out<<
"|" << std::setw(7) << j <<
" | ";
280 out << std::setw(11) << stat.
m_DICE <<
" | ";
281 out << std::setw(11) << stat.
m_Jaccard <<
" | ";
288 sout << stat.
m_DICE <<
";";
296 sout << stat.
m_RMSD <<
";";
299 meanStat.
m_DICE /= m_ImageClassStatistic[i].size();
300 meanStat.
m_Jaccard /= m_ImageClassStatistic[i].size();
308 out <<
"|--------|-------------|-------------|-------------|-------------|-------------|-------------|-------------|--------------|" << std::endl;
309 out << std::setw(7) <<
"| Mean "<<
" | ";
310 out << std::setw(11) << meanStat.
m_DICE <<
" | ";
311 out << std::setw(11) << meanStat.
m_Jaccard <<
" | ";
318 sout << meanStat.
m_DICE <<
";";
327 wMeanStat.
m_DICE /= pointsSum;
336 out << std::setw(7) <<
"| W-Mean"<<
" | ";
337 out << std::setw(11) << wMeanStat.
m_DICE <<
" | ";
338 out << std::setw(11) << wMeanStat.
m_Jaccard <<
" | ";
345 sout << wMeanStat.
m_DICE <<
";";
354 m_ImageStatistic[i].m_Sensitivity =
std::max(0.0,(1.0 * m_ImageStatistic[i].m_TruePositive) / (m_ImageStatistic[i].m_TruePositive + m_ImageStatistic[i].m_FalseNegative));
355 m_ImageStatistic[i].m_Specificity =
std::max(0.0,(1.0 * m_ImageStatistic[i].m_TrueNegative) / ( m_ImageStatistic[i].m_FalsePositive + m_ImageStatistic[i].m_TrueNegative));
357 out << std::setw(7) <<
"| Compl."<<
" | ";
358 out << std::setw(11) <<
" x " <<
" | ";
359 out << std::setw(11) <<
" x " <<
" | ";
360 out << std::setw(11) << m_ImageStatistic[i].m_Sensitivity <<
" | ";
361 out << std::setw(11) <<
" x " <<
" | ";
362 out << std::setw(11) << m_ImageStatistic[i].m_TruePositive <<
" | ";
363 out << std::setw(11) << m_ImageStatistic[i].m_TrueNegative<<
" | ";
364 out << std::setw(11) << m_ImageStatistic[i].m_FalsePositive<<
" | ";
365 out << std::setw(11) << m_ImageStatistic[i].m_FalseNegative <<
" |"<< std::endl;
366 out <<
"|--------|-------------|-------------|-------------|-------------|-------------|-------------|-------------|--------------|" << std::endl;
368 sout << m_ImageStatistic[i].m_Sensitivity <<
";";
369 sout << m_ImageStatistic[i].m_TruePositive <<
";";
370 sout << m_ImageStatistic[i].m_FalsePositive<< std::endl;
377 std::vector<StatisticData> statistics;
379 for (
size_t i = 0; i < m_ImageClassStatistic.size(); i++)
381 statistics.push_back(m_ImageClassStatistic[i][c]);
389 assert(m_ClassCount == 2);
390 assert(m_GroundTruthValueToIndexMapper != NULL);
391 assert(m_TestValueToIndexMapper != NULL);
397 typedef itk::Image<unsigned char, 3> LabelImage;
399 typedef itk::SignedDanielssonDistanceMapImageFilter<LabelImage, ImageType, ImageType> DistanceMapFilterType;
400 typedef itk::ConstantBoundaryCondition<LabelImage> BoundaryConditionType;
401 typedef itk::ConstShapedNeighborhoodIterator<LabelImage, BoundaryConditionType> ConstNeighborhoodIteratorType;
405 ConstNeighborhoodIteratorType::OffsetType offset0 = {{ 0, 0, -1}};
406 ConstNeighborhoodIteratorType::OffsetType offset1 = {{ 0, 0, 1}};
407 ConstNeighborhoodIteratorType::OffsetType offset2 = {{ 0, -1, 0}};
408 ConstNeighborhoodIteratorType::OffsetType offset3 = {{ 0, 1, 0}};
409 ConstNeighborhoodIteratorType::OffsetType offset4 = {{-1, 0, 0}};
410 ConstNeighborhoodIteratorType::OffsetType offset5 = {{ 1, 0, 0}};
412 const int outsideVal = 17;
413 itk::NeighborhoodIterator<LabelImage>::RadiusType radius;
416 BoundaryConditionType bc;
418 bc.SetConstant(outsideVal);
420 ConstNeighborhoodIteratorType neighborhoodIter;
423 std::vector<mitk::StatisticData>* currentImageStatistics = NULL;
425 unsigned int distanceBorderSamples = 0;
426 double totalBorderRMSDistance = 0;
428 int previousImageIndex = -1;
435 if (previousImageIndex != currentImageIndex)
437 previousImageIndex = currentImageIndex;
439 currentImageStatistics = &(m_ImageClassStatistic.at(currentImageIndex));
441 distanceBorderSamples = 0;
442 totalBorderRMSDistance = 0;
447 distanceMapFilter->SetUseImageSpacing(
true);
448 distanceMapFilter->Update();
449 distanceImage = distanceMapFilter->GetOutput();
451 neighborhoodIter = ConstNeighborhoodIteratorType(radius, testIter.
GetImageIterator().GetImage(), testIter.
GetImageIterator().GetImage()->GetRequestedRegion());
452 neighborhoodIter.OverrideBoundaryCondition(&bc);
455 neighborhoodIter.ActivateOffset(offset0);
456 neighborhoodIter.ActivateOffset(offset1);
457 neighborhoodIter.ActivateOffset(offset2);
458 neighborhoodIter.ActivateOffset(offset3);
459 neighborhoodIter.ActivateOffset(offset4);
460 neighborhoodIter.ActivateOffset(offset5);
463 unsigned char testClass = m_TestValueToIndexMapper->operator()(testIter.
GetVoxel());
465 if ( maskIter.
GetVoxel() > 0 && testClass != 0)
471 ConstNeighborhoodIteratorType::ConstIterator iter;
472 for (iter = neighborhoodIter.Begin(); !iter.IsAtEnd(); iter++)
474 if (iter.Get() == outsideVal)
479 if (m_TestValueToIndexMapper->operator()(iter.Get()) != 1 )
488 double currentDistance = distanceImage->GetPixel(testIter.
GetImageIterator().GetIndex());
489 totalBorderRMSDistance += currentDistance * currentDistance;
490 ++distanceBorderSamples;
493 double rmsd = std::sqrt(totalBorderRMSDistance / (
double) distanceBorderSamples);
494 currentImageStatistics->at(1).m_RMSD = rmsd;
std::string GetTestName()
itk::SmartPointer< Self > Pointer
unsigned int m_TruePositive
unsigned int m_FalseNegative
void Print(std::ostream &out, std::ostream &sout=std::cout, bool withHeader=false, std::string label="None")
ImageIterator GetImageIterator()
void SetTestName(std::string name)
std::vector< StatisticData > GetStatisticData(unsigned char c) const
mitk::CollectionStatistic::GetStatisticData
Follow Up Storage - Class to facilitate loading/accessing structured follow-up data.
void SetTestValueToIndexMapper(const ValueToIndexMapper *mapper)
void SetGroundTruthValueToIndexMapper(const ValueToIndexMapper *mapper)
unsigned int m_FalsePositive
vcl_size_t GetClassCount()
DataCollection::Pointer GetCollection()
map::core::discrete::Elements< 3 >::InternalImageType ImageType
void SetGoldName(std::string name)
unsigned int m_TrueNegative
vcl_size_t GetImageIndex()
void ComputeRMSD()
Computes root-mean-square distance of two binary images.
void SetCollection(DataCollection::Pointer collection)
void SetClassCount(vcl_size_t count)
const ValueToIndexMapper * GetTestValueToIndexMapper(void) const
const ValueToIndexMapper * GetGroundTruthValueToIndexMapper(void) const
std::vector< StatisticData > DataVector
itk::SmartPointer< Self > Pointer
int IsInSameVirtualClass(unsigned char gold, unsigned char test)
std::string GetFilePrefix()
std::string GetGoldName()
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.