otb merge requestshttps://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests2023-06-05T12:59:58Zhttps://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/809Update version of diapOTB to 1.0.12021-06-09T13:53:34ZJulien OsmanUpdate version of diapOTB to 1.0.1#### Summary
Include latest release of DiapOTB (v1.0.1)
#### Rationale
DiapOTB v1.0.1 is about to be released. The purpose of this MR is to include this new release in OTB.
#### Implementation Details
The first step consist in setti...#### Summary
Include latest release of DiapOTB (v1.0.1)
#### Rationale
DiapOTB v1.0.1 is about to be released. The purpose of this MR is to include this new release in OTB.
#### Implementation Details
The first step consist in setting the DiapOTB tag to v1.0.1, to follow DiapOTB's release branch. This allow to run the CI on this release branch.
When DiapOTB's release is official, the tag will be changed to the release commit value.
#### 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.3.0https://gitlab.orfeo-toolbox.org/orfeotoolbox/otb/-/merge_requests/736Integrate S1Tiling support apps as official remote module2020-10-05T11:59:05ZLuc HermitteIntegrate S1Tiling support apps as official remote module#### Summary
@tkoleck and I propose in this MR the integration of [S1Tiling](https://gitlab.orfeo-toolbox.org/s1-tiling/s1tiling) support applications as an official remote module.
#### Rationale
This remote module is made of 4 applic...#### Summary
@tkoleck and I propose in this MR the integration of [S1Tiling](https://gitlab.orfeo-toolbox.org/s1-tiling/s1tiling) support applications as an official remote module.
#### Rationale
This remote module is made of 4 applications that we'll like to see distributed alongside OTB.
We actually plan to eventually propose the applications as official OTB applications, but prefer first to provide them as a remote module.
#### Implementation Details
Comments on the code are welcomed. In particular, I have doubts regarding the documentation tags to use.
##### Applications
The following applications are provided:
- `ClampROI`: that sets margins to 0 outside the ROI -- name suggestions are welcomed
- `Synthetize`: that iterates overs a list of overlapping images to keep the
first non null pixel -- name suggestions are welcomed
- `MultitempFilteringFilter`: that implements Quegan speckle filter for SAR Images.
- `MultitempFilteringOutcore`: that computes the outcore of the filter
##### Classes and files
A few helper classes and functions are provided. They should eventually be part of OTB. They are:
- `otb::Interval`, inspired by `boost::numeric::interval` but with a much simpler interface. It can be seen as a 1D region. Its main purpose is to check intersections between (1D) regions and simplify the definition of functions like the generation of input and/or ouput (requested regions)
- `otb::NeatRegionLogger` permits to change the way regions are logged, example: `x ∈ [0..42[, y ∈ [12..24[, size=42x12 @(0, 12)`
- `otb::Span<>` is a C++14 implementation of C++20 `std::span`.
- `otb::ZipIterator<>` aggregates (zips!) multiple image iterators into one. It permits to handle lists of images without having to pay the price for dynamic variable length vector pixels.
- `otb::Synthetize<>` is an alternative (C++) lambda compliant filter that works on list of images (instead of `VectorImage`s) -- name suggestions are welcomed. Note: the current OTBApplication kernel prevents this application from being _pipelined_ in memory.
Other filters are functors are dedicated to the multitemp filter applications.
##### Tests
Some tests exists but we'll have to find some storage to add the tests.
In the current state, tests will fail.
#### 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.2.0https://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/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/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