22 #ifndef otbMarkovRandomFieldFilter_hxx
23 #define otbMarkovRandomFieldFilter_hxx
28 template <
class TInputImage,
class TClassifiedImage>
30 : m_NumberOfClasses(0),
31 m_MaximumNumberOfIterations(50),
33 m_ImageDeltaEnergy(0.0),
34 m_NeighborhoodRadius(1),
35 m_TotalNumberOfValidPixelsInOutputImage(1),
36 m_TotalNumberOfPixelsInInputImage(1),
37 m_ErrorTolerance(0.0),
38 m_SmoothingFactor(1.0),
39 m_NumberOfIterations(0),
41 m_ExternalClassificationSet(false),
42 m_StopCondition(MaximumNumberOfIterations)
47 this->SetNumberOfRequiredInputs(1);
50 std::ostringstream msg;
52 throw itk::ExceptionObject(__FILE__, __LINE__, msg.str(), ITK_LOCATION);
64 template <
class TInputImage,
class TClassifiedImage>
67 m_ExternalClassificationSet =
true;
69 this->itk::ProcessObject::SetNthInput(1,
const_cast<TrainingImageType*
>(trainingImage));
73 template <
class TInputImage,
class TClassifiedImage>
77 if (this->GetNumberOfInputs() < 2)
81 return static_cast<const TrainingImageType*
>(this->itk::ProcessObject::GetInput(1));
84 template <
class TInputImage,
class TClassifiedImage>
87 Superclass::PrintSelf(os, indent);
89 os << indent <<
" MRF Image filter object " << std::endl;
91 os << indent <<
" Number of classes: " << m_NumberOfClasses << std::endl;
93 os << indent <<
" Maximum number of iterations: " << m_MaximumNumberOfIterations << std::endl;
95 os << indent <<
" Error tolerance for convergence: " << m_ErrorTolerance << std::endl;
97 os << indent <<
" Size of the MRF neighborhood radius:" << m_InputImageNeighborhoodRadius << std::endl;
99 os << indent <<
"StopCondition: " << m_StopCondition << std::endl;
101 os << indent <<
" Number of iterations: " << m_NumberOfIterations << std::endl;
103 os << indent <<
" Lambda: " << m_Lambda << std::endl;
109 template <
class TInputImage,
class TClassifiedImage>
116 inputPtr->SetRequestedRegion(outputPtr->GetRequestedRegion());
123 template <
class TInputImage,
class TClassifiedImage>
128 TClassifiedImage* imgData;
129 imgData =
dynamic_cast<TClassifiedImage*
>(output);
130 imgData->SetRequestedRegionToLargestPossibleRegion();
137 template <
class TInputImage,
class TClassifiedImage>
140 typename TInputImage::ConstPointer input = this->GetInput();
141 typename TClassifiedImage::Pointer output = this->GetOutput();
142 output->SetLargestPossibleRegion(input->GetLargestPossibleRegion());
146 template <
class TInputImage,
class TClassifiedImage>
159 this->ApplyMarkovRandomFieldFilter();
166 template <
class TInputImage,
class TClassifiedImage>
171 for (
unsigned int i = 0; i < InputImageDimension; ++i)
173 radius[i] = radiusValue;
175 this->SetNeighborhoodRadius(radius);
183 template <
class TInputImage,
class TClassifiedImage>
187 for (
unsigned int i = 0; i < InputImageDimension; ++i)
189 radius[i] = radiusArray[i];
192 this->SetNeighborhoodRadius(radius);
200 template <
class TInputImage,
class TClassifiedImage>
204 for (
unsigned int i = 0; i < InputImageDimension; ++i)
206 m_InputImageNeighborhoodRadius[i] = radius[i];
207 m_LabelledImageNeighborhoodRadius[i] = radius[i];
217 template <
class TInputImage,
class TClassifiedImage>
224 outputPtr->SetBufferedRegion(outputPtr->GetRequestedRegion());
225 outputPtr->Allocate();
231 if (m_ExternalClassificationSet)
233 typename TrainingImageType::ConstPointer trainingImage = this->GetTrainingInput();
236 while (!outImageIt.IsAtEnd())
240 outImageIt.Set(labelvalue);
248 while (!outImageIt.IsAtEnd())
251 outImageIt.Set(randomvalue);
261 template <
class TInputImage,
class TClassifiedImage>
265 m_ImageDeltaEnergy = 0.0;
273 m_TotalNumberOfPixelsInInputImage = 1;
274 m_TotalNumberOfValidPixelsInOutputImage = 1;
276 for (
unsigned int i = 0; i < InputImageDimension; ++i)
278 m_TotalNumberOfPixelsInInputImage *=
static_cast<int>(inputImageSize[i]);
280 m_TotalNumberOfValidPixelsInOutputImage *= (
static_cast<int>(inputImageSize[i]) - 2 * m_InputImageNeighborhoodRadius[i]);
283 srand((
unsigned)time(
nullptr));
285 if (!m_EnergyRegularization)
287 itkExceptionMacro(<<
"EnergyRegularization is not present");
290 if (!m_EnergyFidelity)
292 itkExceptionMacro(<<
"EnergyFidelity is not present");
297 itkExceptionMacro(<<
"Optimizer is not present");
302 itkExceptionMacro(<<
"Sampler is not present");
305 m_Sampler->SetLambda(m_Lambda);
306 m_Sampler->SetEnergyRegularization(m_EnergyRegularization);
307 m_Sampler->SetEnergyFidelity(m_EnergyFidelity);
308 m_Sampler->SetNumberOfClasses(m_NumberOfClasses);
314 template <
class TInputImage,
class TClassifiedImage>
319 int maxNumPixelError = itk::Math::Round<int, double>(m_ErrorTolerance * m_TotalNumberOfPixelsInInputImage);
321 m_NumberOfIterations = 0;
322 m_ErrorCounter = m_TotalNumberOfValidPixelsInOutputImage;
324 while ((m_NumberOfIterations < m_MaximumNumberOfIterations) && (m_ErrorCounter >= maxNumPixelError))
328 this->MinimizeOnce();
330 otbMsgDevMacro(<<
"m_ErrorCounter/m_TotalNumberOfPixelsInInputImage: " << m_ErrorCounter / ((
double)(m_TotalNumberOfPixelsInInputImage)));
333 ++m_NumberOfIterations;
336 otbMsgDevMacro(<<
"m_NumberOfIterations: " << m_NumberOfIterations);
337 otbMsgDevMacro(<<
"m_MaximumNumberOfIterations: " << m_MaximumNumberOfIterations);
342 if (m_NumberOfIterations >= m_MaximumNumberOfIterations)
344 m_StopCondition = MaximumNumberOfIterations;
346 else if (m_ErrorCounter <= maxNumPixelError)
348 m_StopCondition = ErrorTolerance;
356 template <
class TInputImage,
class TClassifiedImage>
364 for (labelledIterator.GoToBegin(), dataIterator.GoToBegin(); !labelledIterator.IsAtEnd(); ++labelledIterator, ++dataIterator)
368 bool changeValueBool;
369 m_Sampler->Compute(dataIterator, labelledIterator);
370 value = m_Sampler->GetValue();
371 changeValueBool = m_Optimizer->Compute(m_Sampler->GetDeltaEnergy());
374 labelledIterator.SetCenterPixel(value);
376 m_ImageDeltaEnergy += m_Sampler->GetDeltaEnergy();