otbSOMWithMissingValue.txx 4.38 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
 * Copyright (C) 2007-2012 Institut Mines Telecom / Telecom Bretagne
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
Gregoire Mercier's avatar
Gregoire Mercier committed
21

22 23
#ifndef otbSOMWithMissingValue_txx
#define otbSOMWithMissingValue_txx
Gregoire Mercier's avatar
Gregoire Mercier committed
24 25 26 27 28 29 30 31 32

#include "otbSOMWithMissingValue.h"

#include "itkNumericTraits.h"
#include "itkNeighborhoodIterator.h"
#include "otbMacro.h"

namespace otb
{
33 34 35 36 37 38 39 40 41 42 43 44 45 46
template <class TListSample, class TMap,
    class TSOMLearningBehaviorFunctor,
    class TSOMNeighborhoodBehaviorFunctor>
SOMWithMissingValue <TListSample, TMap, TSOMLearningBehaviorFunctor, TSOMNeighborhoodBehaviorFunctor>
::SOMWithMissingValue(void)
{}

template <class TListSample, class TMap,
    class TSOMLearningBehaviorFunctor,
    class TSOMNeighborhoodBehaviorFunctor>
SOMWithMissingValue <TListSample, TMap, TSOMLearningBehaviorFunctor, TSOMNeighborhoodBehaviorFunctor>
::~SOMWithMissingValue(void)
{}

Gregoire Mercier's avatar
Gregoire Mercier committed
47
/**
48
 * Update the output map with a new sample by including the case when some
Gregoire Mercier's avatar
Gregoire Mercier committed
49 50 51 52 53
 * components of this new sample may be missing.
 * \param sample The new sample to learn,
 * \param beta The learning coefficient,
 * \param radius The radius of the nieghbourhood.
 */
OTB Bot's avatar
OTB Bot committed
54
template <class TListSample, class TMap,
OTB Bot's avatar
OTB Bot committed
55 56
    class TSOMLearningBehaviorFunctor,
    class TSOMNeighborhoodBehaviorFunctor>
Gregoire Mercier's avatar
Gregoire Mercier committed
57
void
OTB Bot's avatar
OTB Bot committed
58 59
SOMWithMissingValue<TListSample, TMap, TSOMLearningBehaviorFunctor, TSOMNeighborhoodBehaviorFunctor>
::UpdateMap(const NeuronType& sample, double beta, SizeType& radius)
Gregoire Mercier's avatar
Gregoire Mercier committed
60 61 62 63 64
{
  // output map pointer
  MapPointerType map = this->GetOutput(0);

  // winner index in the map
OTB Bot's avatar
OTB Bot committed
65
  IndexType  position = map->GetWinner(sample);
Gregoire Mercier's avatar
Gregoire Mercier committed
66 67 68
  NeuronType winner = map->GetPixel(position);

  // Local neighborhood definition
OTB Bot's avatar
OTB Bot committed
69 70
  typedef typename MapType::Superclass            ImageMapType;
  typedef itk::NeighborhoodIterator<ImageMapType> NeighborhoodIteratorType;
Gregoire Mercier's avatar
Gregoire Mercier committed
71
  typename MapType::RegionType mapRegion = map->GetLargestPossibleRegion();
OTB Bot's avatar
OTB Bot committed
72
  NeighborhoodIteratorType it(radius, map, mapRegion);
Gregoire Mercier's avatar
Gregoire Mercier committed
73

74
  // Here, the periodic update is achieved 'by hand' since
75
  // PeriodicBoundaryCondition does not allow modifying
Gregoire Mercier's avatar
Gregoire Mercier committed
76
  // VectorImage contents
OTB Bot's avatar
OTB Bot committed
77
  SizeType  mapSize = mapRegion.GetSize();
Gregoire Mercier's avatar
Gregoire Mercier committed
78 79
  IndexType positionToUpdate;

80
  // Iterate over the neighborhood of the winner neuron
OTB Bot's avatar
OTB Bot committed
81
  it.SetLocation(position);
Gregoire Mercier's avatar
Gregoire Mercier committed
82

83
  for (unsigned int i = 0; i < it.Size(); ++i)
OTB Bot's avatar
OTB Bot committed
84
    {
Gregoire Mercier's avatar
Gregoire Mercier committed
85
    typename NeighborhoodIteratorType::OffsetType offset = it.GetOffset(i);
86

Gregoire Mercier's avatar
Gregoire Mercier committed
87
    // The neighborhood is of elliptic shape
OTB Bot's avatar
OTB Bot committed
88
    double theDistance = itk::NumericTraits<double>::Zero;
89
    for (unsigned int j = 0; j < MapType::ImageDimension; ++j)
OTB Bot's avatar
OTB Bot committed
90 91
      theDistance += pow(static_cast<double>(offset[j]), 2.0)
                     / pow(static_cast<double>(radius[j]), 2.0);
Gregoire Mercier's avatar
Gregoire Mercier committed
92

OTB Bot's avatar
OTB Bot committed
93
    if (theDistance <= 1.0)
Gregoire Mercier's avatar
Gregoire Mercier committed
94
      {
95
      for (unsigned int j = 0; j < MapType::ImageDimension; ++j)
OTB Bot's avatar
OTB Bot committed
96
        {
Gregoire Mercier's avatar
Gregoire Mercier committed
97
        int pos = offset[j] + position[j];
OTB Bot's avatar
OTB Bot committed
98 99 100 101
        positionToUpdate[j] = (pos >= 0) ?
                              pos % mapSize[j] :
                              (mapSize[j] - ((-pos) % mapSize[j])) % mapSize[j];
        }
Gregoire Mercier's avatar
Gregoire Mercier committed
102 103

      NeuronType tempNeuron = it.GetPixel(i);
OTB Bot's avatar
OTB Bot committed
104
      NeuronType newNeuron(tempNeuron);
Gregoire Mercier's avatar
Gregoire Mercier committed
105

OTB Bot's avatar
OTB Bot committed
106
      double tempBeta = beta / (1.0 + theDistance);
107
      for (unsigned int j = 0; j < newNeuron.Size(); ++j)
OTB Bot's avatar
OTB Bot committed
108 109
        {
        if (!DistanceType::IsMissingValue(sample[j]))
Gregoire Mercier's avatar
Gregoire Mercier committed
110
          newNeuron[j] += static_cast<typename NeuronType::ValueType>(
OTB Bot's avatar
OTB Bot committed
111 112 113
            (sample[j] - tempNeuron[j]) * tempBeta);
        }
      map->SetPixel(positionToUpdate, newNeuron);
Gregoire Mercier's avatar
Gregoire Mercier committed
114 115 116 117
      }
    }
}

118 119 120 121 122 123 124 125 126 127 128
template <class TListSample, class TMap,
    class TSOMLearningBehaviorFunctor,
    class TSOMNeighborhoodBehaviorFunctor>
void
SOMWithMissingValue<TListSample, TMap, TSOMLearningBehaviorFunctor, TSOMNeighborhoodBehaviorFunctor>
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  Superclass::PrintSelf(os, indent);

} // end PrintSelf

Gregoire Mercier's avatar
Gregoire Mercier committed
129 130 131
} // end iof namespace otb

#endif