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
|
/*
* Copyright (C) 2005-2022 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:
./TextureExample Input/ADS40RoiSmall.png Output/TextureOutput.tif Output/pretty_TextureOutput.png 2 1 1
*/
#include "itkMacro.h"
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
// Pretty RGB output
#include "otbVectorImage.h"
#include "otbImageToVectorImageCastFilter.h"
#include "otbVectorRescaleIntensityImageFilter.h"
#include "otbScalarImageToTexturesFilter.h"
int main(int argc, char* argv[])
{
// Parse command line parameters
if (argc != 7)
{
std::cerr << "Usage: " << argv[0] << " <inputImage> ";
std::cerr << " <outputImage> <outputRescaled> ";
std::cerr << " <radius> <xOffset> <yOffset> ";
std::cerr << std::endl;
return EXIT_FAILURE;
}
const char* infname = argv[1];
const char* outfname = argv[2];
const char* outprettyfname = argv[3];
const unsigned int radius = static_cast<unsigned int>(atoi(argv[4]));
const unsigned int xOffset = static_cast<unsigned int>(atoi(argv[5]));
const unsigned int yOffset = static_cast<unsigned int>(atoi(argv[6]));
using PixelType = double;
const int Dimension = 2;
using ImageType = otb::Image<PixelType, Dimension>;
// After defining the types for the pixels and the images used in the
// example, we define the types for the textures filter. It is
// templated by the input and output image types.
using TexturesFilterType = otb::ScalarImageToTexturesFilter<ImageType, ImageType>;
using ReaderType = otb::ImageFileReader<ImageType>;
using WriterType = otb::ImageFileWriter<ImageType>;
ReaderType::Pointer reader = ReaderType::New();
WriterType::Pointer writer = WriterType::New();
reader->SetFileName(infname);
writer->SetFileName(outfname);
// We can now instantiate the filters.
TexturesFilterType::Pointer texturesFilter = TexturesFilterType::New();
// The texture filters takes at least 2 parameters: the radius of the
// neighborhood on which the texture will be computed and the offset
// used. Texture features are bivariate statistics, that is, they are
// computed using pair of pixels. Each texture feature is defined for
// an offset defining the pixel pair.
//
// The radius parameter can be passed to the filter as a scalar
// parameter if the neighborhood is square, or as \code{SizeType} in
// any case.
//
// The offset is always an array of N values, where N is the number of
// dimensions of the image.
using SizeType = ImageType::SizeType;
SizeType sradius;
sradius.Fill(radius);
texturesFilter->SetRadius(sradius);
using OffsetType = ImageType::OffsetType;
OffsetType offset;
offset[0] = xOffset;
offset[1] = yOffset;
texturesFilter->SetOffset(offset);
// The textures filter will automatically derive the optimal
// bin size for co-occurences histogram, but they need to know
// the input image minimum and maximum. These values can be set
// like this :
texturesFilter->SetInputImageMinimum(0);
texturesFilter->SetInputImageMaximum(255);
// To tune co-occurence histogram resolution, you can use
// the SetNumberOfBinsPerAxis() method.
// We can now plug the pipeline.
texturesFilter->SetInput(reader->GetOutput());
writer->SetInput(texturesFilter->GetInertiaOutput());
writer->Update();
// Pretty image creation for printing
using VectorImageType = otb::VectorImage<double, 2>;
using PrettyVectorImageType = otb::VectorImage<unsigned char, 2>;
using WriterPrettyOutputType = otb::ImageFileWriter<PrettyVectorImageType>;
using VectorCastFilterType = otb::ImageToVectorImageCastFilter<ImageType, VectorImageType>;
using RescalerOutputType = otb::VectorRescaleIntensityImageFilter<VectorImageType, PrettyVectorImageType>;
RescalerOutputType::Pointer outputRescaler = RescalerOutputType::New();
WriterPrettyOutputType::Pointer prettyOutputWriter = WriterPrettyOutputType::New();
VectorCastFilterType::Pointer vectorCastFilter = VectorCastFilterType::New();
vectorCastFilter->SetInput(texturesFilter->GetInertiaOutput());
outputRescaler->SetInput(vectorCastFilter->GetOutput());
PrettyVectorImageType::PixelType min(1), max(1);
min.Fill(0);
max.Fill(255);
outputRescaler->SetOutputMinimum(min);
outputRescaler->SetOutputMaximum(max);
prettyOutputWriter->SetFileName(outprettyfname);
prettyOutputWriter->SetInput(outputRescaler->GetOutput());
prettyOutputWriter->Update();
}
|