Excerpt | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
IntroductionThis page explain how to access OTB C++ application via Python API inside a SNAP Operator Plugin. pre-requsitiesRead how to write a processor in python for a tutorial. - How to write a processor in Python. This tutorial explain all the snap related stuff in creating an java maven project to write a SNAP processor Download and install OTB with python wrapping (see https://www.orfeo-toolbox.org/SoftwareGuide/SoftwareGuidech2.html#x16-190002). ContentHere is a snap-engine-python-operator which use OTB's RadiometricIndices application. https://github.com/senbox-org/snap-examples/tree/master/snap-engine-otb-python-operator This example demonstrates computing ndvi for a source product opened in SNAP through OTB. Note that RadiometricIndices application in OTB is not exclusively for computing NDVI. see its documentation here[link]. The python-operator-plugin ask for red and nir bands that will be used to compute NDVI. The parameter options are handled by ndvi_op-in.xml Project SetupIn order to write a Python plugin for SNAP you need the following tools.
Project structureThe recommended basic project structure looks like as shown in the following code block. We will look at the content and the meaning of each of those files later. <PROJECT_DIR> | pom.xml (the project definition file for maven) \---src \---main +---nbm | manifest.mf (settings for the plugin) +---python | my_python_op-info.xml (metadata about the operator) | my_python_op.py (the actual operator implementation) \---resources | layer.xml (integration into SNAP Desktop) \---META-INF \---services org.esa.snap.python.gpf.PyOperatorSpi (make the operator known to SNAP Engine) Operator implementationAn operator implemented in Python needs to have three methods. An initialize, a compute and a dispose method. Please have a look at the following skeleton on an operator.
__init__ method
We create our otb application in the __init__ method. Variables used to store input and output band are set to None in __init__ method. Initialize method
initialize method takes input from user through UI and create source and target product. We also create band instance which are later used inside computeTileStack method. This method is called only once at start of processing. ComputeTileStack MethodData input to OTB application from SNAP is done using python numpy arrays. Inside computeTileStack method, one can have access to underlying pixels which fall only under the target_rectangle. We pick the pixel data using Tile.getSamplesFloat() and stack into an N-dimensional numpy array. The call for making numpy.ndarray or numpy.array is decided by the input image type (VectorImage, Image, ImageList) of OTB application. Below is the snippet which create N-dimensional numpy array using two bands for the input to RadiometricIndices application.
samples_red and sample_nir represent the underlying array of samples for red and nir bands. w and h and width and height of single target tile respectively. Set Input of OTB application from Numpy arrayOnce we have data we can set this numpy directly as the input parameter to OTB application.
The above code will set the input parameter to a otbVectorImage whose each Compoenent represent the values of numpy array. Setting other parameters for OTB applicationSetting other parameters of OTB application.
The above code will tell RadiometricIndices application to compute only Vegetation:NDVI, where the 1st and 2nd band in the input image (numpy array) represent Red and NIR bands respectively. Execute OTB application
Store Output of OTB application into target product
Note: Tile.setSamples() requires a N-dimensional numpy array even though the function set samples for one single band. This is a limitation in snap python bindings. Our otb application returns an N-D array from GetVectorImageAsNumpyArray() but number of bands is 1 because we compute only one index NDVI. suppose we compute two indices NDVI and WVI, then the "ndvi" will have two bands each representing one index. In that case, we have to workaround to overcome the snap python issue before calling Tile.setSamples() See below code snippet which create a temporary nd array and fill the first slice from ndvi
Full source codehttps://github.com/senbox-org/snap-examples/tree/master/snap-engine-otb-python-operator TestingCompile and Install OTB (instructions for linux)
Clone snap-examples from github forkYou can checkout the sources and import the project. git clone https://github.com/rkanavath/snap-examples Configure Paths
Start Intelij IDEsee How to develop an extension module for configuring IDE and running the processor inside snap desktop. Debugging and Running your Extension in an IDE → IntelliJ IDEA IDE → Debugging and Running with SNAP Desktop Open snap-engine-otb-python-operator/pom.xml References
|
...