OTB  9.0.0
Orfeo Toolbox
otbConfusionMatrixMeasurements.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbConfusionMatrixMeasurements_hxx
22 #define otbConfusionMatrixMeasurements_hxx
23 
25 
26 namespace otb
27 {
28 template <class TConfusionMatrix, class TLabel>
30  : m_KappaIndex(0.0),
31  m_OverallAccuracy(0.0),
32  m_FalseNegativeValue(0.0),
33  m_TrueNegativeValue(0.0),
34  m_FalsePositiveValue(0.0),
35  m_TruePositiveValue(0.0),
36  m_NumberOfClasses(0),
37  m_NumberOfSamples(0)
38 
39 {
41  m_ConfusionMatrix.Fill(0);
42 }
43 
44 
45 template <class TConfusionMatrix, class TLabel>
47 {
48  m_NumberOfClasses = m_ConfusionMatrix.Rows();
49 
50  m_FalseNegativeValues = MeasurementType(m_NumberOfClasses);
51  m_TrueNegativeValues = MeasurementType(m_NumberOfClasses);
52  m_FalsePositiveValues = MeasurementType(m_NumberOfClasses);
53  m_TruePositiveValues = MeasurementType(m_NumberOfClasses);
54  m_FalseNegativeValues.Fill(0);
55  m_FalsePositiveValues.Fill(0);
56  m_TruePositiveValues.Fill(0);
57  m_TrueNegativeValues.Fill(0);
58 
59  const double epsilon = 0.0000000001;
60  double luckyRate = 0.;
61  this->m_NumberOfSamples = 0;
62  this->m_OverallAccuracy = 0.;
63  for (unsigned int i = 0; i < m_NumberOfClasses; ++i)
64  {
65  double sum_along_row_i = 0.;
66  double sum_along_column_i = 0.;
67  for (unsigned int j = 0; j < m_NumberOfClasses; ++j)
68  {
69  sum_along_row_i += m_ConfusionMatrix(i, j);
70  sum_along_column_i += m_ConfusionMatrix(j, i);
71  this->m_NumberOfSamples += m_ConfusionMatrix(i, j);
72  // i != j
73  if (i != j)
74  {
75  this->m_FalseNegativeValues[i] += m_ConfusionMatrix(i, j);
76  this->m_FalsePositiveValues[i] += m_ConfusionMatrix(j, i);
77  }
78  // i == j
79  else
80  {
81  this->m_OverallAccuracy += m_ConfusionMatrix(i, i);
82  this->m_TruePositiveValues[i] = m_ConfusionMatrix(i, i);
83  }
84  }
85  luckyRate += sum_along_row_i * sum_along_column_i;
86  }
87 
88  this->m_TrueNegativeValues.Fill(m_NumberOfSamples);
89  this->m_TrueNegativeValues -= this->m_FalseNegativeValues + this->m_FalsePositiveValues + this->m_TruePositiveValues;
90 
91  if (m_NumberOfClasses == 2)
92  {
93  this->m_TruePositiveValue = m_ConfusionMatrix(0, 0);
94  this->m_FalseNegativeValue = m_ConfusionMatrix(0, 1);
95  this->m_FalsePositiveValue = m_ConfusionMatrix(1, 0);
96  this->m_TrueNegativeValue = m_ConfusionMatrix(1, 1);
97  /*std::cout << "TP= " << this->m_TruePositiveValue << std::endl;
98  std::cout << "FN= " << this->m_FalseNegativeValue << std::endl;
99  std::cout << "FP= " << this->m_FalsePositiveValue << std::endl;
100  std::cout << "TN= " << this->m_TrueNegativeValue << std::endl; */
101  }
102  else
103  {
104  /*std::cout << "TP= " << this->m_TruePositiveValues << std::endl;
105  std::cout << "FN= " << this->m_FalseNegativeValues << std::endl;
106  std::cout << "FP= " << this->m_FalsePositiveValues << std::endl;
107  std::cout << "TN= " << this->m_TrueNegativeValues << std::endl; */
108  }
109 
110  m_Precisions = MeasurementType(m_NumberOfClasses);
111  m_Recalls = MeasurementType(m_NumberOfClasses);
112  m_FScores = MeasurementType(m_NumberOfClasses);
113  m_Precisions.Fill(0.);
114  m_Recalls.Fill(0.);
115  m_FScores.Fill(0.);
116 
117  if (m_NumberOfSamples > 0)
118  {
119  this->m_OverallAccuracy /= static_cast<double>(m_NumberOfSamples);
120  luckyRate /= std::pow(m_NumberOfSamples, 2.0);
121 
122  if (std::abs(1 - luckyRate) > epsilon)
123  {
124  m_KappaIndex = (m_OverallAccuracy - luckyRate) / (1 - luckyRate);
125  }
126  else
127  {
128  this->m_KappaIndex = 1.;
129  }
130  }
131  else
132  {
133  this->m_OverallAccuracy = 0.;
134  this->m_KappaIndex = 0.;
135  // no samples, no need to continue
136  return;
137  }
138 
139  for (unsigned int i = 0; i < m_NumberOfClasses; ++i)
140  {
141  if (std::abs(this->m_TruePositiveValues[i] + this->m_FalsePositiveValues[i]) > epsilon)
142  {
143  this->m_Precisions[i] = this->m_TruePositiveValues[i] / (this->m_TruePositiveValues[i] + this->m_FalsePositiveValues[i]);
144  }
145 
146  if (std::abs(this->m_TruePositiveValues[i] + this->m_FalseNegativeValues[i]) > epsilon)
147  {
148  this->m_Recalls[i] = this->m_TruePositiveValues[i] / (this->m_TruePositiveValues[i] + this->m_FalseNegativeValues[i]);
149  }
150 
151  if (std::abs(this->m_Recalls[i] + this->m_Precisions[i]) > epsilon)
152  {
153  this->m_FScores[i] = 2 * this->m_Recalls[i] * this->m_Precisions[i] / (this->m_Recalls[i] + this->m_Precisions[i]);
154  }
155  }
156 
157 
158  if (m_NumberOfClasses == 2)
159  {
160  if (std::abs(this->m_TruePositiveValue + this->m_FalsePositiveValue) > epsilon)
161  {
162  this->m_Precision = this->m_TruePositiveValue / (this->m_TruePositiveValue + this->m_FalsePositiveValue);
163  }
164  if (std::abs(this->m_TruePositiveValue + this->m_FalseNegativeValue) > epsilon)
165  {
166  this->m_Recall = this->m_TruePositiveValue / (this->m_TruePositiveValue + this->m_FalseNegativeValue);
167  }
168  if (std::abs(this->m_Recall + this->m_Precision) > epsilon)
169  {
170  this->m_FScore = 2 * this->m_Recall * this->m_Precision / (this->m_Recall + this->m_Precision);
171  }
172  }
173 }
174 
175 /*
176 template <class TConfusionMatrix, class TLabel>
177 void
178 ConfusionMatrixMeasurements<TConfusionMatrix, TLabel>
179 ::PrintSelf(std::ostream& os, itk::Indent indent) const
180 {
181  os << indent << "TODO";
182 }*/
183 }
184 
185 #endif
otb::ConfusionMatrixMeasurements::ConfusionMatrixMeasurements
ConfusionMatrixMeasurements()
Definition: otbConfusionMatrixMeasurements.hxx:29
otb::ConfusionMatrixMeasurements::MeasurementType
itk::VariableLengthVector< double > MeasurementType
Definition: otbConfusionMatrixMeasurements.h:76
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otbConfusionMatrixMeasurements.h
otb::ConfusionMatrixMeasurements::ConfusionMatrixType
TConfusionMatrix ConfusionMatrixType
Definition: otbConfusionMatrixMeasurements.h:73
otb::ConfusionMatrixMeasurements::m_ConfusionMatrix
ConfusionMatrixType m_ConfusionMatrix
Definition: otbConfusionMatrixMeasurements.h:182
otb::ConfusionMatrixMeasurements::m_NumberOfClasses
unsigned short m_NumberOfClasses
Definition: otbConfusionMatrixMeasurements.h:179
otb::ConfusionMatrixMeasurements::Compute
void Compute(void)
Definition: otbConfusionMatrixMeasurements.hxx:46