ANIMA  4.0
animaSegmentationMeasuresImageFilter.hxx
Go to the documentation of this file.
1 #pragma once
3 
4 #include "itkImageRegionConstIterator.h"
5 
6 namespace anima
7 {
8 
9 template<typename TLabelImage>
12 {
13  // this filter requires two input images
14  this->SetNumberOfRequiredInputs(2);
15 }
16 
17 template<typename TLabelImage>
18 void
21 {
22  itk::ThreadIdType numberOfThreads = this->GetNumberOfWorkUnits();
23 
24  // Resize the thread temporaries
25  this->m_LabelSetMeasuresPerThread.resize(numberOfThreads);
26 
27  // Initialize the temporaries
28  for (itk::ThreadIdType n = 0;n < numberOfThreads;++n)
29  {
30  this->m_LabelSetMeasuresPerThread[n].clear();
31  }
32 
33  // Initialize the final map
34  this->m_LabelSetMeasures.clear();
35 
36  const LabelImageType* poImgIn = this->GetSourceImage();
37  if (poImgIn)
38  {
39  m_fNbOfPixels = poImgIn->GetLargestPossibleRegion().GetNumberOfPixels();
40  }
41 
42  Superclass::BeforeThreadedGenerateData();
43 }
44 
45 template<typename TLabelImage>
46 void
49 {
50  // Run through the map for each thread and accumulate the set measures.
51  for (itk::ThreadIdType n = 0;n < this->GetNumberOfWorkUnits();++n)
52  {
53  // iterate over the map for this thread
54  for (MapConstIterator threadIt = this->m_LabelSetMeasuresPerThread[n].begin();
55  threadIt != this->m_LabelSetMeasuresPerThread[n].end();
56  ++threadIt)
57  {
58  // does this label exist in the cumulative structure yet?
59  if (m_LabelSetMeasures.find((*threadIt).first) == m_LabelSetMeasures.end())
60  m_LabelSetMeasures[(*threadIt).first] = SegPerfLabelSetMeasures();
61 
62  // accumulate the information from this thread
63  m_LabelSetMeasures[(*threadIt).first].m_Source += (*threadIt).second.m_Source;
64  m_LabelSetMeasures[(*threadIt).first].m_Target += (*threadIt).second.m_Target;
65  m_LabelSetMeasures[(*threadIt).first].m_Union += (*threadIt).second.m_Union;
66  m_LabelSetMeasures[(*threadIt).first].m_TrueNegative += (*threadIt).second.m_TrueNegative;
67  m_LabelSetMeasures[(*threadIt).first].m_Intersection +=
68  (*threadIt).second.m_Intersection;
69  m_LabelSetMeasures[(*threadIt).first].m_SourceComplement +=
70  (*threadIt).second.m_SourceComplement;
71  m_LabelSetMeasures[(*threadIt).first].m_TargetComplement +=
72  (*threadIt).second.m_TargetComplement;
73  } // end of thread map iterator loop
74  } // end of thread loop
75 }
76 
77 template<typename TLabelImage>
78 void
80 ::DynamicThreadedGenerateData(const RegionType& outputRegionForThread)
81 {
82  itk::ImageRegionConstIterator<LabelImageType> itS(this->GetSourceImage(), outputRegionForThread);
83  itk::ImageRegionConstIterator<LabelImageType> itT(this->GetTargetImage(), outputRegionForThread);
84 
85  unsigned int threadId = this->GetSafeThreadId();
86 
87  // support progress methods/callbacks
88  for (itS.GoToBegin(), itT.GoToBegin(); !itS.IsAtEnd(); ++itS, ++itT)
89  {
90  LabelType sourceLabel = itS.Get();
91  LabelType targetLabel = itT.Get();
92 
93  // is the label already in this thread?
94  MapIterator mapItS = m_LabelSetMeasuresPerThread[threadId].find(sourceLabel);
95  // create a new label set measures object
96  if (mapItS == m_LabelSetMeasuresPerThread[threadId].end())
97  m_LabelSetMeasuresPerThread[threadId][sourceLabel] = SegPerfLabelSetMeasures();
98 
99  // create a new label set measures object
100  MapIterator mapItT = m_LabelSetMeasuresPerThread[threadId].find(targetLabel);
101  if (mapItT == this->m_LabelSetMeasuresPerThread[threadId].end())
102  m_LabelSetMeasuresPerThread[threadId][targetLabel] = SegPerfLabelSetMeasures();
103 
104  m_LabelSetMeasuresPerThread[threadId][sourceLabel].m_Source++;
105  m_LabelSetMeasuresPerThread[threadId][targetLabel].m_Target++;
106 
107  if( sourceLabel == targetLabel )
108  {
109  m_LabelSetMeasuresPerThread[threadId][sourceLabel].m_Intersection++;
110  m_LabelSetMeasuresPerThread[threadId][sourceLabel].m_Union++;
111  }
112  else
113  {
114  m_LabelSetMeasuresPerThread[threadId][sourceLabel].m_Union++;
115  m_LabelSetMeasuresPerThread[threadId][targetLabel].m_Union++;
116 
117  m_LabelSetMeasuresPerThread[threadId][sourceLabel].m_SourceComplement++;
118  m_LabelSetMeasuresPerThread[threadId][targetLabel].m_TargetComplement++;
119  }
120 
121  if(sourceLabel == 0 && targetLabel == 0)
122  m_LabelSetMeasuresPerThread[threadId][sourceLabel].m_TrueNegative++;
123  }
124 
125  this->SafeReleaseThreadId(threadId);
126 }
127 
128 template<typename TLabelImage>
132 {
133  RealType numerator = 0.0;
134  RealType denominator = 0.0;
135 
136  for (MapIterator mapIt = this->m_LabelSetMeasures.begin();
137  mapIt != this->m_LabelSetMeasures.end();++mapIt)
138  {
139  // Do not include the background in the final value.
140  if( (*mapIt).first == itk::NumericTraits<LabelType>::Zero )
141  continue;
142 
143  numerator += static_cast<RealType>( (*mapIt).second.m_Intersection );
144  denominator += static_cast<RealType>( (*mapIt).second.m_Union );
145  }
146 
147  return numerator / denominator;
148 }
149 
150 template<typename TLabelImage>
154 {
155  MapIterator mapIt = this->m_LabelSetMeasures.find( label );
156  if (mapIt == this->m_LabelSetMeasures.end())
157  {
158  itkWarningMacro( "Label " << label << " not found." );
159  return 0.0;
160  }
161 
162  RealType value =
163  static_cast<RealType>( (*mapIt).second.m_Intersection ) /
164  static_cast<RealType>( (*mapIt).second.m_Union );
165 
166  return value;
167 }
168 
169 template<typename TLabelImage>
173 {
174  RealType uo = this->getUnionOverlap();
175  return 2.0 * uo / ( 1.0 + uo );
176 }
177 
178 template<typename TLabelImage>
182 {
183  RealType uo = this->getUnionOverlap(label);
184  return 2.0 * uo / (1.0 + uo);
185 }
186 
187 template<typename TLabelImage>
191 {
192  RealType numerator = 0.0;
193  RealType denominator = 0.0;
194  MapType orMap = this->GetLabelSetMeasures();
195  for(MapIterator mapIt = orMap.begin();
196  mapIt != orMap.end();++mapIt)
197  {
198  // Do not include the background in the final value.
199  if((*mapIt).first == itk::NumericTraits<LabelType>::Zero)
200  continue;
201 
202  numerator += static_cast<RealType>( (*mapIt).second.m_Intersection );
203  denominator += static_cast<RealType>( (*mapIt).second.m_Intersection ) + static_cast<RealType>( (*mapIt).second.m_TargetComplement );
204  }
205 
206  return numerator / denominator;
207 }
208 
209 template<typename TLabelImage>
213 {
214  MapIterator mapIt = m_LabelSetMeasures.find(label);
215  if(mapIt == this->m_LabelSetMeasures.end())
216  {
217  itkWarningMacro( "Label " << label << " not found." );
218  return 0.0;
219  }
220 
221  RealType value =
222  static_cast<RealType>((*mapIt).second.m_Intersection) /
223  (static_cast<RealType>((*mapIt).second.m_Intersection) + static_cast<RealType>((*mapIt).second.m_TargetComplement));
224 
225  return value;
226 }
227 
228 template<typename TLabelImage>
232 {
233  unsigned int numberOfLabels = 0;
234  unsigned int i = 1;
235 
236  MapIterator mapIt;
237 
238  do
239  {
240  mapIt = this->m_LabelSetMeasures.find(i);
241  numberOfLabels++;
242  i++;
243  } while (!(mapIt == this->m_LabelSetMeasures.end()));
244 
245  numberOfLabels--;
246 
247  RealType numerator = 0.0;
248  RealType denominator = 0.0;
249  MapType orMap = this->GetLabelSetMeasures();
250  for(MapIterator mapIt = orMap.begin();
251  mapIt != orMap.end();++mapIt)
252  {
253  // Do not include the background in the final value.
254  if ((*mapIt).first == itk::NumericTraits<LabelType>::Zero)
255  {
256  numerator += static_cast<RealType>((*mapIt).second.m_TrueNegative);
257  continue;
258  }
259 
260  denominator += static_cast<RealType>((*mapIt).second.m_SourceComplement);
261  }
262 
263  //numerator = m_fNbOfPixels - numerator;
264  denominator = denominator/numberOfLabels;
265  denominator = denominator + numerator;
266 
267  return numerator / denominator;
268 }
269 
270 template<typename TLabelImage>
274 {
275  MapIterator mapIt = this->m_LabelSetMeasures.find(label);
276  if(mapIt == this->m_LabelSetMeasures.end())
277  {
278  itkWarningMacro("Label " << label << " not found.");
279  return 0.0;
280  }
281 
282  RealType value =
283  (m_fNbOfPixels - static_cast<RealType>((*mapIt).second.m_Union)) /
284  (m_fNbOfPixels - static_cast<RealType>((*mapIt).second.m_Union) + static_cast<RealType>((*mapIt).second.m_SourceComplement));
285 
286  return value;
287 }
288 
289 template<typename TLabelImage>
293 {
294  RealType numerator = 0.0;
295  RealType denominator = 0.0;
296  MapType orMap = this->GetLabelSetMeasures();
297  for(MapIterator mapIt = orMap.begin();
298  mapIt != orMap.end();++mapIt)
299  {
300  // Do not include the background in the final value.
301  if ((*mapIt).first == itk::NumericTraits<LabelType>::Zero)
302  continue;
303 
304  numerator += static_cast<RealType>((*mapIt).second.m_Intersection);
305  denominator += static_cast<RealType>((*mapIt).second.m_Intersection) + static_cast<RealType>((*mapIt).second.m_SourceComplement);
306  }
307  return numerator / denominator;
308 }
309 
310 template<typename TLabelImage>
314 {
315  MapIterator mapIt = this->m_LabelSetMeasures.find( label );
316  if (mapIt == this->m_LabelSetMeasures.end())
317  {
318  itkWarningMacro("Label " << label << " not found.");
319  return 0.0;
320  }
321 
322  RealType value =
323  static_cast<RealType>((*mapIt).second.m_Intersection) /
324  (static_cast<RealType>((*mapIt).second.m_Intersection) + static_cast<RealType>((*mapIt).second.m_SourceComplement));
325 
326  return value;
327 }
328 
329 template<typename TLabelImage>
333 {
334  unsigned int numberOfLabels = 0;
335  unsigned int i = 1;
336 
337  MapIterator mapIt;
338  do
339  {
340  mapIt = this->m_LabelSetMeasures.find(i);
341  numberOfLabels++;
342  i++;
343  } while (!(mapIt == this->m_LabelSetMeasures.end()));
344 
345  numberOfLabels--;
346 
347  RealType numerator = 0.0;
348  RealType denominator = 0.0;
349  MapType orMap = this->GetLabelSetMeasures();
350  for(MapIterator mapIt = orMap.begin();
351  mapIt != orMap.end();++mapIt)
352  {
353  // Do not include the background in the final value.
354  if ((*mapIt).first == itk::NumericTraits<LabelType>::Zero)
355  {
356  numerator += static_cast<RealType>((*mapIt).second.m_TrueNegative);
357  continue;
358  }
359 
360  denominator += static_cast<RealType>((*mapIt).second.m_TargetComplement);
361  }
362 
363  denominator = denominator/numberOfLabels;
364  denominator = numerator + denominator;
365  return numerator / denominator;
366 }
367 
368 template<typename TLabelImage>
372 {
373  MapIterator mapIt = this->m_LabelSetMeasures.find(label);
374  if (mapIt == this->m_LabelSetMeasures.end())
375  {
376  itkWarningMacro("Label " << label << " not found.");
377  return 0.0;
378  }
379 
380  RealType value =
381  (m_fNbOfPixels - static_cast<RealType>( (*mapIt).second.m_Union )) /
382  (m_fNbOfPixels - static_cast<RealType>( (*mapIt).second.m_Union ) + static_cast<RealType>( (*mapIt).second.m_TargetComplement ));
383 
384  return value;
385 }
386 
387 template<typename TLabelImage>
390 {
391  RealType numerator = 0.0;
392  RealType denominator = 0.0;
393  for (MapIterator mapIt = this->m_LabelSetMeasures.begin();
394  mapIt != this->m_LabelSetMeasures.end();++mapIt)
395  {
396  // Do not include the background in the final value.
397  if((*mapIt).first == itk::NumericTraits<LabelType>::Zero)
398  continue;
399 
400  RealType Vt = static_cast<RealType>((*mapIt).second.m_Source);
401  RealType Vgt = static_cast<RealType>((*mapIt).second.m_Target);
402  numerator += Vt - Vgt;
403  denominator += static_cast<RealType>((*mapIt).second.m_Target);
404  }
405 
406  return numerator / denominator;
407 }
408 
409 template<typename TLabelImage>
412 {
413  RealType numerator = 0.0;
414  RealType denominator = 0.0;
415  MapIterator mapIt = this->m_LabelSetMeasures.find(label);
416  if(mapIt == this->m_LabelSetMeasures.end())
417  {
418  itkWarningMacro( "Label " << label << " not found." );
419  return 0.0;
420  }
421 
422  RealType Vt = static_cast<RealType>((*mapIt).second.m_Source);
423  RealType Vgt = static_cast<RealType>((*mapIt).second.m_Target);
424  numerator = Vt - Vgt;
425  denominator = static_cast<RealType>((*mapIt).second.m_Target);
426  return numerator / denominator;
427 }
428 
429 } // end namespace anima
std::map< LabelType, SegPerfLabelSetMeasures > MapType
void DynamicThreadedGenerateData(const RegionType &) ITK_OVERRIDE
itk::NumericTraits< LabelType >::RealType RealType