Commit 0326969a authored by Victor Poughon's avatar Victor Poughon
Browse files

DOC: Render examples in the CookBook

No related merge requests found
Showing with 668 additions and 823 deletions
+668 -823
......@@ -117,10 +117,15 @@ file(COPY ${RST_SOURCE_DIR} DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/Art DESTINATION ${RST_BINARY_DIR})
# Create symlinks to otb-data/Output and otb-data/Input in the rst build directory
# Used for including figures and images in the CookBook
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${OTB_DATA_ROOT}/Output" "${RST_BINARY_DIR}/Output")
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${OTB_DATA_ROOT}/Input" "${RST_BINARY_DIR}/Input")
set(SPHINX_CONF_DIR ${CMAKE_CURRENT_BINARY_DIR})
string(TIMESTAMP OTB_COPYRIGHT_YEAR "%Y")
set(OTB_COPYRIGHT_TEXT "${OTB_COPYRIGHT_YEAR} CNES.The OTB CookBook is licensed under a Creative Commons Attribution-ShareAlike 4.0 International license (CC-BY-SA)")
set(OTB_COPYRIGHT_TEXT "${OTB_COPYRIGHT_YEAR} CNES. The OTB CookBook is licensed under a Creative Commons Attribution-ShareAlike 4.0 International license (CC-BY-SA).")
configure_file(${RST_SOURCE_DIR}/conf.py.in ${SPHINX_CONF_DIR}/conf.py @ONLY)
......@@ -130,7 +135,16 @@ add_custom_target(generate_otbapps_rst
COMMAND ${SH_INTERP} ${CMAKE_CURRENT_BINARY_DIR}/RunApplicationsRstGenerator.sh
${RST_BINARY_DIR}
WORKING_DIRECTORY ${RST_BINARY_DIR}
COMMENT "Auto-generating Application Reference Documentation in RST"
COMMENT "Auto-generating Application Documentation in RST"
DEPENDS OTBSWIGWrapper-all
)
add_custom_target(generate_examples_rst
COMMAND "python3" ${CMAKE_CURRENT_SOURCE_DIR}/Scripts/otbGenerateExamplesRstDoc.py
${RST_BINARY_DIR}
${CMAKE_SOURCE_DIR}
WORKING_DIRECTORY ${RST_BINARY_DIR}
COMMENT "Auto-generating Examples in RST"
DEPENDS OTBSWIGWrapper-all
)
......@@ -152,6 +166,7 @@ add_custom_target(CookBookHTML
-c ${SPHINX_CONF_DIR}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS generate_otbapps_rst
DEPENDS generate_examples_rst
COMMENT "Building RST documentation in html")
add_custom_target(CookBookArchive
......
#!/usr/bin/env python3
#
# Copyright (C) 2005-2019 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.
#
import argparse
import glob
import subprocess
import os
from os.path import join
import re
def run_example(otb_root, otb_data, name, dry_run):
"""
Run an example by name
Assumes the current working directory is an OTB build
"""
# Find binary in bin/
binary_names = glob.glob(join("bin", name))
if len(binary_names) == 0:
raise RuntimeError("Can't find binary for {}".format(name))
if len(binary_names) > 1:
raise RuntimeError("Found {} binaries for {}".format(len(binary_names), name))
binary = os.path.abspath(binary_names[0])
# Find source file in otb_root/Examples/<tag>/name
sources_files = glob.glob(join(otb_root, "Examples/*/" + name + ".cxx"))
if len(sources_files) == 0:
raise RuntimeError("Can't find source file for {}".format(name))
if len(sources_files) > 1:
raise RuntimeError("Found {} source files for {}".format(len(sources_files), name))
filename = os.path.abspath(sources_files[0])
# Extract example usage command arguments
usage_rx = r"\/\* Example usage:\n\.\/[a-zA-Z]+ (.*?)\*\/"
match = re.search(usage_rx, open(filename).read(), flags = re.MULTILINE | re.DOTALL)
if not match:
raise RuntimeError("Can't find example usage in {}".format(filename))
example_args = match.group(1).replace("\\\n", "").split()
# Make sure Output dir exists
os.makedirs(join(otb_data, "Output"), exist_ok=True)
print("$ " + binary + " " + " ".join(example_args))
if dry_run:
return
# Execute the example with otb_data as working directory,
# because paths are given relative to otb_data in the example usage
subprocess.check_call([binary, *example_args], cwd=otb_data)
# TODO handle examples with multiple usage (Examples/BasicFilters/DEMToRainbowExample.cxx)
def main():
parser = argparse.ArgumentParser(usage="Run one or all OTB cxx examples")
parser.add_argument("otb_root", help="Path to otb repository")
parser.add_argument("otb_data", help="Path to otb-data repository")
parser.add_argument("--name", type=str, help="Run only one example with then given name")
parser.add_argument("-n", "--dry-run", action='store_true', help="Dry run, only print commands")
parser.add_argument("-k", "--keep-going", action='store_true', help="Keep going after failing examples")
args = parser.parse_args()
if args.name:
run_example(args.otb_root, args.otb_data, args.name, dry_run=args.dry_run)
else:
list_of_examples =[os.path.splitext(os.path.basename(f))[0] for f in glob.glob(join(args.otb_root, "Examples/*/*.cxx"))]
for name in list_of_examples:
try:
run_example(args.otb_root, args.otb_data, name, dry_run=args.dry_run)
except Exception as e:
if args.keep_going:
print("Warning:", e)
else:
raise
if __name__ == "__main__":
main()
#!/usr/bin/env python3
#
# Copyright (C) 2005-2019 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.
#
import argparse
import os
import os.path
from os.path import join
from collections import defaultdict
import re
import glob
from rst_utils import rst_section, RstPageHeading
def generate_examples_index(rst_dir, list_of_examples):
# Compute dictionary of tag -> (list of examples)
tag_files = defaultdict(list)
for filename in list_of_examples:
tag = filename.split("/")[1]
name, _ = os.path.splitext(filename.split("/")[2])
tag_files[tag].append(join(tag, name + ".rst"))
# Render index file and tag index files
os.makedirs(join(rst_dir, "Examples"), exist_ok=True)
index_f = open(join(rst_dir, "Examples.rst"), "w")
index_f.write(RstPageHeading("Examples", 3, ref="cpp-examples"))
for tag, examples_filenames in tag_files.items():
tag_filename = join("Examples", tag + ".rst")
index_f.write("\t" + tag_filename + "\n")
with open(join(rst_dir, tag_filename), "w") as tag_f:
tag_f.write(RstPageHeading(tag, 3))
for examples_filename in examples_filenames:
tag_f.write("\t" + examples_filename + "\n")
def indent(str):
return "\n".join([" " + line for line in str.split("\n")])
def cpp_uncomment(code):
# Strip '// '
return "\n".join([line[4:] for line in code.split("\n")])
def render_example(filename, otb_root):
"Render a cxx example to rst"
# Read the source code of the cxx example
code = open(join(otb_root, filename)).read()
# Don't show the license header to make it nicer,
# and the cookbook is already under a CC license
examples_license_header = open("templates/examples_license_header.txt").read()
code = code.replace(examples_license_header, "")
# Extract usage
# TODO handle multiple usage
rx_usage = r"\/\* Example usage:\n(\.\/[a-zA-Z]+ (.*?))\*\/"
usage_match = re.search(rx_usage, code, flags = re.MULTILINE | re.DOTALL)
if usage_match is None:
print("Warning: no usage found for example " + filename)
example_usage = ""
else:
example_usage = open("templates/example_usage.rst").read().format(indent(usage_match.group(1).strip()))
# Don't show usage in example source
code = re.sub(rx_usage, "", code, flags = re.MULTILINE | re.DOTALL)
# Make the link to the source code
link_name = os.path.basename(filename)
link_href = "https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/raw/develop/" + filename + "?inline=false"
# Read the description from the example .rst file if it exists
example_rst_file = join(otb_root, filename.replace(".cxx", ".rst"))
if os.path.isfile(example_rst_file):
rst_description = open(example_rst_file).read()
else:
rst_description = ""
# Render the template
template_example = open("templates/example.rst").read()
output_rst = template_example.format(
label="example-" + root,
heading=rst_section(name, "="),
description=rst_description,
usage=example_usage,
code=indent(code.strip()),
link_name=link_name,
link_href=link_href
)
return output_rst
if __name__ == "__main__":
parser = argparse.ArgumentParser(usage="Export examples to rst")
parser.add_argument("rst_dir", help="Directory where rst files are generated")
parser.add_argument("otb_root", help="OTB repository root")
args = parser.parse_args()
# Get list of cxx examples as relative paths from otb_root
list_of_examples = [os.path.relpath(p, start=args.otb_root) for p in glob.glob(join(args.otb_root, "Examples/*/*.cxx"))]
print("Generating rst for {} examples".format(len(list_of_examples)))
# Generate example index and tag indexes
generate_examples_index(join(args.rst_dir, "C++"), list_of_examples)
# Generate examples rst
for filename in list_of_examples:
name = os.path.basename(filename)
tag = filename.split("/")[1]
root, ext = os.path.splitext(name)
os.makedirs(join(args.rst_dir, "C++", "Examples", tag), exist_ok=True)
with open(join(args.rst_dir, "C++", "Examples", tag, root + ".rst"), "w") as output_file:
output_file.write(render_example(filename, args.otb_root))
......@@ -29,6 +29,8 @@ from otbApplication import ParameterType_Bool, ParameterType_Int, ParameterType_
from otb_warnings import application_documentation_warnings
from rst_utils import rst_section, RstPageHeading
linesep = os.linesep
def EncloseString(s):
......@@ -179,17 +181,6 @@ def render_choice(app, key):
choices=choice_entries,
)
def rst_section(text, delimiter, ref=None):
"Make a rst section title"
output = ""
if ref is not None:
output += ".. _" + ref + ":\n\n"
output += text + "\n" + delimiter * len(text) + "\n\n"
return output
def rst_parameter_value(app, key):
"Render a parameter value to rst"
......@@ -400,13 +391,6 @@ def GetApplicationTags(appname):
app = otbApplication.Registry.CreateApplication(appname)
return app.GetDocTags()
def RstPageHeading(text, maxdepth, ref=None):
output = rst_section(text, "=", ref=ref)
output += ".. toctree::" + linesep
output += "\t:maxdepth: " + maxdepth + linesep
output += linesep + linesep
return output
def GenerateRstForApplications(rst_dir):
"Generate .rst files for all applications"
......
def rst_section(text, delimiter, ref=None):
"Make a rst section title"
output = ""
if ref is not None:
output += ".. _" + ref + ":\n\n"
output += text + "\n" + delimiter * len(text) + "\n\n"
return output
def RstPageHeading(text, maxdepth, ref=None):
output = rst_section(text, "=", ref=ref)
output += ".. toctree::\n"
output += "\t:maxdepth: {}\n\n\n".format(maxdepth)
return output
.. _cpp-api:
C++ API
=======
.. toctree::
C++/Examples.rst
......@@ -13,5 +13,6 @@ Table of Contents
AdvancedUse
Recipes
Applications
C++
FAQ
Contributors
.. _{label}:
{heading}
{description}
{usage}
Example source code (`{link_name} <{link_href}>`_):
.. code-block:: cpp
{code}
Example usage:
.. code-block:: bash
{}
/*
* Copyright (C) 2005-2019 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.
*/
......@@ -19,88 +19,57 @@
*/
/* Example usage:
./ApplicationExample Input/QB_Suburb.png Output/ApplicationExample.png
*/
// Software Guide : BeginCommandLineArgs
// INPUTS: {QB_Suburb.png}
// OUTPUTS: {ApplicationExample.png}
// Software Guide : EndCommandLineArgs
// Software Guide : BeginLatex
// This example illustrates the creation of an application.
// A new application is a class, which derives from \subdoxygen{otb}{Wrapper}{Application} class.
// We start by including the needed header files.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"
// Software Guide : EndCodeSnippet
namespace otb
{
// Software Guide : BeginLatex
// Application class is defined in Wrapper namespace.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
namespace Wrapper
{
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// ExampleApplication class is derived from Application class.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
class ApplicationExample : public Application
// Software Guide : EndCodeSnippet
{
public:
// Software Guide : BeginLatex
// Class declaration is followed by \code{ITK} public types for the class, the superclass and
// smart pointers.
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef ApplicationExample Self;
typedef Application Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef ApplicationExample Self;
typedef Application Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
// Following macros are necessary to respect ITK object factory mechanisms. Please report
// to \ref{sec:FilterConventions} for additional information.
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
itkNewMacro(Self);
itkTypeMacro(ExampleApplication, otb::Application);
// Software Guide : EndCodeSnippet
private:
// Software Guide : BeginLatex
// \doxygen{otb}{Application} relies on three main private methods: \code{DoInit()}, \code{DoUpdate()}, and \code{DoExecute()}.
// Section \ref{sec:appArchitecture} gives a description a these methods.
// Software Guide : EndLatex
// Software Guide : BeginLatex
// \code{DoInit()} method contains class information and description, parameter set up, and example values.
// Software Guide : EndLatex
void DoInit() override
{
// Software Guide : BeginLatex
// Application name and description are set using following methods :
// \begin{description}
// \item[\code{SetName()}] Name of the application.
......@@ -111,44 +80,36 @@ private:
// \item[\code{SetDocAuthors()}] Set the application Authors. Author List. Format : "John Doe, Winnie the Pooh" \dots
// \item[\code{SetDocSeeAlso()}] If the application is related to one another, it can be mentioned.
// \end{description}
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
SetName("Example");
SetDescription("This application opens an image and save it. "
"Pay attention, it includes Latex snippets in order to generate "
"software guide documentation");
SetDescription(
"This application opens an image and save it. "
"Pay attention, it includes Latex snippets in order to generate "
"software guide documentation");
SetDocName("Example");
SetDocLongDescription("The purpose of this application is "
"to present parameters types,"
" and Application class framework. "
"It is used to generate Software guide documentation"
" for Application chapter example.");
SetDocLongDescription(
"The purpose of this application is "
"to present parameters types,"
" and Application class framework. "
"It is used to generate Software guide documentation"
" for Application chapter example.");
SetDocLimitations("None");
SetDocAuthors("OTB-Team");
SetDocSeeAlso(" ");
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
// \code{AddDocTag()} method categorize the application using relevant tags.
// The header file \code{otbWrapperTags.h} in OTB sources contains some predefined tags defined in \code{Tags} namespace.
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
AddDocTag(Tags::Analysis);
AddDocTag("Test");
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
// Application parameters declaration is done using \code{AddParameter()} method.
// \code{AddParameter()} requires the input parameter type
// (ParameterType\_InputImage, ParameterType\_Int, ParameterType\_Float), its name and description.
// \subdoxygen{otb}{Wrapper}{Application} class contains methods to set parameters characteristics.
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
AddParameter(ParameterType_InputImage, "in", "Input Image");
AddParameter(ParameterType_OutputImage, "out", "Output Image");
......@@ -181,13 +142,11 @@ private:
AddChoice("inchoice.choice1", "Choice 1");
AddChoice("inchoice.choice2", "Choice 2");
AddChoice("inchoice.choice3", "Choice 3");
AddParameter(ParameterType_Float, "inchoice.choice1.floatchoice1"
, "Example of float parameter for choice1");
AddParameter(ParameterType_Float, "inchoice.choice1.floatchoice1", "Example of float parameter for choice1");
SetDefaultParameterFloat("inchoice.choice1.floatchoice1", 0.125);
AddParameter(ParameterType_Float, "inchoice.choice3.floatchoice3"
, "Example of float parameter for choice3");
AddParameter(ParameterType_Float, "inchoice.choice3.floatchoice3", "Example of float parameter for choice3");
SetDefaultParameterFloat("inchoice.choice3.floatchoice3", 5.0);
AddParameter(ParameterType_Group, "ingroup", "Input group");
......@@ -195,14 +154,12 @@ private:
AddParameter(ParameterType_Int, "ingroup.valint", "Example of integer parameter for group");
MandatoryOff("ingroup.valint");
AddParameter(ParameterType_Group, "ingroup.images", "Input Images group");
AddParameter(ParameterType_InputImage, "ingroup.images.inputimage"
, "Input Image");
AddParameter(ParameterType_InputImage, "ingroup.images.inputimage", "Input Image");
MandatoryOff("ingroup.images.inputimage");
AddParameter(ParameterType_Group, "outgroup", "Output group");
MandatoryOff("outgroup");
AddParameter(ParameterType_OutputImage, "outgroup.outputimage"
, "Output Image");
AddParameter(ParameterType_OutputImage, "outgroup.outputimage", "Output Image");
MandatoryOff("outgroup.outputimage");
AddParameter(ParameterType_InputImageList, "il", "Input image list");
MandatoryOff("il");
......@@ -220,58 +177,42 @@ private:
AddParameter(ParameterType_ComplexOutputImage, "cout", "Output complex image");
MandatoryOff("cin");
MandatoryOff("cout");
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
// An example of command-line is automatically generated. Method \code{SetDocExampleParameterValue()} is
// used to set parameters. Dataset should be located in \code{OTB-Data/Examples} directory.
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
SetDocExampleParameterValue("boolean", "true");
SetDocExampleParameterValue("in", "QB_Suburb.png");
SetDocExampleParameterValue("out", "Application_Example.png");
// Software Guide : EndCodeSnippet
}
// Software Guide : BeginLatex
// \code{DoUpdateParameters()} is called as soon as a parameter value change. Section \ref{sec:appDoUpdateParameters}
// gives a complete description of this method.
// Software Guide : EndLatex
// Software Guide :BeginCodeSnippet
void DoUpdateParameters() override
{
}
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
// \code{DoExecute()} contains the application core. Section \ref{sec:appDoExecute}
// gives a complete description of this method.
// Software Guide : EndLatex
// Software Guide :BeginCodeSnippet
void DoExecute() override
{
FloatVectorImageType::Pointer inImage = GetParameterImage("in");
int paramInt = GetParameterInt("param2");
otbAppLogDEBUG( << paramInt << std::endl );
otbAppLogDEBUG(<< paramInt << std::endl);
int paramFloat = GetParameterFloat("param3");
otbAppLogINFO( << paramFloat );
otbAppLogINFO(<< paramFloat);
SetParameterOutputImage("out", inImage);
}
// Software Guide :EndCodeSnippet
};
}
}
} // namespace Wrapper
} // namespace otb
// Software Guide : BeginLatex
// Finally \code{OTB\_APPLICATION\_EXPORT} is called:
// Software Guide : EndLatex
// Software Guide :BeginCodeSnippet
OTB_APPLICATION_EXPORT(otb::Wrapper::ApplicationExample)
// Software Guide :EndCodeSnippet
......@@ -18,20 +18,18 @@
* limitations under the License.
*/
/* Example usage:
./BandMathFilterExample Input/qb_RoadExtract.tif Output/RoadExtractBandMath.tif Output/qb_BandMath-pretty.jpg
*/
// Software Guide : BeginCommandLineArgs
// INPUTS: {qb_RoadExtract.tif}
// OUTPUTS: {RoadExtractBandMath.tif}, {qb_BandMath-pretty.jpg}
// Software Guide : EndCommandLineArgs
// Software Guide : BeginLatex
// Software Guide : BeginDescription
//
// This filter is based on the mathematical parser library muParser.
// The built in functions and operators list is available at:
// \url{http://muparser.sourceforge.net/mup_features.html}.
// This filter is based on the mathematical parser library muParser.
// The built in functions and operators list is available at:
// http://muparser.sourceforge.net/mup_features.html.
//
// In order to use this filter, at least one input image should be
// In order to use this filter, at least one input image should be
// set. An associated variable name can be specified or not by using
// the corresponding SetNthInput method. For the nth input image, if
// no associated variable name has been specified, a default variable
......@@ -40,9 +38,9 @@
//
// The next step is to set the expression according to the variable
// names. For example, in the default case with three input images the
// following expression is valid : "(b1+b2)*b3".
// following expression is valid: ``(b1+b2)*b3``.
//
// Software Guide : EndLatex
// Software Guide : EndDescription
#include "itkMacro.h"
#include <iostream>
......@@ -55,66 +53,39 @@
#include "itkCastImageFilter.h"
#include "otbVectorImageToImageListFilter.h"
// Software Guide : BeginLatex
//
// We start by including the required header file.
// The aim of this example is to compute the Normalized Difference Vegetation Index (NDVI)
// from a multispectral image and then apply a threshold to this
// index to extract areas containing a dense vegetation canopy.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
#include "otbBandMathImageFilter.h"
// Software Guide : EndCodeSnippet
int main( int argc, char* argv[])
int main(int argc, char* argv[])
{
if (argc != 4)
{
{
std::cerr << "Usage: " << argv[0] << " inputImageFile ";
std::cerr << " outputImageFile ";
std::cerr << " outputPrettyImageFile" << std::endl;
return EXIT_FAILURE;
}
}
// Software Guide : BeginLatex
//
// We start by the classical \code{typedef}s needed for reading and
// writing the images. The \doxygen{otb}{BandMathImageFilter} class
// works with \doxygen{otb}{Image} as input, so we need to define additional
// filters to extract each layer of the multispectral image.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef double PixelType;
typedef otb::VectorImage<PixelType, 2> InputImageType;
typedef otb::Image<PixelType, 2> OutputImageType;
typedef otb::ImageList<OutputImageType> ImageListType;
typedef otb::VectorImageToImageListFilter<InputImageType, ImageListType>
VectorImageToImageListType;
typedef otb::ImageFileReader<InputImageType> ReaderType;
typedef otb::ImageFileWriter<OutputImageType> WriterType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We can now define the type for the filter:
//
// Software Guide : EndLatex
// We start by the typedef needed for reading and
// writing the images. The BandMathImageFilter class
// works with Image as input, so we need to define additional
// filters to extract each layer of the multispectral image.
// Software Guide : BeginCodeSnippet
typedef otb::BandMathImageFilter<OutputImageType> FilterType;
// Software Guide : EndCodeSnippet
typedef double PixelType;
typedef otb::VectorImage<PixelType, 2> InputImageType;
typedef otb::Image<PixelType, 2> OutputImageType;
typedef otb::ImageList<OutputImageType> ImageListType;
typedef otb::VectorImageToImageListFilter<InputImageType, ImageListType> VectorImageToImageListType;
typedef otb::ImageFileReader<InputImageType> ReaderType;
typedef otb::ImageFileWriter<OutputImageType> WriterType;
// Software Guide : BeginLatex
//
// We instantiate the filter, the reader, and the writer:
//
// Software Guide : EndLatex
// We can now define the type for the filter:
typedef otb::BandMathImageFilter<OutputImageType> FilterType;
// Software Guide : BeginCodeSnippet
// We instantiate the filter, the reader, and the writer:
ReaderType::Pointer reader = ReaderType::New();
WriterType::Pointer writer = WriterType::New();
......@@ -123,20 +94,12 @@ int main( int argc, char* argv[])
writer->SetInput(filter->GetOutput());
reader->SetFileName(argv[1]);
writer->SetFileName(argv[2]);
// Software Guide : EndCodeSnippet
reader->UpdateOutputInformation();
// Software Guide : BeginLatex
//
// We now need to extract each band from the input \doxygen{otb}{VectorImage},
// it illustrates the use of the \doxygen{otb}{VectorImageToImageList}.
// Each extracted layer is an input to the \doxygen{otb}{BandMathImageFilter}:
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
// We now need to extract each band from the input \doxygen{otb}{VectorImage},
// it illustrates the use of the \doxygen{otb}{VectorImageToImageList}.
// Each extracted layer is an input to the \doxygen{otb}{BandMathImageFilter}:
VectorImageToImageListType::Pointer imageList = VectorImageToImageListType::New();
imageList->SetInput(reader->GetOutput());
......@@ -144,72 +107,48 @@ int main( int argc, char* argv[])
const unsigned int nbBands = reader->GetOutput()->GetNumberOfComponentsPerPixel();
for(unsigned int j = 0; j < nbBands; ++j)
{
filter->SetNthInput(j, imageList->GetOutput()->GetNthElement(j));
}
// Software Guide : EndCodeSnippet
for (unsigned int j = 0; j < nbBands; ++j)
{
filter->SetNthInput(j, imageList->GetOutput()->GetNthElement(j));
}
// Software Guide : BeginLatex
//
// Now we can define the mathematical expression to perform on the layers (b1, b2, b3, b4).
// The filter takes advantage of the parsing capabilities of the muParser library and
// allows setting the expression as on a digital calculator.
//
// The expression below returns 255 if the ratio $(NIR-RED)/(NIR+RED)$ is greater than 0.4 and 0 if not.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
// Now we can define the mathematical expression to perform on the layers (b1, b2, b3, b4).
// The filter takes advantage of the parsing capabilities of the muParser library and
// allows setting the expression as on a digital calculator.
//
// The expression below returns 255 if the ratio $(NIR-RED)/(NIR+RED)$ is greater than 0.4 and 0 if not.
filter->SetExpression("if((b4-b3)/(b4+b3) > 0.4, 255, 0)");
#ifdef OTB_MUPARSER_HAS_CXX_LOGICAL_OPERATORS
#ifdef OTB_MUPARSER_HAS_CXX_LOGICAL_OPERATORS
filter->SetExpression("((b4-b3)/(b4+b3) > 0.4) ? 255 : 0");
#else
#else
filter->SetExpression("if((b4-b3)/(b4+b3) > 0.4, 255, 0)");
#endif
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We can now plug the pipeline and run it.
//
// Software Guide : EndLatex
#endif
// Software Guide : BeginCodeSnippet
// We can now plug the pipeline and run it.
writer->Update();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The muParser library also provides the possibility to extend existing built-in functions. For example,
// you can use the OTB expression "ndvi(b3, b4)" with the filter. In this instance, the mathematical expression would be
// \textit{if($ndvi(b3, b4)>0.4$, 255, 0)}, which would return the same result.
//
// Software Guide : EndLatex
// Software Guide : BeginLatex
//
// Figure~\ref{fig:BandMathImageFilter} shows the result of the threshold applied to the NDVI index
// of a Quickbird image.
// \begin{figure}
// \center
// \includegraphics[width=0.45\textwidth]{qb_ExtractRoad_pretty.eps}
// \includegraphics[width=0.45\textwidth]{qb_BandMath-pretty.eps}
// \itkcaption[Band Math]{From left to right:
// Original image, thresholded NDVI index.}
// \label{fig:BandMathImageFilter}
// \end{figure}
//
// Software Guide : EndLatex
typedef otb::Image<unsigned char, 2> OutputPrettyImageType;
typedef otb::ImageFileWriter<OutputPrettyImageType> PrettyImageFileWriterType;
// The muParser library also provides the possibility to extend existing built-in functions. For example,
// you can use the OTB expression "ndvi(b3, b4)" with the filter. In this instance, the mathematical expression would be
// \textit{if($ndvi(b3, b4)>0.4$, 255, 0)}, which would return the same result.
// Figure~\ref{fig:BandMathImageFilter} shows the result of the threshold applied to the NDVI index
// of a Quickbird image.
// \begin{figure}
// \center
// \includegraphics[width=0.45\textwidth]{qb_ExtractRoad_pretty.eps}
// \includegraphics[width=0.45\textwidth]{qb_BandMath-pretty.eps}
// \itkcaption[Band Math]{From left to right:
// Original image, thresholded NDVI index.}
// \label{fig:BandMathImageFilter}
// \end{figure}
typedef otb::Image<unsigned char, 2> OutputPrettyImageType;
typedef otb::ImageFileWriter<OutputPrettyImageType> PrettyImageFileWriterType;
typedef itk::CastImageFilter<OutputImageType, OutputPrettyImageType> CastImageFilterType;
PrettyImageFileWriterType::Pointer prettyWriter = PrettyImageFileWriterType::New();
CastImageFilterType::Pointer caster = CastImageFilterType::New();
CastImageFilterType::Pointer caster = CastImageFilterType::New();
caster->SetInput(filter->GetOutput());
prettyWriter->SetInput(caster->GetOutput());
......
......@@ -19,14 +19,11 @@
*/
/* Example usage:
./BandMathXImageFilterExample Input/qb_RoadExtract.tif Output/qb_BandMath-res1.tif Output/qb_BandMath-res2.tif Output/context.txt
*/
// Software Guide : BeginCommandLineArgs
// INPUTS: {qb_RoadExtract.tif}
// OUTPUTS: {qb_BandMath-res1.tif}, {qb_BandMath-res2.tif}, {context.txt}
// Software Guide : EndCommandLineArgs
// Software Guide : BeginLatex
//
// This filter is based on the mathematical parser library muParserX.
// The built in functions and operators list is available at:
// \url{http://articles.beltoforion.de/article.php?a=muparserx}.
......@@ -39,8 +36,6 @@
// corresponding input index plus one (for instance, im1 is related to the first input).
// If the jth input image is multidimensional, then the variable imj represents a vector whose components are related to its bands.
// In order to access the kth band, the variable observes the following pattern : imjbk.
//
// Software Guide : EndLatex
#include "itkMacro.h"
#include <iostream>
......@@ -49,233 +44,138 @@
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
// Software Guide : BeginLatex
//
// We start by including the needed header files.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbBandMathXImageFilter.h"
// Software Guide : EndCodeSnippet
int main( int argc, char* argv[])
int main(int argc, char* argv[])
{
if (argc != 5)
{
{
std::cerr << "Usage: " << argv[0] << " inputImageFile ";
std::cerr << " outputImageFile ";
std::cerr << " outputImageFile2";
std::cerr << " context.txt" << std::endl;
return EXIT_FAILURE;
}
}
// Software Guide : BeginLatex
//
// Then, we set the classical \code{typedef}s needed for reading and
// writing the images. The \doxygen{otb}{BandMathXImageFilter} class
// works with \doxygen{otb}{VectorImage}.
//
// Software Guide : EndLatex
// Then, we set the classical \code{typedef}s needed for reading and
// writing the images. The \doxygen{otb}{BandMathXImageFilter} class
// works with \doxygen{otb}{VectorImage}.
// Software Guide : BeginCodeSnippet
typedef double PixelType;
typedef otb::VectorImage<PixelType, 2> ImageType;
typedef otb::ImageFileReader<ImageType> ReaderType;
typedef otb::ImageFileWriter<ImageType> WriterType;
// Software Guide : EndCodeSnippet
typedef double PixelType;
typedef otb::VectorImage<PixelType, 2> ImageType;
typedef otb::ImageFileReader<ImageType> ReaderType;
typedef otb::ImageFileWriter<ImageType> WriterType;
// Software Guide : BeginLatex
//
// We can now define the type for the filter:
//
// Software Guide : EndLatex
// We can now define the type for the filter:
// Software Guide : BeginCodeSnippet
typedef otb::BandMathXImageFilter<ImageType> FilterType;
// Software Guide : EndCodeSnippet
typedef otb::BandMathXImageFilter<ImageType> FilterType;
// Software Guide : BeginLatex
//
// We instantiate the filter, the reader, and the writer:
//
// Software Guide : EndLatex
// We instantiate the filter, the reader, and the writer:
// Software Guide : BeginCodeSnippet
ReaderType::Pointer reader = ReaderType::New();
WriterType::Pointer writer = WriterType::New();
FilterType::Pointer filter = FilterType::New();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The reader and the writer are parametrized with usual settings:
//
// Software Guide : EndLatex
// The reader and the writer are parametrized with usual settings:
// Software Guide : BeginCodeSnippet
reader->SetFileName(argv[1]);
writer->SetFileName(argv[2]);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The aim of this example is to compute a simple high-pass filter.
// For that purpose, we are going to perform the difference between the original signal
// and its averaged version. The definition of the expression that follows is only suitable for a 4-band image.
// So first, we must check this requirement:
//
// Software Guide : EndLatex
// The aim of this example is to compute a simple high-pass filter.
// For that purpose, we are going to perform the difference between the original signal
// and its averaged version. The definition of the expression that follows is only suitable for a 4-band image.
// So first, we must check this requirement:
// Software Guide : BeginCodeSnippet
reader->UpdateOutputInformation();
if (reader->GetOutput()->GetNumberOfComponentsPerPixel() !=4)
reader->UpdateOutputInformation();
if (reader->GetOutput()->GetNumberOfComponentsPerPixel() != 4)
itkGenericExceptionMacro(<< "Input image must have 4 bands." << std::endl);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Now, we can define the expression. The variable im1 represents a pixel (made of 4 components) of the input image.
// The variable im1b1N5x5 represents a neighborhood of size 5x5 around this pixel (and so on for each band).
// The last element we need is the operator 'mean'. By setting its inputs with four neigborhoods, we tell this operator to process the four related bands.
// As output, it will produce a vector of four components; this is consistent with the fact that we wish to perform a difference with im1.
//
// Thus, the expression is as follows:
// Now, we can define the expression. The variable im1 represents a pixel (made of 4 components) of the input image.
// The variable im1b1N5x5 represents a neighborhood of size 5x5 around this pixel (and so on for each band).
// The last element we need is the operator 'mean'. By setting its inputs with four neigborhoods, we tell this operator to process the four related bands.
// As output, it will produce a vector of four components; this is consistent with the fact that we wish to perform a difference with im1.
//
// Thus, the expression is as follows:
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
filter->SetExpression("im1-mean(im1b1N5x5,im1b2N5x5,im1b3N5x5,im1b4N5x5)");
// Software Guide : EndCodeSnippet
filter->SetExpression("im1-mean(im1b1N5x5,im1b2N5x5,im1b3N5x5,im1b4N5x5)");
// Software Guide : BeginLatex
//
// Note that the importance of the averaging is driven by the names of the neighborhood variables.
// Last thing we have to do, is to set the pipeline:
//
// Software Guide : EndLatex
// Note that the importance of the averaging is driven by the names of the neighborhood variables.
// Last thing we have to do, is to set the pipeline:
// Software Guide : BeginCodeSnippet
filter->SetNthInput(0,reader->GetOutput());
writer->SetInput(filter->GetOutput());
writer->Update();
// Software Guide : EndCodeSnippet
filter->SetNthInput(0, reader->GetOutput());
writer->SetInput(filter->GetOutput());
writer->Update();
// Software Guide : BeginLatex
//
// Figure~\ref{fig:BandMathXImageFilter} shows the result of our high-pass filter.
// \begin{figure}
// \center
// \includegraphics[width=0.45\textwidth]{qb_ExtractRoad_pretty.eps}
// \includegraphics[width=0.45\textwidth]{qb_BandMath-res1.eps}
// \itkcaption[Band Math X]{From left to right:
// Original image, high-pass filter output.}
// \label{fig:BandMathXImageFilter}
// \end{figure}
//
// Software Guide : EndLatex
// Figure~\ref{fig:BandMathXImageFilter} shows the result of our high-pass filter.
// \begin{figure}
// \center
// \includegraphics[width=0.45\textwidth]{qb_ExtractRoad_pretty.eps}
// \includegraphics[width=0.45\textwidth]{qb_BandMath-res1.eps}
// \itkcaption[Band Math X]{From left to right:
// Original image, high-pass filter output.}
// \label{fig:BandMathXImageFilter}
// \end{figure}
// Software Guide : BeginLatex
//
// Now let's see a little bit more complex example.
// The aim now is to give the central pixel a higher weight. Moreover :
// - we wish to use smaller neighborhoods
// - we wish to drop the 4th band
// - we wish to add a given number to each band.
//
// First, we instantiate new filters to later make a proper pipeline:
//
// Software Guide : EndLatex
// Now let's see a little bit more complex example.
// The aim now is to give the central pixel a higher weight. Moreover :
// - we wish to use smaller neighborhoods
// - we wish to drop the 4th band
// - we wish to add a given number to each band.
//
// First, we instantiate new filters to later make a proper pipeline:
// Software Guide : BeginCodeSnippet
ReaderType::Pointer reader2 = ReaderType::New();
WriterType::Pointer writer2 = WriterType::New();
FilterType::Pointer filter2 = FilterType::New();
reader2->SetFileName(argv[1]);
writer2->SetFileName(argv[3]);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We define a new kernel (rows are separated by semi-colons, whereas their elements are separated by commas):
//
// Software Guide : EndLatex
// We define a new kernel (rows are separated by semi-colons, whereas their elements are separated by commas):
// Software Guide : BeginCodeSnippet
filter2->SetMatrix("kernel","{ 0.1 , 0.1 , 0.1; 0.1 , 0.2 , 0.1; 0.1 , 0.1 , 0.1 }");
// Software Guide : EndCodeSnippet
filter2->SetMatrix("kernel", "{ 0.1 , 0.1 , 0.1; 0.1 , 0.2 , 0.1; 0.1 , 0.1 , 0.1 }");
// Software Guide : BeginLatex
//
// We then define a new constant:
//
// Software Guide : EndLatex
// We then define a new constant:
// Software Guide : BeginCodeSnippet
filter2->SetConstant("cst",1.0);
// Software Guide : EndCodeSnippet
filter2->SetConstant("cst", 1.0);
// Software Guide : BeginLatex
//
// We now set the expression (note the use of 'dotpr' operator, as well as the 'bands' operator which is used as a band selector):
//
// Software Guide : EndLatex
// We now set the expression (note the use of 'dotpr' operator, as well as the 'bands' operator which is used as a band selector):
// Software Guide : BeginCodeSnippet
filter2->SetExpression("bands(im1,{1,2,3})-dotpr(kernel,im1b1N3x3,im1b2N3x3,im1b3N3x3) + {cst,cst,cst}");
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// It is possible to export these definitions to a txt file (they will be reusable later thanks to the method ImportContext):
//
// Software Guide : EndLatex
// It is possible to export these definitions to a txt file (they will be reusable later thanks to the method ImportContext):
// Software Guide : BeginCodeSnippet
filter2->ExportContext(argv[4]);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// And finally, we set the pipeline:
//
// Software Guide : EndLatex
// And finally, we set the pipeline:
// Software Guide : BeginCodeSnippet
filter2->SetNthInput(0,reader2->GetOutput());
writer2->SetInput(filter2->GetOutput());
writer2->Update();
// Software Guide : EndCodeSnippet
filter2->SetNthInput(0, reader2->GetOutput());
writer2->SetInput(filter2->GetOutput());
writer2->Update();
// Software Guide : BeginLatex
//
// Figure~\ref{fig:BandMathXImageFilter2} shows the result of the second filter.
// \begin{figure}
// \center
// \includegraphics[width=0.45\textwidth]{qb_ExtractRoad_pretty.eps}
// \includegraphics[width=0.45\textwidth]{qb_BandMath-res2.eps}
// \itkcaption[Band Math X]{From left to right:
// Original image, second filter output.}
// \label{fig:BandMathXImageFilter2}
// \end{figure}
//
// Software Guide : EndLatex
// Figure~\ref{fig:BandMathXImageFilter2} shows the result of the second filter.
// \begin{figure}
// \center
// \includegraphics[width=0.45\textwidth]{qb_ExtractRoad_pretty.eps}
// \includegraphics[width=0.45\textwidth]{qb_BandMath-res2.eps}
// \itkcaption[Band Math X]{From left to right:
// Original image, second filter output.}
// \label{fig:BandMathXImageFilter2}
// \end{figure}
// Software Guide : BeginLatex
//
// Finally, it is strongly recommended to take a look at the cookbook, where additional information and examples can be found (http://www.orfeo-toolbox.org/packages/OTBCookBook.pdf).
//
// Software Guide : EndLatex
// Finally, it is strongly recommended to take a look at the cookbook, where additional information and examples can be found
// (http://www.orfeo-toolbox.org/packages/OTBCookBook.pdf).
return EXIT_SUCCESS;
......
......@@ -19,24 +19,21 @@
*/
/* Example usage:
./DEMToRainbowExample Output/DEMToRainbowImageGenerator.png 6.5 45.5 500 500 0.002 -0.002 Input/DEM_srtm
*/
// Software Guide : BeginCommandLineArgs
// OUTPUTS: {DEMToRainbowImageGenerator.png}
// 6.5 45.5 500 500 0.002 -0.002 ${OTB_DATA_ROOT}/Input/DEM_srtm
// Software Guide : EndCommandLineArgs
// Software Guide : BeginCommandLineArgs
// OUTPUTS: {DEMToHotImageGenerator.png}
// 6.5 45.5 500 500 0.002 -0.002 ${OTB_DATA_ROOT}/Input/DEM_srtm hot
// Software Guide : EndCommandLineArgs
/* Example usage:
./DEMToRainbowExample Output/DEMToHotImageGenerator.png 6.5 45.5 500 500 0.002 -0.002 Input/DEM_srtm hot
*/
/* Example usage:
./DEMToRainbowExample Output/DEMToReliefImageGenerator.png 6.5 45.5 500 500 0.002 -0.002 Input/DEM_srtm relief
*/
// Software Guide : BeginCommandLineArgs
// OUTPUTS: {DEMToReliefImageGenerator.png}
// 6.5 45.5 500 500 0.002 -0.002 ${OTB_DATA_ROOT}/Input/DEM_srtm relief
// Software Guide : EndCommandLineArgs
// Software Guide : BeginLatex
//
// In some situation, it is desirable to represent a gray scale image in color for easier
// interpretation. This is particularly the case if pixel values in the image are used
// to represent some data such as elevation, deformation map,
......@@ -48,8 +45,6 @@
// combined with the \doxygen{otb}{ScalarToRainbowRGBPixelFunctor}. You can refer to the
// source code or to section \ref{sec:ReadDEM} for the DEM conversion to image,
// we will focus on the color conversion part here.
//
// Software Guide : EndLatex
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
......@@ -59,24 +54,22 @@
#include "otbDEMToImageGenerator.h"
#include "otbReliefColormapFunctor.h"
int main(int argc, char * argv[])
int main(int argc, char* argv[])
{
if (argc < 9)
{
std::cout << argv[0] <<
" <output_filename> <Longitude Output Origin point>";
std::cout <<
" <Latitude Output Origin point> <X Output Size> <Y Output size>";
std::cout << " <X Spacing> <Y Spacing> <DEM folder path>" << std::endl;
{
std::cout << argv[0] << " <output_filename> <Longitude Output Origin point>";
std::cout << " <Latitude Output Origin point> <X Output Size> <Y Output size>";
std::cout << " <X Spacing> <Y Spacing> <DEM folder path>" << std::endl;
return EXIT_FAILURE;
}
}
typedef double PixelType;
typedef unsigned char UCharPixelType;
typedef itk::RGBPixel<UCharPixelType> RGBPixelType;
typedef otb::Image<PixelType, 2> ImageType;
typedef otb::Image<RGBPixelType, 2> RGBImageType;
typedef double PixelType;
typedef unsigned char UCharPixelType;
typedef itk::RGBPixel<UCharPixelType> RGBPixelType;
typedef otb::Image<PixelType, 2> ImageType;
typedef otb::Image<RGBPixelType, 2> RGBImageType;
typedef otb::ImageFileWriter<RGBImageType> WriterType;
WriterType::Pointer writer = WriterType::New();
......@@ -86,9 +79,9 @@ int main(int argc, char * argv[])
DEMToImageGeneratorType::Pointer demToImage = DEMToImageGeneratorType::New();
typedef DEMToImageGeneratorType::SizeType SizeType;
typedef DEMToImageGeneratorType::SpacingType SpacingType;
typedef DEMToImageGeneratorType::PointType PointType;
typedef DEMToImageGeneratorType::SizeType SizeType;
typedef DEMToImageGeneratorType::SpacingType SpacingType;
typedef DEMToImageGeneratorType::PointType PointType;
otb::DEMHandler::Instance()->OpenDEMDirectory(argv[8]);
......@@ -110,99 +103,77 @@ int main(int argc, char * argv[])
demToImage->SetOutputSpacing(spacing);
// Software Guide : BeginLatex
//
// As in the previous example, the \doxygen{itk}{ScalarToRGBColormapImageFilter} is
// the filter in charge of calling the functor we specify to do the work for
// each pixel. Here it is the \doxygen{otb}{ScalarToRainbowRGBPixelFunctor}.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef itk::ScalarToRGBColormapImageFilter<ImageType,
RGBImageType> ColorMapFilterType;
ColorMapFilterType::Pointer colormapper = ColorMapFilterType::New();
typedef itk::ScalarToRGBColormapImageFilter<ImageType, RGBImageType> ColorMapFilterType;
ColorMapFilterType::Pointer colormapper = ColorMapFilterType::New();
colormapper->UseInputImageExtremaForScalingOff();
if (argc == 9)
{
typedef otb::Functor::ScalarToRainbowRGBPixelFunctor<PixelType,
RGBPixelType>
ColorMapFunctorType;
ColorMapFunctorType::Pointer colormap = ColorMapFunctorType::New();
{
typedef otb::Functor::ScalarToRainbowRGBPixelFunctor<PixelType, RGBPixelType> ColorMapFunctorType;
ColorMapFunctorType::Pointer colormap = ColorMapFunctorType::New();
colormap->SetMinimumInputValue(0);
colormap->SetMaximumInputValue(4000);
colormapper->SetColormap(colormap);
}
// Software Guide : EndCodeSnippet
}
else
{
{
if (strcmp(argv[9], "hot") == 0)
{
typedef itk::Function::HotColormapFunction<PixelType,
RGBPixelType>
ColorMapFunctorType;
ColorMapFunctorType::Pointer colormap = ColorMapFunctorType::New();
{
typedef itk::Function::HotColormapFunction<PixelType, RGBPixelType> ColorMapFunctorType;
ColorMapFunctorType::Pointer colormap = ColorMapFunctorType::New();
colormap->SetMinimumInputValue(0);
colormap->SetMaximumInputValue(4000);
colormapper->SetColormap(colormap);
}
}
else
{
typedef otb::Functor::ReliefColormapFunctor<PixelType,
RGBPixelType>
ColorMapFunctorType;
ColorMapFunctorType::Pointer colormap = ColorMapFunctorType::New();
{
typedef otb::Functor::ReliefColormapFunctor<PixelType, RGBPixelType> ColorMapFunctorType;
ColorMapFunctorType::Pointer colormap = ColorMapFunctorType::New();
colormap->SetMinimumInputValue(0);
colormap->SetMaximumInputValue(4000);
colormapper->SetColormap(colormap);
}
}
// Software Guide : BeginLatex
//
}
// And we connect the color mapper filter with the filter producing
// the image of the DEM:
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
colormapper->SetInput(demToImage->GetOutput());
// Software Guide : EndCodeSnippet
writer->SetInput(colormapper->GetOutput());
try
{
{
writer->Update();
}
}
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;
}
}
// Software Guide : BeginLatex
//
// Figure~\ref{fig:RAINBOW_FILTER} shows the effect of applying the filter to
// a gray scale image.
//
// \begin{figure}
// \center
// \includegraphics[width=0.44\textwidth]{pretty_DEMToImageGenerator.eps}
// \includegraphics[width=0.44\textwidth]{DEMToRainbowImageGenerator.eps}
// \includegraphics[width=0.44\textwidth]{DEMToHotImageGenerator.eps}
// \includegraphics[width=0.44\textwidth]{DEMToReliefImageGenerator.eps}
// \itkcaption[Grayscale to color]{The gray level DEM extracted from SRTM
// data (top-left) and the same area represented in color.}
// \label{fig:RAINBOW_FILTER}
// \end{figure}
// Software Guide : EndLatex
// \begin{figure}
// \center
// \includegraphics[width=0.44\textwidth]{pretty_DEMToImageGenerator.eps}
// \includegraphics[width=0.44\textwidth]{DEMToRainbowImageGenerator.eps}
// \includegraphics[width=0.44\textwidth]{DEMToHotImageGenerator.eps}
// \includegraphics[width=0.44\textwidth]{DEMToReliefImageGenerator.eps}
// \itkcaption[Grayscale to color]{The gray level DEM extracted from SRTM
// data (top-left) and the same area represented in color.}
// \label{fig:RAINBOW_FILTER}
// \end{figure}
return EXIT_SUCCESS;
}
......@@ -19,15 +19,11 @@
*/
/* Example usage:
./FrostImageFilter Input/GomaSmall.png Output/GomaSmallFrostFiltered.png 5 0.1
*/
// Software Guide : BeginCommandLineArgs
// INPUTS: {GomaSmall.png}
// OUTPUTS: {GomaSmallFrostFiltered.png}
// 5 0.1
// Software Guide : EndCommandLineArgs
// Software Guide : BeginLatex
//
// This example illustrates the use of the \doxygen{otb}{FrostImageFilter}.
// This filter belongs to the family of the edge-preserving smoothing
// filters which are usually used for speckle reduction in radar
......@@ -54,41 +50,31 @@
// will be highlighted.
//
// First, we need to include the header:
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
#include "otbFrostImageFilter.h"
// Software Guide : EndCodeSnippet
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
int main(int argc, char * argv[])
int main(int argc, char* argv[])
{
if (argc != 5)
{
{
std::cerr << "Usage: " << argv[0] << " inputImageFile ";
std::cerr << " outputImageFile radius deramp" << std::endl;
return EXIT_FAILURE;
}
}
typedef unsigned char PixelType;
typedef unsigned char PixelType;
typedef otb::Image<PixelType, 2> InputImageType;
typedef otb::Image<PixelType, 2> OutputImageType;
typedef otb::Image<PixelType, 2> InputImageType;
typedef otb::Image<PixelType, 2> OutputImageType;
// Software Guide : BeginLatex
//
// The filter can be instantiated using the image types defined previously.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::FrostImageFilter<InputImageType, OutputImageType> FilterType;
// Software Guide : EndCodeSnippet
typedef otb::ImageFileReader<InputImageType> ReaderType;
......@@ -101,22 +87,14 @@ int main(int argc, char * argv[])
writer->SetInput(filter->GetOutput());
reader->SetFileName(argv[1]);
// Software Guide : BeginLatex
//
// The image obtained with the reader is passed as input to the
// \doxygen{otb}{FrostImageFilter}.
//
// \index{otb::FrostImageFilter!SetInput()}
// \index{otb::FileImageReader!GetOutput()}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
filter->SetInput(reader->GetOutput());
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The method \code{SetRadius()} defines the size of the window to
// be used for the computation of the local statistics. The method
// \code{SetDeramp()} sets the $K$ coefficient.
......@@ -124,22 +102,17 @@ int main(int argc, char * argv[])
// \index{otb::FrostImageFilter!SetRadius()}
// \index{otb::FrostImageFilter!SetDeramp()}
// \index{SetDeramp()!otb::FrostImageFilter}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
FilterType::SizeType Radius;
Radius[0] = atoi(argv[3]);
Radius[1] = atoi(argv[3]);
filter->SetRadius(Radius);
filter->SetDeramp(atof(argv[4]));
// Software Guide : EndCodeSnippet
writer->SetFileName(argv[2]);
writer->Update();
// Software Guide : BeginLatex
// Figure~\ref{fig:FROST_FILTER} shows the result of applying the Frost
// filter to a SAR image.
// \begin{figure}
......@@ -155,8 +128,6 @@ int main(int argc, char * argv[])
// \begin{itemize}
// \item \doxygen{otb}{LeeImageFilter}
// \end{itemize}
//
// Software Guide : EndLatex
return EXIT_SUCCESS;
}
......@@ -19,14 +19,11 @@
*/
/* Example usage:
./HillShadingExample Output/HillShadingExample.png Output/HillShadingColorExample.png 6.5 45.5 500 500 0.002 -0.002 Input/DEM_srtm
*/
// Software Guide : BeginCommandLineArgs
// OUTPUTS: {HillShadingExample.png}, {HillShadingColorExample.png}
// 6.5 45.5 500 500 0.002 -0.002 ${OTB_DATA_ROOT}/Input/DEM_srtm
// Software Guide : EndCommandLineArgs
// Software Guide : BeginLatex
//
// Visualization of digital elevation models (DEM) is often more intuitive by simulating a
// lighting source and generating the corresponding shadows. This principle is called
// hill shading.
......@@ -38,8 +35,6 @@
// \doxygen{otb}{ReliefColormapFunctor} you can easily generate the classic elevation maps.
//
// This example will focus on the shading itself.
//
// Software Guide : EndLatex
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
......@@ -53,26 +48,25 @@
#include "itkShiftScaleImageFilter.h"
#include "otbWorldFile.h"
int main(int argc, char * argv[])
int main(int argc, char* argv[])
{
if (argc < 10)
{
{
std::cout << argv[0] << " <output_filename> <output_color_filename> "
<< " <Longitude Output Origin point> <Latitude Output Origin point>"
<< " <X Output Size> <Y Output size>"
<< " <X Spacing> <Y Spacing> <DEM folder path>"
<< " [Projection Ref]"
<< std::endl;
<< " [Projection Ref]" << std::endl;
return EXIT_FAILURE;
}
typedef double PixelType;
typedef unsigned char UCharPixelType;
typedef itk::RGBPixel<UCharPixelType> RGBPixelType;
typedef otb::Image<PixelType, 2> ImageType;
typedef otb::Image<RGBPixelType, 2> RGBImageType;
typedef otb::Image<UCharPixelType, 2> ScalarImageType;
}
typedef double PixelType;
typedef unsigned char UCharPixelType;
typedef itk::RGBPixel<UCharPixelType> RGBPixelType;
typedef otb::Image<PixelType, 2> ImageType;
typedef otb::Image<RGBPixelType, 2> RGBImageType;
typedef otb::Image<UCharPixelType, 2> ScalarImageType;
typedef otb::ImageFileWriter<RGBImageType> WriterType;
typedef otb::ImageFileWriter<ScalarImageType> ScalarWriterType;
......@@ -86,9 +80,9 @@ int main(int argc, char * argv[])
DEMToImageGeneratorType::Pointer demToImage = DEMToImageGeneratorType::New();
typedef DEMToImageGeneratorType::SizeType SizeType;
typedef DEMToImageGeneratorType::SpacingType SpacingType;
typedef DEMToImageGeneratorType::PointType PointType;
typedef DEMToImageGeneratorType::SizeType SizeType;
typedef DEMToImageGeneratorType::SpacingType SpacingType;
typedef DEMToImageGeneratorType::PointType PointType;
otb::DEMHandler::Instance()->OpenDEMDirectory(argv[9]);
......@@ -111,69 +105,56 @@ int main(int argc, char * argv[])
demToImage->SetOutputSpacing(spacing);
double res = 0;
if ( argc > 10)
{
if (argc > 10)
{
demToImage->SetOutputProjectionRef(argv[10]);
res = spacing[0];
}
}
else
{
//Compute the resolution (Vincenty formula)
{
// Compute the resolution (Vincenty formula)
double lon1 = origin[0];
double lon2 = origin[0] + size[0] * spacing[0];
double lat1 = origin[1];
double lat2 = origin[1] + size[1] * spacing[1];
double R = 6371; // km
double d = std::acos(std::sin(lat1) * std::sin(lat2) +
std::cos(lat1) * std::cos(lat2) * std::cos(lon2 - lon1)) * R;
res = d / std::sqrt(2.0);
}
// Software Guide : BeginLatex
//
double R = 6371; // km
double d = std::acos(std::sin(lat1) * std::sin(lat2) + std::cos(lat1) * std::cos(lat2) * std::cos(lon2 - lon1)) * R;
res = d / std::sqrt(2.0);
}
// After generating the DEM image as in the DEMToImageGenerator example, you can declare
// the hill shading mechanism. The hill shading is implemented as a functor doing some
// operations in its neighborhood. A convenient filter called \doxygen{otb}{HillShadingFilter}
// is defined around this mechanism.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::HillShadingFilter<ImageType, ImageType> HillShadingFilterType;
HillShadingFilterType::Pointer hillShading = HillShadingFilterType::New();
HillShadingFilterType::Pointer hillShading = HillShadingFilterType::New();
hillShading->SetRadius(1);
hillShading->SetInput(demToImage->GetOutput());
// Software Guide : EndCodeSnippet
hillShading->GetFunctor().SetXRes(res);
hillShading->GetFunctor().SetYRes(res);
typedef itk::ShiftScaleImageFilter<ImageType, ScalarImageType> RescalerType;
RescalerType::Pointer rescaler = RescalerType::New();
RescalerType::Pointer rescaler = RescalerType::New();
rescaler->SetScale(255.0);
rescaler->SetInput(hillShading->GetOutput());
writer->SetInput(rescaler->GetOutput());
typedef itk::ScalarToRGBColormapImageFilter<ImageType,
RGBImageType> ColorMapFilterType;
ColorMapFilterType::Pointer colormapper = ColorMapFilterType::New();
typedef itk::ScalarToRGBColormapImageFilter<ImageType, RGBImageType> ColorMapFilterType;
ColorMapFilterType::Pointer colormapper = ColorMapFilterType::New();
colormapper->UseInputImageExtremaForScalingOff();
typedef otb::Functor::ReliefColormapFunctor<PixelType,
RGBPixelType> ColorMapFunctorType;
ColorMapFunctorType::Pointer colormap = ColorMapFunctorType::New();
typedef otb::Functor::ReliefColormapFunctor<PixelType, RGBPixelType> ColorMapFunctorType;
ColorMapFunctorType::Pointer colormap = ColorMapFunctorType::New();
colormap->SetMinimumInputValue(0);
colormap->SetMaximumInputValue(4000);
colormapper->SetColormap(colormap);
colormapper->SetInput(demToImage->GetOutput());
typedef itk::BinaryFunctorImageFilter<RGBImageType, ImageType, RGBImageType,
otb::Functor::
HillShadeModulationFunctor<RGBPixelType,
PixelType,
RGBPixelType> >
MultiplyFilterType;
typedef itk::BinaryFunctorImageFilter<RGBImageType, ImageType, RGBImageType, otb::Functor::HillShadeModulationFunctor<RGBPixelType, PixelType, RGBPixelType>>
MultiplyFilterType;
MultiplyFilterType::Pointer multiply = MultiplyFilterType::New();
multiply->SetInput1(colormapper->GetOutput());
......@@ -182,20 +163,20 @@ int main(int argc, char * argv[])
writer2->SetInput(multiply->GetOutput());
try
{
{
writer->Update();
writer2->Update();
}
}
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;
}
}
otb::WorldFile::Pointer worldFile = otb::WorldFile::New();
worldFile->SetLonOrigin(origin[0]);
......@@ -208,8 +189,6 @@ int main(int argc, char * argv[])
worldFile->SetImageFilename(argv[2]);
worldFile->Update();
// Software Guide : BeginLatex
//
// Figure~\ref{fig:HILL_SHADING} shows the hill shading result from SRTM data.
//
// \begin{figure}
......@@ -220,7 +199,6 @@ int main(int argc, char * argv[])
// the color representation (right)}
// \label{fig:HILL_SHADING}
// \end{figure}
// Software Guide : EndLatex
return EXIT_SUCCESS;
}
......@@ -19,14 +19,11 @@
*/
/* Example usage:
./IndexedToRGBExample Input/buildingExtractionIndexed.tif Output/buildingExtractionRGB.png Output/buildingExtractionIndexed_scaled.png
*/
// Software Guide : BeginCommandLineArgs
// INPUTS: {buildingExtractionIndexed.tif}
// OUTPUTS: {buildingExtractionRGB.png}, {buildingExtractionIndexed_scaled.png}
// Software Guide : EndCommandLineArgs
// Software Guide : BeginLatex
//
// Some algorithms produce an indexed image as output. In such images,
// each pixel is given a value according to the region number it belongs to.
// This value starting at 0 or 1 is usually an integer value.
......@@ -39,8 +36,6 @@
// such conversion, it is important to ensure that neighborhood region, which are
// likely to have consecutive number have easily dicernable colors. This is done
// randomly using a hash function by the \doxygen{itk}{ScalarToRGBPixelFunctor}.
//
// Software Guide : EndLatex
#include "otbImage.h"
#include "otbImageFileReader.h"
......@@ -50,65 +45,55 @@
#include "itkRescaleIntensityImageFilter.h"
int main(int argc, char * argv[])
int main(int argc, char* argv[])
{
if (argc != 4)
{
{
std::cerr << "Usage: " << argv[0] << " <inputImageFile> ";
std::cerr << " <outputRGBImageFile> <outputScaledImageFile>" << std::endl;
return EXIT_FAILURE;
}
const char * inputFilename = argv[1];
const char * outputRGBFilename = argv[2];
const char * outputScaledFilename = argv[3];
}
const char* inputFilename = argv[1];
const char* outputRGBFilename = argv[2];
const char* outputScaledFilename = argv[3];
typedef otb::Image<unsigned long, 2> ImageType;
typedef otb::Image<itk::RGBPixel<unsigned char>, 2> RGBImageType;
typedef otb::ImageFileReader<ImageType> ReaderType;
ReaderType::Pointer reader = ReaderType::New();
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName(inputFilename);
// Software Guide : BeginLatex
//
// The \doxygen{itk}{UnaryFunctorImageFilter} is the filter in charge of
// calling the functor we specify to do the work for each pixel. Here it is the
// \doxygen{itk}{ScalarToRGBPixelFunctor}.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef itk::Functor::ScalarToRGBPixelFunctor<unsigned long>
ColorMapFunctorType;
typedef itk::UnaryFunctorImageFilter<ImageType, RGBImageType,
ColorMapFunctorType> ColorMapFilterType;
ColorMapFilterType::Pointer colormapper = ColorMapFilterType::New();
typedef itk::Functor::ScalarToRGBPixelFunctor<unsigned long> ColorMapFunctorType;
typedef itk::UnaryFunctorImageFilter<ImageType, RGBImageType, ColorMapFunctorType> ColorMapFilterType;
ColorMapFilterType::Pointer colormapper = ColorMapFilterType::New();
colormapper->SetInput(reader->GetOutput());
// Software Guide : EndCodeSnippet
typedef otb::ImageFileWriter<RGBImageType> WriterType;
WriterType::Pointer writer = WriterType::New();
WriterType::Pointer writer = WriterType::New();
writer->SetFileName(outputRGBFilename);
writer->SetInput(colormapper->GetOutput());
writer->Update();
//The following is just to produce the input image for the software guide
typedef otb::Image<unsigned char, 2> OutputImageType;
typedef itk::RescaleIntensityImageFilter<ImageType,
OutputImageType> RescalerType;
RescalerType::Pointer rescaler = RescalerType::New();
// The following is just to produce the input image for the software guide
typedef otb::Image<unsigned char, 2> OutputImageType;
typedef itk::RescaleIntensityImageFilter<ImageType, OutputImageType> RescalerType;
RescalerType::Pointer rescaler = RescalerType::New();
rescaler->SetInput(reader->GetOutput());
typedef otb::ImageFileWriter<OutputImageType> UCharWriterType;
UCharWriterType::Pointer writer2 = UCharWriterType::New();
UCharWriterType::Pointer writer2 = UCharWriterType::New();
writer2->SetFileName(outputScaledFilename);
writer2->SetInput(rescaler->GetOutput());
writer2->Update();
// Software Guide : BeginLatex
// Figure~\ref{fig:INDEXTORGB_FILTER} shows the result of the conversion
// from an indexed image to a color image.
// \begin{figure}
......@@ -119,8 +104,6 @@ int main(int argc, char * argv[])
// conversion to color image.}
// \label{fig:INDEXTORGB_FILTER}
// \end{figure}
//
// Software Guide : EndLatex
return EXIT_SUCCESS;
}
......@@ -19,171 +19,66 @@
*/
/* Example usage:
./LeeImageFilter Input/GomaSmall.png Output/GomaSmallLeeFiltered.png 3 1
*/
// Software Guide : BeginCommandLineArgs
// INPUTS: {GomaSmall.png}
// OUTPUTS: {GomaSmallLeeFiltered.png}
// 3 1
// Software Guide : EndCommandLineArgs
// Software Guide : BeginLatex
//
// This example illustrates the use of the \doxygen{otb}{LeeImageFilter}.
// This filter belongs to the family of the edge-preserving smoothing
// filters which are usually used for speckle reduction in radar
// images. The Lee filter \cite{LeeFilter} aplies a linear regression
// which minimizes the mean-square error in the frame of a
// multiplicative speckle model.
//
//
// The first step required to use this filter is to include its header file.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
#include "otbLeeImageFilter.h"
// Software Guide : EndCodeSnippet
#include "otbImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
int main(int argc, char * argv[])
int main(int argc, char* argv[])
{
if (argc != 5)
{
{
std::cerr << "Usage: " << argv[0] << " inputImageFile ";
std::cerr << " outputImageFile radius NbLooks" << std::endl;
return EXIT_FAILURE;
}
// Software Guide : BeginLatex
//
// Then we must decide what pixel type to use for the image.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef unsigned char PixelType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The images are defined using the pixel type and the dimension.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::Image<PixelType, 2> InputImageType;
typedef otb::Image<PixelType, 2> OutputImageType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The filter can be instantiated using the image types defined above.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
}
typedef unsigned char PixelType;
// The images are defined using the pixel type and the dimension.
typedef otb::Image<PixelType, 2> InputImageType;
typedef otb::Image<PixelType, 2> OutputImageType;
// The filter can be instantiated using the image types defined above.
typedef otb::LeeImageFilter<InputImageType, OutputImageType> FilterType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// An \doxygen{otb}{ImageFileReader} class is also instantiated in order to read
// An ImageFileReader class is also instantiated in order to read
// image data from a file.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::ImageFileReader<InputImageType> ReaderType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// An \doxygen{otb}{ImageFileWriter} is instantiated in order to write the
// output image to a file.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef otb::ImageFileWriter<OutputImageType> WriterType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Both the filter and the reader are created by invoking their \code{New()}
// methods and assigning the result to SmartPointers.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
ReaderType::Pointer reader = ReaderType::New();
FilterType::Pointer filter = FilterType::New();
// Software Guide : EndCodeSnippet
WriterType::Pointer writer = WriterType::New();
writer->SetInput(filter->GetOutput());
reader->SetFileName(argv[1]);
// Software Guide : BeginLatex
//
// The image obtained with the reader is passed as input to the
// \doxygen{otb}{LeeImageFilter}.
//
// \index{otb::LeeImageFilter!SetInput()}
// \index{otb::FileImageReader!GetOutput()}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
// LeeImageFilter.
filter->SetInput(reader->GetOutput());
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The method \code{SetRadius()} defines the size of the window to
// be used for the computation of the local statistics. The method
// \code{SetNbLooks()} sets the number of looks of the input
// image.
//
// \index{otb::LeeImageFilter!SetRadius()}
// \index{otb::LeeImageFilter!SetNbLooks()}
// \index{SetNbLooks()!otb::LeeImageFilter}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
// The method SetRadius() defines the size of the window to
// be used for the computation of the local statistics. The method
// SetNbLooks() sets the number of looks of the input
// image.
FilterType::SizeType Radius;
Radius[0] = atoi(argv[3]);
Radius[1] = atoi(argv[3]);
filter->SetRadius(Radius);
filter->SetNbLooks(atoi(argv[4]));
// Software Guide : EndCodeSnippet
writer->SetFileName(argv[2]);
writer->Update();
// Software Guide : BeginLatex
// Figure~\ref{fig:LEE_FILTER} shows the result of applying the Lee
// filter to a SAR image.
// \begin{figure}
// \center
// \includegraphics[width=0.44\textwidth]{GomaSmall.eps}
// \includegraphics[width=0.44\textwidth]{GomaSmallLeeFiltered.eps}
// \itkcaption[Lee Filter Application]{Result of applying the
// \doxygen{otb}{LeeImageFilter} to a SAR image.}
// \label{fig:LEE_FILTER}
// \end{figure}
//
// \relatedClasses
// \begin{itemize}
// \item \doxygen{otb}{FrostImageFilter}
// \end{itemize}
//
// Software Guide : EndLatex
return EXIT_SUCCESS;
}
This example illustrates the use of the LeeImageFilter.
This filter belongs to the family of the edge-preserving smoothing
filters which are usually used for speckle reduction in radar
images. The LeeFilter aplies a linear regression
which minimizes the mean-square error in the frame of a
multiplicative speckle model.
.. figure:: /Input/GomaSmall.png
.. figure:: /Output/GomaSmallLeeFiltered.png
Result of applying the Lee filter to a SAR image.
......@@ -19,15 +19,20 @@
*/
/* Example usage:
./MeanShiftSegmentationFilterExample Input/ROI_QB_MUL_1.png \
Output/MSLabeledOutput.tif \
Output/MSClusteredOutput.tif \
Output/MSLabeledOutput-pretty.png \
Output/MSClusteredOutput-pretty.png \
16 \
16 \
100 \
100 \
0.1
*/
// Software Guide : BeginCommandLineArgs
// INPUTS: {ROI_QB_MUL_1.png}
// OUTPUTS: {MSLabeledOutput.tif}, {MSClusteredOutput.tif}, {MSLabeledOutput-pretty.png}, {MSClusteredOutput-pretty.png}
// 16 16 100 100 0.1
// Software Guide : EndCommandLineArgs
// Software Guide : BeginLatex
//
// This example demonstrates the use of the
// \doxygen{otb}{MeanShiftSegmentationFilter} class which implements
// filtering and clustering using the mean shift algorithm
......@@ -37,8 +42,6 @@
// then computed and the algorithm iterates with this new spatial and
// color center. The Mean Shift can be used for edge-preserving
// smoothing, or for clustering.
//
// Software Guide : EndLatex
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
......@@ -49,43 +52,32 @@
#include "itkScalarToRGBPixelFunctor.h"
#include "itkUnaryFunctorImageFilter.h"
// Software Guide : BeginLatex
//
// We start by including the needed header file.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
#include "otbMeanShiftSegmentationFilter.h"
// Software Guide : EndCodeSnippet
int main(int argc, char * argv[])
int main(int argc, char* argv[])
{
if (argc != 11)
{
{
std::cerr << "Usage: " << argv[0] << " infname labeledfname clusteredfname labeledpretty clusteredpretty "
<< "spatialRadius rangeRadius minRegionSize maxiter thres" << std::endl;
<< "spatialRadius rangeRadius minRegionSize maxiter thres" << std::endl;
return EXIT_FAILURE;
}
const char * infname = argv[1];
const char * labeledfname = argv[2];
const char * clusteredfname = argv[3];
const char * labeledpretty = argv[4];
const char * clusteredpretty = argv[5];
const unsigned int spatialRadius = atoi(argv[6]);
const double rangeRadius = atof(argv[7]);
const unsigned int minRegionSize = atoi(argv[8]);
const unsigned int maxiter = atoi(argv[9]);
const double thres = atof(argv[10]);
// Software Guide : BeginLatex
//
}
const char* infname = argv[1];
const char* labeledfname = argv[2];
const char* clusteredfname = argv[3];
const char* labeledpretty = argv[4];
const char* clusteredpretty = argv[5];
const unsigned int spatialRadius = atoi(argv[6]);
const double rangeRadius = atof(argv[7]);
const unsigned int minRegionSize = atoi(argv[8]);
const unsigned int maxiter = atoi(argv[9]);
const double thres = atof(argv[10]);
// We start by the classical \code{typedef}s needed for reading and
// writing the images.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
const unsigned int Dimension = 2;
typedef float PixelType;
......@@ -96,80 +88,50 @@ int main(int argc, char * argv[])
typedef otb::Image<LabelPixelType, Dimension> LabelImageType;
typedef otb::Image<ColorPixelType, Dimension> RGBImageType;
typedef otb::ImageFileReader<ImageType> ReaderType;
typedef otb::ImageFileReader<ImageType> ReaderType;
typedef otb::ImageFileWriter<ImageType> WriterType;
typedef otb::ImageFileWriter<LabelImageType> LabelWriterType;
typedef otb::MeanShiftSegmentationFilter<ImageType, LabelImageType, ImageType> FilterType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We instantiate the filter, the reader, and 2 writers (for the
// labeled and clustered images).
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
FilterType::Pointer filter = FilterType::New();
ReaderType::Pointer reader = ReaderType::New();
WriterType::Pointer writer1 = WriterType::New();
FilterType::Pointer filter = FilterType::New();
ReaderType::Pointer reader = ReaderType::New();
WriterType::Pointer writer1 = WriterType::New();
LabelWriterType::Pointer writer2 = LabelWriterType::New();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We set the file names for the reader and the writers:
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
reader->SetFileName(infname);
writer1->SetFileName(clusteredfname);
writer2->SetFileName(labeledfname);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We can now set the parameters for the filter. There are 3 main
// parameters: the spatial radius used for defining the neighborhood,
// the range radius used for defining the interval in the color space
// and the minimum size for the regions to be kept after clustering.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
filter->SetSpatialBandwidth(spatialRadius);
filter->SetRangeBandwidth(rangeRadius);
filter->SetMinRegionSize(minRegionSize);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// Two another parameters can be set : the maximum iteration number, which defines maximum number of iteration until convergence.
// Algorithm iterative scheme will stop if convergence hasn't been reached after the maximum number of iterations.
// Threshold parameter defines mean-shift vector convergence value. Algorithm iterative scheme will stop if mean-shift vector is below this threshold or if iteration number reached maximum number of iterations.
// Software Guide : EndLatex
// Threshold parameter defines mean-shift vector convergence value. Algorithm iterative scheme will stop if mean-shift vector is below this threshold or if
// iteration number reached maximum number of iterations.
// Software Guide : BeginCodeSnippet
filter->SetMaxIterationNumber(maxiter);
filter->SetThreshold(thres);
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// We can now plug the pipeline and run it.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
filter->SetInput(reader->GetOutput());
writer1->SetInput(filter->GetClusteredOutput());
writer2->SetInput(filter->GetLabelOutput());
writer1->Update();
writer2->Update();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
// Figure~\ref{fig:MeanShiftSegmentationFilter} shows the result of applying the mean shift
// to a Quickbird image.
// \begin{figure}
......@@ -182,16 +144,15 @@ int main(int argc, char * argv[])
// mean shift after clustering , and labeled image.}
// \label{fig:MeanShiftSegmentationFilter}
// \end{figure}
// Software Guide : EndLatex
typedef otb::PrintableImageFilter<ImageType> PrintableFilterType;
PrintableFilterType::Pointer printableImageFilter = PrintableFilterType::New();
PrintableFilterType::Pointer printableImageFilter = PrintableFilterType::New();
printableImageFilter->SetChannel(1);
printableImageFilter->SetChannel(2);
printableImageFilter->SetChannel(3);
typedef PrintableFilterType::OutputImageType OutputImageType;
typedef PrintableFilterType::OutputImageType OutputImageType;
typedef otb::ImageFileWriter<OutputImageType> PrettyWriterType;
PrettyWriterType::Pointer prettyWriter = PrettyWriterType::New();
......@@ -206,9 +167,9 @@ int main(int argc, char * argv[])
LabelRGBWriterType::Pointer labelRGBWriter = LabelRGBWriterType::New();
// Label to RGB image
typedef itk::Functor::ScalarToRGBPixelFunctor<LabelPixelType> FunctorType;
typedef itk::Functor::ScalarToRGBPixelFunctor<LabelPixelType> FunctorType;
typedef itk::UnaryFunctorImageFilter<LabelImageType, RGBImageType, FunctorType> ColorLabelFilterType;
ColorLabelFilterType::Pointer labelToRGB = ColorLabelFilterType::New();
ColorLabelFilterType::Pointer labelToRGB = ColorLabelFilterType::New();
labelToRGB->SetInput(filter->GetLabelOutput());
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment