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
|
/*
* 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.
*/
/* Example usage:
./LabelMapToVectorData Input/labelImage_UnsignedChar.tif Output/LabelMapToVectorData.shp
*/
// \index{otb::LabelMapToVectorDataFilter}
//
//
// This class vectorizes a LabelObject to a VectorData.
//
// The \doxygen{otb}{LabelMapToVectorDataFilter} converts an \doxygen{itk}{LabelMap} to an
// \doxygen{otb}{VectorData} where all the pixels get the attribute
// value of the label object they belong to.
// It uses the class \doxygen{otb}{LabelObjectToPolygonFunctor} which
// follows a finite state machine described in \cite{Francis2000}.
//
// Only polygon conversion is available yet.
#include "otbImageFileReader.h"
#include "otbVectorDataFileWriter.h"
#include "otbVectorData.h"
#include "otbVectorDataProjectionFilter.h"
#include <fstream>
#include <iostream>
#include "otbImage.h"
// These are the main header files which need to be included:
#include "otbLabelMapToVectorDataFilter.h"
#include "otbAttributesMapLabelObject.h"
#include "itkLabelImageToLabelMapFilter.h"
int main(int argc, char* argv[])
{
/** Use the labelObjecttopolygon functor (not thread safe) only polygon conversion is available yet*/
if (argc != 3)
{
std::cerr << "Usage: " << argv[0];
std::cerr << " inputImageFile outputVectorfile(shp)" << std::endl;
return EXIT_FAILURE;
}
const char* infname = argv[1];
const char* outfname = argv[2];
// The image types are defined using pixel types and
// dimension. The input image is defined as an \doxygen{itk}{Image},
// the output is a \doxygen{otb}{VectorData}.
const unsigned int Dimension = 2;
using LabelType = unsigned short;
using LabeledImageType = otb::Image<LabelType, Dimension>;
using VectorDataType = otb::VectorData<double, 2>;
// We instantiate reader and writer types
using LabeledReaderType = otb::ImageFileReader<LabeledImageType>;
using WriterType = otb::VectorDataFileWriter<VectorDataType>;
// Label map typedef
// The Attribute Label Map is
// instantiated using the image pixel types as template parameters.
// The LabelObjectToPolygonFunctor is instantiated with LabelObjectType and PolygonType.
using LabelObjectType = otb::AttributesMapLabelObject<LabelType, Dimension, double>;
using LabelMapType = itk::LabelMap<LabelObjectType>;
using LabelMapFilterType = itk::LabelImageToLabelMapFilter<LabeledImageType, LabelMapType>;
LabeledReaderType::Pointer lreader = LabeledReaderType::New();
WriterType::Pointer writer = WriterType::New();
// Now the reader and writer are instantiated and
// the input image is set and a name is given to the output image.
lreader->SetFileName(infname);
writer->SetFileName(outfname);
// Then, the input image is converted to a map of label objects.
// Here each white region connected regions are converted. So the background is define all zero pixels.
LabelMapFilterType::Pointer labelMapFilter = LabelMapFilterType::New();
labelMapFilter->SetInput(lreader->GetOutput());
labelMapFilter->SetBackgroundValue(itk::NumericTraits<LabelType>::min());
labelMapFilter->Update();
// Then, the \doxygen{otb}{LabelMapToVectorDataFilter} is instantiated. This is
// the main filter which performs the vectorization.
using LabelMapToVectorDataFilterType = otb::LabelMapToVectorDataFilter<LabelMapType, VectorDataType>;
LabelMapToVectorDataFilterType::Pointer MyFilter = LabelMapToVectorDataFilterType::New();
MyFilter->SetInput(labelMapFilter->GetOutput());
MyFilter->Update();
MyFilter->GetOutput()->SetProjectionRef(lreader->GetOutput()->GetProjectionRef());
// The output can be passed to a writer.
writer->SetInput(MyFilter->GetOutput());
// The invocation of the \code{Update()} method on the writer triggers the
// execution of the pipeline. As usual, it is recommended to place update calls in a
// \code{try/catch} block in case errors occur and exceptions are thrown.
try
{
writer->Update();
return EXIT_SUCCESS;
}
catch (itk::ExceptionObject& excep)
{
std::cerr << "Exception caught !" << std::endl;
std::cerr << excep << std::endl;
}
catch (...)
{
std::cout << "Unknown exception !" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
|