From 2396069abdf9fe7dec21e214af4c2e97c373540a Mon Sep 17 00:00:00 2001
From: Victor Poughon <victor.poughon@cnes.fr>
Date: Tue, 12 Mar 2019 16:01:21 +0100
Subject: [PATCH] DOC: move python recipe to python api section

---
 Documentation/Cookbook/rst/PythonAPI.rst      | 373 ++++++++++++++++-
 Documentation/Cookbook/rst/Recipes.rst        |   2 -
 Documentation/Cookbook/rst/recipes/python.rst | 377 ------------------
 3 files changed, 372 insertions(+), 380 deletions(-)
 delete mode 100644 Documentation/Cookbook/rst/recipes/python.rst

diff --git a/Documentation/Cookbook/rst/PythonAPI.rst b/Documentation/Cookbook/rst/PythonAPI.rst
index 9ddecaabca..4fa3ca24b0 100644
--- a/Documentation/Cookbook/rst/PythonAPI.rst
+++ b/Documentation/Cookbook/rst/PythonAPI.rst
@@ -46,5 +46,376 @@ like this small example:
     # This will execute the application and save the output file
     app.ExecuteAndWriteOutput()
 
-For more information about this Python interface, check the recipe section.
+Basics
+------
 
+In the ``otbApplication`` module, two main classes can be manipulated :
+
+-  ``Registry``, which provides access to the list of available
+   applications, and can create applications.
+
+-  ``Application``, the base class for all applications. This allows one to
+   interact with an application instance created by the ``Registry``.
+
+Here is one example of how to use Python to run the ``Smoothing``
+application, changing the algorithm at each iteration.
+
+.. code-block:: python
+
+    #  Example on the use of the Smoothing application
+    #
+
+    # We will use sys.argv to retrieve arguments from the command line.
+    # Here, the script will accept an image file as first argument,
+    # and the basename of the output files, without extension.
+    from sys import argv
+
+    # The python module providing access to OTB applications is otbApplication
+    import otbApplication
+
+    # otbApplication.Registry can tell you what application are available
+    print('Available applications: ')
+    print (str( otbApplication.Registry.GetAvailableApplications()))
+
+    # Let's create the application  "Smoothing"
+    app = otbApplication.Registry.CreateApplication("Smoothing")
+
+    # We print the keys of all its parameters
+    print (app.GetParametersKeys())
+
+    # First, we set the input image filename
+    app.SetParameterString("in", argv[1])
+
+    # The smoothing algorithm can be set with the "type" parameter key
+    # and can take 3 values: 'mean', 'gaussian', 'anidif'
+    for type in ['mean', 'gaussian', 'anidif']:
+
+      print('Running with ' + type + ' smoothing type')
+
+      # Now we configure the smoothing algorithm
+      app.SetParameterString("type", type)
+
+      # Set the output filename, using the algorithm type to differentiate the outputs
+      app.SetParameterString("out", argv[2] + type + ".tif")
+
+      # This will execute the application and save the output to argv[2]
+      app.ExecuteAndWriteOutput()
+
+If you want to handle the parameters from a Python dictionary, you can use the
+functions *SetParameters()* and *GetParameters()*.
+
+.. code-block:: python
+
+    params = {"in":"myInput.tif", "type.mean.radius":4}
+    app.SetParameters(params)
+    params2 = app.GetParameters()
+
+Numpy array processing
+----------------------
+
+Input and output images to any OTB application in the form of NumPy array is now possible in OTB Python wrapping.
+The Python wrapping only exposes OTB Application engine module (called *ApplicationEngine*) which allows one to access existing C++ applications.
+Due to blissful nature of ApplicationEngine's loading mechanism no specific wrapping is required for each application.
+
+NumPy extension to Python wrapping allows data exchange to application as an array rather than a disk file.
+Of course, it is possible to load an image from file and then convert it to NumPy
+array or just provide a file as explained in the previous section via
+Application.SetParameterString(...).
+
+The bridge between NumPy and OTB makes it easy to plug OTB into any image processing chain via Python code that uses
+GIS/Image processing tools such as GDAL, GRASS GIS, OSSIM that can deal with NumPy.
+
+Below code reads an input image using Python Pillow library (fork of PIL) and convert it to
+NumPy array. The NumPy array is used as an input to the application via
+*SetImageFromNumpyArray(...)* method.  The application used in this example is
+ExtractROI. After extracting a small area the output image is taken as NumPy
+array with *GetImageFromNumpyArray(...)* method thus avoid writing output to a
+temporary file.
+
+::
+
+   import sys
+   import os
+   import numpy as np
+   import otbApplication
+   from PIL import Image as PILImage
+
+   pilimage = PILImage.open('poupees.jpg')
+   npimage = np.asarray(pilimage)
+   inshow(pilimage)
+
+   ExtractROI = otbApplication.Registry.CreateApplication('ExtractROI')
+   ExtractROI.SetImageFromNumpyArray('in', npimage)
+   ExtractROI.SetParameterInt('startx', 140)
+   ExtractROI.SetParameterInt('starty', 120)
+   ExtractROI.SetParameterInt('sizex', 150)
+   ExtractROI.SetParameterInt('sizey', 150)
+   ExtractROI.Execute()
+
+   ExtractOutput = ExtractROI.GetImageAsNumpyArray('out')
+   output_pil_image = PILImage.fromarray(np.uint8(ExtractOutput))
+   imshow(output_pil_image)
+
+In-memory connection
+--------------------
+
+Applications are often used as part of larger processing
+workflows. Chaining applications currently requires to write/read back
+images between applications, resulting in heavy I/O operations and a
+significant amount of time dedicated to writing temporary files.
+
+Since OTB 5.8, it is possible to connect an output image parameter
+from one application to the input image parameter of the next
+parameter. This results in the wiring of the internal ITK/OTB
+pipelines together, permitting image streaming between the
+applications. Consequently, this removes the need of writing temporary
+images and improves performance. Only the last application of the processing chain is responsible
+for writing the final result images.
+
+In-memory connection between applications is available both at the C++
+API level and using the Python bindings.
+
+Here is a Python code sample which connects several applications together:
+
+.. code-block:: python
+
+    import otbApplication as otb
+
+    app1 = otb.Registry.CreateApplication("Smoothing")
+    app2 = otb.Registry.CreateApplication("Smoothing")
+    app3 = otb.Registry.CreateApplication("Smoothing")
+    app4 = otb.Registry.CreateApplication("ConcatenateImages")
+
+    app1.IN = argv[1]
+    app1.Execute()
+
+    # Connection between app1.out and app2.in
+    app2.SetParameterInputImage("in",app1.GetParameterOutputImage("out"))
+
+    # Execute call is mandatory to wire the pipeline and expose the
+    # application output. It does not write image
+    app2.Execute()
+
+    app3.IN = argv[1]
+
+    # Execute call is mandatory to wire the pipeline and expose the
+    # application output. It does not write image
+    app3.Execute()
+
+    # Connection between app2.out, app3.out and app4.il using images list
+    app4.AddImageToParameterInputImageList("il",app2.GetParameterOutputImage("out"));
+    app4.AddImageToParameterInputImageList("il",app3.GetParameterOutputImage("out"));
+
+    app4.OUT = argv[2]
+
+    # Call to ExecuteAndWriteOutput() both wires the pipeline and
+    # actually writes the output, only necessary for last application of
+    # the chain.
+    app4.ExecuteAndWriteOutput()
+
+**Note:** Streaming will only work properly if the application internal
+implementation does not break it, for instance by using an internal
+writer to write intermediate data. In this case, execution should
+still be correct, but some intermediate data will be read or written.
+
+Interactions with OTB pipeline
+------------------------------
+
+[Since OTB 6.6]
+
+The application framework has been extended in order to provide ways to
+interact with the pipelines inside each application. It applies only to
+applications that use input or output images. Let's check which  
+functions are available in the ``Application`` class. There are lots of getter 
+functions:
+
++---------------------------------+---------------------------------------+
+| Function name                   | return value                          |
++=================================+=======================================+
+| ``GetImageOrigin(...)``         | origin of the image (physical position|
+|                                 | of the first pixel center)            |
++---------------------------------+---------------------------------------+
+| ``GetImageSpacing(...)``        | signed spacing of the image           |
++---------------------------------+---------------------------------------+
+| ``GetImageSize(...)``           | size of the LargestPossibleRegion     |
++---------------------------------+---------------------------------------+
+| ``GetImageNbBands(...)``        | number of components per pixel        |
++---------------------------------+---------------------------------------+
+| ``GetImageProjection(...)``     | Projection WKT string                 |
++---------------------------------+---------------------------------------+
+| ``GetImageKeywordlist(...)``    | Ossim keywordlist (sensor model)      |
++---------------------------------+---------------------------------------+
+| ``GetImageMetaData(...)``       | the entire MetaDataDictionary         |
++---------------------------------+---------------------------------------+
+| ``GetImageRequestedRegion(...)``| requested region                      |
++---------------------------------+---------------------------------------+
+| ``GetImageBasePixelType(...)``  | pixel type of the underlying          |
+|                                 | Image/VectorImage.                    |
++---------------------------------+---------------------------------------+
+
+All these getters functions use the following arguments:
+
+* ``key``: a string containing the key of the image parameter
+* ``idx``: an optional index (default is 0) that can be used to access ImageList
+  parameters transparently
+
+There is also a function to send orders to the pipeline:
+
+  ``PropagateRequestedRegion(key, region, idx=0)``: sets a given RequestedRegion
+  on the image and propagate it, returns the memory print estimation. This function
+  can be used to measure the requested portion of input images necessary to produce
+  an extract of the full output.
+
+Note: a requested region (like other regions in the C++ API of otb::Image) consists 
+of an image index and a size, which defines a rectangular extract of
+the full image.
+
+This set of functions has been used to enhance the bridge between OTB images
+and Numpy arrays. There are now import and export functions available in
+Python that preserve the metadata of the image during conversions to Numpy
+arrays:
+
+* ``ExportImage(self, key)``: exports an output image parameter into a Python
+  dictionary.
+* ``ImportImage(self, key, dict, index=0)``: imports the image from a Python
+  dictionary into an image parameter (as a monoband image).
+* ``ImportVectorImage(self, key, dict, index=0)``: imports the image from a
+  Python dictionary into an image parameter (as a multiband image).
+
+The Python dictionary used has the following entries:
+
+  * ``'array'``: the Numpy array containing the pixel buffer
+  * ``'origin'``: origin of the image
+  * ``'spacing'``: signed spacing of the image
+  * ``'size'``: full size of the image
+  * ``'region'``: region of the image present in the buffer
+  * ``'metadata'``: metadata dictionary (contains projection, sensor model,...)
+
+Now some basic Q&A about this interface:
+
+    Q: What portion of the image is exported to Numpy array?
+    A: By default, the whole image is exported. If you had a non-empty requested
+    region (the result of calling PropagateRequestedRegion()), then this region
+    is exported.
+    
+    Q: What is the difference between ImportImage and ImportVectorImage?
+    A: The first one is here for Applications that expect a monoband otb::Image.
+    In most cases, you will use the second one: ImportVectorImage.
+    
+    Q: What kind of objects are there in this dictionary export?
+    A: The array is a numpy.ndarray. The other fields are wrapped
+    objects from the OTB library but you can interact with them in a
+    Python way: they support ``len()`` and ``str()`` operator, as well as 
+    bracket operator ``[]``. Some of them also have a ``keys()`` function just like
+    dictionaries.
+    
+This interface allows you to export OTB images (or extracts) to Numpy array,
+process them  by other means, and re-import them with preserved metadata. Please
+note that this is different from an in-memory connection.
+
+Here is a small example of what can be done:
+
+.. code-block:: python
+
+  import otbApplication as otb
+  
+  # Create a smoothing application
+  app = otb.Registry.CreateApplication("Smoothing")
+  app.SetParameterString("in",argv[1])
+  
+  # only call Execute() to setup the pipeline, not ExecuteAndWriteOutput() which would
+  # run it and write the output image
+  app.Execute()
+
+  # Setup a special requested region
+  myRegion = otb.itkRegion()
+  myRegion['size'][0] = 20
+  myRegion['size'][1] = 25
+  myRegion['index'].Fill(10)
+  ram = app.PropagateRequestedRegion("out",myRegion)
+  
+  # Check the requested region on the input image
+  print(app.GetImageRequestedRegion("in"))
+  
+  # Create a ReadImageInfo application
+  app2 = otb.Registry.CreateApplication("ReadImageInfo")
+  
+  # export "out" from Smoothing and import it as "in" in ReadImageInfo
+  ex = app.ExportImage("out")
+  app2.ImportVectorImage("in", ex)
+  app2.Execute()
+  
+  # Check the result of ReadImageInfo
+  someKeys = ['sizex', 'sizey', 'spacingx', 'spacingy', 'sensor', 'projectionref']
+  for key in someKeys:
+    print(key + ' : ' + str(app2.GetParameterValue(key)))
+  
+  # Only a portion of "out" was exported but ReadImageInfo is still able to detect the 
+  # correct full size of the image
+
+
+Corner cases
+------------
+
+There are a few corner cases to be aware of when using Python wrappers. They are
+often limitations, that one day may be solved in future versions. If it
+happens, this documentation will report the OTB version that fixes the issue.
+
+Calling UpdateParameters()
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+These wrappers are made as a mirror of the C++ API, so there is a function
+``UpdateParameters()``. Its role is to update parameters that depend on others.
+It is called at least once at the beginning of ``Execute()``.
+
+In command line and GUI launchers, this functions gets called each time a
+parameter of the application is modified. In Python, this mechanism is not
+automated: there are cases where you may have to call it yourself.
+
+Let's take an example with the application ``PolygonClassStatictics``. In this
+application, the choices available in the parameter ``field`` depend on the list
+of fields actually present in the vector file ``vec``. If you try to set the
+parameters ``vec`` and ``field``, you will get an error:
+
+.. code-block:: python
+
+    import otbApplication as otb
+    app = otb.Registry.CreateApplication("PolygonClassStatistics")
+    app.SetParameterString("vec","../../src/OTB-Data/Input/Classification/variousVectors.sqlite")
+    app.SetParameterString("field", "label")
+
+::
+
+  Traceback (most recent call last):
+    File "<stdin>", line 1, in <module>
+    File "/home/gpasero/Projet_OTB/build/OTB/lib/otb/python/otbApplication.py", line 897, in SetParameterString
+      def SetParameterString(self, *args): return _otbApplication.Application_SetParameterString(self, *args)
+  RuntimeError: Exception thrown in otbApplication Application_SetParameterString: /home/gpasero/Projet_OTB/src/OTB/Modules/Wrappers/ApplicationEngine/src/otbWrapperListViewParameter.cxx:141:
+  itk::ERROR: ListViewParameter(0x149da10): Cannot find label
+
+The error says that the choice ``label`` is not recognized, because ``UpdateParameters()``
+was not called after setting the vector file. The solution is to call it before
+setting the ``field`` parameter:
+
+.. code-block:: python
+
+    app.UpdateParameters()
+    app.SetParameterString("field", "label")
+
+No metadata in NumPy arrays
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+With the NumPy module, it is possible to convert images between OTB and NumPy
+arrays. For instance, when converting from OTB to NumPy array:
+
+* An ``Update()`` of the underlying ``otb::VectorImage`` is requested. Be aware
+  that the full image is generated.
+* The pixel buffer is copied into a ``numpy.array``
+
+As you can see, there is no export of the metadata, such as origin, spacing,
+geographic projection. It means that if you want to re-import a NumPy array back into OTB,
+the image won't have any of these metadata. This can pose problems for applications
+that relate to geometry, projections, and also calibration.
+
+Future developments will probably offer a more adapted structure to import and
+export images between OTB and the Python world.
diff --git a/Documentation/Cookbook/rst/Recipes.rst b/Documentation/Cookbook/rst/Recipes.rst
index 89c84b90b3..7697809f34 100644
--- a/Documentation/Cookbook/rst/Recipes.rst
+++ b/Documentation/Cookbook/rst/Recipes.rst
@@ -18,5 +18,3 @@ and demonstrate how they can be applied.
    recipes/pbclassif.rst
    recipes/featextract.rst
    recipes/stereo.rst
-   recipes/python.rst
-   
diff --git a/Documentation/Cookbook/rst/recipes/python.rst b/Documentation/Cookbook/rst/recipes/python.rst
deleted file mode 100644
index 7813b897cd..0000000000
--- a/Documentation/Cookbook/rst/recipes/python.rst
+++ /dev/null
@@ -1,377 +0,0 @@
-OTB processing in Python
-========================
-
-Basics
-------
-
-In the ``otbApplication`` module, two main classes can be manipulated :
-
--  ``Registry``, which provides access to the list of available
-   applications, and can create applications.
-
--  ``Application``, the base class for all applications. This allows one to
-   interact with an application instance created by the ``Registry``.
-
-Here is one example of how to use Python to run the ``Smoothing``
-application, changing the algorithm at each iteration.
-
-.. code-block:: python
-
-    #  Example on the use of the Smoothing application
-    #
-
-    # We will use sys.argv to retrieve arguments from the command line.
-    # Here, the script will accept an image file as first argument,
-    # and the basename of the output files, without extension.
-    from sys import argv
-
-    # The python module providing access to OTB applications is otbApplication
-    import otbApplication
-
-    # otbApplication.Registry can tell you what application are available
-    print('Available applications: ')
-    print (str( otbApplication.Registry.GetAvailableApplications()))
-
-    # Let's create the application  "Smoothing"
-    app = otbApplication.Registry.CreateApplication("Smoothing")
-
-    # We print the keys of all its parameters
-    print (app.GetParametersKeys())
-
-    # First, we set the input image filename
-    app.SetParameterString("in", argv[1])
-
-    # The smoothing algorithm can be set with the "type" parameter key
-    # and can take 3 values: 'mean', 'gaussian', 'anidif'
-    for type in ['mean', 'gaussian', 'anidif']:
-
-      print('Running with ' + type + ' smoothing type')
-
-      # Now we configure the smoothing algorithm
-      app.SetParameterString("type", type)
-
-      # Set the output filename, using the algorithm type to differentiate the outputs
-      app.SetParameterString("out", argv[2] + type + ".tif")
-
-      # This will execute the application and save the output to argv[2]
-      app.ExecuteAndWriteOutput()
-
-If you want to handle the parameters from a Python dictionary, you can use the
-functions *SetParameters()* and *GetParameters()*.
-
-.. code-block:: python
-
-    params = {"in":"myInput.tif", "type.mean.radius":4}
-    app.SetParameters(params)
-    params2 = app.GetParameters()
-
-Numpy array processing
-----------------------
-
-Input and output images to any OTB application in the form of NumPy array is now possible in OTB Python wrapping.
-The Python wrapping only exposes OTB Application engine module (called *ApplicationEngine*) which allows one to access existing C++ applications.
-Due to blissful nature of ApplicationEngine's loading mechanism no specific wrapping is required for each application.
-
-NumPy extension to Python wrapping allows data exchange to application as an array rather than a disk file.
-Of course, it is possible to load an image from file and then convert it to NumPy
-array or just provide a file as explained in the previous section via
-Application.SetParameterString(...).
-
-The bridge between NumPy and OTB makes it easy to plug OTB into any image processing chain via Python code that uses
-GIS/Image processing tools such as GDAL, GRASS GIS, OSSIM that can deal with NumPy.
-
-Below code reads an input image using Python Pillow library (fork of PIL) and convert it to
-NumPy array. The NumPy array is used as an input to the application via
-*SetImageFromNumpyArray(...)* method.  The application used in this example is
-ExtractROI. After extracting a small area the output image is taken as NumPy
-array with *GetImageFromNumpyArray(...)* method thus avoid writing output to a
-temporary file.
-
-::
-
-   import sys
-   import os
-   import numpy as np
-   import otbApplication
-   from PIL import Image as PILImage
-
-   pilimage = PILImage.open('poupees.jpg')
-   npimage = np.asarray(pilimage)
-   inshow(pilimage)
-
-   ExtractROI = otbApplication.Registry.CreateApplication('ExtractROI')
-   ExtractROI.SetImageFromNumpyArray('in', npimage)
-   ExtractROI.SetParameterInt('startx', 140)
-   ExtractROI.SetParameterInt('starty', 120)
-   ExtractROI.SetParameterInt('sizex', 150)
-   ExtractROI.SetParameterInt('sizey', 150)
-   ExtractROI.Execute()
-
-   ExtractOutput = ExtractROI.GetImageAsNumpyArray('out')
-   output_pil_image = PILImage.fromarray(np.uint8(ExtractOutput))
-   imshow(output_pil_image)
-
-In-memory connection
---------------------
-
-Applications are often used as part of larger processing
-workflows. Chaining applications currently requires to write/read back
-images between applications, resulting in heavy I/O operations and a
-significant amount of time dedicated to writing temporary files.
-
-Since OTB 5.8, it is possible to connect an output image parameter
-from one application to the input image parameter of the next
-parameter. This results in the wiring of the internal ITK/OTB
-pipelines together, permitting image streaming between the
-applications. Consequently, this removes the need of writing temporary
-images and improves performance. Only the last application of the processing chain is responsible
-for writing the final result images.
-
-In-memory connection between applications is available both at the C++
-API level and using the Python bindings.
-
-Here is a Python code sample which connects several applications together:
-
-.. code-block:: python
-
-    import otbApplication as otb
-
-    app1 = otb.Registry.CreateApplication("Smoothing")
-    app2 = otb.Registry.CreateApplication("Smoothing")
-    app3 = otb.Registry.CreateApplication("Smoothing")
-    app4 = otb.Registry.CreateApplication("ConcatenateImages")
-
-    app1.IN = argv[1]
-    app1.Execute()
-
-    # Connection between app1.out and app2.in
-    app2.SetParameterInputImage("in",app1.GetParameterOutputImage("out"))
-
-    # Execute call is mandatory to wire the pipeline and expose the
-    # application output. It does not write image
-    app2.Execute()
-
-    app3.IN = argv[1]
-
-    # Execute call is mandatory to wire the pipeline and expose the
-    # application output. It does not write image
-    app3.Execute()
-
-    # Connection between app2.out, app3.out and app4.il using images list
-    app4.AddImageToParameterInputImageList("il",app2.GetParameterOutputImage("out"));
-    app4.AddImageToParameterInputImageList("il",app3.GetParameterOutputImage("out"));
-
-    app4.OUT = argv[2]
-
-    # Call to ExecuteAndWriteOutput() both wires the pipeline and
-    # actually writes the output, only necessary for last application of
-    # the chain.
-    app4.ExecuteAndWriteOutput()
-
-**Note:** Streaming will only work properly if the application internal
-implementation does not break it, for instance by using an internal
-writer to write intermediate data. In this case, execution should
-still be correct, but some intermediate data will be read or written.
-
-Interactions with OTB pipeline
-------------------------------
-
-[Since OTB 6.6]
-
-The application framework has been extended in order to provide ways to
-interact with the pipelines inside each application. It applies only to
-applications that use input or output images. Let's check which  
-functions are available in the ``Application`` class. There are lots of getter 
-functions:
-
-+---------------------------------+---------------------------------------+
-| Function name                   | return value                          |
-+=================================+=======================================+
-| ``GetImageOrigin(...)``         | origin of the image (physical position|
-|                                 | of the first pixel center)            |
-+---------------------------------+---------------------------------------+
-| ``GetImageSpacing(...)``        | signed spacing of the image           |
-+---------------------------------+---------------------------------------+
-| ``GetImageSize(...)``           | size of the LargestPossibleRegion     |
-+---------------------------------+---------------------------------------+
-| ``GetImageNbBands(...)``        | number of components per pixel        |
-+---------------------------------+---------------------------------------+
-| ``GetImageProjection(...)``     | Projection WKT string                 |
-+---------------------------------+---------------------------------------+
-| ``GetImageKeywordlist(...)``    | Ossim keywordlist (sensor model)      |
-+---------------------------------+---------------------------------------+
-| ``GetImageMetaData(...)``       | the entire MetaDataDictionary         |
-+---------------------------------+---------------------------------------+
-| ``GetImageRequestedRegion(...)``| requested region                      |
-+---------------------------------+---------------------------------------+
-| ``GetImageBasePixelType(...)``  | pixel type of the underlying          |
-|                                 | Image/VectorImage.                    |
-+---------------------------------+---------------------------------------+
-
-All these getters functions use the following arguments:
-
-* ``key``: a string containing the key of the image parameter
-* ``idx``: an optional index (default is 0) that can be used to access ImageList
-  parameters transparently
-
-There is also a function to send orders to the pipeline:
-
-  ``PropagateRequestedRegion(key, region, idx=0)``: sets a given RequestedRegion
-  on the image and propagate it, returns the memory print estimation. This function
-  can be used to measure the requested portion of input images necessary to produce
-  an extract of the full output.
-
-Note: a requested region (like other regions in the C++ API of otb::Image) consists 
-of an image index and a size, which defines a rectangular extract of
-the full image.
-
-This set of functions has been used to enhance the bridge between OTB images
-and Numpy arrays. There are now import and export functions available in
-Python that preserve the metadata of the image during conversions to Numpy
-arrays:
-
-* ``ExportImage(self, key)``: exports an output image parameter into a Python
-  dictionary.
-* ``ImportImage(self, key, dict, index=0)``: imports the image from a Python
-  dictionary into an image parameter (as a monoband image).
-* ``ImportVectorImage(self, key, dict, index=0)``: imports the image from a
-  Python dictionary into an image parameter (as a multiband image).
-
-The Python dictionary used has the following entries:
-
-  * ``'array'``: the Numpy array containing the pixel buffer
-  * ``'origin'``: origin of the image
-  * ``'spacing'``: signed spacing of the image
-  * ``'size'``: full size of the image
-  * ``'region'``: region of the image present in the buffer
-  * ``'metadata'``: metadata dictionary (contains projection, sensor model,...)
-
-Now some basic Q&A about this interface:
-
-    Q: What portion of the image is exported to Numpy array?
-    A: By default, the whole image is exported. If you had a non-empty requested
-    region (the result of calling PropagateRequestedRegion()), then this region
-    is exported.
-    
-    Q: What is the difference between ImportImage and ImportVectorImage?
-    A: The first one is here for Applications that expect a monoband otb::Image.
-    In most cases, you will use the second one: ImportVectorImage.
-    
-    Q: What kind of objects are there in this dictionary export?
-    A: The array is a numpy.ndarray. The other fields are wrapped
-    objects from the OTB library but you can interact with them in a
-    Python way: they support ``len()`` and ``str()`` operator, as well as 
-    bracket operator ``[]``. Some of them also have a ``keys()`` function just like
-    dictionaries.
-    
-This interface allows you to export OTB images (or extracts) to Numpy array,
-process them  by other means, and re-import them with preserved metadata. Please
-note that this is different from an in-memory connection.
-
-Here is a small example of what can be done:
-
-.. code-block:: python
-
-  import otbApplication as otb
-  
-  # Create a smoothing application
-  app = otb.Registry.CreateApplication("Smoothing")
-  app.SetParameterString("in",argv[1])
-  
-  # only call Execute() to setup the pipeline, not ExecuteAndWriteOutput() which would
-  # run it and write the output image
-  app.Execute()
-
-  # Setup a special requested region
-  myRegion = otb.itkRegion()
-  myRegion['size'][0] = 20
-  myRegion['size'][1] = 25
-  myRegion['index'].Fill(10)
-  ram = app.PropagateRequestedRegion("out",myRegion)
-  
-  # Check the requested region on the input image
-  print(app.GetImageRequestedRegion("in"))
-  
-  # Create a ReadImageInfo application
-  app2 = otb.Registry.CreateApplication("ReadImageInfo")
-  
-  # export "out" from Smoothing and import it as "in" in ReadImageInfo
-  ex = app.ExportImage("out")
-  app2.ImportVectorImage("in", ex)
-  app2.Execute()
-  
-  # Check the result of ReadImageInfo
-  someKeys = ['sizex', 'sizey', 'spacingx', 'spacingy', 'sensor', 'projectionref']
-  for key in someKeys:
-    print(key + ' : ' + str(app2.GetParameterValue(key)))
-  
-  # Only a portion of "out" was exported but ReadImageInfo is still able to detect the 
-  # correct full size of the image
-
-
-Corner cases
-------------
-
-There are a few corner cases to be aware of when using Python wrappers. They are
-often limitations, that one day may be solved in future versions. If it
-happens, this documentation will report the OTB version that fixes the issue.
-
-Calling UpdateParameters()
-^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-These wrappers are made as a mirror of the C++ API, so there is a function
-``UpdateParameters()``. Its role is to update parameters that depend on others.
-It is called at least once at the beginning of ``Execute()``.
-
-In command line and GUI launchers, this functions gets called each time a
-parameter of the application is modified. In Python, this mechanism is not
-automated: there are cases where you may have to call it yourself.
-
-Let's take an example with the application ``PolygonClassStatictics``. In this
-application, the choices available in the parameter ``field`` depend on the list
-of fields actually present in the vector file ``vec``. If you try to set the
-parameters ``vec`` and ``field``, you will get an error:
-
-.. code-block:: python
-
-    import otbApplication as otb
-    app = otb.Registry.CreateApplication("PolygonClassStatistics")
-    app.SetParameterString("vec","../../src/OTB-Data/Input/Classification/variousVectors.sqlite")
-    app.SetParameterString("field", "label")
-
-::
-
-  Traceback (most recent call last):
-    File "<stdin>", line 1, in <module>
-    File "/home/gpasero/Projet_OTB/build/OTB/lib/otb/python/otbApplication.py", line 897, in SetParameterString
-      def SetParameterString(self, *args): return _otbApplication.Application_SetParameterString(self, *args)
-  RuntimeError: Exception thrown in otbApplication Application_SetParameterString: /home/gpasero/Projet_OTB/src/OTB/Modules/Wrappers/ApplicationEngine/src/otbWrapperListViewParameter.cxx:141:
-  itk::ERROR: ListViewParameter(0x149da10): Cannot find label
-
-The error says that the choice ``label`` is not recognized, because ``UpdateParameters()``
-was not called after setting the vector file. The solution is to call it before
-setting the ``field`` parameter:
-
-.. code-block:: python
-
-    app.UpdateParameters()
-    app.SetParameterString("field", "label")
-
-No metadata in NumPy arrays
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-With the NumPy module, it is possible to convert images between OTB and NumPy
-arrays. For instance, when converting from OTB to NumPy array:
-
-* An ``Update()`` of the underlying ``otb::VectorImage`` is requested. Be aware
-  that the full image is generated.
-* The pixel buffer is copied into a ``numpy.array``
-
-As you can see, there is no export of the metadata, such as origin, spacing,
-geographic projection. It means that if you want to re-import a NumPy array back into OTB,
-the image won't have any of these metadata. This can pose problems for applications
-that relate to geometry, projections, and also calibration.
-
-Future developments will probably offer a more adapted structure to import and
-export images between OTB and the Python world.
-
-- 
GitLab