File: ClassificationMapRegularizationExample.cxx

package info (click to toggle)
otb 7.2.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 1,005,476 kB
  • sloc: cpp: 270,143; xml: 128,722; ansic: 4,367; sh: 1,768; python: 1,084; perl: 92; makefile: 72
file content (168 lines) | stat: -rw-r--r-- 5,941 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/*
 * Copyright (C) 2005-2020 Centre National d'Etudes Spatiales (CNES)
 *
 * 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.
 */


// After having generated a classification map, it is possible to
// regularize such a labeled image in order to obtain more homogeneous
// areas, which facilitates its interpretation. For this
// purpose, the \doxygen{otb}{NeighborhoodMajorityVotingImageFilter} was
// implemented. Like a morphological filter, this filter uses majority
// voting in a ball shaped neighborhood in order to set each pixel of the
// classification map to the most representative label value in its
// neighborhood.
//
// In this example we will illustrate its use. We start by including the
// appropriate header file.

#include "otbNeighborhoodMajorityVotingImageFilter.h"

#include "itkMacro.h"
#include "otbImage.h"
#include <iostream>

#include <otbImageFileReader.h>
#include "otbImageFileWriter.h"


int main(int itkNotUsed(argc), char* argv[])
{
  // Since the input image is a classification map, we will assume a
  // single band input image for which each pixel value is a label coded
  // on 8 bits as an integer between 0 and 255.

  using IOLabelPixelType       = unsigned char; // 8 bits
  const unsigned int Dimension = 2;

  // Thus, both input and output images are single band labeled images,
  // which are composed of the same type of pixels in this example
  // (unsigned char).

  using IOLabelImageType = otb::Image<IOLabelPixelType, Dimension>;


  // We can now define the type for the neighborhood majority voting filter,
  // which is templated over its input and output images types as well as its
  // structuring element type. Choosing only the input image type in the template
  // of this filter induces that, both input and output images types are the same
  // and that the structuring element is a ball
  // (\doxygen{itk}{BinaryBallStructuringElement}).

  // Neighborhood majority voting filter type
  using NeighborhoodMajorityVotingFilterType = otb::NeighborhoodMajorityVotingImageFilter<IOLabelImageType>;


  // Since the \doxygen{otb}{NeighborhoodMajorityVotingImageFilter} is a
  // neighborhood based image filter, it is necessary to set the structuring
  // element which will be used for the majority voting process. By default, the
  // structuring element is a ball
  // (\doxygen{itk}{BinaryBallStructuringElement}) with a radius defined by two sizes
  // (respectively along X and Y). Thus, it is possible to handle anisotropic
  // structuring elements such as ovals.

  // Binary ball Structuring Element type
  using StructuringType = NeighborhoodMajorityVotingFilterType::KernelType;
  using RadiusType      = StructuringType::RadiusType;


  // Finally, we define the reader and the writer.

  using ReaderType = otb::ImageFileReader<IOLabelImageType>;
  using WriterType = otb::ImageFileWriter<IOLabelImageType>;


  const char* inputFileName  = argv[1];
  const char* outputFileName = argv[2];


  // We instantiate the \doxygen{otb}{NeighborhoodMajorityVotingImageFilter} and the
  // reader objects.

  // Neighborhood majority voting filter
  NeighborhoodMajorityVotingFilterType::Pointer NeighMajVotingFilter;
  NeighMajVotingFilter = NeighborhoodMajorityVotingFilterType::New();

  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(inputFileName);


  std::string      KeepOriginalLabelBoolStr = argv[3];
  unsigned int     radiusX                  = atoi(argv[4]);
  unsigned int     radiusY                  = atoi(argv[5]);
  IOLabelPixelType noDataValue              = atoi(argv[6]);
  IOLabelPixelType undecidedValue           = atoi(argv[7]);


  // The ball shaped structuring element seBall is instantiated and its
  // two radii along X and Y are initialized.

  StructuringType seBall;
  RadiusType      rad;

  rad[0] = radiusX;
  rad[1] = radiusY;

  seBall.SetRadius(rad);
  seBall.CreateStructuringElement();


  // Then, this ball shaped neighborhood is used as the kernel structuring element
  // for the \doxygen{otb}{NeighborhoodMajorityVotingImageFilter}.

  NeighMajVotingFilter->SetKernel(seBall);

  // Not classified input pixels are assumed to have the noDataValue label
  // and will keep this label in the output image.

  NeighMajVotingFilter->SetLabelForNoDataPixels(noDataValue);


  // Furthermore, since the majority voting regularization may lead to different
  // majority labels in the neighborhood, in this case, it would be important to define
  // the filter's behaviour. For this purpose, a Boolean parameter is used
  // in the filter to choose whether pixels with more than one majority class are set
  // to undecidedValue (true), or to their Original labels (false = default value)
  // in the output image.


  NeighMajVotingFilter->SetLabelForUndecidedPixels(undecidedValue);

  if (KeepOriginalLabelBoolStr.compare("true") == 0)
  {
    NeighMajVotingFilter->SetKeepOriginalLabelBool(true);
  }
  else
  {
    NeighMajVotingFilter->SetKeepOriginalLabelBool(false);
  }


  // We plug the pipeline and
  // trigger its execution by updating the output of the writer.


  NeighMajVotingFilter->SetInput(reader->GetOutput());

  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName(outputFileName);
  writer->SetInput(NeighMajVotingFilter->GetOutput());
  writer->Update();

  return EXIT_SUCCESS;
}