21 #include <itkShapedNeighborhoodIterator.h> 22 #include <itkSignedDanielssonDistanceMapImageFilter.h> 26 : m_GroundTruthValueToIndexMapper(nullptr)
27 , m_TestValueToIndexMapper(nullptr)
34 m_GroundTruthValueToIndexMapper =
nullptr;
35 m_TestValueToIndexMapper =
nullptr;
41 m_Collection = collection;
61 m_GroundTruthName = name;
66 return m_GroundTruthName;
81 m_GroundTruthValueToIndexMapper = mapper;
86 return m_GroundTruthValueToIndexMapper;
91 m_TestValueToIndexMapper = mapper;
96 return m_TestValueToIndexMapper;
101 int resultClass = -1;
102 for (std::size_t i = 0; i < m_ConnectionGold.size(); ++i)
104 if (m_ConnectionGold[i] == gold && m_ConnectionTest[i] == test)
106 resultClass = m_ConnectionClass[i];
115 if (m_GroundTruthValueToIndexMapper ==
nullptr)
117 MITK_ERROR <<
"m_GroundTruthValueToIndexMapper is nullptr";
121 if (m_TestValueToIndexMapper ==
nullptr)
123 MITK_ERROR <<
"m_TestValueToIndexMapper is nullptr";
136 if (m_ImageClassStatistic.size() <= imageIndex)
141 m_ImageStatistic.push_back(statData);
143 for (std::size_t i = 0; i < m_ClassCount; ++i)
146 data.push_back(stat);
148 m_ImageClassStatistic.push_back(data);
160 unsigned char goldClass = m_GroundTruthValueToIndexMapper->operator()(goldIter.
GetVoxel());
161 unsigned char testClass = m_TestValueToIndexMapper->operator()(testIter.
GetVoxel());
162 if (goldClass == testClass)
164 m_ImageStatistic[imageIndex].m_TruePositive += 1;
165 for (std::size_t i = 0; i < m_ClassCount; ++i)
169 m_ImageClassStatistic[imageIndex][i].m_TruePositive += 1;
172 m_ImageClassStatistic[imageIndex][i].m_TrueNegative += 1;
177 m_ImageStatistic[imageIndex].m_FalseNegative += 1;
178 m_ImageStatistic[imageIndex].m_FalsePositive += 1;
179 for (std::size_t i = 0; i < m_ClassCount; ++i)
183 m_ImageClassStatistic[imageIndex][i].m_FalseNegative += 1;
184 }
else if ( testClass == i)
186 m_ImageClassStatistic[imageIndex][i].m_FalsePositive += 1;
189 m_ImageClassStatistic[imageIndex][i].m_TrueNegative += 1;
198 MITK_INFO <<
"Evaluated " << index <<
" points";
204 assert(m_ImageClassStatistic.size() > 0);
205 assert(m_ImageClassStatistic[0].size() == m_ClassCount);
209 sout <<
"Label;ImageName;";
210 for (std::size_t i = 0; i < m_ClassCount; ++i)
212 sout <<
"DICE-Class-"<< i <<
";";
213 sout <<
"Jaccard-Class-"<< i <<
";";
214 sout <<
"Sensitivity-Class-"<< i <<
";";
215 sout <<
"Specificity-Class-"<< i <<
";";
216 sout <<
"TP-Class-"<< i <<
";";
217 sout <<
"TN-Class-"<< i <<
";";
218 sout <<
"FP-Class-"<< i <<
";";
219 sout <<
"FN-Class-"<< i <<
";";
221 sout <<
"DICE-MEAN"<<
";";
222 sout <<
"Jaccard-MEAN"<<
";";
223 sout <<
"Sensitivity-MEAN"<<
";";
224 sout <<
"Specificity-MEAN"<<
";";
225 sout <<
"TP-MEAN"<<
";";
226 sout <<
"TN-MEAN"<<
";";
227 sout <<
"FP-MEAN"<<
";";
228 sout <<
"FN-MEAN"<<
";";
229 sout <<
"DICE-WMEAN"<<
";";
230 sout <<
"Jaccard-WMEAN"<<
";";
231 sout <<
"Sensitivity-WMEAN"<<
";";
232 sout <<
"Specificity-WMEAN"<<
";";
233 sout <<
"TP-WMEAN"<<
";";
234 sout <<
"TN-WMEAN"<<
";";
235 sout <<
"FP-WMEAN"<<
";";
236 sout <<
"FN-WMEAN"<<
";";
237 sout <<
"COMPLETE-TRUE/FALSE"<<
";";
238 sout <<
"COMPLETE-TRUES"<<
";";
239 sout <<
"COMPLETE_FALSE"<<
";";
242 out << std::setprecision(5);
245 MITK_INFO <<
"m_ImageClassStatistic.size(): " << m_ImageClassStatistic.size();
247 for (std::size_t i = 0; i < m_ImageClassStatistic.size(); ++i)
249 sout << label <<
";"<< m_ImageNames[i]<<
";";
252 double pointsSum = 0;
254 out <<
"======================================================== Image " << std::setw(3) << i <<
" ========================================================" << std::endl;
255 out <<
" Image ID : " << m_ImageNames[i] <<std::endl;
257 out <<
"|--------|-------------|-------------|-------------|-------------|-------------|-------------|-------------|--------------|" << std::endl;
258 out <<
"| Class | DICE | Jaccard | Sensitivity | Specificity | TP | TN | FP | FN |" << std::endl;
259 out <<
"|--------|-------------|-------------|-------------|-------------|-------------|-------------|-------------|--------------|" << std::endl;
261 for (std::size_t j =0; j < m_ImageClassStatistic[i].size(); ++j)
290 out<<
"|" << std::setw(7) << j <<
" | ";
291 out << std::setw(11) << stat.
m_DICE <<
" | ";
292 out << std::setw(11) << stat.
m_Jaccard <<
" | ";
299 sout << stat.
m_DICE <<
";";
307 sout << stat.
m_RMSD <<
";";
310 meanStat.
m_DICE /= m_ImageClassStatistic[i].size();
311 meanStat.
m_Jaccard /= m_ImageClassStatistic[i].size();
319 out <<
"|--------|-------------|-------------|-------------|-------------|-------------|-------------|-------------|--------------|" << std::endl;
320 out << std::setw(7) <<
"| Mean "<<
" | ";
321 out << std::setw(11) << meanStat.
m_DICE <<
" | ";
322 out << std::setw(11) << meanStat.
m_Jaccard <<
" | ";
329 sout << meanStat.
m_DICE <<
";";
338 wMeanStat.
m_DICE /= pointsSum;
347 out << std::setw(7) <<
"| W-Mean"<<
" | ";
348 out << std::setw(11) << wMeanStat.
m_DICE <<
" | ";
349 out << std::setw(11) << wMeanStat.
m_Jaccard <<
" | ";
356 sout << wMeanStat.
m_DICE <<
";";
365 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));
366 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));
368 out << std::setw(7) <<
"| Compl."<<
" | ";
369 out << std::setw(11) <<
" x " <<
" | ";
370 out << std::setw(11) <<
" x " <<
" | ";
371 out << std::setw(11) << m_ImageStatistic[i].m_Sensitivity <<
" | ";
372 out << std::setw(11) <<
" x " <<
" | ";
373 out << std::setw(11) << m_ImageStatistic[i].m_TruePositive <<
" | ";
374 out << std::setw(11) << m_ImageStatistic[i].m_TrueNegative<<
" | ";
375 out << std::setw(11) << m_ImageStatistic[i].m_FalsePositive<<
" | ";
376 out << std::setw(11) << m_ImageStatistic[i].m_FalseNegative <<
" |"<< std::endl;
377 out <<
"|--------|-------------|-------------|-------------|-------------|-------------|-------------|-------------|--------------|" << std::endl;
379 sout << m_ImageStatistic[i].m_Sensitivity <<
";";
380 sout << m_ImageStatistic[i].m_TruePositive <<
";";
381 sout << m_ImageStatistic[i].m_FalsePositive<< std::endl;
388 std::vector<StatisticData> statistics;
390 for (
size_t i = 0; i < m_ImageClassStatistic.size(); i++)
392 statistics.push_back(m_ImageClassStatistic[i][c]);
400 assert(m_ClassCount == 2);
401 assert(m_GroundTruthValueToIndexMapper !=
nullptr);
402 assert(m_TestValueToIndexMapper !=
nullptr);
408 typedef itk::Image<unsigned char, 3> LabelImage;
410 typedef itk::SignedDanielssonDistanceMapImageFilter<LabelImage, ImageType, ImageType> DistanceMapFilterType;
411 typedef itk::ConstantBoundaryCondition<LabelImage> BoundaryConditionType;
412 typedef itk::ConstShapedNeighborhoodIterator<LabelImage, BoundaryConditionType> ConstNeighborhoodIteratorType;
416 ConstNeighborhoodIteratorType::OffsetType offset0 = {{ 0, 0, -1}};
417 ConstNeighborhoodIteratorType::OffsetType offset1 = {{ 0, 0, 1}};
418 ConstNeighborhoodIteratorType::OffsetType offset2 = {{ 0, -1, 0}};
419 ConstNeighborhoodIteratorType::OffsetType offset3 = {{ 0, 1, 0}};
420 ConstNeighborhoodIteratorType::OffsetType offset4 = {{-1, 0, 0}};
421 ConstNeighborhoodIteratorType::OffsetType offset5 = {{ 1, 0, 0}};
423 const int outsideVal = 17;
424 itk::NeighborhoodIterator<LabelImage>::RadiusType radius;
427 BoundaryConditionType bc;
429 bc.SetConstant(outsideVal);
431 ConstNeighborhoodIteratorType neighborhoodIter;
433 ImageType::Pointer distanceImage;
434 std::vector<mitk::StatisticData>* currentImageStatistics =
nullptr;
436 unsigned int distanceBorderSamples = 0;
437 double totalBorderRMSDistance = 0;
439 int previousImageIndex = -1;
446 if (previousImageIndex != currentImageIndex)
448 previousImageIndex = currentImageIndex;
450 currentImageStatistics = &(m_ImageClassStatistic.at(currentImageIndex));
452 distanceBorderSamples = 0;
453 totalBorderRMSDistance = 0;
456 DistanceMapFilterType::Pointer distanceMapFilter = DistanceMapFilterType::New();
458 distanceMapFilter->SetUseImageSpacing(
true);
459 distanceMapFilter->Update();
460 distanceImage = distanceMapFilter->GetOutput();
462 neighborhoodIter = ConstNeighborhoodIteratorType(radius, testIter.
GetImageIterator().GetImage(), testIter.
GetImageIterator().GetImage()->GetRequestedRegion());
463 neighborhoodIter.OverrideBoundaryCondition(&bc);
466 neighborhoodIter.ActivateOffset(offset0);
467 neighborhoodIter.ActivateOffset(offset1);
468 neighborhoodIter.ActivateOffset(offset2);
469 neighborhoodIter.ActivateOffset(offset3);
470 neighborhoodIter.ActivateOffset(offset4);
471 neighborhoodIter.ActivateOffset(offset5);
474 unsigned char testClass = m_TestValueToIndexMapper->operator()(testIter.
GetVoxel());
476 if ( maskIter.
GetVoxel() > 0 && testClass != 0)
482 ConstNeighborhoodIteratorType::ConstIterator iter;
483 for (iter = neighborhoodIter.Begin(); !iter.IsAtEnd(); iter++)
485 if (iter.Get() == outsideVal)
490 if (m_TestValueToIndexMapper->operator()(iter.Get()) != 1 )
499 double currentDistance = distanceImage->GetPixel(testIter.
GetImageIterator().GetIndex());
500 totalBorderRMSDistance += currentDistance * currentDistance;
501 ++distanceBorderSamples;
504 double rmsd = std::sqrt(totalBorderRMSDistance / (
double) distanceBorderSamples);
505 currentImageStatistics->at(1).m_RMSD = rmsd;
std::string GetTestName()
const ValueToIndexMapper * GetTestValueToIndexMapper(void) const
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)
itk::Image< unsigned char, 3 > ImageType
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()
void SetGoldName(std::string name)
unsigned int m_TrueNegative
vcl_size_t GetImageIndex()
const ValueToIndexMapper * GetGroundTruthValueToIndexMapper(void) const
void ComputeRMSD()
Computes root-mean-square distance of two binary images.
void SetCollection(DataCollection::Pointer collection)
void SetClassCount(vcl_size_t count)
std::vector< StatisticData > GetStatisticData(unsigned char c) const
mitk::CollectionStatistic::GetStatisticData
std::vector< StatisticData > DataVector
itk::SmartPointer< Self > Pointer
int IsInSameVirtualClass(unsigned char gold, unsigned char test)
std::string GetFilePrefix()
std::string GetGoldName()