Request for Changes-12: Enhancement of python wrapping
Contents
Status
- Author: Rashad Kanavath
- Additional Contributors: Julien Malik
- Submitted on 08.10.2015
- 5.2.0
- github branch : https://github.com/CS-SI/OTB/tree/enhance_python_wrapping
- pull request : https://github.com/orfeotoolbox/OTB/pull/4
Summary
This RFC propose two enhancements in existing python wrapping. First is the support of numpy arrays in the application input. Existing bindings only allows input file names in Application.SetParameterString(""). The second enhacement allows a "pythonic" way when writing an application in python. In short you can use Application.PARAMETERKEY= <some-parameter-value>. Note that parameter key must be in block letters. More details about can be found in the implementation details.
Rationale
Ehance python wrapping in OTB.
Implementation details
First of all. I would like to note that all numpy stuff are in ifndef block and will be only enabled if the numpy package is found. No existing python code is thus affected by this changes. Only a different way of providing input to SetParameterString("in") or SetParameterString("out") is added. The SetParameterString( ) for input and output image parameters still accept the file names as before. With this RFC, you can give a numpy array instead of filenames!. Remember that I use in and out as the parameter key for input image and output image respectively. Ofcoure this value is not fixed in the code.
You can now connect two different otb application without any intermediate output files. You can do a Smoothing or OrthoRectification direclty from the output of an ExtractROI or Convert application!. To have a clear picture, I put below a code snippet.
ExtractROI = otbApplication.Registry.CreateApplication("ExtractROI") ExtractROI.SetParameterString("in", inFile) ExtractROI.SetParameterInt("startx", 10) ExtractROI.SetParameterInt("starty", 10) ExtractROI.SetParameterInt("sizex", 250) ExtractROI.SetParameterInt("sizey", 250) ExtractROI.SetParameterUserValue("sizex", True) ExtractROI.SetParameterUserValue("sizey", True) ExtractROI.Execute() ExtractROIOut = ExtractROI.GetVectorImageAsNumpyArray("out", 'float') #write RGB image to file via python #misc.imsave('ExtractROIOut.jpg', ExtractROIOut) Rescale = otbApplication.Registry.CreateApplication("Rescale") #take numpy array from ExtractROI and feed into Rescale Rescale.SetVectorImageFromNumpyArray("in", ExtractROIOut)
You can also have a look at the test code. 'Modules/Wrappers/SWIG/test/python/PythonNumpyTest.py'
Following are the new functions that handle the numpy array to and from application. These functions are part of otbApplication.i. They are included in the python code using swig's extend keyword. They have direct access to python
- GetVectorImageAsNumpyArray
GetVectorImageAsNumpyArray(<parameter key name>, <data-type> [optional] ) This method returns a suitable numpy array of (float/double/int/uint/...) based on the otb::Image/otbVectorImage that is exactly the output of application. (eg: ExtractROI->GetParameter("out")->GetImage() ). The optional <data-type> allows to do a conversion to a specific pixel type. Default is float.
- SetVectorImageFromNumpyArray
SetVectorImageFromNumpyArray(<parameter key name>, output-numpy-variable)
This method set the application's input image parameter. It requires parameter's key and a valid numpy ndarray.
The numpy array exchanged is always an ndarray and it is converted to and from a otb::VectorImage<>.
The Second part of this RFC gives the liberty to have a new 'pythonic style when writing an otb application in python. I will put down a small code snippet to have a clear cut picture of this.
Before RFC:
import otbApplication app = otb.Registry.CreateApplication('OrthoRectification') app.SetParameterString("io.in", "/path/to/image/to/input.tif") app.SetParameterString('map', 'labert2') app.SetParameterString('map', 'epsg') app.SetParameterInt('map.epsg.code', 32768) app.SetParameterString('map', 'utm') app.SetParameterInt('utm.zone', 43) app.MAP.UTM.NORTHHEM = True app.SetParameterString("io.out", "rectified.tif") app.ExecuteAndWriteOutput()
After RFC
import otbApplication app = otb.Registry.CreateApplication('OrthoRectification') app.IO.IN = argv[1] ''#Hold on to see the behaviour of app.MAP. '' app.MAP = 'lambert2' '' # app.MAP.UTM.ZONE = 47 will error out because you have app.MAP = "lambert2". Isn't that cool or what?'' app.MAP = 'epsg' app.MAP.EPSG.CODE = 32768 app.MAP = 'utm' app.MAP.UTM.ZONE = 47 app.MAP.UTM.NORTHHEM = True app.IO.OUT = argv[2] app.ExecuteAndWriteOutput()
Classes and files
Below are the list of classes and files modified and added. All modifications are limited to Modules/Wrappers/SWIG.
Modules/Wrappers/SWIG/
M src/otbWrapperSWIGIncludes.h M src/otbApplication.i M test/python/CMakeLists.txt M src/CMakeLists.txt M otb-module-init.cmake A src/numpy.i A test/python/PythonNumpyTest.py A test/python/PythonNewStyleParametersTest.py
Applications
None
Tests
A pyTvNumpyIO - test output and input via numpy array. A pyTvNewStyleParameters - test the pythonic stlye for writing otb application in python. A pyTvNewStyleParametersInstanciateAll - test the pythonic stlye for writing otb application in python for all parameters and all applications.
Documentation
Inline doxygen comments are added in the sources.
Additional notes
This work is done by CS Team and is under CS Copyright.
A request on swig's issue tracker to include numpy.i as a part of its distribution - https://github.com/swig/swig/issues/361