diff --git a/.gitlab/issue_templates/bugs.md b/.gitlab/issue_templates/bugs.md index 75b403c79f42c0dcd8ee1be513cee9b70787a0a9..378d84f1b9fd63fb4c96cb6ee3319f098b70390d 100644 --- a/.gitlab/issue_templates/bugs.md +++ b/.gitlab/issue_templates/bugs.md @@ -9,3 +9,5 @@ Describe as precisely as possible how to reproduce the bug. Try to isolate a min ### Configuration information OS, OTB version or tag, information related to build (binaries, superbuild, system libs ...) + +/label ~bug diff --git a/.gitlab/issue_templates/feature_request.md b/.gitlab/issue_templates/feature_request.md index 6031fad9a77fc5b1c2dba02fbbe52847963c58e6..5b6ee30b89001a72c48d6f9435fd10ebfb5cd5a7 100644 --- a/.gitlab/issue_templates/feature_request.md +++ b/.gitlab/issue_templates/feature_request.md @@ -1 +1,3 @@ Short summary of the requested feature + +/label ~feature diff --git a/.gitlab/merge_request_templates/request_for_changes.md b/.gitlab/merge_request_templates/request_for_changes.md index 1fcd7227260d3ca5bc769480ba39cf5ef63926d0..354996678a5435ed27f162a2f9b0f2142004d211 100644 --- a/.gitlab/merge_request_templates/request_for_changes.md +++ b/.gitlab/merge_request_templates/request_for_changes.md @@ -10,11 +10,11 @@ Explain the rationale for the changes (possible link to a Request For Comments o #### Classes and files -Give an overview of the implementation: main changes made to classes, files and module. Do not paste complete diff, as it is available in the merge request already. +Give an overview of the implementation: main changes made to classes, files and modules. Do not paste complete diff, as it is available in the merge request already. #### Applications -Describe any changes made to existing applications, or new application that have been added. +Describe any changes made to existing applications, or new applications that have been added. #### Tests @@ -22,7 +22,7 @@ Describe the testing strategy for new features. ### Documentation -List or link documentation modification that were made (doxygen, example, software guide, application documentation, cookbook). +List or link documentation modifications that were made (doxygen, example, software guide, application documentation, cookbook). ### Additional notes diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..bc96c959330c797648434e970e0bfef424721428 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,147 @@ +# How to contribute to Orfeo ToolBox ? + +Thank you for taking the time to contribute to OTB! This document will guide you +through the workflow and best practices you need to know to send your +contribution. + +There are many ways to contribute to OTB: + +* [Reporting a bug](#reporting-bugs) +* [Making a feature request](#feature-requests-and-discussions) +* [Improving documentation](#documentation-improvements) +* [Contributing code (C++, Python, CMake, etc.)](#code-contribution) +* [Publishing a remote module](#remote-modules) + +Our main workflow uses GitLab for source control, issues and task tracking. We +use a self-hosted gitlab instance: + +[`https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb`](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb) + +Remember to check out also our [developers mailing list](https://groups.google.com/forum/?hl=fr#!forum/otb-developers/join), +where we discuss some features, improvements and high level project planning. +You are welcome to ask questions there as a beginner or future OTB contributor! + +## Reporting bugs + +If you have found a bug, you can first [search the existing issues](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/issues?label_name%5B%5D=bug) +to see if it has already been reported. + +If it's a new bug, please [open a new issue on GitLab](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/issues/new). +The 'Bug' issue template will help you provide all important information and +help fixing the bug quicker. Remember to add as much information as possible! + +## Feature requests and discussions + +Feature requests are welcome! Generally you are welcome to simply [open an issue](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/issues) +and discuss your idea there. For more complex requests there is an issue +template for in depth description called 'Request for Comments'. + + +## Documentation improvements + +The two main OTB documentations are the [Software Guide](https://www.orfeo-toolbox.org/SoftwareGuide/index.html) +and the [CookBook](https://www.orfeo-toolbox.org/CookBook/). Their sources are +hosted in the main OTB repository in the `Documentation/` directory. Then, to +contribute documentation use the same workflow as for code contributions (see +below). + +See also the [Compiling documentation](https://wiki.orfeo-toolbox.org/index.php/Compiling_documentation) +wiki page for help on building the Sphinx and Latex source. + +## Code contribution + +The OTB workflow is based on GitLab [Merge Requests](https://docs.gitlab.com/ee/gitlab-basics/add-merge-request.html). +Clone the repository, create a feature branch, commit your changes, push the +feature branch to a fork (or the main repository if you are a core developer), +then send a merge request. + +Note that we also accept PRs on our [GitHub mirror](https://github.com/orfeotoolbox/OTB) +which we will manually merge. + +### Commit message + +On your feature branch, write a good [commit message](https://xkcd.com/1296/): +short and descriptive. If fixing an issue or bug, put the issue number in the +commit message so that GitLab can [crosslink it](https://docs.gitlab.com/ce/user/project/issues/crosslinking_issues.html). +You can prefix your commit message with an indicating flag (DOC, BUG, PKG, +TEST, SuperBuild, etc.). + +Standard prefixes for OTB commit messages: + + BUG: Fix for runtime crash or incorrect result + COMP: Compiler error or warning fix + DOC: Documentation change + ENH: New functionality + PERF: Performance improvement + STYLE: No logic impact (indentation, comments) + WIP: Work In Progress not ready for merge + +For example, here are some good commit messages: + + BUG: #1701 Warn users if parameter string is unset + DOC: Fix typo in Monteverdi French translation + COMP: Allow GeoTIFF and TIFF to be disabled when no 3rd party drags them + +### Merge request + +Your contribution is ready to be added to the main OTB repository? Send a Merge +Request against the `develop` branch on GitLab using the merge request +template. The merge request will then be discussed by the community and the core +OTB team. + +* Merge requests can not be merged until all discussions have been resolved (this is enforced by GitLab) +* Merge requests **must receive at least 2 positives votes from PSC members** before being merged +* The merger is responsible for checking that the branch is up-to-date with develop +* Merge requests can be merged by anyone (not just PSC or RM) with push access to develop +* Merge requests can be merged once the dashboard is proven green for this branch + +Branches can be registered for dashboard testing by adding one line in `Config/feature_branches.txt` in [otb-devutils repository](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-devutils.git). + +For branches in the main repository, the syntax is the following: + +``` +branch_name [otb-data_branch_name] + +``` +The second branch name is optional. It can be set if you need to modify [otb-data](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-data.git) according to your changes. + +For branches in forks, the syntax is the following: +``` +user/branch_name [user/otb-data_branch_name] +``` +Again, the second branch name is optional. + +For users without push access to [otb-devutils repository](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-devutils.git), the modification can be asked through a merge requests to this repository. + +Once the feature branch is registered for testing, it should appear in the *FeatureBranches* section of the [OTB dashboard](https://dash.orfeo-toolbox.org/index.php?project=OTB) next day (remember tests are run on a nighlty basis). + +Do not forget to remove the feature branch for testing once it has been merged. + +## Remote modules + +[Remote Modules](https://wiki.orfeo-toolbox.org/index.php/Remote_Modules) are +the prefered way if you wish to make your apps and filters available to the +community while keeping control and maintenance of their sources. Remote +modules are just like regular modules, except they are not distributed inside +OTB source code. Under some conditions (dependencies, official acceptance +process, etc.), we are also able to distribute your remote module in the +official standalone binaries. See [the wiki](https://wiki.orfeo-toolbox.org/index.php/Remote_Modules) +for more information. + +## Gitlab guidelines + +In order to organize the issues in our Gitlab instance, we use both labels and +milestones. + +The [milestones](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/milestones) should be used to track in which release a feature is merged. +Gitlab can then provide a summary of all features and bugs added to a given release +version. + +Regarding labels, we use the following set: +* ~story: significant feature to be implemented with a detailed work plan, it can + correspond to a Request for Comments that has turned into a development action +* ~bug: Bug, crash or unexpected behavior, reported by a user or a developer +* ~feature: Feature request expressed by an OTB user/developer +* ~"To Do": action is planned +* ~Doing: work in progress +* ~api ~app ~documentation ~monteverdi ~packaging ~qgis: optional context information diff --git a/Documentation/Cookbook/rst/ExtendedFilenames.rst b/Documentation/Cookbook/rst/ExtendedFilenames.rst new file mode 100644 index 0000000000000000000000000000000000000000..02b5512351958d0b5ae88f1de831e9c5c2f823cc --- /dev/null +++ b/Documentation/Cookbook/rst/ExtendedFilenames.rst @@ -0,0 +1,317 @@ +.. _extended-filenames: + +Extended filenames +================================ + +Extended filenames is an interesting feature of OTB. With it, you can control +several aspects of the beahvior of the OTB in the OTB-Applications or in our +own C++ applications. Historically this feature has been desingn to solve +an issue with how to handle geo-referencing information. + +Indeed, there are multiple ways to define geo-referencing information. For +instance, one can use a geographic transform, a cartographic projection, +or a sensor model with RPC coefficients. A single image may contain +several of these elements, such as in the “ortho-ready†products: this +is a type of product still in sensor geometry (the sensor model is +supplied with the image) but it also contains an approximative +geographic transform that can be used to have a quick estimate of the +image localisation. For instance, your product may contain a “.TIF†file +for the image, along with a “.RPB†file that contains the sensor model +coefficients and an “.IMD†file that contains a cartographic projection. + +This case leads to the following question: which geo-referencing +element should be used when opening this image in OTB. In +fact, it depends on the users need. For an orthorectification +application, the sensor model must be used. In order to specify which +information should be skipped, a syntax of extended filenames has been +developed for both reading and writing. + +Since the development of this feature we have extend this mechanism for +other aspaects: like band or overview selection in reader part or support +create option of gdal in writer part.The reader and writer extended filename +support is based on the same syntax, only the options are different. +To benefit from the extended file name mechanism, the following syntax +is to be used: + +:: + + Path/Image.ext?&key1=<value1>&key2=<value2> + +**Note that you’ll probably need to “quote†the filename, especially if calling +applications from the bash command line.** + +Reader options +^^^^^^^^^^^^^^ + +:: + + &geom=<path/filename.geom> + +- Contains the file name of a valid geom file + +- Use the content of the specified geom file instead of + image-embedded geometric information + +- empty by default, use the image-embedded information if available + +----------------------------------------------- + +:: + + &sdataidx=<(int)idx> + +- Select the sub-dataset to read + +- 0 by default + +----------------------------------------------- + +:: + + &resol=<(int)resolution factor> + +- Select the JPEG2000 sub-resolution image to read + +- 0 by default + +----------------------------------------------- + +:: + + &bands=r1,r2,...,rn + +- Select a subset of bands from the input image + +- The syntax is inspired by Python indexing syntax with + bands=r1,r2,r3,...,rn where each ri is a band range that can be : + + - a single index (1-based) : + + - :code:`2` means 2nd band + + - :code:`-1` means last band + + - or a range of bands : + + - :code:`3:` means 3rd band until the last one + + - :code:`:-2` means the first bands until the second to last + + - :code:`2:4` means bands 2,3 and 4 + +- empty by default (all bands are read from the input image) + +----------------------------------------------- + +:: + + &skipcarto=<(bool)true> + +- Skip the cartographic information + +- Clears the projectionref, set the origin to :math:`[0,0]` and the + spacing to :math:`[1/max(1,r),1/max(1,r)]` where :math:`r` is the resolution + factor. + +- Keeps the keyword list + +- false by default + +----------------------------------------------- + +:: + + &skipgeom=<(bool)true> + +- Skip geometric information + +- Clears the keyword list + +- Keeps the projectionref and the origin/spacing information + +- false by default. + +----------------------------------------------- + +:: + + &skiprpctag=<(bool)true> + +- Skip the reading of internal RPC tags (see + [sec:TypesofSensorModels] for details) + +- false by default. + +Writer options +^^^^^^^^^^^^^^ + +:: + + &writegeom=<(bool)false> + +- To activate writing of external geom file + +- true by default + +----------------------------------------------- + +:: + + &writerpctags=<(bool)true> + +- To activate writing of RPC tags in TIFF files + +- false by default + +----------------------------------------------- + +:: + + &gdal:co:<GDALKEY>=<VALUE> + +- To specify a gdal creation option + +- For gdal creation option information, see dedicated gdal documentation for each driver. For example, you can find `here <http://www.gdal.org/frmt_gtiff.html>`_ the information about the GeoTiff create options + +- None by default + +----------------------------------------------- + +:: + + &streaming:type=<VALUE> + +- Activates configuration of streaming through extended filenames + +- Override any previous configuration of streaming + +- Allows to configure the kind of streaming to perform + +- Available values are: + + - auto: tiled or stripped streaming mode chosen automatically + depending on TileHint read from input files + + - tiled: tiled streaming mode + + - stripped: stripped streaming mode + + - none: explicitly deactivate streaming + +- Not set by default + +----------------------------------------------- + +:: + + &streaming:sizemode=<VALUE> + +- Allows to choose how the size of the streaming pieces is computed + +- Available values are: + + - auto: size is estimated from the available memory setting by + evaluating pipeline memory print + + - height: size is set by setting height of strips or tiles + + - nbsplits: size is computed from a given number of splits + +- Default is auto + +----------------------------------------------- + +:: + + &streaming:sizevalue=<VALUE> + +- Parameter for size of streaming pieces computation + +- Value is : + + - if sizemode=auto: available memory in Mb + + - if sizemode=height: height of the strip or tile in pixels + + - if sizemode=nbsplits: number of requested splits for streaming + +- If not provided, the default value is set to 0 and result in + different behaviour depending on sizemode (if set to height or + nbsplits, streaming is deactivated, if set to auto, value is + fetched from configuration or cmake configuration file) + +----------------------------------------------- + +:: + + &box=<startx>:<starty>:<sizex>:<sizey> + +- User defined parameters of output image region + +- The region must be set with 4 unsigned integers (the separator + used is the colon ’:’). Values are: + + - startx: first index on X (starting with 0) + + - starty: first index on Y (starting with 0) + + - sizex: size along X + + - sizey: size along Y + +- The definition of the region follows the same convention as + itk::Region definition in C++. A region is defined by two classes: + the itk::Index and itk::Size classes. The origin of the region + within the image with which it is associated is defined by Index + +----------------------------------------------- + +:: + + &bands=r1,r2,...,rn + +- Select a subset of bands from the output image + +- The syntax is inspired by Python indexing syntax with + bands=r1,r2,r3,...,rn where each ri is a band range that can be : + + - a single index (1-based) : + + - :code:`2` means 2nd band + + - :code:`-1` means last band + + - or a range of bands : + + - :code:`3:` means 3rd band until the last one + + - :code:`:-2` means the first bands until the second to last + + - :code:`2:4` means bands 2,3 and 4 + +- Empty by default (all bands are write from the output image) + +The available syntax for boolean options are: + +- ON, On, on, true, True, 1 are available for setting a ’true’ boolean + value + +- OFF, Off, off, false, False, 0 are available for setting a ’false’ + boolean value + +Examples +^^^^^^^^^^^^^^ + +You can find below some examples: + +- Write a file with blockSize equal to 256 and with DEFLATE compression + +:: + + $ otbcli_Convert -in OTB-Data/Examples/QB_1_ortho.tif -out "/tmp/example1.tif?&gdal:co:TILED=YES&gdal:co:COMPRESS=DEFLATE" + +- Process only first band from a file + +:: + + $ otbcli_Convert -in "OTB-Data/Examples/QB_1_ortho.tif?&bands=1" -out /tmp/example2.tif diff --git a/Documentation/Cookbook/rst/FAQ.rst b/Documentation/Cookbook/rst/FAQ.rst index 490e77a34c1619fb5025e823fcf680d9c3d27c83..83faac13abd949abb9c97b6ad0e07137e19c0ae2 100644 --- a/Documentation/Cookbook/rst/FAQ.rst +++ b/Documentation/Cookbook/rst/FAQ.rst @@ -189,7 +189,7 @@ The first time, you can get the source code using: :: - git clone https://git@git.orfeo-toolbox.org/git/otb.git + git clone https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb.git Then you can build OTB as usual using this directory as the source (refer to build instructions). Later if you want to update your source, @@ -428,7 +428,7 @@ You can get the base doing: :: - git clone https://git@git.orfeo-toolbox.org/git/otb-data.git + git clone https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-data.git This is about 1 GB of data, so it will take a while, but you have to do it only once, as after, a simple diff --git a/Documentation/Cookbook/rst/Installation_Linux_xdk.txt b/Documentation/Cookbook/rst/Installation_Linux_xdk.txt index a81d7f1f6f09f6740bee5b41fc1c4aff4515b6d0..38c890f066429e6af90b2c6cb8ec1f20af269a90 100644 --- a/Documentation/Cookbook/rst/Installation_Linux_xdk.txt +++ b/Documentation/Cookbook/rst/Installation_Linux_xdk.txt @@ -54,7 +54,7 @@ Download, Configure and build OTB :: mkdir -p /opt/OTB/build && cd /opt/OTB - git clone --depth=1 --branch=develop https://git@git.orfeo-toolbox.org/git/otb.git source + git clone --depth=1 --branch=develop https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb.git source cd build && cmake ../source make -j2 diff --git a/Documentation/Cookbook/rst/Monteverdi.rst b/Documentation/Cookbook/rst/Monteverdi.rst index 257ae1a017a0bac15cadf68443a6a5cdf6d236a4..ac362cc2822f7925b3a21159cd8c43958cc194f7 100644 --- a/Documentation/Cookbook/rst/Monteverdi.rst +++ b/Documentation/Cookbook/rst/Monteverdi.rst @@ -321,7 +321,7 @@ Conclusion ~~~~~~~~~~ The images used in this documentation can be found in the OTB-Data -repository (https://git.orfeo-toolbox.org/otb-data.git): +repository (https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-data.git): - in OTB-Data/Input: diff --git a/Documentation/Cookbook/rst/OTB-Applications.rst b/Documentation/Cookbook/rst/OTB-Applications.rst index 4da50bd9f419a096e11957e7c35e2621d9cfbd50..1905a737e7e72d869670d226e69bfa6e02b5b9d7 100644 --- a/Documentation/Cookbook/rst/OTB-Applications.rst +++ b/Documentation/Cookbook/rst/OTB-Applications.rst @@ -360,296 +360,3 @@ among 560 cpus and took only 56 seconds. Note that this MPI parallel invocation of applications is only available for command-line calls to OTB applications, and only for images output parameters. - -.. _extended-filenames: - -Extended filenames ------------------- - -There are multiple ways to define geo-referencing information. For -instance, one can use a geographic transform, a cartographic projection, -or a sensor model with RPC coefficients. A single image may contain -several of these elements, such as in the “ortho-ready†products: this -is a type of product still in sensor geometry (the sensor model is -supplied with the image) but it also contains an approximative -geographic transform that can be used to have a quick estimate of the -image localisation. For instance, your product may contain a “.TIF†file -for the image, along with a “.RPB†file that contains the sensor model -coefficients and an “.IMD†file that contains a cartographic projection. - -This case leads to the following question: which geo-referencing -element should be used when opening this image in OTB. In -fact, it depends on the users need. For an orthorectification -application, the sensor model must be used. In order to specify which -information should be skipped, a syntax of extended filenames has been -developed for both reading and writing. - -The reader and writer extended file name support is based on the same -syntax, only the options are different. To benefit from the extended -file name mechanism, the following syntax is to be used: - -:: - - Path/Image.ext?&key1=<value1>&key2=<value2> - -Note that you’ll probably need to “quote†the filename, especially if calling -applications from the bash command line. - -Reader options -^^^^^^^^^^^^^^ - -:: - - &geom=<path/filename.geom> - -- Contains the file name of a valid geom file - -- Use the content of the specified geom file instead of - image-embedded geometric information - -- empty by default, use the image-embedded information if available - ------------------------------------------------ - -:: - - &sdataidx=<(int)idx> - -- Select the sub-dataset to read - -- 0 by default - ------------------------------------------------ - -:: - - &resol=<(int)resolution factor> - -- Select the JPEG2000 sub-resolution image to read - -- 0 by default - ------------------------------------------------ - -:: - - &bands=r1,r2,...,rn - -- Select a subset of bands from the input image - -- The syntax is inspired by Python indexing syntax with - bands=r1,r2,r3,...,rn where each ri is a band range that can be : - - - a single index (1-based) : - - - :code:`2` means 2nd band - - - :code:`-1` means last band - - - or a range of bands : - - - :code:`3:` means 3rd band until the last one - - - :code:`:-2` means the first bands until the second to last - - - :code:`2:4` means bands 2,3 and 4 - -- empty by default (all bands are read from the input image) - ------------------------------------------------ - -:: - - &skipcarto=<(bool)true> - -- Skip the cartographic information - -- Clears the projectionref, set the origin to :math:`[0,0]` and the - spacing to :math:`[1/max(1,r),1/max(1,r)]` where :math:`r` is the resolution - factor. - -- Keeps the keyword list - -- false by default - ------------------------------------------------ - -:: - - &skipgeom=<(bool)true> - -- Skip geometric information - -- Clears the keyword list - -- Keeps the projectionref and the origin/spacing information - -- false by default. - ------------------------------------------------ - -:: - - &skiprpctag=<(bool)true> - -- Skip the reading of internal RPC tags (see - [sec:TypesofSensorModels] for details) - -- false by default. - -Writer options -^^^^^^^^^^^^^^ - -:: - - &writegeom=<(bool)false> - -- To activate writing of external geom file - -- true by default - ------------------------------------------------ - -:: - - &writerpctags=<(bool)true> - -- To activate writing of RPC tags in TIFF files - -- false by default - ------------------------------------------------ - -:: - - &gdal:co:<GDALKEY>=<VALUE> - -- To specify a gdal creation option - -- For gdal creation option information, see dedicated gdal documentation - -- None by default - ------------------------------------------------ - -:: - - &streaming:type=<VALUE> - -- Activates configuration of streaming through extended filenames - -- Override any previous configuration of streaming - -- Allows to configure the kind of streaming to perform - -- Available values are: - - - auto: tiled or stripped streaming mode chosen automatically - depending on TileHint read from input files - - - tiled: tiled streaming mode - - - stripped: stripped streaming mode - - - none: explicitly deactivate streaming - -- Not set by default - ------------------------------------------------ - -:: - - &streaming:sizemode=<VALUE> - -- Allows to choose how the size of the streaming pieces is computed - -- Available values are: - - - auto: size is estimated from the available memory setting by - evaluating pipeline memory print - - - height: size is set by setting height of strips or tiles - - - nbsplits: size is computed from a given number of splits - -- Default is auto - ------------------------------------------------ - -:: - - &streaming:sizevalue=<VALUE> - -- Parameter for size of streaming pieces computation - -- Value is : - - - if sizemode=auto: available memory in Mb - - - if sizemode=height: height of the strip or tile in pixels - - - if sizemode=nbsplits: number of requested splits for streaming - -- If not provided, the default value is set to 0 and result in - different behaviour depending on sizemode (if set to height or - nbsplits, streaming is deactivated, if set to auto, value is - fetched from configuration or cmake configuration file) - ------------------------------------------------ - -:: - - &box=<startx>:<starty>:<sizex>:<sizey> - -- User defined parameters of output image region - -- The region must be set with 4 unsigned integers (the separator - used is the colon ’:’). Values are: - - - startx: first index on X (starting with 0) - - - starty: first index on Y (starting with 0) - - - sizex: size along X - - - sizey: size along Y - -- The definition of the region follows the same convention as - itk::Region definition in C++. A region is defined by two classes: - the itk::Index and itk::Size classes. The origin of the region - within the image with which it is associated is defined by Index - ------------------------------------------------ - -:: - - &bands=r1,r2,...,rn - -- Select a subset of bands from the output image - -- The syntax is inspired by Python indexing syntax with - bands=r1,r2,r3,...,rn where each ri is a band range that can be : - - - a single index (1-based) : - - - :code:`2` means 2nd band - - - :code:`-1` means last band - - - or a range of bands : - - - :code:`3:` means 3rd band until the last one - - - :code:`:-2` means the first bands until the second to last - - - :code:`2:4` means bands 2,3 and 4 - -- Empty by default (all bands are write from the output image) - -The available syntax for boolean options are: - -- ON, On, on, true, True, 1 are available for setting a ’true’ boolean - value - -- OFF, Off, off, false, False, 0 are available for setting a ’false’ - boolean value diff --git a/Documentation/Cookbook/rst/index_TOC.rst b/Documentation/Cookbook/rst/index_TOC.rst index d09049ccec83ef3be5d654decf11e25998f9e7bc..12565d1577bd6a9211449e2c9e71b2cf0ca291e6 100644 --- a/Documentation/Cookbook/rst/index_TOC.rst +++ b/Documentation/Cookbook/rst/index_TOC.rst @@ -8,6 +8,7 @@ Table of Contents Installation OTB-Applications Monteverdi + ExtendedFilenames Recipes Applications FAQ diff --git a/Documentation/Cookbook/rst/recipes/optpreproc.rst b/Documentation/Cookbook/rst/recipes/optpreproc.rst index 41b1169fa8bf5fa3736bc259f7f0797f72415fe3..e3f00ca3a47bb36f7b98e0128a280d52593f233a 100644 --- a/Documentation/Cookbook/rst/recipes/optpreproc.rst +++ b/Documentation/Cookbook/rst/recipes/optpreproc.rst @@ -242,7 +242,7 @@ path to a file which contains the geoid. `Geoid <http://en.wikipedia.org/wiki/Ge corresponds to the equipotential surface that would coincide with the mean ocean surface of the Earth. -We provide one geoid in the `OTB-Data <https://git.orfeo-toolbox.org/otb-data.git/tree/HEAD:/Input/DEM>`_ repository. +We provide one geoid in the `OTB-Data <https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-data/tree/master/Input/DEM>`_ repository. In all applications, the option **elev.geoid** allows to manage the path to the geoid. Finally, it is also possible to use an average elevation diff --git a/Documentation/Cookbook/rst/recipes/pbclassif.rst b/Documentation/Cookbook/rst/recipes/pbclassif.rst index 1e26e4c7f53a0aafdf701cf3b8bd7ef9bc1fb51a..4202066085f000e6ec8f4b1f1eac313f277de09a 100644 --- a/Documentation/Cookbook/rst/recipes/pbclassif.rst +++ b/Documentation/Cookbook/rst/recipes/pbclassif.rst @@ -525,7 +525,7 @@ Example We consider 4 classes: water, roads, vegetation and buildings with red roofs. Data is available in the OTB-Data -`repository <https://git.orfeo-toolbox.org/otb-data.git/tree/HEAD:/Input/Classification>`_ . +`repository <https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-data/tree/master/Input/Classification>`_ . .. |image_21| image:: ../Art/MonteverdiImages/classification_chain_inputimage.jpg .. |image_22| image:: ../Art/MonteverdiImages/classification_chain_fancyclassif_fusion.jpg diff --git a/Documentation/SoftwareGuide/Latex/Installation.tex b/Documentation/SoftwareGuide/Latex/Installation.tex index ea869b753148edff4d213bf066a1de0b26a24271..e6ab1534d296b6158b0a4627fc4edecfd363992f 100644 --- a/Documentation/SoftwareGuide/Latex/Installation.tex +++ b/Documentation/SoftwareGuide/Latex/Installation.tex @@ -163,7 +163,7 @@ To setup this structure, the following commands can be used: \begin{verbatim} $ mkdir ~/OTB $ cd ~/OTB -$ git clone https://git@git.orfeo-toolbox.org/git/otb.git +$ git clone https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb.git $ mkdir build $ mkdir install \end{verbatim} diff --git a/Documentation/SoftwareGuide/Latex/Introduction.tex b/Documentation/SoftwareGuide/Latex/Introduction.tex index bca731112bbd207b7b598532ed8eb2816cf2ab52..f3ae6653bade821339a938887b6313916cd4125c 100644 --- a/Documentation/SoftwareGuide/Latex/Introduction.tex +++ b/Documentation/SoftwareGuide/Latex/Introduction.tex @@ -100,14 +100,14 @@ process described in Section \ref{chapter:Installation}. There are two other ways of getting the OTB source code: \begin{itemize} \item Clone the current release with \href{https://git-scm.com/}{Git} from the - \href{https://git.orfeo-toolbox.org/otb.git}{OTB git server}, (master branch) + \href{https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb.git}{OTB git server}, (master branch) \item Clone the latest revision with \href{https://git-scm.com/}{Git} from the - \href{https://git.orfeo-toolbox.org/otb.git}{OTB git server} (develop branch). + \href{https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb.git}{OTB git server} (develop branch). \end{itemize} These last two options need a proper \href{https://git-scm.com/}{Git} installation. To get source code from Git, do: \begin{verbatim} -git clone https://git@git.orfeo-toolbox.org/git/otb.git +git clone https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb.git \end{verbatim} Using Git, you can easily navigate through the different versions. The master diff --git a/Documentation/SoftwareGuide/Latex/Tutorial.tex b/Documentation/SoftwareGuide/Latex/Tutorial.tex index be8cd232fc53ecfb8dfe51e5fbae91cb0424fca6..4a09dc660223796abaa0b3f92bb28d4e81660960 100644 --- a/Documentation/SoftwareGuide/Latex/Tutorial.tex +++ b/Documentation/SoftwareGuide/Latex/Tutorial.tex @@ -224,7 +224,7 @@ Once this file is written you just have to run \code{make}. The Get one image from the \code{OTB-Data/Examples} directory from the OTB-Data repository. You can get it either by cloning the OTB data repository -(\code{git clone https://git.orfeo-toolbox.org/otb-data.git}), but that might be quite +(\code{git clone https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-data.git}), but that might be quite long as this also gets the data to run the tests. Alternatively, you can get it from \url{http://www.orfeo-toolbox.org/packages/OTB-Data-Examples.tgz}. Take for example get \code{QB\_Suburb.png}. diff --git a/Modules/Adapters/OSSIMAdapters/include/otbSarSensorModelAdapter.h b/Modules/Adapters/OSSIMAdapters/include/otbSarSensorModelAdapter.h index 692c1574fc7e12b390832546a43154411d6f5e7b..8a713883b6720d0dd9b8e0ce89c03ae924cd75c9 100644 --- a/Modules/Adapters/OSSIMAdapters/include/otbSarSensorModelAdapter.h +++ b/Modules/Adapters/OSSIMAdapters/include/otbSarSensorModelAdapter.h @@ -24,6 +24,7 @@ #include <memory> #include "otbDEMHandler.h" +#include "itkPoint.h" namespace ossimplugins { @@ -62,6 +63,9 @@ public: typedef std::auto_ptr<ossimplugins::ossimSarSensorModel> InternalModelPointer; + using Point2DType = itk::Point<double,2>; + using Point3DType = itk::Point<double,3>; + /** Method for creation through the object factory. */ itkNewMacro(Self); @@ -80,6 +84,21 @@ public: /** Deburst metadata if possible and return lines to keep in image file */ bool Deburst(std::vector<std::pair<unsigned long, unsigned long> > & lines); + /** Transform world point (lat,lon,hgt) to input image point + (col,row) and YZ frame */ + bool WorldToLineSampleYZ(const Point3DType & inGeoPoint, Point2DType & cr, Point2DType & yz) const; + + /** Transform world point (lat,lon,hgt) to input image point + (col,row) */ + bool WorldToLineSample(const Point3DType & inGEoPOint, Point2DType & cr) const; + +/** Transform world point (lat,lon,hgt) to satellite position (x,y,z) and satellite velocity */ + bool WorldToSatPositionAndVelocity(const Point3DType & inGeoPoint, Point3DType & satelitePosition, + Point3DType & sateliteVelocity) const; + + /** Transform world point (lat,lon,hgt) to cartesian point (x,y,z) */ + static bool WorldToCartesian(const Point3DType & inGeoPoint, Point3DType & outCartesianPoint); + static bool ImageLineToDeburstLine(const std::vector<std::pair<unsigned long,unsigned long> >& lines, unsigned long imageLine, unsigned long & deburstLine); static void DeburstLineToImageLine(const std::vector<std::pair<unsigned long,unsigned long> >& lines, unsigned long deburstLine, unsigned long & imageLine); diff --git a/Modules/Adapters/OSSIMAdapters/src/otbImageKeywordlist.cxx b/Modules/Adapters/OSSIMAdapters/src/otbImageKeywordlist.cxx index 36550717ca0ade79935fad796beb91624afdf008..6063915cfb4996895de1371735454092f81368d7 100644 --- a/Modules/Adapters/OSSIMAdapters/src/otbImageKeywordlist.cxx +++ b/Modules/Adapters/OSSIMAdapters/src/otbImageKeywordlist.cxx @@ -287,60 +287,15 @@ ReadGeometryFromImage(const std::string& filename, bool checkRpcTag) } /**********************************************************/ - /* Third try : look for external geom file and RPC tags */ + /* Third try : look for RPC tags */ /**********************************************************/ - if (!hasMetaData) + if (!hasMetaData && checkRpcTag) { - // If still no metadata, try the ".geom" file - ossimFilename ossimGeomFile = ossimFilename(filename).setExtension(".geom"); - otb_kwl = ReadGeometryFromGEOMFile(ossimGeomFile); - - // also check any RPC tags - ImageKeywordlist rpc_kwl; - if (checkRpcTag) - { - rpc_kwl = ReadGeometryFromRPCTag(filename); - } - - if (otb_kwl.HasKey("type")) - { - // external geom has a "type" keyword - std::string geomType(otb_kwl.GetMetadataByKey("type")); - ossimProjection *testProj = ossimProjectionFactoryRegistry::instance() - ->createProjection(ossimString(geomType)); - if (dynamic_cast<ossimSensorModel*>(testProj)) - { - // "type" keyword corresponds to a sensor model : don't erase it - if (rpc_kwl.GetSize() > 0) - { - rpc_kwl.ClearMetadataByKey("type"); - } - - ossimKeywordlist ossim_test_kwl; - otb_kwl.convertToOSSIMKeywordlist(ossim_test_kwl); - testProj = ossimProjectionFactoryRegistry::instance() - ->createProjection(ossim_test_kwl); - if (testProj) - { - // external geom contains a valid sensor geometry - hasMetaData = true; - } - } - } + // check any RPC tags + otb_kwl = ReadGeometryFromRPCTag(filename); - // copy keywords found in RPC tags if the external geom is not valid - if (!hasMetaData && rpc_kwl.GetSize() > 0) + if (!otb_kwl.Empty()) { - const ImageKeywordlist::KeywordlistMap &kwlMap = rpc_kwl.GetKeywordlist(); - for (ImageKeywordlist::KeywordlistMap::const_iterator it = kwlMap.begin(); - it != kwlMap.end(); - ++it) - { - if (it->second != "") - { - otb_kwl.AddKey(it->first , it->second); - } - } hasMetaData = true; } } diff --git a/Modules/Adapters/OSSIMAdapters/src/otbSarSensorModelAdapter.cxx b/Modules/Adapters/OSSIMAdapters/src/otbSarSensorModelAdapter.cxx index 62d5203af5c4d7dc04f4b9a3d66706cef1fa084a..56bcfbca01f498b1f8cc020b5c8e839ebf809cbb 100644 --- a/Modules/Adapters/OSSIMAdapters/src/otbSarSensorModelAdapter.cxx +++ b/Modules/Adapters/OSSIMAdapters/src/otbSarSensorModelAdapter.cxx @@ -109,7 +109,112 @@ void SarSensorModelAdapter::DeburstLineToImageLine(const std::vector<std::pair<u ossimplugins::ossimSarSensorModel::deburstLineToImageLine(lines,deburstLine,imageLine); } +bool SarSensorModelAdapter::WorldToLineSampleYZ(const Point3DType & inGeoPoint, Point2DType & cr, Point2DType & yz) const +{ + if(m_SensorModel.get() == ITK_NULLPTR) + { + return false; + } + + ossimGpt inGpt; + inGpt.lon = inGeoPoint[0]; + inGpt.lat = inGeoPoint[1]; + inGpt.hgt = inGeoPoint[2]; + + ossimDpt outDpt; + + double y(0.),z(0.); + m_SensorModel->worldToLineSampleYZ(inGpt,outDpt,y,z); + + if(outDpt.isNan()) + return false; + + cr[0]=outDpt.x; + cr[1]=outDpt.y; + yz[0]=y; + yz[1]=z; + + return true; +} +bool SarSensorModelAdapter::WorldToLineSample(const Point3DType & inGeoPoint, Point2DType & cr) const +{ + if(m_SensorModel.get() == ITK_NULLPTR) + { + return false; + } + + ossimGpt inGpt; + inGpt.lon = inGeoPoint[0]; + inGpt.lat = inGeoPoint[1]; + inGpt.hgt = inGeoPoint[2]; + + ossimDpt outDpt; + + m_SensorModel->worldToLineSample(inGpt,outDpt); + + if(outDpt.isNan()) + return false; + + cr[0]=outDpt.x; + cr[1]=outDpt.y; + + return true; +} + +bool SarSensorModelAdapter::WorldToCartesian(const Point3DType & inGeoPoint, Point3DType & outCartesianPoint) +{ + ossimGpt inGpt; + inGpt.lon = inGeoPoint[0]; + inGpt.lat = inGeoPoint[1]; + inGpt.hgt = inGeoPoint[2]; + + ossimEcefPoint outCartesien(inGpt); + + if(outCartesien.isNan()) + return false; + + outCartesianPoint[0] = outCartesien.x(); + outCartesianPoint[1] = outCartesien.y(); + outCartesianPoint[2] = outCartesien.z(); + + return true; +} + +bool SarSensorModelAdapter::WorldToSatPositionAndVelocity(const Point3DType & inGeoPoint, + Point3DType & satelitePosition, + Point3DType & sateliteVelocity) const +{ + if(m_SensorModel.get() == ITK_NULLPTR) + { + return false; + } + + ossimGpt inGpt; + inGpt.lon = inGeoPoint[0]; + inGpt.lat = inGeoPoint[1]; + inGpt.hgt = inGeoPoint[2]; + + ossimplugins::ossimSarSensorModel::TimeType azimuthTime; + double rangeTime; + ossimEcefPoint sensorPos; + ossimEcefVector sensorVel; + + const bool success = m_SensorModel->worldToAzimuthRangeTime(inGpt, azimuthTime, rangeTime,sensorPos,sensorVel); + + if(sensorPos.isNan() || !success) + return false; + + satelitePosition[0] = sensorPos.x(); + satelitePosition[1] = sensorPos.y(); + satelitePosition[2] = sensorPos.z(); + + sateliteVelocity[0] = sensorVel.x(); + sateliteVelocity[1] = sensorVel.y(); + sateliteVelocity[2] = sensorVel.z(); + + return true; +} } // namespace otb diff --git a/Modules/Adapters/OSSIMAdapters/test/CMakeLists.txt b/Modules/Adapters/OSSIMAdapters/test/CMakeLists.txt index 54a7117fc93c342e11d0e77b2b5226c70c0104cc..8dadc14ff05f911b3fa0af4cca37e05592cecced 100644 --- a/Modules/Adapters/OSSIMAdapters/test/CMakeLists.txt +++ b/Modules/Adapters/OSSIMAdapters/test/CMakeLists.txt @@ -31,6 +31,7 @@ otbGeometricSarSensorModelAdapter.cxx otbPlatformPositionAdapter.cxx otbDEMHandlerTest.cxx otbRPCSolverAdapterTest.cxx +otbSarSensorModelAdapterTest.cxx ) add_executable(otbOSSIMAdaptersTestDriver ${OTBOSSIMAdaptersTests}) @@ -499,3 +500,8 @@ otb_add_test(NAME uaTvRPCSolverAdapterValidationTest COMMAND otbOSSIMAdaptersTes ${INPUTDATA}/DEM/egm96.grd ) + +otb_add_test(NAME uaTvSarSensorModelAdapter COMMAND otbOSSIMAdaptersTestDriver + otbSarSensorModelAdapterTest + ${INPUTDATA}/s1a-iw1-slc-vh-amp_xt.geom + ) diff --git a/Modules/Adapters/OSSIMAdapters/test/otbOSSIMAdaptersTestDriver.cxx b/Modules/Adapters/OSSIMAdapters/test/otbOSSIMAdaptersTestDriver.cxx index 911e57e671884e9bb003e399b605b6dfd3dacf29..5f7295d6dffdb208aafde1ab1326ecdd544bd24f 100644 --- a/Modules/Adapters/OSSIMAdapters/test/otbOSSIMAdaptersTestDriver.cxx +++ b/Modules/Adapters/OSSIMAdapters/test/otbOSSIMAdaptersTestDriver.cxx @@ -33,4 +33,5 @@ void RegisterTests() REGISTER_TEST(otbPlatformPositionComputeBaselineTest); REGISTER_TEST(otbDEMHandlerTest); REGISTER_TEST(otbRPCSolverAdapterTest); + REGISTER_TEST(otbSarSensorModelAdapterTest); } diff --git a/Modules/Adapters/OSSIMAdapters/test/otbSarSensorModelAdapterTest.cxx b/Modules/Adapters/OSSIMAdapters/test/otbSarSensorModelAdapterTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..d48f10066193796158002b55aba127b464814ccc --- /dev/null +++ b/Modules/Adapters/OSSIMAdapters/test/otbSarSensorModelAdapterTest.cxx @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2005-2017 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. + */ + + +#include <fstream> +#include <iomanip> + +#include "otbSarSensorModelAdapter.h" +#include "otbImageKeywordlist.h" + + +int otbSarSensorModelAdapterTest(int itkNotUsed(argc), char* argv[]) +{ + std::string infname = argv[1]; + + otb::SarSensorModelAdapter::Pointer sensorModel = otb::SarSensorModelAdapter::New(); + + auto kwl = otb::ReadGeometryFromGEOMFile(infname); + + bool success = sensorModel->LoadState(kwl); + + if(!success) + { + std::cerr<<"Could not LoadState() from keyword list read from"<<infname<<std::endl; + return EXIT_FAILURE; + } + + std::vector<std::pair<unsigned long, unsigned long> > lines; + success = sensorModel->Deburst(lines); + + if(!success) + { + std::cerr<<"Deburst() call failed."<<std::endl; + return EXIT_FAILURE; + } + + + otb::ImageKeywordlist outKwl; + success = sensorModel->SaveState(outKwl); + if(!success) + { + std::cerr<<"SaveState() call failed."<<std::endl; + return EXIT_FAILURE; + } + + + otb::SarSensorModelAdapter::Point2DType out1,out2; + otb::SarSensorModelAdapter::Point3DType in, out3, out4, out5; + + // GCP 99 from input geom file + //support_data.geom.gcp[99].world_pt.hgt: 2.238244926818182e+02 + //support_data.geom.gcp[99].world_pt.lat: 4.323458093295080e+01 + //support_data.geom.gcp[99].world_pt.lon: 1.116316013091967e+00 + + in[0] = 4.323458093295080e+01; + in[1] = 1.116316013091967e+00; + in[2] = 2.238244926818182e+02; + + sensorModel->WorldToLineSample(in,out1); + sensorModel->WorldToLineSampleYZ(in,out1,out2); + + sensorModel->WorldToCartesian(in, out5); + sensorModel->WorldToSatPositionAndVelocity(in,out3, out4); + + + return EXIT_SUCCESS; +} diff --git a/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx b/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx index ff4f4b01e4be8c30476b4aef78dadaf9819e606f..4a35145462f48ac18220bafc08c5ab2998426f35 100644 --- a/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx +++ b/Modules/Applications/AppClassification/app/otbPolygonClassStatistics.cxx @@ -76,7 +76,7 @@ private: SetDocName("Polygon Class Statistics"); SetDocLongDescription("The application processes a set of geometries " "intended for training (they should have a field giving the associated " - "class). The geometries are analysed against a support image to compute " + "class). The geometries are analyzed against a support image to compute " "statistics : \n" " - number of samples per class\n" " - number of samples per geometry\n" @@ -92,17 +92,17 @@ private: AddDocTag(Tags::Learning); - AddParameter(ParameterType_InputImage, "in", "InputImage"); + AddParameter(ParameterType_InputImage, "in", "Input image"); SetParameterDescription("in", "Support image that will be classified"); - AddParameter(ParameterType_InputImage, "mask", "InputMask"); + AddParameter(ParameterType_InputImage, "mask", "Input validity mask"); SetParameterDescription("mask", "Validity mask (only pixels corresponding to a mask value greater than 0 will be used for statistics)"); MandatoryOff("mask"); AddParameter(ParameterType_InputFilename, "vec", "Input vectors"); - SetParameterDescription("vec","Input geometries to analyse"); + SetParameterDescription("vec","Input geometries to analyze"); - AddParameter(ParameterType_OutputFilename, "out", "Output Statistics"); + AddParameter(ParameterType_OutputFilename, "out", "Output XML statistics file"); SetParameterDescription("out","Output file to store statistics (XML format)"); AddParameter(ParameterType_ListView, "field", "Field Name"); @@ -155,6 +155,22 @@ private: } } } + + // Check that the extension of the output parameter is XML (mandatory for + // StatisticsXMLFileWriter) + // Check it here to trigger the error before polygons analysis + + if ( HasValue("out") ) + { + // Store filename extension + // Check that the right extension is given : expected .xml + const std::string extension = itksys::SystemTools::GetFilenameLastExtension(this->GetParameterString("out")); + + if (itksys::SystemTools::LowerCase(extension) != ".xml") + { + otbAppLogFATAL( << extension << " is a wrong extension for parameter \"out\": Expected .xml" ); + } + } } void DoExecute() ITK_OVERRIDE @@ -223,7 +239,7 @@ private: filter->SetLayerIndex(this->GetParameterInt("layer")); filter->GetStreamer()->SetAutomaticAdaptativeStreaming(GetParameterInt("ram")); - AddProcess(filter->GetStreamer(),"Analyse polygons..."); + AddProcess(filter->GetStreamer(),"Analyze polygons..."); filter->Update(); FilterType::ClassCountMapType &classCount = filter->GetClassCountOutput()->Get(); diff --git a/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx b/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx index 54dbe894f6520795efb9066b3d1546f89c991cd8..c853f4863b75e799d10a1199098cffae48640792 100644 --- a/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx +++ b/Modules/Applications/AppDomainTransform/app/otbDomainTransform.cxx @@ -264,7 +264,7 @@ private: { // fft ttransform bool shift = IsParameterEnabled( "mode.fft.shift"); - typedef otb::Image< std::complex<OutputPixelType> > ComplexOutputImageType; + typedef otb::Image< std::complex<OutputPixelType> > ComplexOutputImageType; if (dir == 0 ) { diff --git a/Modules/Applications/AppImageUtils/test/CMakeLists.txt b/Modules/Applications/AppImageUtils/test/CMakeLists.txt index d2852f4d46be0c1a130e293c101fdd1934e60aae..d428cc87bbeae493384dbbc4be46fb87b0807cc7 100644 --- a/Modules/Applications/AppImageUtils/test/CMakeLists.txt +++ b/Modules/Applications/AppImageUtils/test/CMakeLists.txt @@ -173,6 +173,14 @@ otb_test_application(NAME apTvUtExtractROIRightInputFile ${INPUTDATA}/couleurs_extrait.png ${TEMP}/apTvUtExtractROIRightInputFile.tif) +otb_test_application(NAME apTvUtExtractROIComplexInputFile + APP ExtractROI + OPTIONS -in ${INPUTDATA}/complexInputCfloat.tif + -out ${TEMP}/apTvUtExtractROIComplexInputFile.tif cfloat + VALID --compare-image ${NOTOL} + ${INPUTDATA}/complexInputCfloat.tif + ${TEMP}/apTvUtExtractROIComplexInputFile.tif) + #----------- Rescale TESTS ---------------- otb_test_application(NAME apTvUtRescaleTest @@ -207,6 +215,11 @@ otb_test_application(NAME apTuUtReadImageInfoExtendedFilename_reader OPTIONS -in ${INPUTDATA}/ToulouseExtract_WithGeom.tif?&skipgeom=true&skipcarto=true ) +otb_test_application(NAME apTuUtReadComplexImageInfoFilename_reader + APP ReadImageInfo + OPTIONS -in ${INPUTDATA}/complexInputCfloat.tif + ) + set(TESTNAME "gd-pleiades-1" #LARGEINPUT{PLEIADES/TLSE_JP2_DIMAPv2_PRIMARY_PMS_lossless_12bits/IMGPHR_201222215194743808/IMG_PHR1A_PMS_201201151100183_SEN_IPU_20120222_0901-001_R1C1.JP2} diff --git a/Modules/Applications/AppOpticalCalibration/app/otbOpticalCalibration.cxx b/Modules/Applications/AppOpticalCalibration/app/otbOpticalCalibration.cxx index 87e7dc310fa0cc14efda2c900c0b29942d3feb11..829c4f3052c9d95683dd55b0d62b28d5bd1f14f9 100644 --- a/Modules/Applications/AppOpticalCalibration/app/otbOpticalCalibration.cxx +++ b/Modules/Applications/AppOpticalCalibration/app/otbOpticalCalibration.cxx @@ -29,7 +29,7 @@ #include "otbReflectanceToRadianceImageFilter.h" #include "otbReflectanceToSurfaceReflectanceImageFilter.h" #include "itkMultiplyImageFilter.h" -#include "otbClampVectorImageFilter.h" +#include "otbClampImageFilter.h" #include "otbSurfaceAdjacencyEffectCorrectionSchemeFilter.h" #include "otbGroundSpacingImageFunction.h" #include "vnl/vnl_random.h" @@ -92,7 +92,7 @@ public: typedef itk::MultiplyImageFilter<DoubleVectorImageType,DoubleImageType,DoubleVectorImageType> ScaleFilterOutDoubleType; - typedef otb::ClampVectorImageFilter<DoubleVectorImageType, + typedef otb::ClampImageFilter<DoubleVectorImageType, DoubleVectorImageType> ClampFilterType; typedef ReflectanceToSurfaceReflectanceImageFilter<DoubleVectorImageType, diff --git a/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx b/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx index 4a91dda2f5183e34a8bd470684302805b54d5609..751678774184b69c0d048d18f906c2ecdb55694c 100644 --- a/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx +++ b/Modules/Applications/AppSARCalibration/app/otbSARCalibration.cxx @@ -60,7 +60,7 @@ private: AddDocTag(Tags::Calibration); AddDocTag(Tags::SAR); - AddParameter(ParameterType_ComplexInputImage, "in", "Input Image"); + AddParameter(ParameterType_InputImage, "in", "Input Image"); SetParameterDescription("in", "Input complex image"); AddParameter(ParameterType_OutputImage, "out", "Output Image"); diff --git a/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx b/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx index 155795417f8c78b96317cd7676e4ed1294be90b4..796d3f4e26a9fd34b7e7891f81846dab6fa95c2a 100644 --- a/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx +++ b/Modules/Applications/AppSARDecompositions/app/otbSARDecompositions.cxx @@ -31,7 +31,7 @@ #include "otbSinclairToReciprocalCoherencyMatrixFunctor.h" #include "otbPerBandVectorImageFilter.h" #include "itkMeanImageFilter.h" -#include "otbNRIBandImagesToOneNComplexBandsImage.h" +// #include "otbNRIBandImagesToOneNComplexBandsImage.h" #include "otbImageListToVectorImageFilter.h" #include "otbImageList.h" @@ -109,21 +109,21 @@ private: AddDocTag(Tags::SAR); - AddParameter(ParameterType_ComplexInputImage, "inhh", "Input Image"); + AddParameter(ParameterType_InputImage, "inhh", "Input Image"); SetParameterDescription("inhh", "Input image (HH)"); - AddParameter(ParameterType_ComplexInputImage, "inhv", "Input Image"); + AddParameter(ParameterType_InputImage, "inhv", "Input Image"); SetParameterDescription("inhv", "Input image (HV)"); MandatoryOff("inhv"); - AddParameter(ParameterType_ComplexInputImage, "invh", "Input Image"); + AddParameter(ParameterType_InputImage, "invh", "Input Image"); SetParameterDescription("invh", "Input image (VH)"); MandatoryOff("invh"); - AddParameter(ParameterType_ComplexInputImage, "invv", "Input Image"); + AddParameter(ParameterType_InputImage, "invv", "Input Image"); SetParameterDescription("invv", "Input image (VV)"); - AddParameter(ParameterType_ComplexOutputImage, "out", "Output Image"); + AddParameter(ParameterType_OutputImage, "out", "Output Image"); SetParameterDescription("out", "Output image"); AddParameter(ParameterType_Choice, "decomp", "Decompositions"); @@ -201,7 +201,7 @@ private: m_MeanFilter->SetInput(m_SRFilter->GetOutput()); m_HAFilter->SetInput(m_MeanFilter->GetOutput()); - SetParameterComplexOutputImage("out", m_HAFilter->GetOutput() ); + SetParameterOutputImage("out", m_HAFilter->GetOutput() ); break; @@ -220,7 +220,7 @@ private: m_MeanFilter->SetInput(m_SRFilter->GetOutput()); m_BarnesFilter->SetInput(m_MeanFilter->GetOutput()); - SetParameterComplexOutputImage("out", m_BarnesFilter->GetOutput() ); + SetParameterOutputImage("out", m_BarnesFilter->GetOutput() ); break; @@ -239,7 +239,7 @@ private: m_MeanFilter->SetInput(m_SRFilter->GetOutput()); m_HuynenFilter->SetInput(m_MeanFilter->GetOutput()); - SetParameterComplexOutputImage("out", m_HuynenFilter->GetOutput() ); + SetParameterOutputImage("out", m_HuynenFilter->GetOutput() ); break; @@ -257,7 +257,7 @@ private: m_Concatener->SetInput( m_ImageList ); m_PauliFilter->SetInput(m_Concatener->GetOutput()); - SetParameterComplexOutputImage("out", m_PauliFilter->GetOutput() ); + SetParameterOutputImage("out", m_PauliFilter->GetOutput() ); break; } diff --git a/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx b/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx index 9c8c06211234eef4f9f8207c1762e6f10fbe88fb..657643541d477617e13a196a4a2853f76920f569 100644 --- a/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx +++ b/Modules/Applications/AppSARPolarMatrixConvert/app/otbSARPolarMatrixConvert.cxx @@ -232,7 +232,7 @@ private: AddDocTag(Tags::SAR); - AddParameter(ParameterType_ComplexInputImage, "inc", "Input : multi-band complex image"); + AddParameter(ParameterType_InputImage, "inc", "Input : multi-band complex image"); SetParameterDescription("inc", "Input : multi-band complex image"); MandatoryOff("inc"); @@ -241,23 +241,23 @@ private: MandatoryOff("inf"); - AddParameter(ParameterType_ComplexInputImage, "inhh", "Input : one-band complex image (HH)"); + AddParameter(ParameterType_InputImage, "inhh", "Input : one-band complex image (HH)"); SetParameterDescription("inhh", "Input : one-band complex image (HH)"); MandatoryOff("inhh"); - AddParameter(ParameterType_ComplexInputImage, "inhv", "Input : one-band complex image (HV)"); + AddParameter(ParameterType_InputImage, "inhv", "Input : one-band complex image (HV)"); SetParameterDescription("inhv", "Input : one-band complex image (HV)"); MandatoryOff("inhv"); - AddParameter(ParameterType_ComplexInputImage, "invh", "Input : one-band complex image (VH)"); + AddParameter(ParameterType_InputImage, "invh", "Input : one-band complex image (VH)"); SetParameterDescription("invh", "Input : one-band complex image (VH)"); MandatoryOff("invh"); - AddParameter(ParameterType_ComplexInputImage, "invv", "Input : one-band complex image (VV)"); + AddParameter(ParameterType_InputImage, "invv", "Input : one-band complex image (VV)"); SetParameterDescription("invv", "Input : one-band complex image (VV)"); MandatoryOff("invv"); - AddParameter(ParameterType_ComplexOutputImage, "outc", "Output Complex Image"); + AddParameter(ParameterType_OutputImage, "outc", "Output Complex Image"); SetParameterDescription("outc", "Output Complex image."); MandatoryOff("outc"); @@ -509,7 +509,7 @@ private: m_RCohSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh")); m_RCohSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv")); - SetParameterComplexOutputImage("outc", m_RCohSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output : 6 complex channels + SetParameterOutputImage("outc", m_RCohSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output : 6 complex channels break; @@ -526,7 +526,7 @@ private: m_RCovSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh")); m_RCovSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv")); - SetParameterComplexOutputImage("outc", m_RCovSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output : 6 complex channels + SetParameterOutputImage("outc", m_RCovSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output : 6 complex channels break; @@ -544,7 +544,7 @@ private: m_RCCSRFilter->SetInputHH(GetParameterComplexDoubleImage("inhh")); m_RCCSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv")); - SetParameterComplexOutputImage("outc", m_RCCSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output : 6 complex channels + SetParameterOutputImage("outc", m_RCCSRFilter->GetOutput() ); // input : 3 x 1 complex channel | output : 6 complex channels break; @@ -565,7 +565,7 @@ private: m_RCCDFilter = RCCDFilterType::New(); m_RCCDFilter->SetInput(GetParameterComplexDoubleVectorImage("inc")); - SetParameterComplexOutputImage("outc", m_RCCDFilter->GetOutput() ); // input : 6 complex channels | 3 complex channels + SetParameterOutputImage("outc", m_RCCDFilter->GetOutput() ); // input : 6 complex channels | 3 complex channels break; @@ -575,7 +575,7 @@ private: m_RCRCFilter = RCRCFilterType::New(); m_RCRCFilter->SetInput(GetParameterComplexDoubleVectorImage("inc")); - SetParameterComplexOutputImage("outc", m_RCRCFilter->GetOutput() ); // input : 6 complex channels | 6 complex channels + SetParameterOutputImage("outc", m_RCRCFilter->GetOutput() ); // input : 6 complex channels | 6 complex channels break; @@ -586,7 +586,7 @@ private: m_RLCRCCFilter = RLCRCCFilterType::New(); m_RLCRCCFilter->SetInput(GetParameterComplexDoubleVectorImage("inc")); - SetParameterComplexOutputImage("outc", m_RLCRCCFilter->GetOutput() ); // input : 6 complex channels | output : 6 complex channels + SetParameterOutputImage("outc", m_RLCRCCFilter->GetOutput() ); // input : 6 complex channels | output : 6 complex channels break; @@ -597,7 +597,7 @@ private: m_MRCFilter->SetInput(GetParameterDoubleVectorImage("inf")); - SetParameterComplexOutputImage("outc", m_MRCFilter->GetOutput() ); // input : 16 real channels | output : 6 complex channels + SetParameterOutputImage("outc", m_MRCFilter->GetOutput() ); // input : 16 real channels | output : 6 complex channels break; @@ -615,7 +615,7 @@ private: m_CohSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh")); m_CohSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv")); - SetParameterComplexOutputImage("outc", m_CohSRFilter->GetOutput() ); // input : 4 x 1 complex channel | 10 complex channels + SetParameterOutputImage("outc", m_CohSRFilter->GetOutput() ); // input : 4 x 1 complex channel | 10 complex channels break; @@ -630,7 +630,7 @@ private: m_CovSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh")); m_CovSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv")); - SetParameterComplexOutputImage("outc", m_CovSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 10 complex channels + SetParameterOutputImage("outc", m_CovSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 10 complex channels break; @@ -644,7 +644,7 @@ private: m_CCSRFilter->SetInputVH(GetParameterComplexDoubleImage("invh")); m_CCSRFilter->SetInputVV(GetParameterComplexDoubleImage("invv")); - SetParameterComplexOutputImage("outc", m_CCSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 10 complex channels + SetParameterOutputImage("outc", m_CCSRFilter->GetOutput() ); // input : 4 x 1 complex channel | output : 10 complex channels break; diff --git a/Modules/Applications/AppSARPolarSynth/app/otbSARPolarSynth.cxx b/Modules/Applications/AppSARPolarSynth/app/otbSARPolarSynth.cxx index 236ac0789fa1e8e2077e9903bcc5c4c0e8aa9733..3db956847e1dba701365e3c1823e8d5370525063 100644 --- a/Modules/Applications/AppSARPolarSynth/app/otbSARPolarSynth.cxx +++ b/Modules/Applications/AppSARPolarSynth/app/otbSARPolarSynth.cxx @@ -86,7 +86,7 @@ private: AddDocTag(Tags::SAR); - AddParameter(ParameterType_ComplexInputImage, "in", "Input Image"); + AddParameter(ParameterType_InputImage, "in", "Input Image"); SetParameterDescription("in", "Input image."); AddParameter(ParameterType_OutputImage, "out", "Output Image"); SetParameterDescription("out", "Output image."); diff --git a/Modules/Applications/AppSARUtils/app/otbComputeModulusAndPhase.cxx b/Modules/Applications/AppSARUtils/app/otbComputeModulusAndPhase.cxx index 39db311e799737b730973d68c5156d273366896b..ec91b7e53b6c04b398a1e3d854475758d1f9d21e 100644 --- a/Modules/Applications/AppSARUtils/app/otbComputeModulusAndPhase.cxx +++ b/Modules/Applications/AppSARUtils/app/otbComputeModulusAndPhase.cxx @@ -75,7 +75,7 @@ private: AddDocTag(Tags::SAR); AddDocTag(Tags::Manip); // Input images - AddParameter(ParameterType_ComplexInputImage, "in", "Input Image"); + AddParameter(ParameterType_InputImage, "in", "Input Image"); SetParameterDescription("in", "Input image (complex single band)"); // Outputs @@ -110,7 +110,7 @@ private: m_Modulus = ModulusFilterType::New(); m_Phase = PhaseFilterType::New(); - ComplexFloatVectorImageType::Pointer inImage = GetParameterComplexImage("in"); + ComplexFloatVectorImageType::Pointer inImage = GetParameterComplexFloatVectorImage("in"); if (inImage->GetNumberOfComponentsPerPixel() != 1) { diff --git a/Modules/Core/ImageBase/include/otbDefaultConvertPixelTraits.h b/Modules/Core/ImageBase/include/otbDefaultConvertPixelTraits.h index 3339a54a1a39b6be9d8ddd5dc17a757289a87213..be11633e7b98a62cded643e040e26aa76abd5d4c 100644 --- a/Modules/Core/ImageBase/include/otbDefaultConvertPixelTraits.h +++ b/Modules/Core/ImageBase/include/otbDefaultConvertPixelTraits.h @@ -1,5 +1,4 @@ /* - * Copyright (C) 1999-2011 Insight Software Consortium * Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES) * * This file is part of Orfeo Toolbox @@ -19,322 +18,67 @@ * limitations under the License. */ - #ifndef otbDefaultConvertPixelTraits_h #define otbDefaultConvertPixelTraits_h -#include "itkOffset.h" -#include "itkVector.h" -#include "itkMatrix.h" +#include "itkDefaultConvertPixelTraits.h" -namespace otb +namespace otb { -/** \class DefaultConvertPixelTraits - * \brief Traits class used to by ConvertPixels to convert blocks of pixels. - * - * TOutputPixelType is the destination type. The input type is inferred - * by the templated static function Convert. - * - * This implementation does a simple assignment operator, so if you are - * going from a higher bit representation to a lower bit one (int to - * char), you may want to specialize and add some sort of transfer function. - * - * \ingroup OTBImageBase - */ -template<typename PixelType> -class DefaultConvertPixelTraits + +template < typename PixelType> +class DefaultConvertPixelTraits +: public itk::DefaultConvertPixelTraits < PixelType > { public: - /** Determine the pixel data type. */ - typedef typename PixelType::ComponentType ComponentType; - - /** Return the number of components per pixel. */ - static unsigned int GetNumberOfComponents() - { return PixelType::GetNumberOfComponents(); } - - /** Return the nth component of the pixel. */ - static ComponentType GetNthComponent(int c, const PixelType& pixel) - { return pixel.GetNthComponent(c); } - - /** Set the nth component of the pixel. */ - static void SetNthComponent(int c, PixelType& pixel, const ComponentType& v) - { pixel.SetNthComponent(c, v); } - static void SetNthComponent(int itkNotUsed(c), PixelType & pixel, const PixelType& v) - { pixel = v; } + typedef itk::DefaultConvertPixelTraits < PixelType > SuperClass; + using typename SuperClass::ComponentType; - /** Return a single scalar value from this pixel. */ - static ComponentType GetScalarValue(const PixelType& pixel) - { return pixel.GetScalarValue(); } + using SuperClass::SetNthComponent; + static void SetNthComponent(int , PixelType & pixel, const PixelType & v) + { + pixel = v; + } }; -#define OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(type) \ -template<> \ -class DefaultConvertPixelTraits<type> \ -{ \ -public: \ - typedef type ComponentType; \ - static unsigned int GetNumberOfComponents() \ - { \ - return 1; \ - } \ - static void SetNthComponent(int , type& pixel, const ComponentType& v) \ - { \ - pixel = v; \ - } \ - static type GetScalarValue(const type& pixel) \ - { \ - return pixel; \ - } \ -}; - -OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(float) -OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(double) -OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(int) -OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(char) -OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(short) -OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned int) -OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(signed char) -OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned char) -OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned short) -OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(long) -OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(unsigned long) -OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL(bool) - -#undef OTB_DEFAULTCONVERTTRAITS_NATIVE_SPECIAL - -// -// Default traits for the Offset<> pixel type -// +template < typename T > +class DefaultConvertPixelTraits < ::std::complex < T > > +: public itk::DefaultConvertPixelTraits < ::std::complex < T > > +{ +public: -#define OTB_DEFAULTCONVERTTRAITS_OFFSET_TYPE(dimension) \ -template<> \ -class DefaultConvertPixelTraits< itk::Offset<dimension> > \ -{ \ -public: \ - typedef itk::Offset<dimension> TargetType; \ - typedef TargetType::OffsetValueType ComponentType; \ - static unsigned int GetNumberOfComponents() \ - { \ - return dimension; \ - } \ - static void SetNthComponent(int i, TargetType & pixel, const ComponentType& v) \ - { \ - pixel[i] = v; \ - } \ - static void SetNthComponent(int , TargetType & pixel, const TargetType& v) \ - { \ - pixel = v; \ - } \ - static ComponentType GetScalarValue(const TargetType& pixel) \ - { \ - return pixel[0]; \ - } \ + typedef itk::DefaultConvertPixelTraits < ::std::complex < T > > SuperClass; + using typename SuperClass::TargetType ; + using typename SuperClass::ComponentType ; + + using SuperClass::SetNthComponent ; + + static void SetNthComponent(int , TargetType & pixel, const TargetType & v) + { + pixel = v; + } + + static TargetType GetNthComponent ( int , const TargetType & pixel ) + { + return pixel; + } + + static ComponentType GetScalarValue(const TargetType& pixel) + { + /* + * This seems to be dead code, since the complex to scalar + * conversion is done by ConvertPixelBuffer + * + * Historically, it was returning std::norm, which causes + * compilation error on MacOSX 10.9. + * Now returns the equivalent implementation of std::norm. + */ + return static_cast<ComponentType>( pixel.real()*pixel.real() + + pixel.imag()*pixel.imag() ); + } }; - -// Define traits for Offset<> from dimensions 1 to 5 - OTB_DEFAULTCONVERTTRAITS_OFFSET_TYPE(1) - OTB_DEFAULTCONVERTTRAITS_OFFSET_TYPE(2) - OTB_DEFAULTCONVERTTRAITS_OFFSET_TYPE(3) - OTB_DEFAULTCONVERTTRAITS_OFFSET_TYPE(4) - OTB_DEFAULTCONVERTTRAITS_OFFSET_TYPE(5) - -// -// Default traits for the pixel types deriving from FixedArray<> -// - -#define OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(type,componenttype, dimension) \ -template<> \ -class DefaultConvertPixelTraits< type< componenttype, dimension> > \ -{ \ -public: \ - typedef type< componenttype, dimension > TargetType; \ - typedef componenttype ComponentType; \ - static unsigned int GetNumberOfComponents() \ - { \ - return dimension; \ - } \ - static void SetNthComponent(int i, TargetType & pixel, const ComponentType& v) \ - { \ - pixel[i] = v; \ - } \ - static void SetNthComponent(int , TargetType & pixel, const TargetType& v) \ - { \ - pixel = v; \ - } \ - static ComponentType GetScalarValue(const TargetType& pixel) \ - { \ - return pixel[0]; \ - } \ -}; \ - -// -// -// Define traits for Classed deriving from FixedArray from dimensions 1 to 6 -// These classes include: Vector, CovariantVector and Point. -// -// -#define OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, Type) \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,1) \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,2) \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,3) \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,4) \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,5) \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE(ArrayType,Type,6) - -#define OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(ArrayType) \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, char); \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, signed char); \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned char); \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, short); \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned short); \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, int); \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned int); \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, long); \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, unsigned long); \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, float); \ - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_MACRO(ArrayType, double); - - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(itk::Vector); - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(itk::CovariantVector); - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(itk::Point); - OTB_DEFAULTCONVERTTRAITS_FIXEDARRAY_TYPE_ALL_TYPES_MACRO(itk::FixedArray); - -// -// End of Traits for the classes deriving from FixedArray. -// -// - - -// -// Default traits for the pixel types deriving from Matrix<> -// - -#define OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE(type,componenttype,rows,cols) \ -template<> \ -class DefaultConvertPixelTraits< type< componenttype, rows, cols > > \ -{ \ -public: \ - typedef type< componenttype, rows, cols > TargetType; \ - typedef componenttype ComponentType; \ - static unsigned int GetNumberOfComponents() \ - { \ - return rows * cols; \ - } \ - static void SetNthComponent(int i, TargetType & pixel, const ComponentType& v) \ - { \ - const unsigned int row = i / cols; \ - const unsigned int col = i % cols; \ - pixel[row][col] = v; \ - } \ - static void SetNthComponent(int , TargetType & pixel, const TargetType& v) \ - { \ - pixel = v; \ - } \ - static ComponentType GetScalarValue(const TargetType& pixel) \ - { \ - return pixel[0][0]; \ - } \ -}; \ - -// -// -// Define traits for Classed deriving from Matrix from dimensions 1 to 6 -// -// -#define OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, Type) \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,1,1) \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,2,2) \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,3,3) \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,4,4) \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,5,5) \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE(ArrayType,Type,6,6) - -#define OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_TYPES_MACRO(ArrayType) \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, char); \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, signed char); \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned char); \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, short); \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned short); \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, int); \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned int); \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, long); \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, unsigned long); \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, float); \ - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_MACRO(ArrayType, double); - -// -// Add here other classes that derive from Matrix or that have the same API -// - OTB_DEFAULTCONVERTTRAITS_MATRIX_TYPE_ALL_TYPES_MACRO(itk::Matrix); - -// -// End of Traits for the classes deriving from Matrix. -// -// - - -// -// Default traits for the pixel types deriving from std::complex<> -// - -#define OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE( componenttype ) \ -template<> \ -class DefaultConvertPixelTraits< ::std::complex< componenttype > > \ -{ \ -public: \ - typedef ::std::complex< componenttype> TargetType; \ - typedef componenttype ComponentType; \ - static unsigned int GetNumberOfComponents() \ - { \ - return 2; \ - } \ - static void SetNthComponent(int i, TargetType & pixel, const ComponentType& v) \ - { \ - if( i == 0 ) \ - { \ - pixel = TargetType( v, pixel.imag() ); \ - } \ - else \ - { \ - pixel = TargetType( pixel.real(), v ); \ - } \ - } \ - static void SetNthComponent(int , TargetType & pixel, const TargetType& v) \ - { \ - pixel = v; \ - } \ - static ComponentType GetScalarValue(const TargetType& pixel) \ - { \ - /* \ - * This seems to be dead code, since the complex to scalar \ - * conversion is done by ConvertPixelBuffer \ - * \ - * Historically, it was returning std::norm, which causes \ - * compilation error on MacOSX 10.9. \ - * Now returns the equivalent implementation of std::norm. \ - */ \ - return static_cast<ComponentType>( pixel.real()*pixel.real() \ - + pixel.imag()*pixel.imag() ); \ - } \ -}; \ - -OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(float); -OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(double); -OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(signed int); -OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(unsigned int); -OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(short int); -OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(signed char); -OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(unsigned char); -OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(signed long); -OTB_DEFAULTCONVERTTRAITS_COMPLEX_TYPE(unsigned long); - -// -// End of Traits for the classes deriving from std::complex. -// -// - -} // end namespace otb +} // end namespace #endif diff --git a/Modules/Core/ObjectList/include/otbImageList.h b/Modules/Core/ObjectList/include/otbImageList.h index 611d84a47a18efdb93a79085fa4a764968338ddf..4cb77bddec306437bccb05b45b81bdf71c9b9610 100644 --- a/Modules/Core/ObjectList/include/otbImageList.h +++ b/Modules/Core/ObjectList/include/otbImageList.h @@ -68,6 +68,8 @@ public: throw (itk::InvalidRequestedRegionError) ITK_OVERRIDE; void UpdateOutputData(void) ITK_OVERRIDE; + void SetRequestedRegion(const itk::DataObject * source); + protected: /** Constructor */ ImageList() {}; diff --git a/Modules/Core/ObjectList/include/otbImageList.txx b/Modules/Core/ObjectList/include/otbImageList.txx index dc0cbc9b6fef35e3430891fb9cd08a7e4324aefd..dec0ab8b3e5ce3a834ee5a6dc9a247831d432f5b 100644 --- a/Modules/Core/ObjectList/include/otbImageList.txx +++ b/Modules/Core/ObjectList/include/otbImageList.txx @@ -39,10 +39,32 @@ ImageList<TImage> || it.Get()->GetDataReleased() || it.Get()->RequestedRegionIsOutsideOfTheBufferedRegion()) { + if(it.Get()->GetSource()) + { + it.Get()->GetSource()->UpdateOutputData(it.Get()); + } + } + } +} + +template <class TImage> +void +ImageList<TImage> +::PropagateRequestedRegion() throw (itk::InvalidRequestedRegionError) + { + Superclass::PropagateRequestedRegion(); + + for (ConstIterator it = this->Begin(); it != this->End(); ++it) + { + if (it.Get()->GetUpdateMTime() < it.Get()->GetPipelineMTime() + || it.Get()->GetDataReleased() + || it.Get()->RequestedRegionIsOutsideOfTheBufferedRegion()) + { + if (it.Get()->GetSource()) { it.Get()->GetSource()->PropagateRequestedRegion(it.Get()); - + // Check that the requested region lies within the largest possible region if (!it.Get()->VerifyRequestedRegion()) { @@ -51,23 +73,24 @@ ImageList<TImage> e.SetLocation(ITK_LOCATION); e.SetDataObject(it.Get()); e.SetDescription("Requested region is (at least partially) outside the largest possible region."); - + throw e; } - - it.Get()->GetSource()->UpdateOutputData(it.Get()); } } } -} + } -template <class TImage> +template<class TImage> void ImageList<TImage> -::PropagateRequestedRegion() throw (itk::InvalidRequestedRegionError) - { - Superclass::PropagateRequestedRegion(); - } +::SetRequestedRegion(const itk::DataObject * source) +{ + for (ConstIterator it = this->Begin(); it != this->End(); ++it) + { + it.Get()->SetRequestedRegion(source); + } +} template <class TImage> void diff --git a/Modules/Core/Streaming/include/otbPipelineMemoryPrintCalculator.h b/Modules/Core/Streaming/include/otbPipelineMemoryPrintCalculator.h index 826478711d24b2c9ab3ac7e75d4e8586354c8afb..41fe7808e9d84a0d0ae3017996e417ea0cd97c3a 100644 --- a/Modules/Core/Streaming/include/otbPipelineMemoryPrintCalculator.h +++ b/Modules/Core/Streaming/include/otbPipelineMemoryPrintCalculator.h @@ -121,7 +121,7 @@ public: static const double MegabyteToByte; /** Evaluate the print (in bytes) of a single data object */ - MemoryPrintType EvaluateDataObjectPrint(DataObjectType * data) const; + MemoryPrintType EvaluateDataObjectPrint(DataObjectType * data); protected: /** Constructor */ diff --git a/Modules/Core/Streaming/src/otbPipelineMemoryPrintCalculator.cxx b/Modules/Core/Streaming/src/otbPipelineMemoryPrintCalculator.cxx index 033c58bc379fed6aba092e28e346b1d58ab35b84..d7d62e8c88cd6a779425feb92d5c9eeea7a71497 100644 --- a/Modules/Core/Streaming/src/otbPipelineMemoryPrintCalculator.cxx +++ b/Modules/Core/Streaming/src/otbPipelineMemoryPrintCalculator.cxx @@ -162,7 +162,7 @@ PipelineMemoryPrintCalculator PipelineMemoryPrintCalculator::MemoryPrintType PipelineMemoryPrintCalculator -::EvaluateDataObjectPrint(DataObjectType * data) const +::EvaluateDataObjectPrint(DataObjectType * data) { otbMsgDevMacro(<< "EvaluateMemoryPrint for " << data->GetNameOfClass() << " (" << data << ")") @@ -183,11 +183,13 @@ PipelineMemoryPrintCalculator { \ ImageList<Image<type, 2> > * imageList = dynamic_cast<otb::ImageList<otb::Image<type, 2> > *>(data); \ MemoryPrintType print(0); \ - for(ImageList<Image<type, 2> >::ConstIterator it = imageList->Begin(); \ + for(ImageList<Image<type, 2> >::Iterator it = imageList->Begin(); \ it != imageList->End(); ++it) \ { \ - print += it.Get()->GetRequestedRegion().GetNumberOfPixels() \ - * it.Get()->GetNumberOfComponentsPerPixel() * sizeof(type); \ + if(it.Get()->GetSource()) \ + print += this->EvaluateProcessObjectPrintRecursive(it.Get()->GetSource());\ + else \ + print += this->EvaluateDataObjectPrint(it.Get()); \ } \ return print; \ } \ @@ -198,8 +200,10 @@ PipelineMemoryPrintCalculator for(ImageList<VectorImage<type, 2> >::ConstIterator it = imageList->Begin(); \ it != imageList->End(); ++it) \ { \ - print += it.Get()->GetRequestedRegion().GetNumberOfPixels() \ - * it.Get()->GetNumberOfComponentsPerPixel() * sizeof(type); \ + if(it.Get()->GetSource()) \ + print += this->EvaluateProcessObjectPrintRecursive(it.Get()->GetSource());\ + else \ + print += this->EvaluateDataObjectPrint(it.Get()); \ } \ return print; \ } \ diff --git a/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.h b/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.h index 6fdd16e955a3b7a754779b6d1acd76de60e711d8..478eb952220a8cf08eed6b8550114d2053ba2ccd 100644 --- a/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.h +++ b/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.h @@ -21,121 +21,104 @@ #ifndef otbClampImageFilter_h #define otbClampImageFilter_h -#include "itkImageToImageFilter.h" +#include "otbConvertTypeFunctor.h" +#include "itkUnaryFunctorImageFilter.h" namespace otb { /** \class ClampImageFilter - * \brief Set image values to a user-specified value if they are below, - * above, or between simple threshold values. + * \brief Clamp image values to be below, over, or between threhold values. * * ClampImageFilter clamp image values to be between an upper * and lower value. Values lower than m_Lower values are set to lower, * and values greater than upper threshold are set to upper threshold * value. + * This filter can also be used to cast any type of image into any other type + * as long as those types are arithmetics or complex. * * By default lower and upper thresholds are set to the maximum and - * minimum bounds of the image pixel type. - * - * The pixels must support the operators >= and <=. + * minimum bounds of the image internal pixel value. * * \ingroup IntensityImageFilters Multithreaded * * \ingroup OTBImageManipulation */ template <class TInputImage, class TOutputImage=TInputImage> - class ITK_EXPORT ClampImageFilter : public itk::ImageToImageFilter<TInputImage, TOutputImage> + class ITK_EXPORT ClampImageFilter + : public itk::UnaryFunctorImageFilter< TInputImage , TOutputImage , + Functor::ConvertTypeFunctor <typename TInputImage::PixelType , + typename TOutputImage::PixelType> > { public: /** Standard class typedefs. */ - typedef ClampImageFilter Self; - typedef itk::ImageToImageFilter<TInputImage, TOutputImage> Superclass; - typedef itk::SmartPointer<Self> Pointer; - typedef itk::SmartPointer<const Self> ConstPointer; + typedef ClampImageFilter Self; + typedef itk::UnaryFunctorImageFilter< TInputImage , TOutputImage , + Functor::ConvertTypeFunctor <typename TInputImage::PixelType , + typename TOutputImage::PixelType> > Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; /** Method for creation through the object factory. */ - itkNewMacro(Self); + itkNewMacro( Self ); /** Run-time type information (and related methods). */ - itkTypeMacro(ClampImageFilter, itk::ImageToImageFilter); + itkTypeMacro( ClampImageFilter , itk::UnaryFunctorImageFilter ); /** Some additional typedefs. */ typedef TInputImage InputImageType; - typedef typename InputImageType::ConstPointer InputImagePointer; typedef typename InputImageType::RegionType InputImageRegionType; typedef typename InputImageType::PixelType InputImagePixelType; /** Some additional typedefs. */ - typedef TOutputImage OutputImageType; - typedef typename OutputImageType::Pointer OutputImagePointer; - typedef typename OutputImageType::RegionType OutputImageRegionType; - typedef typename OutputImageType::PixelType OutputImagePixelType; + typedef TOutputImage OutputImageType; + typedef typename OutputImageType::RegionType OutputImageRegionType; + typedef typename OutputImageType::PixelType OutputImagePixelType; + typedef typename OutputImageType::InternalPixelType OutputInternalPixelType; + typedef typename itk::NumericTraits< OutputInternalPixelType >::ValueType OutputPixelValueType; - /** The values greater than or equal to the value are set to OutsideValue. */ - void ClampAbove(const OutputImagePixelType &thresh); + /** The values greater than or equal to the value are set to \p thresh. */ + void ClampAbove(const OutputPixelValueType &thresh); - /** The values less than or equal to the value are set to OutsideValue. */ - void ClampBelow(const OutputImagePixelType &thresh); + /** The values less than or equal to the value are set to \p thresh. */ + void ClampBelow(const OutputPixelValueType &thresh); - /** The values outside the range are set to OutsideValue. */ - void ClampOutside(const OutputImagePixelType &lower, const OutputImagePixelType &upper); + /** The values outside the range are set to \p lower or \p upper. */ + void ClampOutside(const OutputPixelValueType &lower, const OutputPixelValueType &upper); /** Set/Get methods to set the lower threshold */ - void SetLower(OutputImagePixelType val) - { - m_Lower = val; - m_DLower = static_cast<double>(val); - this->Modified(); - } - itkGetConstMacro(Lower, OutputImagePixelType); + void SetLower(OutputPixelValueType val); + + itkGetConstMacro(Lower, OutputPixelValueType); /** Set/Get methods to set the upper threshold */ - void SetUpper(OutputImagePixelType val) - { - m_Upper = val; - m_DUpper = static_cast<double>(val); - this->Modified(); - } - itkGetConstMacro(Upper, OutputImagePixelType); + void SetUpper(OutputPixelValueType val); + + itkGetConstMacro(Upper, OutputPixelValueType); protected: ClampImageFilter(); - ~ClampImageFilter() ITK_OVERRIDE {}; - void PrintSelf(std::ostream& os, itk::Indent indent) const ITK_OVERRIDE; - - /** ClampImageFilter can be implemented as a multithreaded filter. - * Therefore, this implementation provides a ThreadedGenerateData() routine - * which is called for each processing thread. The output image data is - * allocated automatically by the superclass prior to calling - * ThreadedGenerateData(). ThreadedGenerateData can only write to the - * portion of the output image specified by the parameter - * "outputRegionForThread" - * - * \sa ImageToImageFilter::ThreadedGenerateData(), - * ImageToImageFilter::GenerateData() */ - void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, - itk::ThreadIdType threadId ) ITK_OVERRIDE; - - void GenerateOutputInformation(void) ITK_OVERRIDE - { - Superclass::GenerateOutputInformation(); + ~ClampImageFilter() override {}; + void PrintSelf(std::ostream& os, itk::Indent indent) const override; - this->GetOutput()->SetNumberOfComponentsPerPixel( this->GetInput()->GetNumberOfComponentsPerPixel() ); - } + void GenerateOutputInformation(void) override + { + Superclass::GenerateOutputInformation(); + unsigned int sizeIn = this->GetInput()->GetNumberOfComponentsPerPixel(); + this->GetFunctor().SetInputComponents( sizeIn ); + this->GetOutput()->SetNumberOfComponentsPerPixel( + this->GetFunctor().GetOutputSize () ); + } private: - ClampImageFilter(const Self&); //purposely not implemented - void operator=(const Self&); //purposely not implemented - - double m_DLower; - double m_DUpper; + ClampImageFilter(const Self&) = delete ; + void operator=(const Self&) = delete ; - OutputImagePixelType m_Lower; - OutputImagePixelType m_Upper; + OutputPixelValueType m_Lower; + OutputPixelValueType m_Upper; }; diff --git a/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.txx b/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.txx index fd1ed1320ec1cbe7768eb8ccb44f7b9ba317d8f9..b1ac37e2e3df315e4b2e402f9034a73ef25a4665 100644 --- a/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.txx +++ b/Modules/Filtering/ImageManipulation/include/otbClampImageFilter.txx @@ -25,6 +25,7 @@ #include "otbClampImageFilter.h" #include "itkImageRegionIterator.h" #include "itkNumericTraits.h" +#include <limits> #include "itkObjectFactory.h" #include "itkProgressReporter.h" @@ -38,13 +39,35 @@ template <class TInputImage, class TOutputImage> ClampImageFilter<TInputImage, TOutputImage> ::ClampImageFilter() { - m_Lower = itk::NumericTraits<OutputImagePixelType>::NonpositiveMin(); - m_Upper = itk::NumericTraits<OutputImagePixelType>::max(); + m_Lower = std::numeric_limits < OutputPixelValueType >::lowest(); + m_Upper = std::numeric_limits < OutputPixelValueType >::max(); +} - m_DLower = static_cast<double>(m_Lower); - m_DUpper = static_cast<double>(m_Upper); +template <class TInputImage, class TOutputImage> +void +ClampImageFilter<TInputImage, TOutputImage> +::SetLower(OutputPixelValueType val) +{ + if ( m_Lower != val ) + { + m_Lower = val; + this->GetFunctor().SetLowest( m_Lower ); + this->Modified(); + } } +template <class TInputImage, class TOutputImage> +void +ClampImageFilter<TInputImage, TOutputImage> +::SetUpper(OutputPixelValueType val) +{ + if ( m_Upper != val ) + { + m_Upper = val; + this->GetFunctor().SetHighest( m_Upper ); + this->Modified(); + } +} /** * @@ -70,14 +93,15 @@ ClampImageFilter<TInputImage, TOutputImage> template <class TInputImage, class TOutputImage> void ClampImageFilter<TInputImage, TOutputImage> -::ClampAbove(const OutputImagePixelType &thresh) +::ClampAbove(const OutputPixelValueType &thresh) { if (m_Upper != thresh - || m_Lower > itk::NumericTraits<OutputImagePixelType>::NonpositiveMin()) + || m_Lower > std::numeric_limits < OutputPixelValueType >::lowest()) { - m_Lower = itk::NumericTraits<OutputImagePixelType>::NonpositiveMin(); + m_Lower = std::numeric_limits < OutputPixelValueType >::lowest(); m_Upper = thresh; - m_DUpper = static_cast<double>(m_Upper); + this->GetFunctor().SetLowest( m_Lower ); + this->GetFunctor().SetHighest( m_Upper ); this->Modified(); } } @@ -88,13 +112,14 @@ ClampImageFilter<TInputImage, TOutputImage> template <class TInputImage, class TOutputImage> void ClampImageFilter<TInputImage, TOutputImage> -::ClampBelow(const OutputImagePixelType &thresh) +::ClampBelow(const OutputPixelValueType &thresh) { - if (m_Lower != thresh || m_Upper < itk::NumericTraits<OutputImagePixelType>::max()) + if (m_Lower != thresh || m_Upper < std::numeric_limits < OutputPixelValueType >::max()) { + m_Upper = std::numeric_limits < OutputPixelValueType >::max(); m_Lower = thresh; - m_DLower = m_Lower; - m_Upper = itk::NumericTraits<InputImagePixelType>::max(); + this->GetFunctor().SetLowest( m_Lower ); + this->GetFunctor().SetHighest( m_Upper ); this->Modified(); } } @@ -106,7 +131,7 @@ ClampImageFilter<TInputImage, TOutputImage> template <class TInputImage, class TOutputImage> void ClampImageFilter<TInputImage, TOutputImage> -::ClampOutside(const OutputImagePixelType &lower, const OutputImagePixelType &upper) +::ClampOutside(const OutputPixelValueType &lower, const OutputPixelValueType &upper) { if (lower > upper) { @@ -118,73 +143,12 @@ ClampImageFilter<TInputImage, TOutputImage> { m_Lower = lower; m_Upper = upper; - m_DLower = m_Lower; - m_DUpper = m_Upper; + this->GetFunctor().SetLowest( m_Lower ); + this->GetFunctor().SetHighest( m_Upper ); this->Modified(); } } - -/** - * - */ -template <class TInputImage, class TOutputImage> -void -ClampImageFilter<TInputImage, TOutputImage> -::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, - itk::ThreadIdType threadId) -{ - itkDebugMacro(<<"Actually executing"); - - // Get the input and output pointers - InputImagePointer inputPtr = this->GetInput(); - OutputImagePointer outputPtr = this->GetOutput(0); - - // Define/declare an iterator that will walk the output region for this - // thread. - typedef itk::ImageRegionConstIterator<TInputImage> InputIterator; - typedef itk::ImageRegionIterator<TOutputImage> OutputIterator; - - InputIterator inIt(inputPtr, outputRegionForThread); - OutputIterator outIt(outputPtr, outputRegionForThread); - - // support progress methods/callbacks - itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels()); - - // walk the regions, threshold each pixel - while( !outIt.IsAtEnd() && !inIt.IsAtEnd() ) - { - // Cast the value of the pixel to double in order to compare - // with the double version of the upper and the lower bounds of - // output image - const double value = static_cast<double>(inIt.Get()); - OutputImagePixelType outPix = m_Lower; - - if ( m_DLower <= value && value <= m_DUpper) - { - // pixel passes to output unchanged - outPix = static_cast<OutputImagePixelType>(value); - } - /* Already outPix is initialized with m_Lower even for preventing Warning. - * - else if ( value < m_DLower ) - { - outPix = m_Lower; - } - */ - else if ( value > m_DUpper) - { - outPix = m_Upper; - } - - outIt.Set( outPix ); - - ++inIt; - ++outIt; - progress.CompletedPixel(); - } -} - } // end namespace itk #endif diff --git a/Modules/Filtering/ImageManipulation/include/otbClampVectorImageFilter.h b/Modules/Filtering/ImageManipulation/include/otbClampVectorImageFilter.h index 053c3060001c7bc0961d1f4aac7d16ead7cd1fa2..50b43302e4bc18ff3d0cb89c998ee05c5fc710a2 100644 --- a/Modules/Filtering/ImageManipulation/include/otbClampVectorImageFilter.h +++ b/Modules/Filtering/ImageManipulation/include/otbClampVectorImageFilter.h @@ -21,6 +21,7 @@ #ifndef otbClampVectorImageFilter_h #define otbClampVectorImageFilter_h +#include <vcl_deprecated_header.h> #include "itkImageToImageFilter.h" namespace otb diff --git a/Modules/Filtering/ImageManipulation/include/otbConvertTypeFunctor.h b/Modules/Filtering/ImageManipulation/include/otbConvertTypeFunctor.h new file mode 100644 index 0000000000000000000000000000000000000000..c5a73b5cb1591868f4f67a1ddf65df3b5544a6ff --- /dev/null +++ b/Modules/Filtering/ImageManipulation/include/otbConvertTypeFunctor.h @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2005-2017 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. + */ + +#ifndef otbConvertTypeFunctor_h +#define otbConvertTypeFunctor_h + +#include <limits> +#include <type_traits> +#include <boost/type_traits/is_complex.hpp> +#include <boost/type_traits/is_scalar.hpp> + +#include "itkNumericTraits.h" +#include "otbDefaultConvertPixelTraits.h" + +namespace otb +{ +namespace Functor +{ + +template < class TInputPixelType , class TOutputPixelType > +class ConvertTypeFunctor +{ +public: + typedef TInputPixelType InputPixelType; + typedef TOutputPixelType OutputPixelType; + typedef ConvertTypeFunctor Self; + + typedef typename itk::NumericTraits < InputPixelType > :: ValueType InputInternalPixelType; + typedef typename itk::NumericTraits < OutputPixelType > :: ValueType OutputInternalPixelType; + + typedef typename itk::NumericTraits < InputInternalPixelType > :: ValueType InputPixelValueType; + typedef typename itk::NumericTraits < OutputInternalPixelType > :: ValueType OutputPixelValueType; + + static constexpr bool m_cInPix = boost::is_complex < InputPixelType > :: value ; + static constexpr bool m_cOutPix = boost::is_complex < OutputPixelType > :: value ; + static constexpr bool m_cInInternalPix = boost::is_complex < InputInternalPixelType > :: value ; + static constexpr bool m_cOutInternalPix = boost::is_complex < OutputInternalPixelType > :: value ; + + ConvertTypeFunctor() + // m_cInPix ( boost::is_complex < InputPixelType > :: value ) , + // m_cOutPix ( boost::is_complex < OutputPixelType > :: value ) , + // m_cInInternalPix ( boost::is_complex < InputInternalPixelType > :: value ) , + // m_cOutInternalPix ( boost::is_complex < OutputInternalPixelType > :: value ) + { + m_LowestB = std::numeric_limits < OutputPixelValueType >::lowest(); + m_HighestB = std::numeric_limits < OutputPixelValueType >::max(); + + m_LowestBD = static_cast < double > ( m_LowestB ); + m_HighestBD = static_cast < double > ( m_HighestB ); + + // m_cInPix = boost::is_complex < InputPixelType > :: value ; + // m_cOutPix = boost::is_complex < OutputPixelType > :: value ; + // m_cInInternalPix = boost::is_complex < InputInternalPixelType > :: value ; + // m_cOutInternalPix = boost::is_complex < OutputInternalPixelType > :: value ; + } + + // template < class InternalPixelType > + void SetInputComponents( unsigned int sizeIn ) + { + m_CompIn = sizeIn ; + if ( m_cInPix ) + { + // needed as ITK thinks that one complex component is actually + // two components... + m_CompIn /= 2 ; + } + } + + unsigned int GetOutputSize() + { + if ( m_cInInternalPix || m_cInPix ) + m_Scal = 2 * m_CompIn; + else + m_Scal = m_CompIn; + + OutputPixelType out; + unsigned int size = + itk::NumericTraits < OutputPixelType > :: GetLength( out ); + if ( size == 0 ) // That means it is a variable size container + { + if ( m_cOutInternalPix ) + m_CompOut = ( m_Scal + 1 ) / 2 ; + else + m_CompOut = m_Scal ; + } + // It is a fixed size container, m_CompOut should be equal to its size + else if ( m_cOutPix ) // one complex is one component + m_CompOut = 1 ; + else // fized size container or scalar + m_CompOut = size; + + + return m_CompOut ; + } + + void SetLowest( OutputPixelValueType & lowest ) + { + m_LowestB = lowest; + m_LowestBD = static_cast < double > ( m_LowestB ); + } + + void SetHighest( OutputPixelValueType & highest ) + { + m_HighestB = highest; + m_HighestBD = static_cast < double > ( m_HighestB ); + } + + OutputPixelType operator() ( InputPixelType const & in ) const + { + std::vector < double > vPixel; + for ( unsigned int i = 0 ; i < m_CompIn ; i ++) + FillIn < InputPixelType > ( i , in , vPixel ); + assert( m_Scal == vPixel.size() ); + if ( ( m_cOutPix || m_cOutInternalPix ) && vPixel.size()%2 ) + { + vPixel.push_back(0); // last component has no imaginary part + } + Clamp( vPixel ); + OutputPixelType out; + + int hack = 1; + if ( m_cOutPix ) + hack += 1; // needed in case we have OutputPixelType == complex<t> as + // itk::NumericTraits::SetLength() will ask a length of 2! + itk::NumericTraits < OutputPixelType > :: SetLength( out , + hack * m_CompOut ); + + for ( unsigned int i = 0 ; i < m_CompOut ; i ++) + FillOut < OutputPixelType > ( i , out , vPixel ); + return out; + } + + ~ConvertTypeFunctor() {}; + +protected: + + template <class PixelType , + std::enable_if_t < std::is_arithmetic < PixelType > ::value , int > = 0 > + void FillIn( unsigned int i , + InputPixelType const & pix , + std::vector < double > & vPix ) const + { + vPix.push_back( DefaultConvertPixelTraits < InputPixelType > :: + GetNthComponent( i , pix ) ); + } + + template <class PixelType , + std::enable_if_t < boost::is_complex < PixelType > :: value , int > = 0 > + void FillIn( unsigned int i , + InputPixelType const & pix , + std::vector < double > & vPix ) const + { + PixelType comp = DefaultConvertPixelTraits < InputPixelType > :: + GetNthComponent( i , pix ); + vPix.push_back( static_cast < double > ( real( comp ) ) ); + vPix.push_back( static_cast < double > ( imag( comp ) ) ); + } + + template <class PixelType , + std::enable_if_t < !( boost::is_complex < PixelType > :: value + || std::is_arithmetic < PixelType > ::value ) , int > = 0 > + void FillIn( unsigned int i , + InputPixelType const & pix , + std::vector < double > & vPix ) const + { + FillIn < InputInternalPixelType > ( i , pix , vPix ); + } + + void Clamp( std::vector < double > & vPixel ) const + { + for ( double & comp : vPixel ) + { + if ( comp >= m_HighestBD ) + comp = m_HighestBD; + else if ( comp <= m_LowestBD ) + comp = m_LowestBD; + } + } + + template <class PixelType , + std::enable_if_t < std::is_arithmetic < PixelType > ::value , int > = 0 > + void FillOut( unsigned int i , + OutputPixelType & pix , + std::vector < double > & vPix ) const + { + DefaultConvertPixelTraits < OutputPixelType > :: + SetNthComponent( i , pix , vPix[i] ); + } + + template <class PixelType , + std::enable_if_t < boost::is_complex < PixelType > :: value , int > = 0 > + void FillOut( unsigned int i , + OutputPixelType & pix , + std::vector < double > & vPix ) const + { + DefaultConvertPixelTraits < OutputPixelType > :: + SetNthComponent( i , pix , + PixelType ( vPix[ 2 * i] , vPix[ 2 * i + 1] ) ); + } + + template <class PixelType , + std::enable_if_t < !( boost::is_complex < PixelType > :: value + || std::is_arithmetic < PixelType > ::value ) , int > = 0 > + void FillOut( unsigned int i , + OutputPixelType & pix , + std::vector < double > & vPix ) const + { + FillOut < OutputInternalPixelType > ( i , pix , vPix ); + } + +private: + ConvertTypeFunctor(const Self &) = delete; + void operator =(const Self&) = delete; + + double m_LowestBD , m_HighestBD ; + OutputPixelValueType m_LowestB , m_HighestB ; + unsigned int m_CompIn , m_CompOut , m_Scal ; + // const bool m_cInPix , m_cOutPix , m_cInInternalPix , m_cOutInternalPix ; + +}; + +} //end namespace Functor + +} //end namespace otb + +#endif diff --git a/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h index 8582158d36343dd3449f79e27e7135fb04a435b7..01fe68c1150b7ce971cc105833b431b980d3981a 100644 --- a/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h +++ b/Modules/Filtering/ImageManipulation/include/otbOneRIBandImageToOneComplexBandImage.h @@ -21,6 +21,7 @@ #ifndef otbOneRIBandImageToOneComplexBandImage_h #define otbOneRIBandImageToOneComplexBandImage_h +#include <vcl_deprecated_header.h> #include "itkImageToImageFilter.h" #include "itkImage.h" #include "itkNumericTraits.h" diff --git a/Modules/Filtering/ImageManipulation/include/otbRealImageToComplexImageFilter.h b/Modules/Filtering/ImageManipulation/include/otbRealImageToComplexImageFilter.h index c426b5a2f9e5a2225d842b51cb92640841bcefbd..8e86ee82f3bf7df11abc7ba99955e673e3b522e8 100644 --- a/Modules/Filtering/ImageManipulation/include/otbRealImageToComplexImageFilter.h +++ b/Modules/Filtering/ImageManipulation/include/otbRealImageToComplexImageFilter.h @@ -21,6 +21,7 @@ #ifndef otbRealImageToComplexImageFilter_h #define otbRealImageToComplexImageFilter_h +#include <vcl_deprecated_header.h> #include "itkUnaryFunctorImageFilter.h" #include "vnl/vnl_math.h" diff --git a/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h index 538b07214964f53fb86a9238d9417b968ae13630..c4adb6a9f7b78e4b040a916ef1a970ff6be05627 100644 --- a/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h +++ b/Modules/Filtering/ImageManipulation/include/otbTwoNRIBandsImageToNComplexBandsImage.h @@ -21,6 +21,7 @@ #ifndef otbTwoNRIBandsImageToNComplexBandsImage_h #define otbTwoNRIBandsImageToNComplexBandsImage_h +#include <vcl_deprecated_header.h> #include "itkImageToImageFilter.h" #include "itkImage.h" #include "itkNumericTraits.h" diff --git a/Modules/Filtering/ImageManipulation/test/CMakeLists.txt b/Modules/Filtering/ImageManipulation/test/CMakeLists.txt index 386b4294793890480773aa72640551525dfaedcf..834a6d3da072adf5c4dbc385d46db7931132de97 100644 --- a/Modules/Filtering/ImageManipulation/test/CMakeLists.txt +++ b/Modules/Filtering/ImageManipulation/test/CMakeLists.txt @@ -58,7 +58,6 @@ otbStreamingInnerProductVectorImageFilter.cxx otbPhaseFunctorTest.cxx otbShiftScaleVectorImageFilterNew.cxx otbChangeLabelImageFilter.cxx -otbClampVectorImageFilter.cxx otbPrintableImageFilterNew.cxx otbShiftScaleImageAdaptorNew.cxx otbStreamingInnerProductVectorImageFilterNew.cxx @@ -442,20 +441,6 @@ otb_add_test(NAME bfTvChangeLabelImageFilter COMMAND otbImageManipulationTestDri 255 # upper threshold ) - -otb_add_test(NAME bfTvClampVectorImageFilterTest COMMAND otbImageManipulationTestDriver - --compare-image 0.0001 - ${BASELINE}/bfTvClampVectorImageFilterTest_Output.tif - ${TEMP}/bfTvClampVectorImageFilterTest_Output.tif - otbClampVectorImageFilterTest - ${INPUTDATA}/QB_TOULOUSE_MUL_Extract_500_500.tif - ${TEMP}/bfTvClampVectorImageFilterTest_Output.tif - ) - -otb_add_test(NAME bfTuClampVectorImageFilterNew COMMAND otbImageManipulationTestDriver - otbClampVectorImageFilterNew - ) - otb_add_test(NAME bfTuPrintableImageFilterNew COMMAND otbImageManipulationTestDriver otbPrintableImageFilterNew) @@ -638,6 +623,11 @@ otb_add_test(NAME bfTvClampImageFilterTest COMMAND otbImageManipulationTestDrive ${TEMP}/bfTvClampImageFilterTest_Output.tif ) +otb_add_test(NAME bfTvClampImageFilterConversionTest COMMAND otbImageManipulationTestDriver + otbClampImageFilterConversionTest + ${INPUTDATA}/veryverySmallFSATSW.tif + ) + otb_add_test(NAME coTvConcatenateVectorImageFilter COMMAND otbImageManipulationTestDriver --compare-image ${NOTOL} ${BASELINE}/coConcatenateVectorImageFilterOutput1.hdr diff --git a/Modules/Filtering/ImageManipulation/test/otbClampImageFilter.cxx b/Modules/Filtering/ImageManipulation/test/otbClampImageFilter.cxx index 82deca5f4fc74917e5e3bc5d78bf1acf5e0a41c6..29ac5602eacbc38ffda2b5914822024b2a20d0df 100644 --- a/Modules/Filtering/ImageManipulation/test/otbClampImageFilter.cxx +++ b/Modules/Filtering/ImageManipulation/test/otbClampImageFilter.cxx @@ -21,10 +21,14 @@ #include "otbClampImageFilter.h" #include "otbImage.h" +#include "otbVectorImage.h" +#include <limits> #include "otbImageFileReader.h" #include "otbImageFileWriter.h" +#include "itkImageRegionConstIterator.h" + /** Pixel typedefs */ typedef double InputPixelType; typedef unsigned int OutputPixelType; @@ -65,3 +69,423 @@ int otbClampImageFilterTest(int itkNotUsed(argc), char* argv[]) return EXIT_SUCCESS; } + +template < class InImageType , class OutImageType > +typename OutImageType::Pointer +Cross ( std::string const & inputFileName ) +{ + typedef otb::ImageFileReader< InImageType > ReaderType; + typedef otb::ClampImageFilter< InImageType , OutImageType > ClampFilter; + typename ReaderType::Pointer reader ( ReaderType::New() ); + reader->SetFileName( inputFileName ); + typename ClampFilter::Pointer clamp ( ClampFilter::New() ); + clamp->SetInput( reader->GetOutput() ); + clamp->Update(); + return clamp->GetOutput(); +} + +template < class OutImageType > +typename OutImageType::Pointer +Cross ( otb::VectorImage< std::complex<float> >::Pointer input ) +{ + typedef otb::ClampImageFilter< otb::VectorImage< std::complex<float> > , + OutImageType > ClampFilter; + typename ClampFilter::Pointer clamp ( ClampFilter::New() ); + clamp->SetInput( input ); + clamp->Update(); + return clamp->GetOutput(); +} + +template < class OutImageType > +typename OutImageType::Pointer +Cross ( otb::Image< itk::FixedArray< std::complex<float> , 2 > >::Pointer input ) +{ + typedef otb::ClampImageFilter< otb::Image< itk::FixedArray< std::complex<float> , 2 > > , + OutImageType > ClampFilter; + typename ClampFilter::Pointer clamp ( ClampFilter::New() ); + clamp->SetInput( input ); + clamp->Update(); + return clamp->GetOutput(); +} + +typedef otb::VectorImage<double> ImageRefType; + +template <class ImageType > +bool +CompareImageReal( const ImageRefType::Pointer imRef , + const ImageType * im ) +{ + typedef typename ImageType::PixelType RealPixelType; + + RealPixelType min = std::numeric_limits< RealPixelType >::lowest(); + RealPixelType max = std::numeric_limits< RealPixelType >::max(); + auto itRef = itk::ImageRegionConstIterator< ImageRefType >( imRef , + imRef->GetLargestPossibleRegion() ); + auto it = itk::ImageRegionConstIterator< ImageType >( im , + im->GetLargestPossibleRegion() ); + itRef.GoToBegin(); + it.GoToBegin(); + RealPixelType val; + double ref; + while ( !it.IsAtEnd() ) + { + val = it.Get(); + ref = itRef.Get()[0]; + if ( ref > static_cast<double>( max ) && val != max ) + { + return false; + } + else if ( ref < static_cast<double>( min ) && val != min ) + { + return false; + } + else if ( static_cast<RealPixelType>( ref ) != val ) + { + return false; + } + ++it; + ++itRef; + } + return true; +} + +template <class ImageType > +bool +CompareVectorReal( const ImageRefType::Pointer imRef , + const ImageType * im ) +{ + typedef typename ImageType::InternalPixelType RealPixelType; + RealPixelType min = std::numeric_limits< RealPixelType >::lowest(); + RealPixelType max = std::numeric_limits< RealPixelType >::max(); + auto itRef = itk::ImageRegionConstIterator< ImageRefType >( imRef , + imRef->GetLargestPossibleRegion() ); + auto it = itk::ImageRegionConstIterator< ImageType >( im , + im->GetLargestPossibleRegion() ); + itRef.GoToBegin(); + it.GoToBegin(); + unsigned int nbChanel = im->GetNumberOfComponentsPerPixel (); + // unsigned int nbChanelRef = imRef->GetNumberOfComponentsPerPixel (); + RealPixelType val; + double ref; + while ( !it.IsAtEnd() ) + { + // std::cout<<it.Get()<<std::endl; + // std::cout<<itRef.Get()<<std::endl; + for ( unsigned int i = 0 ; i < nbChanel ; i++ ) + { + val = it.Get()[i]; + ref = itRef.Get()[i]; + + if ( ref > static_cast<double>( max ) && val != max ) + { + std::cout<<"ref : "<<static_cast<RealPixelType>(ref)<<std::endl; + std::cout<<"val : "<<val<<std::endl; + return false; + } + else if ( ref < static_cast<double>( min ) && val != min ) + { + std::cout<<"ref : "<<static_cast<RealPixelType>(ref)<<std::endl; + std::cout<<"val : "<<val<<std::endl; + return false; + } + else if ( static_cast<RealPixelType>(ref) != val ) + { + std::cout<<"ref : "<<static_cast<RealPixelType>(ref)<<std::endl; + std::cout<<"val : "<<val<<std::endl; + return false; + } + } + ++it; + ++itRef; + } + return true; +} + +template <class ImageType > +bool +CompareImageComplex( const ImageRefType::Pointer imageRef , + const ImageType * im ) +{ + typedef typename ImageType::PixelType ComplexType; + typedef typename ComplexType::value_type RealType; + + RealType min = std::numeric_limits< RealType >::lowest(); + RealType max = std::numeric_limits< RealType >::max(); + auto itRef = itk::ImageRegionConstIterator< ImageRefType >( imageRef , + imageRef->GetLargestPossibleRegion() ); + auto it = itk::ImageRegionConstIterator< ImageType >( im , + im->GetLargestPossibleRegion() ); + itRef.GoToBegin(); + it.GoToBegin(); + ComplexType val; + double reRef , imRef; + while ( !it.IsAtEnd() ) + { + val = it.Get(); + reRef = itRef.Get()[0]; + imRef = itRef.Get()[1]; + if ( ( reRef > static_cast<double>( max ) && val.real() != max ) + || ( imRef > static_cast<double>( max ) && val.imag() != max ) ) + { + return false; + } + else if ( ( reRef < static_cast<double>( min ) && val.real() != min ) + || ( imRef < static_cast<double>( min ) && val.imag() != min ) ) + { + return false; + } + else if ( static_cast<RealType>( reRef ) != val.real() + || static_cast<RealType>( imRef ) != val.imag() ) + { + return false; + } + ++it; + ++itRef; + } + return true; +} + +template <class ImageType > +bool +CompareVectorComplex( const ImageRefType::Pointer imageRef , + const ImageType * im ) +{ + typedef typename ImageType::InternalPixelType ComplexType; + typedef typename ComplexType::value_type RealType; + + RealType min = std::numeric_limits< RealType >::lowest(); + RealType max = std::numeric_limits< RealType >::max(); + auto itRef = itk::ImageRegionConstIterator< ImageRefType >( imageRef , + imageRef->GetLargestPossibleRegion() ); + auto it = itk::ImageRegionConstIterator< ImageType >( im , + im->GetLargestPossibleRegion() ); + itRef.GoToBegin(); + it.GoToBegin(); + unsigned int nbChanel = im->GetNumberOfComponentsPerPixel (); + ComplexType val; + float reRef , imRef; + while ( !it.IsAtEnd() ) + { + for (unsigned int i = 0 ; i < nbChanel ; i++ ) + { + val = it.Get()[i]; + reRef = itRef.Get()[ 2 * i ]; + imRef = itRef.Get()[ 2 * i + 1 ]; + if ( ( reRef > static_cast<double>( max ) && val.real() != max ) + || ( imRef > static_cast<double>( max ) && val.imag() != max ) ) + { + return false; + } + else if ( ( reRef < static_cast<double>( min ) && val.real() != min ) + || ( imRef < static_cast<double>( min ) && val.imag() != min ) ) + { + return false; + } + else if ( static_cast<RealType>( reRef ) != val.real() + || static_cast<RealType>( imRef ) != val.imag() ) + { + return false; + } + } + ++it; + ++itRef; + } + return true; +} + +template <class ImageType > +bool +CompareArrayComplex( const ImageRefType::Pointer imageRef , + const ImageType * im ) +{ + typedef typename ImageType::PixelType ArrayType; + typedef typename ArrayType::ValueType ComplexType; + typedef typename ComplexType::value_type RealType; + + RealType min = std::numeric_limits< RealType >::lowest(); + RealType max = std::numeric_limits< RealType >::max(); + auto itRef = itk::ImageRegionConstIterator< ImageRefType >( imageRef , + imageRef->GetLargestPossibleRegion() ); + auto it = itk::ImageRegionConstIterator< ImageType >( im , + im->GetLargestPossibleRegion() ); + itRef.GoToBegin(); + it.GoToBegin(); + unsigned int nbChanel = im->GetNumberOfComponentsPerPixel (); + ComplexType val; + float reRef , imRef; + while ( !it.IsAtEnd() ) + { + for (unsigned int i = 0 ; i < nbChanel ; i++ ) + { + val = it.Get()[i]; + reRef = itRef.Get()[ 2 * i ]; + imRef = itRef.Get()[ 2 * i + 1 ]; + if ( ( reRef > static_cast<double>( max ) && val.real() != max ) + || ( imRef > static_cast<double>( max ) && val.imag() != max ) ) + { + return false; + } + else if ( ( reRef < static_cast<double>( min ) && val.real() != min ) + || ( imRef < static_cast<double>( min ) && val.imag() != min ) ) + { + return false; + } + else if ( static_cast<RealType>( reRef ) != val.real() + || static_cast<RealType>( imRef ) != val.imag() ) + { + return false; + } + } + ++it; + ++itRef; + } + return true; +} + +int otbClampImageFilterConversionTest(int itkNotUsed(argc), char* argv[]) +{ + typedef otb::ImageFileReader< ImageRefType > ReaderType; + ReaderType::Pointer reader ( ReaderType::New() ); + reader->SetFileName( argv[1] ); + reader->Update(); + ImageRefType::Pointer imageRef = reader->GetOutput(); + + // vect<real> --> vect<real> + otb::VectorImage< short >::Pointer image0 = + Cross < otb::VectorImage< double > , otb::VectorImage< short > > ( argv[1] ); + bool test0 = CompareVectorReal < otb::VectorImage< short > >( imageRef , image0 ); + std::cout<< "Test 0 : "<<test0<<std::endl; + image0 =nullptr; + + // vect<real> --> vect<complex> + otb::VectorImage< std::complex<unsigned short>>::Pointer image1 = + Cross < otb::VectorImage< float > , otb::VectorImage<std::complex<unsigned short>> > ( argv[1] ); + bool test1 = CompareVectorComplex < otb::VectorImage<std::complex<unsigned short>> >( imageRef , image1 ); + std::cout<< "Test 1 : "<<test1<<std::endl; + image1 = nullptr; + + // vect<real> --> image<real> + otb::Image<int>::Pointer image2 = + Cross < otb::VectorImage< float > , otb::Image<int> > ( argv[1] ); + bool test2 = CompareImageReal < otb::Image<int> >( imageRef , image2 ); + std::cout<< "Test 2 : "<<test2<<std::endl; + image2 = nullptr; + + // vect<real> --> image<complex> + otb::Image< std::complex<float>>::Pointer image3 = + Cross < otb::VectorImage< float > , otb::Image<std::complex<float>> > ( argv[1] ); + bool test3 = CompareImageComplex < otb::Image<std::complex<float>> >( imageRef , image3 ); + std::cout<< "Test 3 : "<<test3<<std::endl; + image3 = nullptr; + + // image<real> --> image<real> + otb::Image< unsigned short >::Pointer image4 = + Cross < otb::Image< itk::FixedArray < double , 4 > > , otb::Image< unsigned short > > ( argv[1] ); + bool test4 = CompareImageReal < otb::Image< unsigned short > >( imageRef , image4 ); + std::cout<< "Test 4 : "<<test4<<std::endl; + image4 = nullptr; + + // image<real> --> image<complex> + otb::Image< std::complex<int> >::Pointer image5 = + Cross < otb::Image< itk::FixedArray < double , 4 > > , otb::Image< std::complex<int> > > ( argv[1] ); + bool test5 = CompareImageComplex < otb::Image< std::complex<int> > >( imageRef , image5 ); + std::cout<< "Test 5 : "<<test5<<std::endl; + image5 = nullptr; + + // image<real> --> vector<real> + otb::VectorImage< float >::Pointer image6 = + Cross < otb::Image< itk::FixedArray < double , 4 > > , otb::VectorImage< float > > ( argv[1] ); + bool test6 = CompareVectorReal < otb::VectorImage< float > >( imageRef , image6 ); + std::cout<< "Test 6 : "<<test6<<std::endl; + image6 = nullptr; + + // image<real> --> vector<complex> + otb::VectorImage< std::complex<float> >::Pointer image7 = + Cross < otb::Image< itk::FixedArray < double , 4 > > , otb::VectorImage< std::complex<float> > > ( argv[1] ); + bool test7 = CompareVectorComplex < otb::VectorImage< std::complex<float> > >( imageRef , image7 ); + std::cout<< "Test 7 : "<<test7<<std::endl; + + // vector<complex> --> vector<real> + otb::VectorImage< int >::Pointer image8 = + Cross < otb::VectorImage< int > > ( image7 ); + bool test8 = CompareVectorReal < otb::VectorImage< int > >( imageRef , image8 ); + std::cout<< "Test 8 : "<<test8<<std::endl; + image8=nullptr; + + // vector<complex> --> vector<complex> + otb::VectorImage< std::complex<int> >::Pointer image9 = + Cross < otb::VectorImage< std::complex<int> > > ( image7 ); + bool test9 = CompareVectorComplex < otb::VectorImage< std::complex<int> > >( imageRef , image9 ); + std::cout<< "Test 9 : "<<test9<<std::endl; + image9=nullptr; + + // vector<complex> --> image<real> + otb::Image< int >::Pointer image10 = + Cross < otb::Image< int > > ( image7 ); + bool test10 = CompareImageReal < otb::Image< int > >( imageRef , image10 ); + std::cout<< "Test 10 : "<<test10<<std::endl; + image10=nullptr; + + // vector<complex> --> image<complex> + otb::Image< std::complex<unsigned short> >::Pointer image11 = + Cross < otb::Image< std::complex<unsigned short> > > ( image7 ); + bool test11 = CompareImageComplex < otb::Image< std::complex<unsigned short> > >( imageRef , image11 ); + std::cout<< "Test 11 : "<<test11<<std::endl; + image11=nullptr; + + // image<complex> --> vector<complex> + otb::VectorImage<std::complex<float>>::Pointer image12 = + Cross < otb::Image< std::complex<float> > , otb::VectorImage< std::complex<float>> > ( argv[1] ); + bool test12 = CompareVectorComplex < otb::VectorImage<std::complex<float>> >( imageRef , image12 ); + std::cout<< "Test 12 : "<<test12<<std::endl; + image12 = nullptr; + + // image<complex> --> image<complex> + otb::Image< std::complex< short >>::Pointer image13 = + Cross < otb::Image< std::complex<float> > , otb::Image< std::complex< short >> > ( argv[1] ); + bool test13 = CompareImageComplex < otb::Image< std::complex< short >> >( imageRef , image13 ); + std::cout<< "Test 13 : "<<test13<<std::endl; + image13 = nullptr; + + // image<complex> --> image<real> + otb::Image< int >::Pointer image14 = + Cross < otb::Image< std::complex<float> > , otb::Image< int > > ( argv[1] ); + bool test14 = CompareImageReal < otb::Image< int > >( imageRef , image14 ); + std::cout<< "Test 14 : "<<test14<<std::endl; + image14 = nullptr; + + // image<complex> --> vector<real> + otb::VectorImage< unsigned short >::Pointer image15 = + Cross < otb::Image< std::complex<float> > , otb::VectorImage< unsigned short > > ( argv[1] ); + bool test15 = CompareVectorReal < otb::VectorImage< unsigned short > >( imageRef , image15 ); + std::cout<< "Test 15 : "<<test15<<std::endl; + image15 = nullptr; + + // image<fixedarray<real>> --> image<fixedarray<complex>> + otb::Image< itk::FixedArray < std::complex<float> , 2 > >::Pointer image16 = + Cross < otb::Image< itk::FixedArray < double , 4 > > , + otb::Image< itk::FixedArray < std::complex<float> , 2 > > > ( argv[1] ); + bool test16 = CompareArrayComplex < otb::Image< itk::FixedArray < std::complex<float> , 2 > > >( imageRef , image16 ); + std::cout<< "Test 16 : "<<test16<<std::endl; + + // image<fixedarray<complex>> --> vectorimage<real> + otb::VectorImage< int >::Pointer image17 = + Cross < otb::VectorImage< int > >( image16 ); + bool test17 = CompareVectorReal < otb::VectorImage< int > >( imageRef , image17 ); + std::cout<< "Test 17 : "<<test17<<std::endl; + image17 = nullptr; + + // vector<real> --> image<fixedarray<complex>> + otb::Image< itk::FixedArray < std::complex<float> , 2 > >::Pointer image18 = + Cross < otb::VectorImage< int > , + otb::Image< itk::FixedArray < std::complex<float> , 2 > > > ( argv[1] ); + bool test18 = CompareArrayComplex < otb::Image< itk::FixedArray < std::complex<float> , 2 > > >( imageRef , image18 ); + image18 = nullptr; + std::cout<< "Test 18 : "<<test18<<std::endl; + + if (test1 && test2 && test3 && test4 && test5 &&test6 && test7 && test8 + && test9 && test10 && test11 && test12 && test13 && test14 && test15 + && test16 && test17 && test18 ) + return EXIT_SUCCESS; + return EXIT_FAILURE; +} diff --git a/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx b/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx index b5176d976154edad57bcd2f470a2cff6eb76085c..c5b59f8ef2d62eb790adf085e5c9121db5f28d4a 100644 --- a/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx +++ b/Modules/Filtering/ImageManipulation/test/otbImageManipulationTestDriver.cxx @@ -61,8 +61,6 @@ void RegisterTests() REGISTER_TEST(otbPhaseFunctorTest); REGISTER_TEST(otbShiftScaleVectorImageFilterNew); REGISTER_TEST(otbChangeLabelImageFilter); - REGISTER_TEST(otbClampVectorImageFilterNew); - REGISTER_TEST(otbClampVectorImageFilterTest); REGISTER_TEST(otbPrintableImageFilterNew); REGISTER_TEST(otbShiftScaleImageAdaptorNew); REGISTER_TEST(otbStreamingInnerProductVectorImageFilterNew); @@ -87,6 +85,7 @@ void RegisterTests() REGISTER_TEST(otbMultiplyByScalarImageFilterTest); REGISTER_TEST(otbClampImageFilterNew); REGISTER_TEST(otbClampImageFilterTest); + REGISTER_TEST(otbClampImageFilterConversionTest); REGISTER_TEST(otbConcatenateVectorImageFilter); REGISTER_TEST(otbBinaryImageMinimalBoundingRegionCalculatorNew); REGISTER_TEST(otbVectorRescaleIntensityImageFilterNew); diff --git a/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx b/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx index b7d8de1665289709964b8938b56ab693ee62b93b..41a18d0bb3b611e3eee571932648c0803e92c3aa 100644 --- a/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx +++ b/Modules/Filtering/ImageManipulation/test/otbOneRIBandImageToOneComplexBandImage.cxx @@ -20,7 +20,8 @@ #include "itkMacro.h" -#include "otbOneRIBandImageToOneComplexBandImage.h" +// #include "otbOneRIBandImageToOneComplexBandImage.h" +#include "otbClampImageFilter.h" #include "otbImage.h" #include "otbVectorImage.h" @@ -37,7 +38,7 @@ int otbOneRIBandImageToOneComplexBandImage(int itkNotUsed(argc), char * argv[]) typedef otb::Image<OutputPixelType, 2> OutputImageType; - typedef otb::OneRIBandImageToOneComplexBandImage<InputImageType, OutputImageType> FilterType; + typedef otb::ClampImageFilter<InputImageType, OutputImageType> FilterType; typedef otb::ImageFileReader<InputImageType> ReaderType; typedef otb::ImageFileWriter<OutputImageType> WriterType; diff --git a/Modules/IO/IOXML/include/otbStatisticsXMLFileWriter.txx b/Modules/IO/IOXML/include/otbStatisticsXMLFileWriter.txx index f1d830132a227162ceb539c3435fd8436b085de4..b20416b4d77617e0c23ea967603cbd910489ea5c 100644 --- a/Modules/IO/IOXML/include/otbStatisticsXMLFileWriter.txx +++ b/Modules/IO/IOXML/include/otbStatisticsXMLFileWriter.txx @@ -72,7 +72,7 @@ StatisticsXMLFileWriter<TMeasurementVector> itkExceptionMacro(<<"The XML output FileName is empty, please set the filename via the method SetFileName"); // Check that the right extension is given : expected .xml */ - std::string extension = itksys::SystemTools::GetFilenameLastExtension(m_FileName); + const std::string extension = itksys::SystemTools::GetFilenameLastExtension(m_FileName); if (itksys::SystemTools::LowerCase(extension) != ".xml") { itkExceptionMacro(<<extension diff --git a/Modules/IO/ImageIO/include/otbImageFileReader.txx b/Modules/IO/ImageIO/include/otbImageFileReader.txx index 98a37bf87b51b5caade4258ab231a45b1f39c87a..87cc50b6e38b3de373d20c163872d5898b885666 100644 --- a/Modules/IO/ImageIO/include/otbImageFileReader.txx +++ b/Modules/IO/ImageIO/include/otbImageFileReader.txx @@ -398,18 +398,33 @@ ImageFileReader<TOutputImage, ConvertPixelTraits> { std::string lFileNameOssimKeywordlist = GetDerivedDatasetSourceFileName(m_FileName); + std::string extension = itksys::SystemTools::GetFilenameLastExtension(lFileNameOssimKeywordlist); + std::string attachedGeom = lFileNameOssimKeywordlist.substr( + 0, + lFileNameOssimKeywordlist.size() - extension.size()) + std::string(".geom"); // Update otb Keywordlist ImageKeywordlist otb_kwl; - if (!m_FilenameHelper->ExtGEOMFileNameIsSet()) + + // Case 1: external geom supplied through extended filename + if (m_FilenameHelper->ExtGEOMFileNameIsSet()) { - otb_kwl = ReadGeometryFromImage(lFileNameOssimKeywordlist,!m_FilenameHelper->GetSkipRpcTag()); - otbMsgDevMacro(<< "Loading internal kwl"); + otb_kwl = ReadGeometryFromGEOMFile(m_FilenameHelper->GetExtGEOMFileName()); + otbMsgDevMacro(<< "Loading external kwl: "<< m_FilenameHelper->GetExtGEOMFileName()); } + // Case 2: attached geom (if present) + else if (itksys::SystemTools::FileExists(attachedGeom)) + { + otb_kwl = ReadGeometryFromGEOMFile(attachedGeom); + otbMsgDevMacro(<< "Loading attached kwl"); + } + // Case 3: find an ossimPluginProjection + // Case 4: find an ossimProjection + // Case 5: find RPC tags in TIF else { - otb_kwl = ReadGeometryFromGEOMFile(m_FilenameHelper->GetExtGEOMFileName()); - otbMsgDevMacro(<< "Loading external kwl"); + otb_kwl = ReadGeometryFromImage(lFileNameOssimKeywordlist,!m_FilenameHelper->GetSkipRpcTag()); + otbMsgDevMacro(<< "Loading internal kwl"); } // Don't add an empty ossim keyword list diff --git a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx index 2973a7a8a3a2e251cdef0ffcf55f034eb6b217aa..502438a0d2a4ebb6bc1b85ce59e8e419fb16206a 100644 --- a/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx +++ b/Modules/Learning/Sampling/include/otbPersistentSamplingFilterBase.txx @@ -265,6 +265,11 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage> } this->m_InMemoryOutputs.push_back(tmpContainer); } + + if (oSRS) + { + oSRS->Release(); + } } template <class TInputImage, class TMaskImage> @@ -734,7 +739,7 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage> } const unsigned int nbFeatThread = std::ceil(inLayer.GetFeatureCount(true) / (float) numberOfThreads); - assert(nbFeatThread > 0); + //assert(nbFeatThread > 0); OGRFeatureDefn &layerDefn = inLayer.GetLayerDefn(); ogr::Layer::const_iterator featIt = inLayer.begin(); @@ -807,6 +812,11 @@ PersistentSamplingFilterBase<TInputImage,TMaskImage> OGRFieldDefn fieldDefn(layerDefn.GetFieldDefn(k)); outLayer.CreateField(fieldDefn); } + + if (oSRS) + { + oSRS->Release(); + } } // Add new fields diff --git a/Modules/Learning/Sampling/test/otbImageSampleExtractorFilterTest.cxx b/Modules/Learning/Sampling/test/otbImageSampleExtractorFilterTest.cxx index 138032ea734aad7266bdfb020d54d547be05a9b3..414a7730276e95d4f41392d04c458d9f3af80035 100644 --- a/Modules/Learning/Sampling/test/otbImageSampleExtractorFilterTest.cxx +++ b/Modules/Learning/Sampling/test/otbImageSampleExtractorFilterTest.cxx @@ -129,6 +129,7 @@ int otbImageSampleExtractorFilterUpdate(int argc, char* argv[]) output->CreateLayer( inLayer.GetName(), oSRS, inLayer.GetLayerDefn().GetGeomType()); + oSRS->Release(); otb::ogr::Layer dstLayer = output->GetLayer(0); OGRFieldDefn labelField(classFieldName.c_str(),OFTString); dstLayer.CreateField(labelField, true); diff --git a/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h index d76968ecf1929a8f8034e016c8b13fa2d2ff3bfb..542b29e6f8c65dd98cd919bcf0f363cc8072c193 100644 --- a/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h +++ b/Modules/ThirdParty/OssimPlugins/include/ossim/ossimSarSensorModel.h @@ -238,13 +238,36 @@ public: * \param[in] worldPoint World point to geocode * \param[out] azimuthTime Estimated zero-doppler azimuth time * \param[out] rangeTime Estimated range time + * \param[out] interpSensorPos interpolated ECEF sensor position + * \param[out] interpSensorVel interpolated ECEF sensor velocity * \return True if success, false otherwise. In this case, * azimuthTime and rangeTime will not be modified. */ - /*virtual*/ bool worldToAzimuthRangeTime(const ossimGpt& worldPt, TimeType & azimuthTime, double & rangeTime) const; + /*virtual*/ bool worldToAzimuthRangeTime(const ossimGpt& worldPt, TimeType & azimuthTime, double & rangeTime, ossimEcefPoint & interpSensorPos, ossimEcefVector & interpSensorVel) const; - // TODO: document me - /*virtual*/ void lineSampleToAzimuthRangeTime(const ossimDpt & imPt, TimeType & azimuthTime, double & rangeTime) const; + /** + * This method implement inverse sar geolocation similar to + * worldToLineSample, except that it also returns (y,z) + * coordinates, defined as follows: + * Let n = |sensorPos|, + * ps2 = scalar_product(sensorPos,worldPoint) + * d = distance(sensorPos,worldPoint) + * + * z = n - ps2/n + * y = sqrt(d*d - z*z) + * + * sign of y is furher adapted to be inverted if sensor is left or + * right looking + * + * \param[in] worldPoint World point to geocode + * \param[out] imPt Corresponding estimated image point + * \param[out] y + * \param[out] z + * \return True if success, false otherwise. In this case, + */ + void worldToLineSampleYZ(const ossimGpt& worldPt, ossimDpt& imPt, double & y, double & z) const; + + void lineSampleToAzimuthRangeTime(const ossimDpt & imPt, TimeType & azimuthTime, double & rangeTime) const; // TODO: document me bool autovalidateInverseModelFromGCPs(const double & xtol = 1, const double & ytol = 1, const double azTimeTol = 500, const double &rangeTimeTo=0.0000000001) const; @@ -419,7 +442,8 @@ protected: ProductType theProductType; // GRD/SLC DurationType theAzimuthTimeOffset; // Offset computed double theRangeTimeOffset; // Offset in seconds, computed - + bool theRightLookingFlag; + static const double C; static const unsigned int thePluginVersion; // version of the SarSensorModel plugin diff --git a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp index ac695a2a4b790ebce7671fc7e27c62a954e91098..61e85f63c090b292f148b0019ddef1ac3ec59689 100644 --- a/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp +++ b/Modules/ThirdParty/OssimPlugins/src/ossim/ossimSarSensorModel.cpp @@ -12,7 +12,7 @@ * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. - * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -137,7 +137,8 @@ namespace ossimplugins theRangeResolution(0.), theBistaticCorrectionNeeded(false), theAzimuthTimeOffset(seconds(0)), - theRangeTimeOffset(0.) + theRangeTimeOffset(0.), + theRightLookingFlag(true) {} ossimSarSensorModel::GCPRecordType const& @@ -220,7 +221,58 @@ namespace ossimplugins TimeType azimuthTime; double rangeTime; - const bool success = worldToAzimuthRangeTime(worldPt, azimuthTime, rangeTime); + ossimEcefPoint sensorPos; + ossimEcefVector sensorVel; + + const bool success = worldToAzimuthRangeTime(worldPt, azimuthTime, rangeTime, sensorPos, sensorVel); + + if(!success) + { + imPt.makeNan(); + return; + } + // std::clog << "AzimuthTime: " << azimuthTime << "\n"; + // std::clog << "RangeTime: " << rangeTime << "\n"; + // std::clog << "GRD: " << isGRD() << "\n"; + + // Convert azimuth time to line + azimuthTimeToLine(azimuthTime,imPt.y); + + if(isGRD()) + { + // GRD case + double groundRange(0); + slantRangeToGroundRange(rangeTime*C/2,azimuthTime,groundRange); + // std::clog << "GroundRange: " << groundRange << "\n"; + // std::clog << "TheRangeResolution: " << theRangeResolution << "\n"; + + // Eq 32 p. 31 + // TODO: possible micro-optimization: precompute 1/theRangeResolution, and + // use * + imPt.x = groundRange/theRangeResolution; + } + else + { + // std::clog << "TheNearRangeTime: " << theNearRangeTime << "\n"; + // std::clog << "TheRangeSamplingRate: " << theRangeSamplingRate << "\n"; + // SLC case + // Eq 23 and 24 p. 28 + imPt.x = (rangeTime - theNearRangeTime)*theRangeSamplingRate; + } + } + +void ossimSarSensorModel::worldToLineSampleYZ(const ossimGpt& worldPt, ossimDpt & imPt, double & y, double & z) const + { + // std::clog << "ossimSarSensorModel::worldToLineSample()\n"; + assert(theRangeResolution>0&&"theRangeResolution is null."); + + // First compute azimuth and range time + TimeType azimuthTime; + double rangeTime; + ossimEcefPoint sensorPos; + ossimEcefVector sensorVel; + + const bool success = worldToAzimuthRangeTime(worldPt, azimuthTime, rangeTime,sensorPos,sensorVel); if(!success) { @@ -255,9 +307,35 @@ namespace ossimplugins // Eq 23 and 24 p. 28 imPt.x = (rangeTime - theNearRangeTime)*theRangeSamplingRate; } + + // Now computes Y and Z + ossimEcefPoint inputPt(worldPt); + double NormeS = sqrt(sensorPos[0]*sensorPos[0] + sensorPos[1]*sensorPos[1] + sensorPos[2]*sensorPos[2]); /* distance du radar */ + double PS2 = inputPt[0]*sensorPos[0] + inputPt[1]*sensorPos[1] + inputPt[2]*sensorPos[2]; + + // TODO check for small NormesS to avoid division by zero ? + // Should never happen ... + assert(NormeS>1e-6); + z = NormeS - PS2/NormeS; + + double distance = sqrt((sensorPos[0]-inputPt[0])*(sensorPos[0]-inputPt[0]) + + (sensorPos[1]-inputPt[1])*(sensorPos[1]-inputPt[1]) + + (sensorPos[2]-inputPt[2])*(sensorPos[2]-inputPt[2])); + + y = sqrt(distance*distance - z*z); + + // Check view side and change sign of Y accordingly + if ( (( sensorVel[0] * (sensorPos[1]* inputPt[2] - sensorPos[2]* inputPt[1]) + + sensorVel[1] * (sensorPos[2]* inputPt[0] - sensorPos[0]* inputPt[2]) + + sensorVel[2] * (sensorPos[0]* inputPt[1] - sensorPos[1]* inputPt[0])) > 0) ^ theRightLookingFlag ) + { + y = -y; + } } - bool ossimSarSensorModel::worldToAzimuthRangeTime(const ossimGpt& worldPt, TimeType & azimuthTime, double & rangeTime) const + + +bool ossimSarSensorModel::worldToAzimuthRangeTime(const ossimGpt& worldPt, TimeType & azimuthTime, double & rangeTime, ossimEcefPoint & interpSensorPos, ossimEcefVector & interpSensorVel) const { // std::clog << "ossimSarSensorModel::worldToAzimuthRangeTime()\n"; // First convert lat/lon to ECEF @@ -265,8 +343,6 @@ namespace ossimplugins // Compute zero doppler time TimeType interpTime; - ossimEcefPoint interpSensorPos; - ossimEcefVector interpSensorVel; const bool success = zeroDopplerLookup(inputPt,azimuthTime,interpSensorPos,interpSensorVel); @@ -857,7 +933,9 @@ namespace ossimplugins double estimatedRangeTime; // Estimate times - const bool s1 = this->worldToAzimuthRangeTime(gcpIt->worldPt,estimatedAzimuthTime,estimatedRangeTime); + ossimEcefPoint sensorPos; + ossimEcefVector sensorVel; + const bool s1 = this->worldToAzimuthRangeTime(gcpIt->worldPt,estimatedAzimuthTime,estimatedRangeTime,sensorPos, sensorVel); this->worldToLineSample(gcpIt->worldPt,estimatedImPt); const bool thisSuccess @@ -964,8 +1042,10 @@ namespace ossimplugins TimeType estimatedAzimuthTime; double estimatedRangeTime; + ossimEcefPoint sensorPos; + ossimEcefVector sensorVel; // Estimate times - const bool s1 = this->worldToAzimuthRangeTime(gcpIt->worldPt,estimatedAzimuthTime,estimatedRangeTime); + const bool s1 = this->worldToAzimuthRangeTime(gcpIt->worldPt,estimatedAzimuthTime,estimatedRangeTime, sensorPos, sensorVel); if(s1) { @@ -985,8 +1065,11 @@ namespace ossimplugins TimeType estimatedAzimuthTime; double estimatedRangeTime; + ossimEcefPoint sensorPos; + ossimEcefVector sensorVel; + // Estimate times - const bool s1 = this->worldToAzimuthRangeTime(gcpIt->worldPt,estimatedAzimuthTime,estimatedRangeTime); + const bool s1 = this->worldToAzimuthRangeTime(gcpIt->worldPt,estimatedAzimuthTime,estimatedRangeTime, sensorPos, sensorVel); if(s1) { diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h index f97134cbd1e4eb32f6768168b50eb5cab7c94158..c6317be14289016f5a5f9636b1af864a1d0c969c 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h @@ -592,11 +592,16 @@ public: { \ Image##Type::Pointer ret; \ Parameter* param = GetParameterByKey(parameter); \ - if (dynamic_cast<InputImageParameter*>(param)) \ + InputImageParameter* paramDown = dynamic_cast<InputImageParameter*>(param); \ + ComplexInputImageParameter* paramDownC = dynamic_cast<ComplexInputImageParameter*>(param); \ + if ( paramDown ) \ { \ - InputImageParameter* paramDown = dynamic_cast<InputImageParameter*>(param); \ ret = paramDown->Get##Image(); \ } \ + else if ( paramDownC ) /* Support of ComplexInputImageParameter */ \ + { \ + ret = paramDownC->Get##Image(); \ + } \ return ret; \ } @@ -619,30 +624,16 @@ public: otbGetParameterImageMacro(UInt8RGBImage); otbGetParameterImageMacro(UInt8RGBAImage); - /* Get a complex image value - * - * Can be called for types : - * \li ParameterType_ComplexInputImage - */ - -#define otbGetParameterComplexImageMacro( Image ) \ - Image##Type * GetParameter##Image( std::string parameter ) \ - { \ - Image##Type::Pointer ret; \ - Parameter* param = GetParameterByKey(parameter); \ - ComplexInputImageParameter* paramDown = dynamic_cast<ComplexInputImageParameter*>(param); \ - if (paramDown) \ - { \ - ret = paramDown->Get##Image(); \ - } \ - return ret; \ - } - - otbGetParameterComplexImageMacro(ComplexFloatImage); - otbGetParameterComplexImageMacro(ComplexDoubleImage); + // Complex image + otbGetParameterImageMacro(ComplexInt16Image); + otbGetParameterImageMacro(ComplexInt32Image); + otbGetParameterImageMacro(ComplexFloatImage); + otbGetParameterImageMacro(ComplexDoubleImage); - otbGetParameterComplexImageMacro(ComplexFloatVectorImage); - otbGetParameterComplexImageMacro(ComplexDoubleVectorImage); + otbGetParameterImageMacro(ComplexInt16VectorImage); + otbGetParameterImageMacro(ComplexInt32VectorImage); + otbGetParameterImageMacro(ComplexFloatVectorImage); + otbGetParameterImageMacro(ComplexDoubleVectorImage); /* Get an image list value * diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.h index 1fa00dd77d70660769bdd48e0031ac0d77d8e368..264967e376a209e0bf36929e4f4960b2e8cc5490 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.h +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.h @@ -60,12 +60,37 @@ public: ComplexFloatVectorImageType* GetImage(); /** Get the input image as XXXImageType */ + ComplexInt16ImageType* GetComplexInt16Image(); + ComplexInt32ImageType* GetComplexInt32Image(); ComplexFloatImageType* GetComplexFloatImage(); ComplexDoubleImageType* GetComplexDoubleImage(); + ComplexInt16VectorImageType* GetComplexInt16VectorImage(); + ComplexInt32VectorImageType* GetComplexInt32VectorImage(); ComplexFloatVectorImageType* GetComplexFloatVectorImage(); ComplexDoubleVectorImageType* GetComplexDoubleVectorImage(); +/* Support for ComplexInputImageParameter. This has been done to support +the macro otbGetParameterImageMacro of otbWrapperApplication.h */ + UInt8ImageType* GetUInt8Image(); + UInt16ImageType* GetUInt16Image(); + Int16ImageType* GetInt16Image(); + UInt32ImageType* GetUInt32Image(); + Int32ImageType* GetInt32Image(); + FloatImageType* GetFloatImage(); + DoubleImageType* GetDoubleImage(); + + UInt8VectorImageType* GetUInt8VectorImage(); + UInt16VectorImageType* GetUInt16VectorImage(); + Int16VectorImageType* GetInt16VectorImage(); + UInt32VectorImageType* GetUInt32VectorImage(); + Int32VectorImageType* GetInt32VectorImage(); + FloatVectorImageType* GetFloatVectorImage(); + DoubleVectorImageType* GetDoubleVectorImage(); + + UInt8RGBImageType* GetUInt8RGBImage(); + UInt8RGBAImageType* GetUInt8RGBAImage(); + /** Get the input image as templated image type. */ template <class TImageType> TImageType* GetImage(); @@ -81,15 +106,6 @@ public: template <class TComplexInputImage, class TOutputImage> TOutputImage* CastImage(); - /** Cast an image to an image of the same type - * Image to Image, VectorImage to VectorImage, RGBAImage to RGBAImage. */ - template <class TComplexInputImage, class TOutputImage> - TOutputImage* SimpleCastImage(); - - /** Cast an image to a vector image. */ - template <class TComplexInputImage, class TOutputImage> - TOutputImage* CastVectorImageFromImage(); - bool HasValue() const ITK_OVERRIDE; void ClearValue() ITK_OVERRIDE; @@ -107,9 +123,6 @@ protected: /** Readers typedefs */ - typedef otb::ImageFileReader<ComplexFloatImageType> ComplexFloatReaderType; - typedef otb::ImageFileReader<ComplexDoubleImageType> ComplexDoubleReaderType; - typedef otb::ImageFileReader<ComplexFloatVectorImageType> ComplexFloatVectorReaderType; typedef otb::ImageFileReader<ComplexDoubleVectorImageType> ComplexDoubleVectorReaderType; @@ -128,33 +141,6 @@ private: }; // End class ComplexInputImage Parameter - -// template specializations of CastImage<> should be declared in header -// so that the linker knows they exist when building OTB Applications - -#define otbDefineCastImageMacro(ComplexInputImageType, OutputImageType) \ - template<> OutputImageType * \ - ComplexInputImageParameter::CastImage<ComplexInputImageType , OutputImageType>(); \ - -#define otbGenericDefineCastImageMacro(ComplexInputImageType, prefix) \ - otbDefineCastImageMacro(ComplexInputImageType, ComplexFloat##prefix##ImageType) \ - otbDefineCastImageMacro(ComplexInputImageType, ComplexDouble##prefix##ImageType) - - -/********************************************************************* -********************** Image -> Image -**********************************************************************/ - - otbGenericDefineCastImageMacro(ComplexFloatImageType, ) - otbGenericDefineCastImageMacro(ComplexDoubleImageType, ) - - -/********************************************************************* -********************** VectorImage -> VectorImage -**********************************************************************/ - otbGenericDefineCastImageMacro(ComplexFloatVectorImageType, Vector) - otbGenericDefineCastImageMacro(ComplexDoubleVectorImageType, Vector) - } // End namespace Wrapper } // End namespace otb diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.txx b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.txx index 774dfdbf789b8cdb48252f76e7aad13bba90399c..92e8dfd32e135ecc522a178f90a2be8fd3e1386a 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.txx +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexInputImageParameter.txx @@ -24,8 +24,9 @@ #include "otbWrapperComplexInputImageParameter.h" #include "itkUnaryFunctorImageFilter.h" -#include "itkCastImageFilter.h" -#include "otbImageToVectorImageCastFilter.h" +// #include "itkCastImageFilter.h" +// #include "otbImageToVectorImageCastFilter.h" +#include "otbClampImageFilter.h" namespace otb { @@ -91,7 +92,15 @@ ComplexInputImageParameter::GetImage() } else { - if (dynamic_cast<ComplexFloatVectorImageType*>(m_Image.GetPointer())) + if (dynamic_cast<ComplexInt16VectorImageType*>(m_Image.GetPointer())) + { + return CastImage<ComplexInt16VectorImageType, TOutputImage>(); + } + else if (dynamic_cast<ComplexInt32VectorImageType*>(m_Image.GetPointer())) + { + return CastImage<ComplexInt32VectorImageType, TOutputImage>(); + } + else if (dynamic_cast<ComplexFloatVectorImageType*>(m_Image.GetPointer())) { return CastImage<ComplexFloatVectorImageType, TOutputImage>(); } @@ -99,6 +108,14 @@ ComplexInputImageParameter::GetImage() { return CastImage<ComplexDoubleVectorImageType, TOutputImage>(); } + else if (dynamic_cast<ComplexInt16ImageType*>(m_Image.GetPointer())) + { + return CastImage<ComplexInt16ImageType, TOutputImage>(); + } + else if (dynamic_cast<ComplexInt32ImageType*>(m_Image.GetPointer())) + { + return CastImage<ComplexInt32ImageType, TOutputImage>(); + } else if (dynamic_cast<ComplexFloatImageType*>(m_Image.GetPointer())) { return CastImage<ComplexFloatImageType, TOutputImage>(); @@ -119,38 +136,10 @@ ComplexInputImageParameter::GetImage() template <class TComplexInputImage, class TOutputImage> TOutputImage* ComplexInputImageParameter::CastImage() -{ - itkExceptionMacro("Cast from "<<typeid(TComplexInputImage).name() - <<" to "<<typeid(TOutputImage).name()<<" not authorized."); -} - - -template <class TComplexInputImage, class TOutputImage> -TOutputImage* -ComplexInputImageParameter::SimpleCastImage() -{ - TComplexInputImage* realComplexInputImage = dynamic_cast<TComplexInputImage*>(m_Image.GetPointer()); - - typedef itk::CastImageFilter<TComplexInputImage, TOutputImage> CasterType; - typename CasterType::Pointer caster = CasterType::New(); - - caster->SetInput(realComplexInputImage); - caster->UpdateOutputInformation(); - - m_Image = caster->GetOutput(); - m_Caster = caster; - - return caster->GetOutput(); -} - - -template <class TComplexInputImage, class TOutputImage> -TOutputImage* -ComplexInputImageParameter::CastVectorImageFromImage() { TComplexInputImage* realComplexInputImage = dynamic_cast<TComplexInputImage*>(m_Image.GetPointer()); - typedef ImageToVectorImageCastFilter<TComplexInputImage, TOutputImage> CasterType; + typedef ClampImageFilter<TComplexInputImage, TOutputImage> CasterType; typename CasterType::Pointer caster = CasterType::New(); caster->SetInput(realComplexInputImage); @@ -160,6 +149,8 @@ ComplexInputImageParameter::CastVectorImageFromImage() m_Caster = caster; return caster->GetOutput(); + // itkExceptionMacro("Cast from "<<typeid(TComplexInputImage).name() + // <<" to "<<typeid(TOutputImage).name()<<" not authorized."); } template <class TComplexInputImage> diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h index 371c4d416691d36e3e07ffe50ea69c1580c20284..0613816b47f09f9c38ceafa4ad9fccbedea2582e 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperComplexOutputImageParameter.h @@ -122,23 +122,18 @@ protected: template <class TInputVectorImageType> void SwitchVectorImageWrite(); - //FloatVectorImageType::Pointer m_Image; ImageBaseType::Pointer m_Image; std::string m_FileName; ComplexImagePixelType m_ComplexPixelType; ComplexImagePixelType m_DefaultComplexPixelType; - typedef otb::ImageFileWriter<ComplexFloatImageType> ComplexFloatWriterType; - typedef otb::ImageFileWriter<ComplexDoubleImageType> ComplexDoubleWriterType; - - + typedef otb::ImageFileWriter<ComplexInt16VectorImageType> ComplexVectorInt16WriterType; + typedef otb::ImageFileWriter<ComplexInt32VectorImageType> ComplexVectorInt32WriterType; typedef otb::ImageFileWriter<ComplexFloatVectorImageType> ComplexVectorFloatWriterType; typedef otb::ImageFileWriter<ComplexDoubleVectorImageType> ComplexVectorDoubleWriterType; - - ComplexFloatWriterType::Pointer m_ComplexFloatWriter; - ComplexDoubleWriterType::Pointer m_ComplexDoubleWriter; - + ComplexVectorInt16WriterType::Pointer m_ComplexVectorInt16Writer; + ComplexVectorInt32WriterType::Pointer m_ComplexVectorInt32Writer; ComplexVectorFloatWriterType::Pointer m_ComplexVectorFloatWriter; ComplexVectorDoubleWriterType::Pointer m_ComplexVectorDoubleWriter; diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h index 6ff36eedeed7f32c1382aa06be580d2904741967..3f83839de104e5bb536c821d9efa2573d13e8890 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.h @@ -80,6 +80,16 @@ public: UInt8RGBImageType* GetUInt8RGBImage(); UInt8RGBAImageType* GetUInt8RGBAImage(); + // Complex image + ComplexInt16ImageType* GetComplexInt16Image(); + ComplexInt32ImageType* GetComplexInt32Image(); + ComplexFloatImageType* GetComplexFloatImage(); + ComplexDoubleImageType* GetComplexDoubleImage(); + + ComplexInt16VectorImageType* GetComplexInt16VectorImage(); + ComplexInt32VectorImageType* GetComplexInt32VectorImage(); + ComplexFloatVectorImageType* GetComplexFloatVectorImage(); + ComplexDoubleVectorImageType* GetComplexDoubleVectorImage(); /** Get the input image as templated image type. */ template <class TImageType> @@ -97,17 +107,6 @@ public: template <class TInputImage, class TOutputImage> TOutputImage* CastImage(); - /** Cast an image to an image of the same type - * Image to Image, VectorImage to VectorImage, RGBAImage to RGBAImage. */ - template <class TInputImage, class TOutputImage> - TOutputImage* SimpleCastImage(); - - - /** Cast an image to a vector image. */ - template <class TInputImage, class TOutputImage> - TOutputImage* CastVectorImageFromImage(); - - bool HasValue() const ITK_OVERRIDE; void ClearValue() ITK_OVERRIDE; @@ -145,6 +144,17 @@ protected: typedef otb::ImageFileReader<UInt8RGBImageType> UInt8RGBReaderType; typedef otb::ImageFileReader<UInt8RGBAImageType> UInt8RGBAReaderType; + // Complex + typedef otb::ImageFileReader<ComplexInt16ImageType> ComplexInt16ReaderType; + typedef otb::ImageFileReader<ComplexInt32ImageType> ComplexInt32ReaderType; + typedef otb::ImageFileReader<ComplexFloatImageType> ComplexFloatReaderType; + typedef otb::ImageFileReader<ComplexDoubleImageType> ComplexDoubleReaderType; + + typedef otb::ImageFileReader<ComplexInt16VectorImageType> ComplexInt16VectorReaderType; + typedef otb::ImageFileReader<ComplexInt32VectorImageType> ComplexInt32VectorReaderType; + typedef otb::ImageFileReader<ComplexFloatVectorImageType> ComplexFloatVectorReaderType; + typedef otb::ImageFileReader<ComplexDoubleVectorImageType> ComplexDoubleVectorReaderType; + itk::ProcessObject::Pointer m_Reader; itk::ProcessObject::Pointer m_Caster; @@ -160,63 +170,6 @@ private: }; // End class InputImage Parameter - -// template specializations of CastImage<> should be declared in header -// so that the linker knows they exist when building OTB Applications - -#define otbDeclareCastImageMacro(InputImageType, OutputImageType) \ - template<> OTBApplicationEngine_EXPORT OutputImageType * \ - InputImageParameter::CastImage<InputImageType , OutputImageType>(); \ - -#define otbGenericDeclareCastImageMacro(InputImageType, prefix) \ - otbDeclareCastImageMacro(InputImageType, UInt8##prefix##ImageType) \ - otbDeclareCastImageMacro(InputImageType, UInt16##prefix##ImageType) \ - otbDeclareCastImageMacro(InputImageType, Int16##prefix##ImageType) \ - otbDeclareCastImageMacro(InputImageType, UInt32##prefix##ImageType) \ - otbDeclareCastImageMacro(InputImageType, Int32##prefix##ImageType) \ - otbDeclareCastImageMacro(InputImageType, Float##prefix##ImageType) \ - otbDeclareCastImageMacro(InputImageType, Double##prefix##ImageType) - - -/********************************************************************* -********************** Image -> Image -**********************************************************************/ -otbGenericDeclareCastImageMacro(UInt8ImageType, ) -otbGenericDeclareCastImageMacro(Int16ImageType, ) -otbGenericDeclareCastImageMacro(UInt16ImageType, ) -otbGenericDeclareCastImageMacro(Int32ImageType, ) -otbGenericDeclareCastImageMacro(UInt32ImageType, ) -otbGenericDeclareCastImageMacro(FloatImageType, ) -otbGenericDeclareCastImageMacro(DoubleImageType, ) - - -/********************************************************************* -********************** VectorImage -> VectorImage -**********************************************************************/ -otbGenericDeclareCastImageMacro(UInt8VectorImageType, Vector) -otbGenericDeclareCastImageMacro(Int16VectorImageType, Vector) -otbGenericDeclareCastImageMacro(UInt16VectorImageType, Vector) -otbGenericDeclareCastImageMacro(Int32VectorImageType, Vector) -otbGenericDeclareCastImageMacro(UInt32VectorImageType, Vector) -otbGenericDeclareCastImageMacro(FloatVectorImageType, Vector) -otbGenericDeclareCastImageMacro(DoubleVectorImageType, Vector) - - -/********************************************************************* -********************** Image -> VectorImage -**********************************************************************/ -otbGenericDeclareCastImageMacro(UInt8ImageType, Vector) -otbGenericDeclareCastImageMacro(Int16ImageType, Vector) -otbGenericDeclareCastImageMacro(UInt16ImageType, Vector) -otbGenericDeclareCastImageMacro(Int32ImageType, Vector) -otbGenericDeclareCastImageMacro(UInt32ImageType, Vector) -otbGenericDeclareCastImageMacro(FloatImageType, Vector) -otbGenericDeclareCastImageMacro(DoubleImageType, Vector) - -#undef otbDeclareCastImageMacro -#undef otbGenericDeclareCastImageMacro - - } // End namespace Wrapper } // End namespace otb diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx index 9db0e6140868eb635b115f0b46627f956615d178..74e7385133261080cf1e05a831fbac8608f94abe 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperInputImageParameter.txx @@ -24,8 +24,7 @@ #include "otbWrapperInputImageParameter.h" #include "itkUnaryFunctorImageFilter.h" -#include "itkCastImageFilter.h" -#include "otbImageToVectorImageCastFilter.h" +#include "otbClampImageFilter.h" namespace otb { @@ -138,6 +137,22 @@ InputImageParameter::GetImage() { return CastImage<DoubleImageType, TImageType> (); } + else if (dynamic_cast<ComplexInt16ImageType*>(m_Image.GetPointer())) + { + return CastImage<ComplexInt16ImageType, TImageType>(); + } + else if (dynamic_cast<ComplexInt32ImageType*>(m_Image.GetPointer())) + { + return CastImage<ComplexInt32ImageType, TImageType>(); + } + else if (dynamic_cast<ComplexFloatImageType*>(m_Image.GetPointer())) + { + return CastImage<ComplexFloatImageType, TImageType>(); + } + else if (dynamic_cast<ComplexDoubleImageType*>(m_Image.GetPointer())) + { + return CastImage<ComplexDoubleImageType, TImageType>(); + } else if (dynamic_cast<UInt8VectorImageType*> (m_Image.GetPointer())) { return CastImage<UInt8VectorImageType, TImageType> (); @@ -174,6 +189,22 @@ InputImageParameter::GetImage() { return CastImage<UInt8RGBImageType, TImageType> (); } + else if (dynamic_cast<ComplexInt16VectorImageType*>(m_Image.GetPointer())) + { + return CastImage<ComplexInt16VectorImageType, TImageType>(); + } + else if (dynamic_cast<ComplexInt32VectorImageType*>(m_Image.GetPointer())) + { + return CastImage<ComplexInt32VectorImageType, TImageType>(); + } + else if (dynamic_cast<ComplexFloatVectorImageType*>(m_Image.GetPointer())) + { + return CastImage<ComplexFloatVectorImageType, TImageType>(); + } + else if (dynamic_cast<ComplexDoubleVectorImageType*>(m_Image.GetPointer())) + { + return CastImage<ComplexDoubleVectorImageType, TImageType>(); + } else { #if INPUT_IMAGE_PARAMETER_GET_IMAGE_EXCEPTION @@ -190,14 +221,6 @@ InputImageParameter::GetImage() template <class TInputImage, class TOutputImage> TOutputImage* InputImageParameter::CastImage() -{ - itkExceptionMacro("Cast from "<<typeid(TInputImage).name()<<" to "<<typeid(TOutputImage).name()<<" not authorized."); -} - - -template <class TInputImage, class TOutputImage> -TOutputImage* -InputImageParameter::SimpleCastImage() { if ( dynamic_cast<TOutputImage*> (m_Image.GetPointer()) ) { @@ -207,7 +230,7 @@ InputImageParameter::SimpleCastImage() { TInputImage* realInputImage = dynamic_cast<TInputImage*>(m_Image.GetPointer()); - typedef itk::CastImageFilter<TInputImage, TOutputImage> CasterType; + typedef ClampImageFilter<TInputImage, TOutputImage> CasterType; typename CasterType::Pointer caster = CasterType::New(); caster->SetInput(realInputImage); @@ -217,29 +240,10 @@ InputImageParameter::SimpleCastImage() m_Caster = caster; return caster->GetOutput(); - } + } + // itkExceptionMacro("Cast from "<<typeid(TInputImage).name()<<" to "<<typeid(TOutputImage).name()<<" not authorized."); } - -template <class TInputImage, class TOutputImage> -TOutputImage* -InputImageParameter::CastVectorImageFromImage() -{ - TInputImage* realInputImage = dynamic_cast<TInputImage*>(m_Image.GetPointer()); - - typedef ImageToVectorImageCastFilter<TInputImage, TOutputImage> CasterType; - typename CasterType::Pointer caster = CasterType::New(); - - caster->SetInput(realInputImage); - caster->UpdateOutputInformation(); - - m_Image = caster->GetOutput(); - m_Caster = caster; - - return caster->GetOutput(); -} - - template <class TInputImage> void InputImageParameter::SetImage(TInputImage* image) diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h index b420299ff6b707f8ccbed39577b488684e527fae..fd0c392b706d11977caa60031c601b046860210c 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperOutputImageParameter.h @@ -119,9 +119,6 @@ protected: /** Destructor */ ~OutputImageParameter() ITK_OVERRIDE; - template <class TInputImageType> - void SwitchImageWrite(); - template <class TInputVectorImageType> void SwitchVectorImageWrite(); @@ -137,14 +134,6 @@ protected: ImagePixelType m_PixelType; ImagePixelType m_DefaultPixelType; - typedef otb::ImageFileWriter<UInt8ImageType> UInt8WriterType; - typedef otb::ImageFileWriter<Int16ImageType> Int16WriterType; - typedef otb::ImageFileWriter<UInt16ImageType> UInt16WriterType; - typedef otb::ImageFileWriter<Int32ImageType> Int32WriterType; - typedef otb::ImageFileWriter<UInt32ImageType> UInt32WriterType; - typedef otb::ImageFileWriter<FloatImageType> FloatWriterType; - typedef otb::ImageFileWriter<DoubleImageType> DoubleWriterType; - typedef otb::ImageFileWriter<UInt8VectorImageType> VectorUInt8WriterType; typedef otb::ImageFileWriter<Int16VectorImageType> VectorInt16WriterType; typedef otb::ImageFileWriter<UInt16VectorImageType> VectorUInt16WriterType; @@ -156,13 +145,10 @@ protected: typedef otb::ImageFileWriter<UInt8RGBAImageType> RGBAUInt8WriterType; typedef otb::ImageFileWriter<UInt8RGBImageType> RGBUInt8WriterType; - UInt8WriterType::Pointer m_UInt8Writer; - Int16WriterType::Pointer m_Int16Writer; - UInt16WriterType::Pointer m_UInt16Writer; - Int32WriterType::Pointer m_Int32Writer; - UInt32WriterType::Pointer m_UInt32Writer; - FloatWriterType::Pointer m_FloatWriter; - DoubleWriterType::Pointer m_DoubleWriter; + typedef otb::ImageFileWriter<ComplexInt16VectorImageType> ComplexVectorInt16WriterType; + typedef otb::ImageFileWriter<ComplexInt32VectorImageType> ComplexVectorInt32WriterType; + typedef otb::ImageFileWriter<ComplexFloatVectorImageType> ComplexVectorFloatWriterType; + typedef otb::ImageFileWriter<ComplexDoubleVectorImageType> ComplexVectorDoubleWriterType; VectorUInt8WriterType::Pointer m_VectorUInt8Writer; VectorInt16WriterType::Pointer m_VectorInt16Writer; @@ -175,6 +161,11 @@ protected: RGBUInt8WriterType::Pointer m_RGBUInt8Writer; RGBAUInt8WriterType::Pointer m_RGBAUInt8Writer; + ComplexVectorInt16WriterType::Pointer m_ComplexVectorInt16Writer; + ComplexVectorInt32WriterType::Pointer m_ComplexVectorInt32Writer; + ComplexVectorFloatWriterType::Pointer m_ComplexVectorFloatWriter; + ComplexVectorDoubleWriterType::Pointer m_ComplexVectorDoubleWriter; + private: OutputImageParameter(const Parameter &); //purposely not implemented void operator =(const Parameter&); //purposely not implemented diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h index 63dafb639b432a1e3508084cdcc860b7c9efc7ae..8a31e1f2c45040b1a7c69334311bdbc762c4c2fa 100644 --- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h +++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperTypes.h @@ -77,10 +77,16 @@ typedef enum ImagePixelType_uint32, ImagePixelType_float, ImagePixelType_double, + ImagePixelType_cint16, + ImagePixelType_cint32, + ImagePixelType_cfloat, + ImagePixelType_cdouble, } ImagePixelType; typedef enum { + ComplexImagePixelType_int16, + ComplexImagePixelType_int32, ComplexImagePixelType_float, ComplexImagePixelType_double, } ComplexImagePixelType; @@ -119,13 +125,19 @@ typedef otb::VectorImage<double> DoubleVectorImageType; typedef otb::Image< itk::RGBPixel<unsigned char> > UInt8RGBImageType; typedef otb::Image< itk::RGBAPixel<unsigned char> > UInt8RGBAImageType; +typedef std::complex<short> Int16ComplexPixelType; +typedef std::complex<int> Int32ComplexPixelType; typedef std::complex<float> FloatComplexPixelType; typedef std::complex<double> DoubleComplexPixelType; -// Complex Image Type (first : double and float) +// Complex Image Type +typedef otb::Image< Int16ComplexPixelType, 2 > ComplexInt16ImageType; +typedef otb::Image< Int32ComplexPixelType, 2 > ComplexInt32ImageType; typedef otb::Image< FloatComplexPixelType, 2 > ComplexFloatImageType; typedef otb::Image< DoubleComplexPixelType, 2 > ComplexDoubleImageType; +typedef otb::VectorImage< Int16ComplexPixelType, 2 > ComplexInt16VectorImageType; +typedef otb::VectorImage< Int32ComplexPixelType, 2 > ComplexInt32VectorImageType; typedef otb::VectorImage<FloatComplexPixelType, 2 > ComplexFloatVectorImageType; typedef otb::VectorImage< DoubleComplexPixelType, 2 > ComplexDoubleVectorImageType; diff --git a/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt b/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt index 343f9db8354ca588189b10f7fcf625413225f1e4..45d0427a4910b17dba0d51cbbce91ebc67492940 100644 --- a/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt +++ b/Modules/Wrappers/ApplicationEngine/src/CMakeLists.txt @@ -31,13 +31,6 @@ set( OTBApplicationEngine_SRC otbWrapperInputFilenameListParameter.cxx otbWrapperOutputImageParameter.cxx otbWrapperInputImageParameter.cxx - otbWrapperInputImageParameterUInt8.cxx - otbWrapperInputImageParameterInt16.cxx - otbWrapperInputImageParameterUInt16.cxx - otbWrapperInputImageParameterInt32.cxx - otbWrapperInputImageParameterUInt32.cxx - otbWrapperInputImageParameterFloat.cxx - otbWrapperInputImageParameterDouble.cxx otbWrapperParameterKey.cxx otbWrapperDocExampleStructure.cxx otbWrapperInputVectorDataParameter.cxx diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexInputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexInputImageParameter.cxx index 6c59ad4c83753feeacf012655642eba680586279..22629f407458a925afa397824fa678456a9878d6 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexInputImageParameter.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexInputImageParameter.cxx @@ -73,14 +73,18 @@ ComplexInputImageParameter::GetImage() return this->GetImage< image##Type > (); \ } +otbGetImageMacro(ComplexInt16Image); +otbGetImageMacro(ComplexInt32Image); otbGetImageMacro(ComplexFloatImage); otbGetImageMacro(ComplexDoubleImage); +otbGetImageMacro(ComplexInt16VectorImage); +otbGetImageMacro(ComplexInt32VectorImage); otbGetImageMacro(ComplexFloatVectorImage); otbGetImageMacro(ComplexDoubleVectorImage); -#define otbCastImageMacro(ComplexInputImageType, OutputImageType, theMethod) \ +/*#define otbCastImageMacro(ComplexInputImageType, OutputImageType, theMethod) \ template<> OutputImageType * \ ComplexInputImageParameter::CastImage<ComplexInputImageType , OutputImageType>() \ { \ @@ -89,22 +93,22 @@ otbGetImageMacro(ComplexDoubleVectorImage); #define otbGenericCastImageMacro(ComplexInputImageType, theMethod, prefix) \ otbCastImageMacro(ComplexInputImageType, ComplexFloat##prefix##ImageType, theMethod) \ - otbCastImageMacro(ComplexInputImageType, ComplexDouble##prefix##ImageType, theMethod) + otbCastImageMacro(ComplexInputImageType, ComplexDouble##prefix##ImageType, theMethod)*/ -/********************************************************************* +/******************************************************************** ********************** Image -> Image -**********************************************************************/ +*********************************************************************/ - otbGenericCastImageMacro(ComplexFloatImageType, SimpleCastImage, ) - otbGenericCastImageMacro(ComplexDoubleImageType, SimpleCastImage, ) +// otbGenericCastImageMacro(ComplexFloatImageType, SimpleCastImage, ) +// otbGenericCastImageMacro(ComplexDoubleImageType, SimpleCastImage, ) /********************************************************************* ********************** VectorImage -> VectorImage **********************************************************************/ - otbGenericCastImageMacro(ComplexFloatVectorImageType, SimpleCastImage, Vector) - otbGenericCastImageMacro(ComplexDoubleVectorImageType, SimpleCastImage, Vector) +// otbGenericCastImageMacro(ComplexFloatVectorImageType, SimpleCastImage, Vector) +// otbGenericCastImageMacro(ComplexDoubleVectorImageType, SimpleCastImage, Vector) void ComplexInputImageParameter::SetImage(ComplexFloatVectorImageType* image) @@ -133,6 +137,38 @@ ComplexInputImageParameter::ClearValue() m_UseFilename = true; } +/* Support for ComplexInputImageParameter. This has been done to support +the macro otbGetParameterImageMacro of otbWrapperApplication.h */ +#define otbGetFalseImageMacro(image) \ + image##Type * \ + ComplexInputImageParameter::Get##image () \ + { \ + return nullptr; \ + } + +otbGetFalseImageMacro(DoubleImage); +otbGetFalseImageMacro(DoubleVectorImage); + +otbGetFalseImageMacro(FloatImage); +otbGetFalseImageMacro(FloatVectorImage); + +otbGetFalseImageMacro(Int16Image); +otbGetFalseImageMacro(Int16VectorImage); + +otbGetFalseImageMacro(UInt16Image); +otbGetFalseImageMacro(UInt16VectorImage); + +otbGetFalseImageMacro(Int32Image); +otbGetFalseImageMacro(Int32VectorImage); + +otbGetFalseImageMacro(UInt32Image); +otbGetFalseImageMacro(UInt32VectorImage); + +otbGetFalseImageMacro(UInt8Image); +otbGetFalseImageMacro(UInt8VectorImage); + +otbGetFalseImageMacro(UInt8RGBImage); +otbGetFalseImageMacro(UInt8RGBAImage); } } diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx index 64ef3657181d767341ce804d642374d6ed7b6a27..6d86118c4591da5f17e8a932356fbede5d2cdc3d 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperComplexOutputImageParameter.cxx @@ -20,8 +20,7 @@ #include "otbWrapperComplexOutputImageParameter.h" #include "itkUnaryFunctorImageFilter.h" -#include "itkCastImageFilter.h" -#include "itkVectorCastImageFilter.h" +#include "otbClampImageFilter.h" #ifdef OTB_USE_MPI @@ -59,6 +58,16 @@ ComplexOutputImageParameter::ConvertPixelTypeToString(ComplexImagePixelType type std::string ret; switch(type) { + case ComplexImagePixelType_int16: + { + ret = "cint16"; + break; + } + case ComplexImagePixelType_int32: + { + ret = "cint32"; + break; + } case ComplexImagePixelType_float: { ret = "cfloat"; @@ -76,7 +85,11 @@ ComplexOutputImageParameter::ConvertPixelTypeToString(ComplexImagePixelType type bool ComplexOutputImageParameter::ConvertStringToPixelType(const std::string &value, ComplexImagePixelType &type) { - if (value == "cfloat") + if (value == "cint16") + type = ComplexImagePixelType_int16; + if (value == "cint32") + type = ComplexImagePixelType_int32; + else if (value == "cfloat") type = ComplexImagePixelType_float; else if (value == "cdouble") type = ComplexImagePixelType_double; @@ -87,16 +100,15 @@ ComplexOutputImageParameter::ConvertStringToPixelType(const std::string &value, void ComplexOutputImageParameter::InitializeWriters() { - m_ComplexFloatWriter = ComplexFloatWriterType::New(); - m_ComplexDoubleWriter = ComplexDoubleWriterType::New(); - + m_ComplexVectorInt16Writer = ComplexVectorInt16WriterType::New(); + m_ComplexVectorInt32Writer = ComplexVectorInt32WriterType::New(); m_ComplexVectorFloatWriter = ComplexVectorFloatWriterType::New(); m_ComplexVectorDoubleWriter = ComplexVectorDoubleWriterType::New(); } template <typename TInput, typename TOutput> void CastAndWriteImage(itk::ImageBase<2> * in, otb::ImageFileWriter<TOutput> * writer, const std::string & filename, const unsigned int & ramValue) { - typedef itk::CastImageFilter<TInput, TOutput> ClampFilterType; + typedef ClampImageFilter<TInput, TOutput> ClampFilterType; typename ClampFilterType::Pointer clampFilter = ClampFilterType::New(); clampFilter->SetInput( dynamic_cast<TInput*>(in)); @@ -157,46 +169,58 @@ ComplexOutputImageParameter::SwitchImageWrite() { switch(m_ComplexPixelType ) { - case ComplexImagePixelType_float: + case ComplexImagePixelType_int16: { - CastAndWriteImage<TInputImageType,ComplexFloatImageType>(m_Image,m_ComplexFloatWriter,m_FileName,m_RAMValue); + CastAndWriteImage<TInputImageType,ComplexInt16VectorImageType>( + m_Image , + m_ComplexVectorInt16Writer , + m_FileName , + m_RAMValue ); break; } - case ComplexImagePixelType_double: + case ComplexImagePixelType_int32: { - CastAndWriteImage<TInputImageType,ComplexDoubleImageType>(m_Image,m_ComplexDoubleWriter,m_FileName,m_RAMValue); + CastAndWriteImage<TInputImageType,ComplexInt32VectorImageType>( + m_Image , + m_ComplexVectorInt32Writer , + m_FileName , + m_RAMValue ); break; } - } -} - - -template <class TInputVectorImageType> -void -ComplexOutputImageParameter::SwitchVectorImageWrite() - { - switch(m_ComplexPixelType ) - { case ComplexImagePixelType_float: { - CastAndWriteImage<TInputVectorImageType,ComplexFloatVectorImageType>(m_Image,m_ComplexVectorFloatWriter,m_FileName,m_RAMValue); + CastAndWriteImage<TInputImageType,ComplexFloatVectorImageType>( + m_Image , + m_ComplexVectorFloatWriter , + m_FileName , + m_RAMValue ); break; } case ComplexImagePixelType_double: { - CastAndWriteImage<TInputVectorImageType,ComplexDoubleVectorImageType>(m_Image,m_ComplexVectorDoubleWriter,m_FileName,m_RAMValue); + CastAndWriteImage<TInputImageType,ComplexDoubleVectorImageType>( + m_Image , + m_ComplexVectorDoubleWriter , + m_FileName , + m_RAMValue ); break; } } - } - +} void ComplexOutputImageParameter::Write() { m_Image->UpdateOutputInformation(); - - if (dynamic_cast<ComplexFloatImageType*>(m_Image.GetPointer())) + if (dynamic_cast<ComplexInt16ImageType*>(m_Image.GetPointer())) + { + SwitchImageWrite<ComplexInt16ImageType>(); + } + else if (dynamic_cast<ComplexInt16ImageType*>(m_Image.GetPointer())) + { + SwitchImageWrite<ComplexInt16ImageType>(); + } + else if (dynamic_cast<ComplexFloatImageType*>(m_Image.GetPointer())) { SwitchImageWrite<ComplexFloatImageType>(); } @@ -204,13 +228,21 @@ ComplexOutputImageParameter::Write() { SwitchImageWrite<ComplexDoubleImageType>(); } + else if (dynamic_cast<ComplexInt16VectorImageType*>(m_Image.GetPointer())) + { + SwitchImageWrite<ComplexInt16VectorImageType>(); + } + else if (dynamic_cast<ComplexInt32VectorImageType*>(m_Image.GetPointer())) + { + SwitchImageWrite<ComplexInt32VectorImageType>(); + } else if (dynamic_cast<ComplexFloatVectorImageType*>(m_Image.GetPointer())) { - SwitchVectorImageWrite<ComplexFloatVectorImageType>(); + SwitchImageWrite<ComplexFloatVectorImageType>(); } else if (dynamic_cast<ComplexDoubleVectorImageType*>(m_Image.GetPointer())) { - SwitchVectorImageWrite<ComplexDoubleVectorImageType>(); + SwitchImageWrite<ComplexDoubleVectorImageType>(); } else { @@ -221,33 +253,25 @@ ComplexOutputImageParameter::Write() itk::ProcessObject* ComplexOutputImageParameter::GetWriter() { - int type = 0; - // 0 : image - // 1 : VectorImage - - if ( dynamic_cast<ComplexFloatVectorImageType*>( m_Image.GetPointer()) || - dynamic_cast<ComplexDoubleVectorImageType*>(m_Image.GetPointer())) - { - type = 1; - } - itk::ProcessObject* writer = ITK_NULLPTR; switch ( GetComplexPixelType() ) { + case ComplexImagePixelType_int16: + { + writer = m_ComplexVectorInt16Writer; + } + case ComplexImagePixelType_int32: + { + writer = m_ComplexVectorInt32Writer; + } case ComplexImagePixelType_float: { - if( type == 1 ) writer = m_ComplexVectorFloatWriter; - else - writer = m_ComplexFloatWriter; break; } case ComplexImagePixelType_double: { - if( type == 1 ) writer = m_ComplexVectorDoubleWriter; - else - writer = m_ComplexDoubleWriter; break; } } diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx index f645553e03907713a71ffd57b2dcab6539d88ec5..726f1dbe3ca72c67b825b2a6a385844dbc826319 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperElevationParametersHandler.cxx @@ -57,7 +57,11 @@ void ElevationParametersHandler::AddElevationParameters(Application::Pointer app oss.str(""); oss << key<<".geoid"; app->AddParameter(ParameterType_InputFilename, oss.str(), "Geoid File"); - app->SetParameterDescription(oss.str(),"Use a geoid grid to get the height above the ellipsoid in case there is no DEM available, no coverage for some points or pixels with no_data in the DEM tiles. A version of the geoid can be found on the OTB website (https://git.orfeo-toolbox.org/otb-data.git/blob/HEAD:/Input/DEM/egm96.grd)."); + app->SetParameterDescription(oss.str(),"Use a geoid grid to get the height " + "above the ellipsoid in case there is no DEM available, no coverage for " + "some points or pixels with no_data in the DEM tiles. A version of the " + "geoid can be found on the OTB website" + "(https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb-data/blob/master/Input/DEM/egm96.grd)."); app->MandatoryOff(oss.str()); std::string geoidFromConfig = otb::ConfigurationManager::GetGeoidFile(); diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx index 166ab2956ad5fc46a6bd1df6a1298e3066b4f23f..fe226ef2ffbd7ccb6f588e3926642181c31819ea 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameter.cxx @@ -70,6 +70,17 @@ InputImageParameter::GetImage() otbGetImageMacro(UInt8RGBImage); otbGetImageMacro(UInt8RGBAImage); +otbGetImageAndVectorImageMacro(UInt8); +otbGetImageAndVectorImageMacro(UInt16); +otbGetImageAndVectorImageMacro(UInt32); +otbGetImageAndVectorImageMacro(Int16); +otbGetImageAndVectorImageMacro(Int32); +otbGetImageAndVectorImageMacro(Float); +otbGetImageAndVectorImageMacro(Double); +otbGetImageAndVectorImageMacro(ComplexInt16); +otbGetImageAndVectorImageMacro(ComplexInt32); +otbGetImageAndVectorImageMacro(ComplexFloat); +otbGetImageAndVectorImageMacro(ComplexDouble); void diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterDouble.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterDouble.cxx deleted file mode 100644 index e6a07bc294ff440924d5efa5f42f5634cffd1081..0000000000000000000000000000000000000000 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterDouble.cxx +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2005-2017 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. - */ - -#include "otbWrapperInputImageParameter.h" -#include "itksys/SystemTools.hxx" -#include "otbWrapperTypes.h" -#include "otbWrapperInputImageParameterMacros.h" -#include "otb_boost_string_header.h" - -namespace otb -{ -namespace Wrapper -{ -otbGetImageMacro(DoubleImage); -otbGetImageMacro(DoubleVectorImage) -otbGenericCastImageMacro(DoubleImageType, SimpleCastImage, ) -otbGenericCastImageMacro(DoubleVectorImageType, SimpleCastImage, Vector) -otbGenericCastImageMacro(DoubleImageType, CastVectorImageFromImage, Vector) -} -} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterFloat.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterFloat.cxx deleted file mode 100644 index fda1544048718215b7dd7757d37baeee12fbb6af..0000000000000000000000000000000000000000 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterFloat.cxx +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2005-2017 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. - */ - -#include "otbWrapperInputImageParameter.h" -#include "otbWrapperInputImageParameterMacros.h" -#include "itksys/SystemTools.hxx" -#include "otbWrapperTypes.h" -#include "otb_boost_string_header.h" - -namespace otb -{ -namespace Wrapper -{ -otbGetImageMacro(FloatImage); -otbGetImageMacro(FloatVectorImage) -otbGenericCastImageMacro(FloatImageType, SimpleCastImage, ) -otbGenericCastImageMacro(FloatVectorImageType, SimpleCastImage, Vector) -otbGenericCastImageMacro(FloatImageType, CastVectorImageFromImage, Vector) -} -} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt16.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt16.cxx deleted file mode 100644 index 22f617fce468169f23ed64db00e695902430f127..0000000000000000000000000000000000000000 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt16.cxx +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2005-2017 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. - */ - -#include "otbWrapperInputImageParameter.h" -#include "itksys/SystemTools.hxx" -#include "otbWrapperTypes.h" -#include "otbWrapperInputImageParameterMacros.h" -#include "otb_boost_string_header.h" - -namespace otb -{ -namespace Wrapper -{ -otbGetImageMacro(Int16Image); -otbGetImageMacro(Int16VectorImage) -otbGenericCastImageMacro(Int16ImageType, SimpleCastImage, ) -otbGenericCastImageMacro(Int16VectorImageType, SimpleCastImage, Vector) -otbGenericCastImageMacro(Int16ImageType, CastVectorImageFromImage, Vector) -} -} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt32.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt32.cxx deleted file mode 100644 index ab59107c9e357068ef461bd3b975ec3e16d524b2..0000000000000000000000000000000000000000 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterInt32.cxx +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2005-2017 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. - */ - -#include "otbWrapperInputImageParameter.h" -#include "itksys/SystemTools.hxx" -#include "otbWrapperTypes.h" -#include "otbWrapperInputImageParameterMacros.h" -#include "otb_boost_string_header.h" - -namespace otb -{ -namespace Wrapper -{ -otbGetImageMacro(Int32Image); -otbGetImageMacro(Int32VectorImage) -otbGenericCastImageMacro(Int32ImageType, SimpleCastImage, ) -otbGenericCastImageMacro(Int32VectorImageType, SimpleCastImage, Vector) -otbGenericCastImageMacro(Int32ImageType, CastVectorImageFromImage, Vector) -} -} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterMacros.h b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterMacros.h index 4cc9d4d7ae998e8aec82b0856b8ac6e44dcad377..2f1a7915b4f9b1491fde3ba0f9d77fc004e9e021 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterMacros.h +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterMacros.h @@ -28,22 +28,9 @@ return this->GetImage< image##Type > (); \ } - -#define otbCastImageMacro(InputImageType, OutputImageType, theMethod) \ - template<> OutputImageType * \ - InputImageParameter::CastImage<InputImageType , OutputImageType>() \ - { \ - return this->theMethod<InputImageType , OutputImageType>(); \ - } - -#define otbGenericCastImageMacro(InputImageType, theMethod, prefix) \ - otbCastImageMacro(InputImageType, UInt8##prefix##ImageType, theMethod) \ - otbCastImageMacro(InputImageType, UInt16##prefix##ImageType, theMethod) \ - otbCastImageMacro(InputImageType, Int16##prefix##ImageType, theMethod) \ - otbCastImageMacro(InputImageType, UInt32##prefix##ImageType, theMethod) \ - otbCastImageMacro(InputImageType, Int32##prefix##ImageType, theMethod) \ - otbCastImageMacro(InputImageType, Float##prefix##ImageType, theMethod) \ - otbCastImageMacro(InputImageType, Double##prefix##ImageType, theMethod) +#define otbGetImageAndVectorImageMacro(type) \ + otbGetImageMacro(type##Image); \ + otbGetImageMacro(type##VectorImage); #endif diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt16.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt16.cxx deleted file mode 100644 index c63857e57bd7bfd30fb466f74e9e36bcc1ddeea7..0000000000000000000000000000000000000000 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt16.cxx +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2005-2017 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. - */ - -#include "otbWrapperInputImageParameter.h" -#include "itksys/SystemTools.hxx" -#include "otbWrapperTypes.h" -#include "otbWrapperInputImageParameterMacros.h" -#include "otb_boost_string_header.h" - -namespace otb -{ -namespace Wrapper -{ -otbGetImageMacro(UInt16Image); -otbGetImageMacro(UInt16VectorImage) -otbGenericCastImageMacro(UInt16ImageType, SimpleCastImage, ) -otbGenericCastImageMacro(UInt16VectorImageType, SimpleCastImage, Vector) -otbGenericCastImageMacro(UInt16ImageType, CastVectorImageFromImage, Vector) -} -} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt32.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt32.cxx deleted file mode 100644 index 50fdf0adf18aefe30b7b1efac80f2b5028619565..0000000000000000000000000000000000000000 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt32.cxx +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2005-2017 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. - */ - -#include "otbWrapperInputImageParameter.h" -#include "itksys/SystemTools.hxx" -#include "otbWrapperTypes.h" -#include "otbWrapperInputImageParameterMacros.h" -#include "otb_boost_string_header.h" - -namespace otb -{ -namespace Wrapper -{ -otbGetImageMacro(UInt32Image); -otbGetImageMacro(UInt32VectorImage) -otbGenericCastImageMacro(UInt32ImageType, SimpleCastImage, ) -otbGenericCastImageMacro(UInt32VectorImageType, SimpleCastImage, Vector) -otbGenericCastImageMacro(UInt32ImageType, CastVectorImageFromImage, Vector) -} -} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt8.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt8.cxx deleted file mode 100644 index d388456e4267e8ba0753d54ff05439657d2c2e13..0000000000000000000000000000000000000000 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperInputImageParameterUInt8.cxx +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2005-2017 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. - */ - -#include "otbWrapperInputImageParameter.h" -#include "itksys/SystemTools.hxx" -#include "otbWrapperTypes.h" -#include "otbWrapperInputImageParameterMacros.h" -#include "otb_boost_string_header.h" - -namespace otb -{ -namespace Wrapper -{ -otbGetImageMacro(UInt8Image); -otbGetImageMacro(UInt8VectorImage) -otbGenericCastImageMacro(UInt8ImageType, SimpleCastImage, ) -otbGenericCastImageMacro(UInt8VectorImageType, SimpleCastImage, Vector) -otbGenericCastImageMacro(UInt8ImageType, CastVectorImageFromImage, Vector) -} -} diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx index 2790bdce255aa5d0e8a3f92ab625e274ce48bf10..d0dd6678797767b6f50d61ba0a9667173d1a77e1 100644 --- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx +++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperOutputImageParameter.cxx @@ -20,7 +20,6 @@ #include "otbWrapperOutputImageParameter.h" #include "otbClampImageFilter.h" -#include "otbClampVectorImageFilter.h" #include "otbImageIOFactory.h" #include "itksys/SystemTools.hxx" @@ -94,6 +93,26 @@ std::string OutputImageParameter::ConvertPixelTypeToString(ImagePixelType type) ret = "double"; break; } + case ImagePixelType_cint16: + { + ret = "cint16"; + break; + } + case ImagePixelType_cint32: + { + ret = "cint32"; + break; + } + case ImagePixelType_cfloat: + { + ret = "cfloat"; + break; + } + case ImagePixelType_cdouble: + { + ret = "cdouble"; + break; + } } return ret; } @@ -115,6 +134,14 @@ OutputImageParameter::ConvertStringToPixelType(const std::string &value, ImagePi type = ImagePixelType_float; else if (value == "double") type = ImagePixelType_double; + else if (value == "cint16") + type = ImagePixelType_cint16; + else if (value == "cint32") + type = ImagePixelType_cint32; + else if (value == "cfloat") + type = ImagePixelType_cfloat; + else if (value == "cdouble") + type = ImagePixelType_cdouble; else return false; return true; @@ -122,14 +149,6 @@ OutputImageParameter::ConvertStringToPixelType(const std::string &value, ImagePi void OutputImageParameter::InitializeWriters() { - m_UInt8Writer = UInt8WriterType::New(); - m_Int16Writer = Int16WriterType::New(); - m_UInt16Writer = UInt16WriterType::New(); - m_Int32Writer = Int32WriterType::New(); - m_UInt32Writer = UInt32WriterType::New(); - m_FloatWriter = FloatWriterType::New(); - m_DoubleWriter = DoubleWriterType::New(); - m_VectorUInt8Writer = VectorUInt8WriterType::New(); m_VectorInt16Writer = VectorInt16WriterType::New(); m_VectorUInt16Writer = VectorUInt16WriterType::New(); @@ -140,13 +159,24 @@ void OutputImageParameter::InitializeWriters() m_RGBUInt8Writer = RGBUInt8WriterType::New(); m_RGBAUInt8Writer = RGBAUInt8WriterType::New(); + + m_ComplexVectorInt16Writer = ComplexVectorInt16WriterType::New(); + m_ComplexVectorInt32Writer = ComplexVectorInt32WriterType::New(); + m_ComplexVectorFloatWriter = ComplexVectorFloatWriterType::New(); + m_ComplexVectorDoubleWriter = ComplexVectorDoubleWriterType::New(); } -template <typename TInput, typename TOutput> void ClampAndWriteImage(itk::ImageBase<2> * in, otb::ImageFileWriter<TOutput> * writer, const std::string & filename, const unsigned int & ramValue) +template <typename TInput, typename TOutput> +void +ClampAndWriteVectorImage( itk::ImageBase<2> * in , + otb::ImageFileWriter<TOutput> * writer , + const std::string & filename , + const unsigned int & ramValue ) { - typedef otb::ClampImageFilter<TInput, TOutput> ClampFilterType; - typename ClampFilterType::Pointer clampFilter = ClampFilterType::New(); + typedef ClampImageFilter < TInput , TOutput > ClampFilterType; + typename ClampFilterType::Pointer clampFilter ( ClampFilterType::New() ); + clampFilter->SetInput( dynamic_cast<TInput*>(in)); bool useStandardWriter = true; @@ -200,152 +230,116 @@ template <typename TInput, typename TOutput> void ClampAndWriteImage(itk::ImageB } } -template <typename TInput, typename TOutput > void ClampAndWriteVectorImage(itk::ImageBase<2> * in, otb::ImageFileWriter<TOutput > * writer, const std::string & filename, const unsigned int & ramValue) -{ - typedef otb::ClampVectorImageFilter<TInput, TOutput> ClampFilterType; - typename ClampFilterType::Pointer clampFilter = ClampFilterType::New(); - clampFilter->SetInput( dynamic_cast<TInput*>(in)); - - bool useStandardWriter = true; - -#ifdef OTB_USE_MPI - - otb::MPIConfig::Pointer mpiConfig = otb::MPIConfig::Instance(); - - if (mpiConfig->GetNbProcs() > 1) - { - useStandardWriter = false; - - // Get file extension - std::string extension = itksys::SystemTools::GetFilenameExtension(filename); - - if(extension == ".vrt") - { - // Use the WriteMPI function - WriteMPI(clampFilter->GetOutput(),filename,ramValue); - } - #ifdef OTB_USE_SPTW - else if (extension == ".tif") - { - // Use simple parallel tiff writer - typedef otb::SimpleParallelTiffWriter<TOutput> SPTWriterType; - - typename SPTWriterType::Pointer sptWriter = SPTWriterType::New(); - sptWriter->SetFileName(filename); - sptWriter->SetInput(clampFilter->GetOutput()); - sptWriter->SetAutomaticAdaptativeStreaming(ramValue); - sptWriter->Update(); - } - - #endif - else - { - itkGenericExceptionMacro("File format "<<extension<<" not supported for parallel writing with MPI. Supported formats are .vrt and .tif. Extended filenames are not supported."); - } - } - #endif - - if(useStandardWriter) - { - - writer->SetFileName( filename ); - writer->SetInput(clampFilter->GetOutput()); - writer->SetAutomaticAdaptativeStreaming(ramValue); - writer->Update(); - } -} - - -template <class TInputImageType> +template <class TInput> void -OutputImageParameter::SwitchImageWrite() -{ +OutputImageParameter::SwitchVectorImageWrite() + { switch(m_PixelType ) { case ImagePixelType_uint8: { - ClampAndWriteImage<TInputImageType,UInt8ImageType>(m_Image,m_UInt8Writer,m_FileName,m_RAMValue); + ClampAndWriteVectorImage< TInput , UInt8VectorImageType > ( + m_Image , + m_VectorUInt8Writer , + m_FileName , + m_RAMValue ); break; } case ImagePixelType_int16: { - ClampAndWriteImage<TInputImageType,Int16ImageType>(m_Image,m_Int16Writer,m_FileName,m_RAMValue); + ClampAndWriteVectorImage< TInput , Int16VectorImageType > ( + m_Image , + m_VectorInt16Writer , + m_FileName , + m_RAMValue ); break; } case ImagePixelType_uint16: { - ClampAndWriteImage<TInputImageType,UInt16ImageType>(m_Image,m_UInt16Writer,m_FileName,m_RAMValue); + ClampAndWriteVectorImage< TInput , UInt16VectorImageType > ( + m_Image , + m_VectorUInt16Writer , + m_FileName , + m_RAMValue ); break; } case ImagePixelType_int32: { - ClampAndWriteImage<TInputImageType,Int32ImageType>(m_Image,m_Int32Writer,m_FileName,m_RAMValue); + ClampAndWriteVectorImage< TInput , Int32VectorImageType > ( + m_Image , + m_VectorInt32Writer , + m_FileName , + m_RAMValue ); break; } case ImagePixelType_uint32: { - ClampAndWriteImage<TInputImageType,UInt32ImageType>(m_Image,m_UInt32Writer,m_FileName,m_RAMValue); + ClampAndWriteVectorImage< TInput , UInt32VectorImageType > ( + m_Image , + m_VectorUInt32Writer , + m_FileName , + m_RAMValue ); break; } case ImagePixelType_float: { - ClampAndWriteImage<TInputImageType,FloatImageType>(m_Image,m_FloatWriter,m_FileName,m_RAMValue); + ClampAndWriteVectorImage< TInput , FloatVectorImageType > ( + m_Image , + m_VectorFloatWriter , + m_FileName , + m_RAMValue ); break; } case ImagePixelType_double: { - ClampAndWriteImage<TInputImageType,DoubleImageType>(m_Image,m_DoubleWriter,m_FileName,m_RAMValue); - break; - } - } -} - - -template <class TInputVectorImageType> -void -OutputImageParameter::SwitchVectorImageWrite() - { - switch(m_PixelType ) - { - case ImagePixelType_uint8: - { - ClampAndWriteVectorImage<TInputVectorImageType,UInt8VectorImageType>(m_Image,m_VectorUInt8Writer,m_FileName,m_RAMValue); - break; - } - case ImagePixelType_int16: - { - ClampAndWriteVectorImage<TInputVectorImageType,Int16VectorImageType>(m_Image,m_VectorInt16Writer,m_FileName,m_RAMValue); + ClampAndWriteVectorImage< TInput , DoubleVectorImageType > ( + m_Image , + m_VectorDoubleWriter , + m_FileName , + m_RAMValue ); break; } - case ImagePixelType_uint16: + case ImagePixelType_cint16: { - ClampAndWriteVectorImage<TInputVectorImageType,UInt16VectorImageType>(m_Image,m_VectorUInt16Writer,m_FileName,m_RAMValue); + ClampAndWriteVectorImage < TInput , ComplexInt16VectorImageType > ( + m_Image , + m_ComplexVectorInt16Writer , + m_FileName , + m_RAMValue ); break; } - case ImagePixelType_int32: + case ImagePixelType_cint32: { - ClampAndWriteVectorImage<TInputVectorImageType,Int32VectorImageType>(m_Image,m_VectorInt32Writer,m_FileName,m_RAMValue); + ClampAndWriteVectorImage < TInput , ComplexInt32VectorImageType > ( + m_Image , + m_ComplexVectorInt32Writer , + m_FileName , + m_RAMValue ); break; } - case ImagePixelType_uint32: + case ImagePixelType_cfloat: { - ClampAndWriteVectorImage<TInputVectorImageType,UInt32VectorImageType>(m_Image,m_VectorUInt32Writer,m_FileName,m_RAMValue); + ClampAndWriteVectorImage < TInput , ComplexFloatVectorImageType > ( + m_Image , + m_ComplexVectorFloatWriter , + m_FileName , + m_RAMValue ); break; } - case ImagePixelType_float: + case ImagePixelType_cdouble: { - ClampAndWriteVectorImage<TInputVectorImageType,FloatVectorImageType>(m_Image,m_VectorFloatWriter,m_FileName,m_RAMValue); - break; - } - case ImagePixelType_double: - { - ClampAndWriteVectorImage<TInputVectorImageType,DoubleVectorImageType>(m_Image,m_VectorDoubleWriter,m_FileName,m_RAMValue); + ClampAndWriteVectorImage < TInput , ComplexDoubleVectorImageType > ( + m_Image , + m_ComplexVectorDoubleWriter , + m_FileName , + m_RAMValue ); break; } + default: + break; } } - template <class TInputRGBAImageType> void OutputImageParameter::SwitchRGBAImageWrite() @@ -383,31 +377,47 @@ OutputImageParameter::Write() if (dynamic_cast<UInt8ImageType*>(m_Image.GetPointer())) { - SwitchImageWrite<UInt8ImageType>(); + SwitchVectorImageWrite<UInt8ImageType>(); } else if (dynamic_cast<Int16ImageType*>(m_Image.GetPointer())) { - SwitchImageWrite<Int16ImageType>(); + SwitchVectorImageWrite<Int16ImageType>(); } else if (dynamic_cast<UInt16ImageType*>(m_Image.GetPointer())) { - SwitchImageWrite<UInt16ImageType>(); + SwitchVectorImageWrite<UInt16ImageType>(); } else if (dynamic_cast<Int32ImageType*>(m_Image.GetPointer())) { - SwitchImageWrite<Int32ImageType>(); + SwitchVectorImageWrite<Int32ImageType>(); } else if (dynamic_cast<UInt32ImageType*>(m_Image.GetPointer())) { - SwitchImageWrite<UInt32ImageType>(); + SwitchVectorImageWrite<UInt32ImageType>(); } else if (dynamic_cast<FloatImageType*>(m_Image.GetPointer())) { - SwitchImageWrite<FloatImageType>(); + SwitchVectorImageWrite<FloatImageType>(); } else if (dynamic_cast<DoubleImageType*>(m_Image.GetPointer())) { - SwitchImageWrite<DoubleImageType>(); + SwitchVectorImageWrite<DoubleImageType>(); + } + else if (dynamic_cast<ComplexInt16ImageType*>(m_Image.GetPointer()) ) + { + SwitchVectorImageWrite<ComplexInt16ImageType>(); + } + else if (dynamic_cast<ComplexInt32ImageType*>(m_Image.GetPointer()) ) + { + SwitchVectorImageWrite<ComplexInt32ImageType>(); + } + else if (dynamic_cast<ComplexFloatImageType*>(m_Image.GetPointer()) ) + { + SwitchVectorImageWrite<ComplexFloatImageType>(); + } + else if (dynamic_cast<ComplexDoubleImageType*>(m_Image.GetPointer()) ) + { + SwitchVectorImageWrite<ComplexDoubleImageType>(); } else if (dynamic_cast<UInt8VectorImageType*>(m_Image.GetPointer())) { @@ -437,6 +447,22 @@ OutputImageParameter::Write() { SwitchVectorImageWrite<DoubleVectorImageType>(); } + else if (dynamic_cast<ComplexInt16VectorImageType*>(m_Image.GetPointer())) + { + SwitchVectorImageWrite<ComplexInt16VectorImageType>(); + } + else if (dynamic_cast<ComplexInt32VectorImageType*>(m_Image.GetPointer())) + { + SwitchVectorImageWrite<ComplexInt32VectorImageType>(); + } + else if (dynamic_cast<ComplexFloatVectorImageType*>(m_Image.GetPointer())) + { + SwitchVectorImageWrite<ComplexFloatVectorImageType>(); + } + else if (dynamic_cast<ComplexDoubleVectorImageType*>(m_Image.GetPointer())) + { + SwitchVectorImageWrite<ComplexDoubleVectorImageType>(); + } else if (dynamic_cast<UInt8RGBImageType*>(m_Image.GetPointer())) { SwitchRGBImageWrite<UInt8RGBImageType>(); @@ -455,23 +481,14 @@ OutputImageParameter::Write() itk::ProcessObject* OutputImageParameter::GetWriter() { - int type = 0; + int type = 1; // 0 : image // 1 : VectorImage // 2 : RGBAImage // 3 : RGBImage itk::ProcessObject* writer = ITK_NULLPTR; - if (dynamic_cast<UInt8VectorImageType*> (m_Image.GetPointer()) - || dynamic_cast<Int16VectorImageType*> (m_Image.GetPointer()) - || dynamic_cast<UInt16VectorImageType*> (m_Image.GetPointer()) - || dynamic_cast<Int32VectorImageType*> (m_Image.GetPointer()) - || dynamic_cast<UInt32VectorImageType*> (m_Image.GetPointer()) - || dynamic_cast<FloatVectorImageType*> (m_Image.GetPointer()) - || dynamic_cast<DoubleVectorImageType*> (m_Image.GetPointer())) - { - type = 1; - } - else if (dynamic_cast<UInt8RGBAImageType*> (m_Image.GetPointer())) + + if (dynamic_cast<UInt8RGBAImageType*> (m_Image.GetPointer())) { type = 2; writer = m_RGBAUInt8Writer; @@ -492,9 +509,6 @@ OutputImageParameter::GetWriter() { switch(type) { - case 0: - writer = m_UInt8Writer; - break; case 1: writer = m_VectorUInt8Writer; break; @@ -511,48 +525,60 @@ OutputImageParameter::GetWriter() { if (type == 1) writer = m_VectorInt16Writer; - else - if (type == 0) writer = m_Int16Writer; break; } case ImagePixelType_uint16: { if (type == 1) writer = m_VectorUInt16Writer; - else - if (type == 0) writer = m_UInt16Writer; break; } case ImagePixelType_int32: { if (type == 1) writer = m_VectorInt32Writer; - else - if (type == 0) writer = m_Int32Writer; break; } case ImagePixelType_uint32: { if (type == 1) writer = m_VectorUInt32Writer; - else - if (type == 0) writer = m_UInt32Writer; break; } case ImagePixelType_float: { if (type == 1) writer = m_VectorFloatWriter; - else - if (type == 0) writer = m_FloatWriter; break; } case ImagePixelType_double: { if (type == 1) writer = m_VectorDoubleWriter; - else - if (type == 0) writer = m_DoubleWriter; + break; + } + case ImagePixelType_cint16: + { + if( type == 1 ) + writer = m_ComplexVectorInt16Writer; + break; + } + case ImagePixelType_cint32: + { + if( type == 1 ) + writer = m_ComplexVectorInt32Writer; + break; + } + case ImagePixelType_cfloat: + { + if( type == 1 ) + writer = m_ComplexVectorFloatWriter; + break; + } + case ImagePixelType_cdouble: + { + if( type == 1 ) + writer = m_ComplexVectorDoubleWriter; break; } } diff --git a/Modules/Wrappers/ApplicationEngine/test/CMakeLists.txt b/Modules/Wrappers/ApplicationEngine/test/CMakeLists.txt index 860c8673636aff84ee7d5ae5f26c9c5ab0bc733d..319466cb4c49d21b321d55aa57ff0df847f56a53 100644 --- a/Modules/Wrappers/ApplicationEngine/test/CMakeLists.txt +++ b/Modules/Wrappers/ApplicationEngine/test/CMakeLists.txt @@ -171,6 +171,12 @@ otb_add_test(NAME owTvOutputImageParameter COMMAND otbApplicationEngineTestDrive "my description" ) +#~ otb_add_test(NAME owTvOutputImageParameterConversion COMMAND otbApplicationEngineTestDriver + #~ otbWrapperOutputImageParameterConversionTest + #~ ${INPUTDATA}/poupees.tif + #~ ${TEMP}/poupees_out.tif + #~ ) + otb_add_test(NAME owTvDocExampleStructureTest COMMAND otbApplicationEngineTestDriver --compare-ascii ${NOTOL} ${BASELINE}/owTuDocExampleStructureTest.txt diff --git a/Modules/Wrappers/ApplicationEngine/test/otbApplicationEngineTestDriver.cxx b/Modules/Wrappers/ApplicationEngine/test/otbApplicationEngineTestDriver.cxx index f5b3aabf3d5b4642044293927422883c491198f1..5ccef4965304591a54437f5f75e1d4070bff360a 100644 --- a/Modules/Wrappers/ApplicationEngine/test/otbApplicationEngineTestDriver.cxx +++ b/Modules/Wrappers/ApplicationEngine/test/otbApplicationEngineTestDriver.cxx @@ -51,5 +51,6 @@ void RegisterTests() REGISTER_TEST(otbWrapperInputVectorDataParameterNew); REGISTER_TEST(otbWrapperOutputImageParameterNew); REGISTER_TEST(otbWrapperOutputImageParameterTest1); + //~ REGISTER_TEST(otbWrapperOutputImageParameterConversionTest); REGISTER_TEST(otbApplicationMemoryConnectTest); } diff --git a/Modules/Wrappers/ApplicationEngine/test/otbWrapperOutputImageParameterTest.cxx b/Modules/Wrappers/ApplicationEngine/test/otbWrapperOutputImageParameterTest.cxx index 76d6c6056e6ba55ed46f3edda89923fc1ad0c861..ea8899b8e0d50685f8e0973f17e1a50081dde7f5 100644 --- a/Modules/Wrappers/ApplicationEngine/test/otbWrapperOutputImageParameterTest.cxx +++ b/Modules/Wrappers/ApplicationEngine/test/otbWrapperOutputImageParameterTest.cxx @@ -23,8 +23,10 @@ #endif #include "otbWrapperOutputImageParameter.h" +#include "otbWrapperInputImageParameter.h" #include "otbImageFileReader.h" #include "otbWrapperTypes.h" +#include <vector> int otbWrapperOutputImageParameterNew(int itkNotUsed(argc), char * itkNotUsed(argv)[]) { @@ -34,7 +36,6 @@ int otbWrapperOutputImageParameterNew(int itkNotUsed(argc), char * itkNotUsed(ar return EXIT_SUCCESS; } - int otbWrapperOutputImageParameterTest1(int itkNotUsed(argc), char* argv[]) { typedef otb::Wrapper::OutputImageParameter OutputImageParameterType; @@ -59,3 +60,59 @@ int otbWrapperOutputImageParameterTest1(int itkNotUsed(argc), char* argv[]) return EXIT_SUCCESS; } + + +// template < typename ImageType > +// void Cross( int p , std::string inputfilename, std::string outputfilename) +// { +// otb::Wrapper::InputImageParameter::Pointer paramIn ( +// otb::Wrapper::InputImageParameter::New() ); +// paramIn->SetFromFileName( inputfilename ); +// otb::Wrapper::OutputImageParameter::Pointer paramOut( +// otb::Wrapper::OutputImageParameter::New() ); +// paramOut->SetFileName( outputfilename ); +// paramOut->SetImage(paramIn->GetImage<ImageType>()); +// paramOut->InitializeWriters(); +// paramOut->SetPixelType(static_cast<otb::Wrapper::ImagePixelType>(p)); +// paramOut->Write(); +// } + + +// int otbWrapperOutputImageParameterConversionTest(int , char* argv[]) +// { +// std::string filenamein = argv[1]; +// std::string filenameout = argv[2] ; +// std::string extension = filenameout.substr( filenameout.find_last_of('.') ); + +// filenameout = filenameout.substr( 0 , filenameout.find_last_of('.') ); + +// for ( int i = otb::Wrapper::ImagePixelType_uint8 ; i < 11 ; i++ ) +// { +// std::string type = +// otb::Wrapper::OutputImageParameter::ConvertPixelTypeToString( +// static_cast<otb::Wrapper::ImagePixelType>(i) ); +// Cross< otb::Wrapper::UInt8ImageType > (i , filenamein , filenameout+"_UInt8_"+ type + extension ) ; +// Cross< otb::Wrapper::Int16ImageType > ( i , filenamein , filenameout+"_Int16_"+ type + extension ) ; +// Cross< otb::Wrapper::UInt16ImageType > ( i , filenamein , filenameout+"_UInt16_"+ type + extension ) ; +// Cross< otb::Wrapper::Int32ImageType > ( i , filenamein , filenameout+"_Int21_"+ type + extension ) ; +// Cross< otb::Wrapper::UInt32ImageType > ( i , filenamein , filenameout+"_UInt32_"+ type + extension ) ; +// Cross< otb::Wrapper::FloatImageType > ( i , filenamein , filenameout+"_float_"+ type + extension ) ; +// Cross< otb::Wrapper::DoubleImageType > ( i , filenamein , filenameout+"_double_"+ type + extension ) ; +// Cross< otb::Wrapper::UInt8VectorImageType > ( i , filenamein , filenameout+"_UInt8Vect_"+ type + extension ) ; +// Cross< otb::Wrapper::Int16VectorImageType > ( i , filenamein , filenameout+"_Int16Vect_"+ type + extension ) ; +// Cross< otb::Wrapper::UInt16VectorImageType > ( i , filenamein , filenameout+"_UInt16Vect_"+ type + extension ) ; +// Cross< otb::Wrapper::Int32VectorImageType > ( i , filenamein , filenameout+"_Int21Vect_"+ type + extension ) ; +// Cross< otb::Wrapper::UInt32VectorImageType > ( i , filenamein , filenameout+"_UInt32Vect_"+ type + extension ) ; +// Cross< otb::Wrapper::FloatVectorImageType > ( i , filenamein , filenameout+"_floatVect_"+ type + extension ) ; +// Cross< otb::Wrapper::DoubleVectorImageType > ( i , filenamein , filenameout+"_doubleVect_"+ type + extension ) ; +// Cross< otb::Wrapper::ComplexInt16ImageType > ( i , filenamein , filenameout+"_CInt16_"+ type + extension ) ; +// Cross< otb::Wrapper::ComplexInt32ImageType > ( i , filenamein , filenameout+"_CInt32_"+ type + extension ) ; +// Cross< otb::Wrapper::ComplexFloatImageType > ( i , filenamein , filenameout+"_Cfloat_"+ type + extension ) ; +// Cross< otb::Wrapper::ComplexDoubleImageType > ( i , filenamein , filenameout+"_Cdouble_"+ type + extension ) ; +// Cross< otb::Wrapper::ComplexInt16VectorImageType > ( i , filenamein , filenameout+"_CInt16Vect_"+ type + extension ) ; +// Cross< otb::Wrapper::ComplexInt32VectorImageType > ( i , filenamein , filenameout+"_CInt32Vect_"+ type + extension ) ; +// Cross< otb::Wrapper::ComplexFloatVectorImageType > ( i , filenamein , filenameout+"_CfloatVect_"+ type + extension ) ; +// Cross< otb::Wrapper::ComplexDoubleVectorImageType > ( i , filenamein , filenameout+"_CdoubleVect_"+ type + extension ) ; +// } +// return 0; +// } diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexOutputImageParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexOutputImageParameter.cxx index 0cd5800dfa462ba05af6123a247ca48c15d29d78..ab35389152756e9c4db507cd6478520ae5db9bba 100644 --- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexOutputImageParameter.cxx +++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetComplexOutputImageParameter.cxx @@ -67,6 +67,8 @@ void QtWidgetComplexOutputImageParameter::DoCreateWidget() // Set the Output PixelType choice Combobox m_ComboBox = new QComboBox; m_ComboBox->setToolTip("Complex Output Pixel Type"); + m_ComboBox->addItem( "cint16"); + m_ComboBox->addItem( "cint32"); m_ComboBox->addItem( "cfloat"); m_ComboBox->addItem( "cdouble"); m_ComboBox->setCurrentIndex(m_OutputImageParam->GetComplexPixelType()); diff --git a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputImageParameter.cxx b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputImageParameter.cxx index 140ff6534f8487f97bbda7d0a99fc49128401843..9bcf5430d20d65864bb072d00a32792806610411 100644 --- a/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputImageParameter.cxx +++ b/Modules/Wrappers/QtWidget/src/otbWrapperQtWidgetOutputImageParameter.cxx @@ -75,6 +75,10 @@ void QtWidgetOutputImageParameter::DoCreateWidget() m_ComboBox->addItem( "uint 32"); m_ComboBox->addItem( "float"); m_ComboBox->addItem( "double"); + m_ComboBox->addItem( "cint16"); + m_ComboBox->addItem( "cint32"); + m_ComboBox->addItem( "cfloat"); + m_ComboBox->addItem( "cdouble"); m_ComboBox->setCurrentIndex(m_OutputImageParam->GetPixelType()); connect( m_ComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(SetPixelType(int)) ); connect( m_ComboBox, SIGNAL(currentIndexChanged(int)), GetModel(), SLOT(NotifyUpdate()) ); diff --git a/PSC.md b/PSC.md new file mode 100644 index 0000000000000000000000000000000000000000..c798cec66eaa4a3b3f4538861ed26ea12560c139 --- /dev/null +++ b/PSC.md @@ -0,0 +1,280 @@ +# Project Steering Committee + +This document describes the Project Steering Committee of the Orfeo ToolBox. + +## PSC scope + +The aim of the **OTB Project Steering committee (PSC)** is to provide +high level guidance and coordination for the ORFEO ToolBox. + +It provides a central point of contact for the project and arbitrates +disputes. It is also a stable base of “institutional knowledge†to the +project and tries its best to involve more developers. + +It should help to guarantee that OTB remains open and company neutral. + +### Roadmaps + +The PSC gathers and publishes high level roadmaps for OTB: + +- Feature roadmap +- Technical roadmap (developer and coding guidelines and workflows, + target systems, packaging ...) +- Infrastructure roadmap (SCM, wiki, dashboard ...) + +The PSC also publishes the guidelines and the acceptance policy for +feature requests. It enforces them. It monitors and approves new feature +requests. + +### Communication + +The PSC coordinates communication actions: + +- Ensures that the wiki is up-to-date, +- Ensures that the website is up-to-date and proposes new content, +- Ensures regular posting on the blog and social networks, +- Keeps track of opportunities to communicate: Symposium and events + where OTB should be represented, +- Keeps track of opportunities from communities: Google Summer of Code + project, link with other OSGeo and FOSS projects, +- Is responsible for the organization of events around OTB (i.e. users + meetings and hackathon). + +### User support and documentation + +The PSC ensures that users are given an appropriate support: + +- Ensures that support is working (unanswered questions, questions + from other places than the user list ...) +- Proposes addition to the documentation based on users feedback, +- Proposes new features for the roadmap based on users feedback, +- Proposes new ways for support and documentation + +### Contribution management + +The PSC publishes the guidelines and acceptance policy for +contributions. It enforces them. + +It monitors and approves new proposals. + +It ensures that contribution is as easy as possible, by monitoring +technical means for contribution and proposing evolutions to guidelines, +policies and means. + +### Release planning + +The PSC publishes release guidelines and policies, and enforces them. + +The PSC puts together the next Release roadmap and proposes a planning. +It is then responsible for the release preparation. + +The final approval for a release is given by the PSC (motion proposed to +the otb-developers mailing list). + +### Handling of legal issues + +The PSC is responsible for addressing any issue about copyright or +licensing that may occur, and most importantly, it is responsible for +taking preventive actions about those issues. + +## How does the PSC work? + +This section describes how the PSC works. It is inspired by existing +governance statuses in other open source community projects related to +OTB like +[GDAL](https://trac.osgeo.org/gdal/wiki/GovernanceAndCommunity), +[Quantum +GIS](http://www2.qgis.org/en/site/getinvolved/governance/index.html) or +[GRASS](http://trac.osgeo.org/grass/wiki/PSC). + +### PSC members + +All members have equal standing and voice in the PSC. The PSC seats are +non-expiring. PSC members may resign their position, or be asked to +vacate their seat after a unanimous vote of no confidence from the +remaining PSC members. + +The expectations on PSC members are: + +- Be willing to commit to the OTB development effort +- Be responsive to requests for information from fellow members +- Be able and willing to attend on-line meetings +- Act in the best interests of the project + +It is important to note that the PSC is not a legal entity! + +### Roles + +Members can be assigned roles corresponding to each category of the PSC +scope described above. + +Being assigned a role does not mean undertaking all necessary actions, +but rather ensuring that actions will be undertaken. + +In addition to their specific roles, members of the PSC commit to +participate actively in discussions and votes. + +One member of the PSC is designated as the Chair and is the ultimate +adjudicator in case of deadlock or irretrievable break down of +decision-making, or in case of disputes over voting. + +### When is a PSC vote required? + +A vote of the PSC is required in the following cases: + +1. Merge Request +2. Addition or removal of PSC members (including the selection of a new + Chair) +3. Release process + +In addition, a vote can be summoned for: + +1. Changing PSC rules and processes +2. Anything else that might be controversial + +#### Merge Request + +A Merge Request describes a change in Orfeo ToolBox code, API, +infrastructure or processes that need to be submitted to the PSC vote: + +- Anything that could cause backward compatibility issues, +- Adding substantial amounts of new code, +- Changing inter-subsystem APIs, or objects, + +It should describe : + +1. What changes will be made and why they will make a better Orfeo + ToolBox +2. When will those changes be available (target release or date) +3. Who will be developing the proposed changes + +Those elements can be provided in an email to the developer list or on a +git hosted platform (GitLab, GitHub, etc.). + +#### Add or remove PSC members + +To be eligible for membership in the PSC, a person should demonstrate +**a substantial and ongoing involvement in OTB**. The PSC is not only +composed of OTB developers as there are many ways to join and contribute +to the project. Anyone is eligible to be nominated to the OTB PSC. +Ideally, nominees would be OTB users or developers who have a deep +understanding of the project. In addition, nominees should meet the +qualifications set forth in this document. Anyone can submit a +nomination. + +#### Release phases + +The release manager (the PSC member in charge of release planning) +submits to vote the following release decisions: + +1. Date of the next release +2. Codename of the next release +3. Date and revision of Release Candidate +4. Date and revision of Final Release +5. Date and revision of bug-fixes Release + +### Process + +- Proposals are written up and submitted as GitLab merge requests or on the + otb-developers mailing list for discussion and voting, by any interested + party, not just committee members. Proposals are available for review for at + least three days before a vote can be closed. It is acknowledged that some + more complex issues may require more time for discussion and deliberation. +- Respondents may vote “+1†to indicate support for the proposal and a + willingness to support implementation. +- Respondents may vote “-1†to veto a proposal, but must provide + argumented reasoning and alternate approaches to resolve the problem + within the two days. +- A vote of -0 indicates mild disagreement, but has no effect. A 0 + indicates no opinion. A +0 indicates mild support, but has no + effect. +- Anyone may comment and vote on proposals on the list or on the merge request + thread, but only members of the PSC's votes (including the Chair) will be + counted (“eligible votersâ€). +- A proposal will be accepted if it receives at least +2 (including + the proponent) and no vetos (-1) +- If a proposal is vetoed, and it cannot be revised to satisfy all + parties, then it can be resubmitted for an override vote in which a + majority of all eligible voters indicating +1 is sufficient to pass + it. Note that this is a majority of all committee members, not just + those who actively vote. +- The Chair adjudicates in cases of disputes about voting. + +A summary of discussions is published in a dedicated section of the wiki +[Requests for Changes](https://wiki.orfeo-toolbox.org/index.php/Requests_for_Changes). + +## Current members and roles + +In March 2015, CNES nominated 3 persons deeply involved in OTB as +initial PSC members. They are responsible for defining PSC rules and +establishing a fully functioning PSC. PSC has now 4 members. + +**Name** | **Affiliation** | **Email** | **Role** | +----------------------------|------------------|----------------------------------|--------------------------------------------| +Manuel Grizonnet (resigned) | CNES | manuel.grizonnet AT cnes DOT fr | Infrastructure, legal issues | +Rémi Cresson | IRSTEA | cresson.r AT gmail DOT com | Release Manager for release 5.2 | +Guillaume Pasero | CS-SI | guillaume.pasero AT c-s DOT fr | release planner | +Jordi Inglada (resigned) | CNES/CESBIO | jordi.inglada AT cesbio DOT eu | | +Julien Michel | CNES | julien.michel AT cnes DOT fr | Communication, contributions | +Victor Poughon | CNES | victor.poughon AT cnes DOT fr | User support and documentation, roadmaps | + +## Release manager + +A **release manager** is nominated for each release. Nomination is made +shortly after previous release announcement. A **backup release +manager** is also nominated, to assist and possibly step in if the +official release manager is not available. The **release manager** and +his/her backup can be a member of the PSC, but also another member of +otb-developers list willing to take the spot. + +The **release manager** is in charge of : + +1. Listing and tracking all major features proposed for next release + (from call for contribution in the early phase and then approved + RFCs) +2. Planing release date and ensures sync with RFCs execution, +3. Approving feature branch merges (if possible, leave at least 3 days + between RFC submission and merge, so that people have time to do a + review) +4. Actually merging feature branches when authors do not have commit + rights (github pull request for instance) +5. Tracking remote module that can be candidate for official inclusion + in next release, and ensuring they will be included (see + [Contributors guidelines](CONTRIBUTING.md)) +6. Submitting the start of the [release + process](https://wiki.orfeo-toolbox.org/index.php/How_to_Release) to PSC vote +7. Ensuring proper execution of [release + process](https://wiki.orfeo-toolbox.org/index.php/How_to_Release) + +**Feature freeze:** Starting the release process is also called *feature +freeze* which describes the period between the creation of the release +branch and the announcement of the release. It's an important time for +the RM who should ensures the proper execution of the release process +and facilitate the communication between developers. The RM is among +other things responsible of gathering feedback on bugs that need to be +fixed before the release, making a list that is public to be able to +follow progression of the release process. + +**Remember:** all new features must be submitted by Merge Requests and +approved by the PSC. The release manager only approves the feature +branches merge. + +### Feature branch merge acceptance checklist + +1. The feature branch corresponds to an [approved + Merge Request](#process) +2. The feature branch is synched with develop +3. The feature branch is tested on the dashboard + and has no major failure + (compilation errors, tremendous amount of warning or failing tests, + segfault or not executed tests) +4. Feature branch author are available during days following the merge + to analyse dashboard and fix things in case of unexpected issues + after the merge + +It is important to note that a feature branch should be kept relatively +small and does not necessarily correspond to the full implementation of +a RFC. Small consistent branches implementing parts of RFC can be merged +early. Further evolutions and implementations of the RFC can be done by +continuing the feature branch or opening new branches, and approval of +Release Manager should be requested again before merging. diff --git a/README.md b/README.md index 7ae06474de74ecf4067b6d10a725c8488155d0aa..657504a2dc83be7443ec9802656653346b3f7426 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -#  Orfeo Toolbox +#  Orfeo Toolbox ## Open Source processing of remote sensing images Orfeo ToolBox (OTB) is an open-source project for state-of-the-art remote @@ -23,12 +23,12 @@ not a black box! * [OTB's website](https://www.orfeo-toolbox.org/) * [Documentation](https://www.orfeo-toolbox.org/documentation/) * [Downloads](https://www.orfeo-toolbox.org/download/) -* [Public git repositories](https://git.orfeo-toolbox.org/) +* [Public git repositories](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb) * [GitHub mirror](https://github.com/orfeotoolbox/) * [Build status](http://dash.orfeo-toolbox.org/index.php?project=OTB) -* [Bug tracker](https://bugs.orfeo-toolbox.org/) +* [Bug tracker](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/issues?label_name%5B%5D=bug) * [Wiki](http://wiki.orfeo-toolbox.org/index.php/Main_Page) -* [Task tracking](http://scrum.orfeo-toolbox.org) +* [Task tracking](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/issues) ### Join the community Get help, share your experience and contribute to the Orfeo-Toolbox project by @@ -37,10 +37,13 @@ joining our community and mailing lists. [https://www.orfeo-toolbox.org/community/](https://www.orfeo-toolbox.org/community/) ### Contributing -Please see the wiki for contributors guidelines. +Please see [CONTRIBUTING.md](CONTRIBUTING.md) for contributors guidelines. ### License Please see the license and the Copyright directory for legal issues on the use of the software. ### Issues -Please report any issue you might encouter to [our bugtracker](http://bugs.orfeo-toolbox.org). +Please report any issue you might encouter to [our bugtracker](https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/issues?label_name%5B%5D=bug). + +### Governance +The Orfeo ToolBox project is governed by the [Project Steering Committee](PSC.md) and its members.