otb merge requestshttps://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests2022-10-18T09:39:48Zhttps://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/938Robust extended filename options interpretation2022-10-18T09:39:48ZRémi CressonRobust extended filename options interpretation#### Summary
Closes #2312
#### Rationale
When input file paths are HTTP URIs, like the one we can use with [vsicurl](https://gdal.org/user/virtual_file_systems.html#network-based-file-systems), the extended filename options deduction...#### Summary
Closes #2312
#### Rationale
When input file paths are HTTP URIs, like the one we can use with [vsicurl](https://gdal.org/user/virtual_file_systems.html#network-based-file-systems), the extended filename options deduction can be a mess.
The current implementation only split the filename from the first encountered `?` character.
This is wrong, since such character can be part of a HTTP request pointing to an online raster file.
#### Implementation Details
The new implementation consider that the last occurrence of `?&` marks the beginning of the extended filename options.
##### Classes and files
- ENH: `Modules/Core/Common/src/otbExtendedFilenameHelper.cxx` (new implementation)
- REFAC: `Modules/IO/ExtendedFilename/src/otbExtendedFilenameToReaderOptions.cxx` (shorter code)
- FIX: some tests contained wrong extended filename pattern ([the documentation](https://www.orfeo-toolbox.org/CookBook/ExtendedFilenames.html) clearly states the right pattern is _Path/Image.ext_**?&**_key1=value1&key2=value2_).
- `Modules/Adapters/GdalAdapters/test/CMakeLists.txt`
- `Modules/IO/ExtendedFilename/test/CMakeLists.txt`
- `Modules/IO/ImageIO/test/CMakeLists.txt`
- `Modules/Applications/AppSARCalibration/test/CMakeLists.txt`
- `Modules/Core/ImageBase/test/CMakeLists.txt`
#### Copyright
The copyright owner is *INRAE* and has signed the ORFEO ToolBox Contributor License Agreement.
<hr>
***Check before merging:***
- All discussions are resolved
- At least 2 :thumbsup: votes from core developers, no :thumbsdown: vote.
- The feature branch is (reasonably) up-to-date with the base branch
- Dashboard is green
- Copyright owner has signed the ORFEO ToolBox Contributor License Agreement
- Optionally, run `git diff develop... -U0 --no-color | clang-format-diff.py -p1 -i` on latest changes and commitRémi CressonRémi Cressonhttps://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/937Draft: Reduce memory footprint when ImageFileWriter can't stream its input pi...2022-10-18T08:37:20ZRémi CressonDraft: Reduce memory footprint when ImageFileWriter can't stream its input pipeline to the output fileCloses #2310
This MR enables to reduce memory footprint to write output images into file formats that does not support streaming write.
# Benchmarks
All benchmarks have been performed on a laptop with 32Gb RAM, SSD, Ubuntu 20.04 + a l...Closes #2310
This MR enables to reduce memory footprint to write output images into file formats that does not support streaming write.
# Benchmarks
All benchmarks have been performed on a laptop with 32Gb RAM, SSD, Ubuntu 20.04 + a lot of tabs opened in web browser (that makes roughly **20Gb** RAM available). We let OTB with the default `OTB_MAX_RAM_HINT` which I believe is 256Mb.
Our goal is to perform the pansharpening of a Spot-7 (or Pléiades, or PNeo) image, in an output image format for which the GDAL driver only supports the `GDALDriver::CreateCopy()`, which is intended to create a copy of an existing dataset (hence the whole dataset must already exist, either in-memory or in another raster file).
In the following, we use the [GDAL Cloud Optimized Geotiff driver](https://gdal.org/drivers/raster/cog.html) to write the output image.
We use the following command to perform the processing:
```
otbcli_BundleToPerfectSensor -inp $dim_pan -inxs $dim_xs -out "/data/pxs.tif" int16
```
We did use some Spot-7 image but of course we expect the same kind of behavior for Pléiades and PNeo.
# Measurements
We have measured the processing time on the `BundleToPerfectSensor`.
## 10k x 10k subset:
When everything is fine, and the memory budget is enough.
* BundleToPerfectSensor (cog): **52s**
- BundleToPerfectSensor (cog, OTB_FORCE_STREAMING=1): **53s**
## 20k x 20k subset:
When the image is big and the processing without streaming requires extra memory.
### Original approach (trigger the entire pipeline, everything is in-memory)
![Fail](/uploads/2d18343dd79e5a5162f6eeb00539674e/image140.jpg)
### Proposed approach (when OTB_FORCE_STREAMING is set to 1)
![Force_streaming](/uploads/d5d88d1354feb5e56fb49964af251500/toto.jpg)
### Comparison with original approach + gdal_translate
- BundleToPerfectSensor (cog, `OTB_FORCE_STREAMING=1`): **3m37s**
- BundleToPerfectSensor (gtiff) + gdal_translate (cog): 1m24s + 2m09s = **3m33s**
# Conclusion
## PROS
- The MR enables to save memory when writing output image format for which the GDAL driver only supports the `GDALDriver::CreateCopy()`
## CONS
- Saving the output image in a streamable-capable raster format + using gdal_translate to achieve the final conversion is **as fast**, and **use a ridiculous smaller memory footprint** (because the whole output image is not stored in memory).
- Ultimately, there will always be an image size, for which the memory budget won't be enough, even with the `OTB_FORCE_STREAMING` approach. In this case, the user will fall back to the otb + gdal_translate approach.
# Discussion
Maybe this MR should be generalized to python API in order to get the output as numpy array with `OTB_FORCE_STREAMING` (for now, the entire pipeline is triggered over the largest possible image region).Rémi CressonRémi Cressonhttps://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/926rpcSolver: Avoid setting equation system multiple times2022-09-01T08:49:43ZJulien OsmanrpcSolver: Avoid setting equation system multiple times#### Summary
Implements !897 that was closed prematurely.
Also update the link to the Geoid files, [after a message on the forum](https://forum.orfeo-toolbox.org/t/update-egm96-gr-hdr-file-in-otb-data-repository/1435?u=julienosman).
#...#### Summary
Implements !897 that was closed prematurely.
Also update the link to the Geoid files, [after a message on the forum](https://forum.orfeo-toolbox.org/t/update-egm96-gr-hdr-file-in-otb-data-repository/1435?u=julienosman).
#### Copyright
The copyright owner is *CNES* and has signed the ORFEO ToolBox Contributor License Agreement.
<hr>
***Check before merging:***
- All discussions are resolved
- At least 2 :thumbsup: votes from core developers, no :thumbsdown: vote.
- The feature branch is (reasonably) up-to-date with the base branch
- Dashboard is green
- Copyright owner has signed the ORFEO ToolBox Contributor License Agreement
- Optionally, run `git diff develop... -U0 --no-color | clang-format-diff.py -p1 -i` on latest changes and commit8.1.0Julien OsmanJulien Osmanhttps://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/623WIP: Changed floats to doubles in parameters2019-11-06T15:23:30Zguillaume pernotWIP: Changed floats to doubles in parametersUpdate tests accordingly
Closes #1971Update tests accordingly
Closes #19717.1.0https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/290Named inputs in FunctorImageFilter2019-09-19T08:43:14ZJulien MichelNamed inputs in FunctorImageFilterThis MR is an addition to the main MR !268 which is the target branch.
It introduces a new intermediate filter called `VariadicNamedInputsImageFilter` which allows to statically name inputs of the filter, in the following manner:
```c+...This MR is an addition to the main MR !268 which is the target branch.
It introduces a new intermediate filter called `VariadicNamedInputsImageFilter` which allows to statically name inputs of the filter, in the following manner:
```c++
// Test VariadicNamedInputsImageFilter
struct xs {}; // tag for xs input
struct pan {}; // tag for pan input
using Names = std::tuple<xs,pan>; // input mapping type
auto filterWithNames = otb::VariadicNamedInputsImageFilter<VectorImageType, Names, VectorImageType,ImageType>::New();
filterWithNames->SetVNamedInput<xs>(vimage);
filterWithNames->SetVNamedInput<pan>(image);
std::cout<<filterWithNames->GetVNamedInput<xs>()<< filterWithNames->GetVNamedInput<pan>()<<std::endl;
```
`FunctorImageFilter` now has a second template parameter defaulted to `void`, to hold this mapping. If the parameter value is void, superclass is `VariadicInputsImageFilter`, and behavior is the same as in !268. Otherwise it is `VariadicNamedInputsImageFilter` and the parameter is used to enable the `SetVNamedInput<>()` setters.
Why all this ? One issue we ran into when actually trying to refactor old otb code with the new `FunctorImageFilter` is that most functor usage in OTB imply the definition of a new Filter class, which is doing:
* Setting the number of output bands (now covered by `FunctorImageFilter`)
* Passing parameters to the functor (can be easily replaced by `filter->GetFunctor().SetAlpha()`).
* Exposing meaningful name for input setters: for instance `SetInput1()` -> `SetInputMask()`
The latter is important, because otherwise you are left with guessing what is the order of inputs (which is derived from the functor).
Now, with the proposed named inputs interface, one could remove completely the definition of the class, and simply doing (example from the polarimetry module):
```c++
namespace polarimetry_tags
{
struct hh {};
struct hv {};
struct vh {};
struct vv {};
}
// This is the entire declaration of SinclairToCovarianceMatrixFilter
template <typename TInputImage, typename TOutputImage> SinclairToCovarianceMatrixFilter
= FunctorImageFilter< Functor::SinclairToCovarianceMatrixFunctor <typename TInputImage::PixelType,
typename TOutputImage::PixelType> ,
std::tuple<polarimetry_tags::hh,
polarimetry_tags::hv,
polarimetry_tags::vh,
polarimetry_tags::vv> >;
// This is how to use it
using namespace polarimetry_tags;
auto filter = SinclairToCovarianceMatrixFilter<InputImageType,OutputImageType>::New();
filter->SetVNamedInput<hh>(in1);
filter->SetVNamedInput<hv>(in2);
// ... Of course previous SetVinput<0>() SetVInput<1>() or even SetVInputs(in1,in2,in3,in4) still work
```
This would save a lot of code and be a real helper to refactor some Modules (for instance the radiometric indices).
The code is compiling and working, but I would like to get some feedback on this idea, hence the MR.7.0.0https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/191Parameter Refactoring : String Parameter2019-09-19T08:55:00ZAntoine RegimbeauParameter Refactoring : String Parameter**The target branch of this MR is *param_refactoring***
This MR presents the new `StringParameter` class. It derives from the `SingleParameter` class. Here is its API :
```c++
public :
virtual void SetDefaultValue( std::string val...**The target branch of this MR is *param_refactoring***
This MR presents the new `StringParameter` class. It derives from the `SingleParameter` class. Here is its API :
```c++
public :
virtual void SetDefaultValue( std::string val)
virtual const std::string & GetDefaultValue() const
virtual void Reset() override
//Public coming from the SingleParameter class
virtual void SetValue( const std::string & val , int i = 0 ) override
virtual std::string GetValue( int i = -1 ) const override
//Public coming from the Parameter class
/*(function toggling boolean such as Mandatory, Active, UserValue, UserLevel
or dealing with Role, Root, Key, Name and Description are omitted)*/
virtual void ClearValue()
virtual std::string GetValue( int i = -1 ) const = 0;
virtual void SetValue( const std::string & val , int i = 0 ) = 0;
```
If you have any ideas or comments on what we could add to the API of the parameter, feel free to express yourself!
As this kind of MR has not been done for the other classes (Parameter, SingleParameter, NumericalParameter) you can also comment on it here.
Associated MR !367.0.0https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/916Draft: Resolve "Add support for Pleiades Neo products"2023-06-05T12:59:58ZFlorian DouziechDraft: Resolve "Add support for Pleiades Neo products"Closes #2289Closes #22898.2.0Florian DouziechFlorian Douziechhttps://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/799Switch to c++172023-04-03T06:21:10ZJulien OsmanSwitch to c++17#### Summary
Upgrade to the C++ 2017 standard
#### Rationale
OTB is currently compiled with c++14. Now that the c++17 standard is well implemented by the compilers, we could upgrad to c++17. This would come with a lot of advantages:
...#### Summary
Upgrade to the C++ 2017 standard
#### Rationale
OTB is currently compiled with c++14. Now that the c++17 standard is well implemented by the compilers, we could upgrad to c++17. This would come with a lot of advantages:
- There are a lot of TODOs in the code telling that when we switch to c++17 we will be able to simplify that part of code.
- The new `std::clamp` is useful (and could simplify !797).
- We will be able to remove the homemade emulation of the string_view, and use the standard one.
- A bunch of new algorithms and mathematical functions.
- Some new features concerning the templates
- The new `if constexpr` will be handful to simplify the code.
- Many other goodies.
This update means we drop support for older compilers (like VisualC++14).
#### Implementation Details
Modify CMAKE_CXX_STANDARD to 17 in main CMakeFiles.txt.
Remove the REGISTER keyword from 6S code.
#### Copyright
The copyright owner is *CNES* and has signed the ORFEO ToolBox Contributor License Agreement.
<hr>
***Check before merging:***
- All discussions are resolved
- At least 2 :thumbsup: votes from core developers, no :thumbsdown: vote.
- The feature branch is (reasonably) up-to-date with the base branch
- Dashboard is green
- Copyright owner has signed the ORFEO ToolBox Contributor License Agreement
- Optionally, run `git diff develop... -U0 --no-color | clang-format-diff.py -p1 -i` on latest changes and commithttps://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/622WIP: Resolve "double precision parameters input in applications"2019-10-30T14:07:33Zguillaume pernotWIP: Resolve "double precision parameters input in applications"Closes #1971Closes #1971https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/609Integration of the multiImageFileWriter in the application engine (wip)2019-10-22T14:36:03ZCédric TraizetIntegration of the multiImageFileWriter in the application engine (wip)#### Summary
This is still WIP, I want to test the branch on CI.
#### Copyright
The copyright owner is *CNES* and has signed the ORFEO ToolBox Contributor License Agreement.
<hr>
***Check before merging:***
- All discussions are r...#### Summary
This is still WIP, I want to test the branch on CI.
#### Copyright
The copyright owner is *CNES* and has signed the ORFEO ToolBox Contributor License Agreement.
<hr>
***Check before merging:***
- All discussions are resolved
- At least 2 :thumbsup: votes from core developers, no :thumbsdown: vote.
- The feature branch is (reasonably) up-to-date with the base branch
- Dashboard is green
- Copyright owner has signed the ORFEO ToolBox Contributor License Agreement
- Optionally, run `git diff develop... -U0 --no-color | clang-format-diff.py -p1 -i` on latest changes and commit7.1.0Cédric TraizetCédric Traizethttps://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/268WIP: A really, really generic functor filter2018-11-19T16:30:36ZJulien MichelWIP: A really, really generic functor filter#### Summary
This MR provides THE ultimate functor filter. Let see why and how.
Note: this is a WIP, also the code is functional. It misses documentation and reviews. I am submitting this now because it already represents a huge amount...#### Summary
This MR provides THE ultimate functor filter. Let see why and how.
Note: this is a WIP, also the code is functional. It misses documentation and reviews. I am submitting this now because it already represents a huge amount of work and I want to get feedbacks on the idea before proceeding any further.
#### Rationale
We have a lot of base classes to define different cases of functor filters (with a `VectorImage` or Image output, with 2, 3 or more inputs, with neighborhood ...). Moreover, the very principle of functors is to be simple to use, but most often there is a lot of boiler plate code needed even for the simplest thing. This leads to `BandMathFilter` being preferred, which is a disaster in terms of maintenance and performances. So let see if we can do something really, really simple for the user.
The idea is that we could replace a LOT of code with this filter, only keeping the bare functor definitions, that will work with the current implementation.
#### Examples of use
This MR is rather complex, with a lot of meta-programming, sfinae and the rest, so I would like to present it from the user perspective. For the sake of the demonstration, `image`, `image1`, `image2` ... will denote instances of `otb::Image<T>`, and `vimage`, `vimage0`, `vimage1` ... will denote instances of `otb::VectorImage<T>`.
Lets start with a very simple example. Let say I have a scalar image, and want to multiply it by 10. I could of course use the well known `MultiplyByScalarImageFilter` (really?), but lets use a lambda:
```c++
double scale = 10.;
// dummy lambda that multiply by a scalar
auto lambda = [scale](double p)
{
return scale*p;
};
// Create a filter that will accept an otb::Image<double> as input and produce an otb::Image<double>
auto filterLambda = NewFunctorFilter(lambda);
// Set the inputs using variadic SetVInputs
filterLambda->SetVInputs(image);
// All good, lets run it
filterLambda->Update();
```
So what happens under the hood? Well `NewFunctorFilter` calls the `FunctorImageFilter` method which analyses the `operator()` prototype and knows how to call it with the correct types. A lambda, 3 lines of code, and you have a fully functioning filter. Cool? Wait there is more.
```c++
// dummy lambda that sums 3 images with different types
auto lambda = [](double p, unsigned int p1, short p2)
{
return static_cast<double>(p)+static_cast<double>(p1) + static_cast<double>(p2);
};
// Create a filter that will accept otb::Image<double>, otb::Image<unsigned int>,otb::Image<short> as inputs and produce an otb::Image<double>
auto filterLambda = NewFunctorFilter(lambda);
// Set the inputs using variadic SetVinputs
filterLambda->SetVInputs(image, image0, image1); // image is otb::Image<double>, image0 is otb::Image<unsigned int> and image1 is otb::Image<short>
// All good, lets run it
filterLambda->Update();
```
So this is practically the same example as before, except that (you get it) it shows that you can use a lambda with any number of input arguments. It will build the corresponding filter, and you just have to set the inputs and run it. Pretty cool no? Wait there is more.
```c++
// lambda that returns the norm of the input vector pixel
auto lambda = [](const itk::VariableLengthVector<double> & inv)
{
return inv.GetNorm();
};
// Create a filter that will accept otb::VectorImage<double>, as inputs and produce an otb::Image<double>
auto filterLambda = NewFunctorFilter(lambda);
// Set the inputs using variadic SetVinputs
filterLambda->SetVInputs(vimage); // vimage is otb::VectorImage<double>
// All good, lets run it
filterLambda->Update();
```
Yes, it supports `VariableLengthVector` as `operator()` arguments, and yes before you ask, you can combine any number of scalar and VariableLengthVector types as you like. But wait, there is more.
```c++
// lambda that performs neighborhood averaging
auto lambda = [](const itk::Neighborhood<short> & in)
{
double out(0);
for(auto it = in.Begin(); it!=in.End();++it)
out+=static_cast<TOut>(*it);
out/=in.Size();
return out;
};
// Create a filter that will accept otb::Image<short>, as inputs and produce an otb::Image<double>
auto filterLambda = NewFunctorFilter(lambda,{{3,3}});
// Set the inputs using variadic SetVinputs
filterLambda->SetVInputs(image); // image is otb::VectorImage<short>
// All good, lets run it
filterLambda->Update();
```
Yes, you can use `itk::Neighborhood<T>`, and even `itk::Neighborhood<itk::VariableLengthVector<T>>`. In this case, you just have to provide the radius to `NewFunctorFilter`. But wait, there is more.
This works with lambda but also with any class that has an `operator()`. For instance, the following is a variadic functor that can add any (compile time defined) number of images.
```c++
template <typename O, typename ...T> struct VariadicAdd
{
auto operator()(T... ins) const
{
std::vector<O> outVector{static_cast<O>(ins)...};
return std::accumulate(outVector.begin(), outVector.end(),0);
}
};
```
And here is how to use it:
```c++
using AddFunctorType = VariadicAdd<double, double, double>;
auto add = NewFunctorFilter(AddFunctorType{});
add->SetVInputs(image,image);
add->Update();
```
Now comes the tricky part. What if the functor produces a `VariableLengthVector` ? Well in that case we must provide a way to tell the filter how many output bands it has to allocate. Lets see how to do that:
```c++
template<typename O, typename T> struct BandExtraction
{
BandExtraction(unsigned int indices...) : m_Indices({indices}){}
auto operator()(const itk::VariableLengthVector<T> & in) const
{
itk::VariableLengthVector<O> out(m_Indices.size());
size_t idx = 0;
for(auto v: m_Indices)
{
out[idx] = static_cast<O>(in[v]);
++idx;
}
return out;
}
// This time OutputSize does not depend on input image size, hence
// the ...
size_t OutputSize(...) const
{
return m_Indices.size();
}
// set of band indices to extract
std::set<unsigned int> m_Indices;
};
```
Note that there is now a `size_t OuptutSize(...) const` method that tells the filter how many bands the output will have.
And how to use it:
```c++
using ExtractFunctorType = BandExtraction<double,double>;
ExtractFunctorType extractFunctor{1,2};
auto extract = NewFunctorFilter(extractFunctor);
extract->SetVInputs(vimage);
extract->Update();
```
But what if the number of ouptut bands depends on the number of input bands? Well this is still possible:
```c++
// helper function to implement next functor (convert a scalar value
// to a VariableLengthVector)
template <typename T> itk::VariableLengthVector<T> toVector(const T & in)
{
itk::VariableLengthVector<T> out;
out.SetSize(1);
out[0] = in;
return out;
}
// helper function to implement next functor, VariableLengthVectorVersion (returns in)
template <typename T> const itk::VariableLengthVector<T> & toVector(const itk::VariableLengthVector<T> & in)
{
return in;
}
// helper function to implement next functor, Merge two VariableLengthVector in-place
template <typename v1, typename v2> void concatenateVectors(v1 & a, const v2 & b)
{
const size_t previousSizeOfA = a.GetSize();
a.SetSize(previousSizeOfA+b.GetSize());
for(size_t it = 0; it<b.Size();++it)
{
a[previousSizeOfA+it] = static_cast<typename v1::ValueType>(b[it]);
}
}
// helper function to implement next functor, Merge N VariableLengthVector in-place
template <typename v1, typename v2, typename ...vn> void concatenateVectors(v1 & a, const v2 & b, const vn&... z)
{
concatenateVectors(a,b);
concatenateVectors(a,z...);
}
// N images (all types) -> vector image
// This functor concatenates N images (N = variadic) of type
// VectorImage and or Image, into a single VectorImage
template<typename O, typename ...T> struct VariadicConcatenate
{
auto operator()(const T &... ins) const
{
itk::VariableLengthVector<O> out;
concatenateVectors(out, toVector(ins)...);
return out;
}
// Must define OutputSize because output pixel is vector
constexpr size_t OutputSize(const std::array<size_t, sizeof...(T)> inputsNbBands) const
{
return std::accumulate(inputsNbBands.begin(),inputsNbBands.end(),0);
}
};
```
As you can see, the prototype of OuptutSize() is a bit more complex because it will recieve from the filter an array of the inputs number of bands, which can be used to derive the output number of bands. Note that this is an awesome functor that concatenates any number of inputs, either `Image` or `VectorImage`!
How to use it:
```c++
using ConcatFunctorType = VariadicConcatenate<double, double, itk::VariableLengthVector<double> >;
auto concatenate = NewFunctorFilter(ConcatFunctorType{});
concatenate->SetVInputs(image,vimage);
concatenate->Update();
```
Can we define a lambda that returns a `VariableLengthVector` ? We can not add an `OutputSize()` method in a lambda ... But there is a solution for that:
```c++
/ test FunctorImageFilter with a lambda that returns a
// VariableLengthVector
// Converts a neighborhood to a VariableLengthVector
auto Lambda2 = [](const itk::Neighborhood<double> & in)
{
itk::VariableLengthVector<double> out(in.Size());
std::size_t idx{0};
for(auto it = in.Begin(); it!=in.End();++it,++idx)
{
out[idx]=*it;
}
return out;
};
// In this case, we use the helper function which allows to specify
// the number of outputs
auto filterLambda2 = NewFunctorFilter(Lambda2,vimage->GetNumberOfComponentsPerPixel(),{{3,3}});
filterLambda2->SetVInputs(image);
filterLambda2->Update();
```
As you can see, in this case we need to specify the number of output bands to the `NewFunctorFilter`.
#### Implementation Details
More on that coming soon.
#### Copyright
Thanks to Jordi Inglada for the starting this together, and for many inputs.
The copyright owner is *CNES* and has signed the ORFEO ToolBox Contributor License Agreement.
<hr>
***Check before merging:***
- All discussions are resolved
- At least 2 :thumbsup: votes from core developers, no :thumbsdown: vote.
- The feature branch is (reasonably) up-to-date with the base branch
- Dashboard is green
- Copyright owner has signed the ORFEO ToolBox Contributor License Agreement7.0.0https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/255Resolve "use GIT_TAG "master" on develop branch for all RemoteModules"2018-10-30T08:20:39ZRashad KanavathResolve "use GIT_TAG "master" on develop branch for all RemoteModules"#### Summary
Gives a short summary of the changes.
#### Rationale
Changes in OTB, platform, compilers, upgrade of dependencies might need
a change in remote module code. This code is maintained (mostly) by
people not invovled ...#### Summary
Gives a short summary of the changes.
#### Rationale
Changes in OTB, platform, compilers, upgrade of dependencies might need
a change in remote module code. This code is maintained (mostly) by
people not invovled in everyday activity of OTB. Due to delay in make
changes dashboard of OTB will be broken. It keeps happening again.
Current workflow:
1. create issue on remote module repo
2. review/propose a merge request on that project
3. test this remote module (manually) on all platforms
4. create a new mr to update GIT_TAG
New workflow:
1. use "master" for GIT_TAG
2. allow remote module devs to continue pushing fixes
3. GIT_TAG will be updated during release process after creation of
release-X.Y branch
Benenfits:
* developers of OTB can test latest version of a remote module
when using develop
* users can get access to latest version of a remote module
when using develop
* developers of remote module can test latest changes with latest OTB
on all platforms (using cdash)
* reduce delay and avoid updating GIT_TAG with each module in between
releases.
#### Implementation Details
<!---
##### Classes and files
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 applications that have been added.
-->
<!---
##### Tests
Describe the testing strategy for new features.
-->
<!---
##### Documentation
List or link documentation modifications that were made (doxygen, example, Software Guide, application documentation, CookBook).
-->
#### Additional notes
<!--- List remaining open issues if any, and additional notes. -->
#### Copyright
The copyright owner is *COPYRIGHT OWNER (OR OWNER'S AGENT)* and has signed the ORFEO ToolBox Contributor License Agreement.
<hr>
***Check before merging:***
- All discussions are resolved
- At least 2 :thumbsup: votes from core developers, no :thumbsdown: vote.
- The feature branch is (reasonably) up-to-date with the base branch
- Dashboard is green
- Copyright owner has signed the ORFEO ToolBox Contributor License Agreement
https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/241Implementation of the raster output for Zonalstatistics2019-09-19T08:49:14ZJordi IngladaImplementation of the raster output for ZonalstatisticsAlso added some tests and 2 baselines in otb-dataAlso added some tests and 2 baselines in otb-data7.0.0Rémi CressonRémi Cressonhttps://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/227REFAC: allow vector/xml/raster output regardless of the input type2019-09-19T08:50:23ZJordi IngladaREFAC: allow vector/xml/raster output regardless of the input typeDecouple the type of input mode of defining the objects (vector data
or labelimage) from the type of output produced (vector data, xml file
or raster image).
Not implemented yet: vector data output when input is labelimage. I still ...Decouple the type of input mode of defining the objects (vector data
or labelimage) from the type of output produced (vector data, xml file
or raster image).
Not implemented yet: vector data output when input is labelimage. I still have not decided how this should be done. Maybe with a UnaryFunctorImageFilter taking the labelimage and generating the output values from the maps containing the stats and then rasterizing the output of this filter?7.0.0Rémi CressonRémi Cressonhttps://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/75WIP: Resolve "Improve generation of QGis descriptors"2018-04-26T13:16:36ZRashad KanavathWIP: Resolve "Improve generation of QGis descriptors"Closes #1562Closes #15627.0.0https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/62Enhance VectorDataToLabelImageFilter2018-04-20T13:28:01ZRémi CressonEnhance VectorDataToLabelImageFilterI made a few little corrections in the `otbVectorDataToLabelImageFilter`:
* Fix a typo (woah!),
* Add a `m_BackgroundValue` (plus its `itkSetMacro`/`itkGetMacro`): usefull when to want a specific value for pixels where no geometries ...I made a few little corrections in the `otbVectorDataToLabelImageFilter`:
* Fix a typo (woah!),
* Add a `m_BackgroundValue` (plus its `itkSetMacro`/`itkGetMacro`): usefull when to want a specific value for pixels where no geometries are burnt,
* Add an `itkSetMacro`/`itkGetMacro` for the already implemented `m_DefaultBurnValue`Rémi CressonRémi Cressonhttps://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/37Connected components2022-01-10T08:41:33ZCédric TraizetConnected components#### Summary
Implements new applications for large scale connected components segmentation.
#### Rationale
The existing connected component application performs the following steps :
1. Compute a label image (raster mono-band...#### Summary
Implements new applications for large scale connected components segmentation.
#### Rationale
The existing connected component application performs the following steps :
1. Compute a label image (raster mono-band image with integer pixel values) from a multi-band image, a same label is assigned to "connected" pixels. Two pixels are said to be connected if the MuParser expression given as an input returns true (for example "distance<5"). The input image is therefore segmented in group of connected pixels. Additionally, a mask expression (also using MuParser) can be given to mask some pixels.
1. The label image is converted to an ITK label map (see http://www.insight-journal.org/browse/publication/176).
1. Geometric and radiometric attributes are computed using the label map and the input image (size, perimeter, mean, variance, kurtosis etc)
1. An OBIA expression (MuParser) is used to filter some objects of the label map, for example filter objects that verify "size<15"
1. The LabelMap is then vectorized.
1. If connected component is used inside the large scale segmentation framework, some connected components that may have been splitted during vectorization will be merged.
There are two main problems with this application :
- It does too many things, for example an user may want to only perform the vectorization of a label image (this is the original goal of the mask filtering application described at the beginning of this issue).
- It doesn't work well with threading. Filtering (4) is done before fusion of segments (6), and the features are therefore computed on splitted segments.
We propose a different workflow for connected components, with the following steps :
- Compute the label image (same as 1. )
- Vectorize the label image, and merge the splitted segments
- Compute the geometric features from the vector data (size and perimeter)
- Filter the vector data using the computed geometric features and radiometric features.
Each of these steps is performed in a different application. This workflow does not use ITK's Label Maps, instead we use the persistent filters from the segmentation framework to perform vectorization (abstract filter PersistentImageToOGRLayerFilter), and the persistent filters from the sampling framework (abstract filter PersistentSamplingFilterBase).
#### Implementation Details
##### Classes and files
- New persistent filter `PersistentLabelImageVectorizationFilter` and the associated decorator `LabelImageVectorizationFilter` in files otbPersistentLabelImageVectorizationFilter.h/hxx.
- New filter `ConnectedComponentStreamStitchingFilter` in files otbConnectedComponentStreamStitchingFilter.h/hxx
- New filter `OGRDataToPolygonGeometricFeaturesFilter` in files otbOGRDataToPolygonGeometricFeaturesFilter.h/hxx
##### Applications
There is one new application for each step described above :
- `ImageConnectedComponentSegmentation`
- `LabelImageVectorization`
- `ComputePolygonsGeometricFeatures`
- `ObjectBasedFiltering`.
There is also a composite application chaining all these applications : `LargeScaleConnectedComponent`.
##### Tests
validation tests have been created for the application
#### Copyright
The copyright owner is CNES and has signed the ORFEO ToolBox Contributor License Agreement.
7.0.0Cédric TraizetCédric Traizet