ClassificationMapRegularizationExample.cxx 7.27 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
/*
 * Copyright (C) 2005-2017 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.
 */
20 21 22 23 24 25


// Software Guide : BeginLatex
//
// After having generated a classification map, it is possible to
// regularize such a labeled image in order to obtain more homogeneous
26
// areas, which facilitates its interpretation. For this
27 28 29
// 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
30
// classification map to the most representative label value in its
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
// neighborhood.
//
// In this example we will illustrate its use. We start by including the
// appropriate header file.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "otbNeighborhoodMajorityVotingImageFilter.h"
// Software Guide : EndCodeSnippet

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

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


50
int main(int itkNotUsed(argc), char * argv[])
51 52 53 54 55 56 57 58 59
{
// Software Guide : BeginLatex
//
// 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.
//
// Software Guide : EndLatex

OTB Bot's avatar
STYLE  
OTB Bot committed
60
// Software Guide : BeginCodeSnippet
61
  typedef unsigned char IOLabelPixelType; // 8 bits
62 63
  const unsigned int Dimension = 2;
// Software Guide : EndCodeSnippet
64

65 66 67 68 69 70 71
// Software Guide : BeginLatex
//
// 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).
//
// Software Guide : EndLatex
72

OTB Bot's avatar
STYLE  
OTB Bot committed
73
// Software Guide : BeginCodeSnippet
74
  typedef otb::Image<IOLabelPixelType, Dimension> IOLabelImageType;
75 76 77 78 79 80
// Software Guide : EndCodeSnippet


// Software Guide : BeginLatex
//
// We can now define the type for the neighborhood majority voting filter,
81
// which is templated over its input and output images types as well as its
82 83 84 85
// 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}).
86 87
//
// Software Guide : EndLatex
88

OTB Bot's avatar
STYLE  
OTB Bot committed
89
// Software Guide : BeginCodeSnippet
90
  // Neighborhood majority voting filter type
91 92
  typedef otb::NeighborhoodMajorityVotingImageFilter<IOLabelImageType>
   NeighborhoodMajorityVotingFilterType;
93 94 95 96 97 98 99 100 101 102 103 104 105 106
// Software Guide : EndCodeSnippet


// Software Guide : BeginLatex
//
// 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.
//
// Software Guide : EndLatex
107

108 109 110 111 112 113 114 115 116 117 118 119 120 121
// Software Guide : BeginCodeSnippet
  // Binary ball Structuring Element type
  typedef NeighborhoodMajorityVotingFilterType::KernelType StructuringType;
  typedef StructuringType::RadiusType RadiusType;
// Software Guide : EndCodeSnippet


// Software Guide : BeginLatex
//
// Finally, we define the reader and the writer.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
122 123
  typedef otb::ImageFileReader<IOLabelImageType> ReaderType;
  typedef otb::ImageFileWriter<IOLabelImageType> WriterType;
124
// Software Guide : EndCodeSnippet
125 126


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

130 131 132

// Software Guide : BeginLatex
//
OTB Bot's avatar
STYLE  
OTB Bot committed
133
// We instantiate the \doxygen{otb}{NeighborhoodMajorityVotingImageFilter} and the
134 135 136 137 138 139 140 141
// reader objects.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  // Neighborhood majority voting filter
  NeighborhoodMajorityVotingFilterType::Pointer NeighMajVotingFilter;
  NeighMajVotingFilter = NeighborhoodMajorityVotingFilterType::New();
142

143 144 145
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName(inputFileName);
// Software Guide : EndCodeSnippet
146 147


148 149 150
  std::string KeepOriginalLabelBoolStr = argv[3];
  unsigned int radiusX = atoi(argv[4]);
  unsigned int radiusY = atoi(argv[5]);
151 152
  IOLabelPixelType noDataValue = atoi(argv[6]);
  IOLabelPixelType undecidedValue = atoi(argv[7]);
153 154


155 156 157 158 159 160
// Software Guide : BeginLatex
//
// The ball shaped structuring element seBall is instantiated and its
// two radii along X and Y are initialized.
//
// Software Guide : EndLatex
161

162 163 164
// Software Guide : BeginCodeSnippet
  StructuringType seBall;
  RadiusType rad;
165

166 167 168 169 170 171
  rad[0] = radiusX;
  rad[1] = radiusY;

  seBall.SetRadius(rad);
  seBall.CreateStructuringElement();
// Software Guide : EndCodeSnippet
172 173


174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
// Software Guide : BeginLatex
//
// Then, this ball shaped neighborhood is used as the kernel structuring element
// for the \doxygen{otb}{NeighborhoodMajorityVotingImageFilter}.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  NeighMajVotingFilter->SetKernel(seBall);
// Software Guide : EndCodeSnippet

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

// Software Guide : BeginCodeSnippet
  NeighMajVotingFilter->SetLabelForNoDataPixels(noDataValue);
// Software Guide : EndCodeSnippet


// Software Guide : BeginLatex
//
199 200 201
// 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
202 203 204 205 206 207 208 209 210
// 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.
//
// Software Guide : EndLatex


// Software Guide : BeginCodeSnippet
  NeighMajVotingFilter->SetLabelForUndecidedPixels(undecidedValue);
211

212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232
  if (KeepOriginalLabelBoolStr.compare("true") == 0)
  {
    NeighMajVotingFilter->SetKeepOriginalLabelBool(true);
  }
  else
  {
    NeighMajVotingFilter->SetKeepOriginalLabelBool(false);
  }
// Software Guide : EndCodeSnippet


// Software Guide : BeginLatex
//
// We plug the pipeline and
// trigger its execution by updating the output of the writer.
//
// Software Guide : EndLatex


// Software Guide : BeginCodeSnippet
  NeighMajVotingFilter->SetInput(reader->GetOutput());
233

234 235 236 237 238
  WriterType::Pointer writer = WriterType::New();
  writer->SetFileName(outputFileName);
  writer->SetInput(NeighMajVotingFilter->GetOutput());
  writer->Update();
// Software Guide : EndCodeSnippet
239

240 241
  return EXIT_SUCCESS;
}