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
|
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
// Software Guide : BeginLatex
//
// The K-Means classification proposed by ITK for images is limited to
// scalar images and is not streamed. In this example, we show
// how the use of the \doxygen{otb}{KMeansImageClassificationFilter}
// allows for a simple implementation of a K-Means classification
// application. We will start by including the appropirate header file.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
#include "otbKMeansImageClassificationFilter.h"
// Software Guide : EndCodeSnippet
#include "otbVectorImage.h"
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
int main(int itkNotUsed(argc), char * argv[])
{
const char * infname = argv[1];
const char * outfname = argv[2];
const unsigned int nbClasses = atoi(argv[3]);
// Software Guide : BeginLatex
//
// We will assume double precision input images and will also define
// the type for the labeled pixels.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
const unsigned int Dimension = 2;
typedef double PixelType;
typedef unsigned short LabeledPixelType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Our classifier will be generic enough to be able to process images
// with any number of bands. We read the images as
// \doxygen{otb}{VectorImage}s. The labeled image will be a scalar image.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::VectorImage<PixelType, Dimension> ImageType;
typedef otb::Image<LabeledPixelType, Dimension> LabeledImageType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We can now define the type for the classifier filter, which is
// templated over its input and output image types.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::KMeansImageClassificationFilter<ImageType, LabeledImageType>
ClassificationFilterType;
typedef ClassificationFilterType::KMeansParametersType KMeansParametersType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// And finally, we define the reader and the writer. Since the images
// to classify can be very big, we will use a streamed writer which
// will trigger the streaming ability of the classifier.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::ImageFileReader<ImageType> ReaderType;
typedef otb::ImageFileWriter<LabeledImageType> WriterType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We instantiate the classifier and the reader objects and we set
// their parameters. Please note the call of the
// \code{GenerateOutputInformation()} method on the reader in order to
// have available the information about the input image (size, number
// of bands, etc.) without needing to actually read the image.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
ClassificationFilterType::Pointer filter = ClassificationFilterType::New();
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName(infname);
reader->GenerateOutputInformation();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The classifier needs as input the centroids of
// the classes. We declare the parameter vector, and we read the
// centroids from the arguments of the program.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
const unsigned int sampleSize =
ClassificationFilterType::MaxSampleDimension;
const unsigned int parameterSize = nbClasses * sampleSize;
KMeansParametersType parameters;
parameters.SetSize(parameterSize);
parameters.Fill(0);
for (unsigned int i = 0; i < nbClasses; ++i)
{
for (unsigned int j = 0; j <
reader->GetOutput()->GetNumberOfComponentsPerPixel(); ++j)
{
parameters[i * sampleSize + j] =
atof(argv[4 + i *
reader->GetOutput()->GetNumberOfComponentsPerPixel()
+ j]);
}
}
std::cout << "Parameters: " << parameters << std::endl;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We set the parameters for the classifier, we plug the pipeline and
// trigger its execution by updating the output of the writer.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
filter->SetCentroids(parameters);
filter->SetInput(reader->GetOutput());
WriterType::Pointer writer = WriterType::New();
writer->SetInput(filter->GetOutput());
writer->SetFileName(outfname);
writer->Update();
// Software Guide : EndCodeSnippet
return EXIT_SUCCESS;
}
|