Commit a89c8b15 authored by Edwin Carlinet's avatar Edwin Carlinet
Browse files

Merge branch 'development/cleanup-image-builder' into 'development/ranges'

Cleanup image builder

See merge request !58
parents 80769096 24674519
......@@ -128,7 +128,7 @@ variables:
PACKAGE_NAME: "pylene" # Conan package name
PACKAGE_TAG: "testing" # Conan tag
PACKAGE_VERSION: "head" # Version to build
CONAN_USER: "carlinet"
CONAN_USER: "lrde"
pages:
<<: *documentation-base
......
......@@ -18,7 +18,7 @@ namespace mln
mln_entering("mln::compute_gradient_magnitude");
image2d<float> grad;
resize(grad, f).init(1.0);
resize(grad, f).set_init_value(1.0);
box2d dom = f.domain();
sbox2d d2f = {dom.pmin - point2d{2, 2}, dom.pmax, point2d{2, 2}};
......
......@@ -156,7 +156,7 @@ namespace mln
// 2. We set the weights value point-wise
image2d<unsigned> dmap;
resize(dmap, t[0]._get_data()->m_pmap).init(0);
resize(dmap, t[0]._get_data()->m_pmap).set_init_value(0);
mln_foreach (auto px, dmap.pixels())
{
......
......@@ -22,7 +22,7 @@ namespace mln
, m_parent(parent)
, m_out(S)
{
resize(m_dejavu, m_ima).init(false);
resize(m_dejavu, m_ima).set_init_value(false);
// m_back = S + ima.domain().size();
}
......
......@@ -30,7 +30,7 @@ int main(int argc, char** argv)
io::imread(argv[3], S);
image2d<unsigned> area;
resize(area, f).init(0);
resize(area, f).set_init_value(0);
// Accumulate
mln_reverse_foreach (unsigned i, S.values())
......
......@@ -116,7 +116,7 @@ namespace mln
{
if (use_dejavu)
{
resize(m_deja_vu, ima).init(false);
resize(m_deja_vu, ima).set_init_value(false);
extension::fill(m_deja_vu, true);
}
......
......@@ -41,7 +41,7 @@ namespace mln
{
if (!use_dejavu)
{
resize(m_parent, ima).init((size_type)UNINITIALIZED);
resize(m_parent, ima).set_init_value((size_type)UNINITIALIZED);
extension::fill(m_parent, (size_type)INQUEUE);
}
else
......
......@@ -66,11 +66,11 @@ namespace mln
image2d<internal::aux_data<size_type>> ttree;
image2d<internal::aux_data<size_type>> tnode;
resize(parent, ima).init(UNINITIALIZED);
resize(parent, ima).set_init_value(UNINITIALIZED);
resize(lowestNode, ima);
internal::aux_data<size_type> x = {0, 0};
resize(ttree, ima).init(x);
resize(tnode, ima).init(x);
resize(ttree, ima).set_init_value(x);
resize(tnode, ima).set_init_value(x);
/* coucou */
......
......@@ -54,7 +54,7 @@ namespace mln
{
if (use_dejavu)
{
resize(deja_vu, ima).init(false);
resize(deja_vu, ima).set_init_value(false);
extension::fill(deja_vu, true);
}
......
......@@ -40,7 +40,7 @@ namespace mln
{
if (!use_dejavu)
{
resize(m_parent, ima).init(UNINITIALIZED);
resize(m_parent, ima).set_init_value(UNINITIALIZED);
extension::fill(m_parent, INQUEUE);
}
else
......
......@@ -51,7 +51,7 @@ namespace mln
m_S = new std::vector<size_type>(n);
resize(m_parent, ima);
resize(m_zpar, ima).init(UNINITIALIZED);
resize(m_zpar, ima).set_init_value(UNINITIALIZED);
m_nsplit = 0;
}
......@@ -87,7 +87,7 @@ namespace mln
image2d<bool> deja_vu;
if (use_dejavu)
resize(deja_vu, ima).init(false);
resize(deja_vu, ima).set_init_value(false);
size_type first_index = ima.index_of_point(ima.domain().pmin);
size_type last_index = ima.index_of_point(ima.domain().pmax) - ima.index_strides()[0];
......
......@@ -44,7 +44,7 @@ namespace mln
{
resize(m_parent, ima);
aux_data x = {0, UNINITIALIZED, 0};
resize(m_aux, ima).init(x);
resize(m_aux, ima).set_init_value(x);
size_type n = m_ima.domain().size();
m_S = new std::vector<size_type>(n);
......@@ -80,7 +80,7 @@ namespace mln
image2d<bool> deja_vu;
if (use_dejavu)
resize(deja_vu, ima).init(false);
resize(deja_vu, ima).set_init_value(false);
const box2d& d = m_ima.domain();
size_type i = (d.pmax[1] - d.pmin[1]) * (domain.pmin[0] - d.pmin[0]);
......
......@@ -200,7 +200,7 @@ namespace mln
bool check_S(const image2d<size_type>& parent, const size_type* begin, const size_type* end)
{
image2d<bool> dejavu;
resize(dejavu, parent).init(false);
resize(dejavu, parent).set_init_value(false);
dejavu[*begin] = true;
for (; begin != end; ++begin)
......
......@@ -148,7 +148,7 @@ namespace mln
typedef typename tree_t::node_type node_t;
image2d<V> saliency;
resize(saliency, tree._get_data()->m_pmap).init(0);
resize(saliency, tree._get_data()->m_pmap).set_init_value(0);
auto depth = morpho::compute_depth(tree);
......
......@@ -113,7 +113,7 @@ BENCHMARK_F(BMAlgorithms, fill_ibuffer2d_rgb8)(benchmark::State& st)
BENCHMARK_F(BMAlgorithms, copy_buffer2d_uint8_baseline)(benchmark::State& st)
{
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::init());
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::image_build_params{});
while (st.KeepRunning())
copy_baseline(m_input_uint8, output_uint8);
st.SetBytesProcessed(st.iterations() * m_pixel_count);
......@@ -121,7 +121,7 @@ BENCHMARK_F(BMAlgorithms, copy_buffer2d_uint8_baseline)(benchmark::State& st)
BENCHMARK_F(BMAlgorithms, copy_buffer2d_uint8)(benchmark::State& st)
{
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::init());
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::image_build_params{});
while (st.KeepRunning())
copy(m_input_uint8, output_uint8);
st.SetBytesProcessed(st.iterations() * m_pixel_count);
......@@ -129,7 +129,7 @@ BENCHMARK_F(BMAlgorithms, copy_buffer2d_uint8)(benchmark::State& st)
BENCHMARK_F(BMAlgorithms, copy_ibuffer2d_rgb8_baseline)(benchmark::State& st)
{
mln::image2d<mln::rgb8> output_rgb8(m_input_rgb8, mln::init());
mln::image2d<mln::rgb8> output_rgb8(m_input_rgb8, mln::image_build_params{});
while (st.KeepRunning())
copy_baseline(m_input_rgb8, output_rgb8);
st.SetBytesProcessed(st.iterations() * m_pixel_count);
......@@ -137,7 +137,7 @@ BENCHMARK_F(BMAlgorithms, copy_ibuffer2d_rgb8_baseline)(benchmark::State& st)
BENCHMARK_F(BMAlgorithms, copy_ibuffer2d_rgb8)(benchmark::State& st)
{
mln::image2d<mln::rgb8> output_rgb8(m_input_rgb8, mln::init());
mln::image2d<mln::rgb8> output_rgb8(m_input_rgb8, mln::image_build_params{});
while (st.KeepRunning())
copy(m_input_rgb8, output_rgb8);
st.SetBytesProcessed(st.iterations() * m_pixel_count);
......@@ -237,7 +237,7 @@ BENCHMARK_F(BMAlgorithms, equal_ibuffer2d_rgb8)(benchmark::State& st)
BENCHMARK_F(BMAlgorithms, paste_buffer2d_uint8_baseline)(benchmark::State& st)
{
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::init());
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::image_build_params{});
while (st.KeepRunning())
paste_baseline(m_input_uint8, output_uint8);
st.SetBytesProcessed(st.iterations() * m_pixel_count);
......@@ -245,7 +245,7 @@ BENCHMARK_F(BMAlgorithms, paste_buffer2d_uint8_baseline)(benchmark::State& st)
BENCHMARK_F(BMAlgorithms, paste_buffer2d_uint8)(benchmark::State& st)
{
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::init());
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::image_build_params{});
while (st.KeepRunning())
paste(m_input_uint8, output_uint8);
st.SetBytesProcessed(st.iterations() * m_pixel_count);
......@@ -253,7 +253,7 @@ BENCHMARK_F(BMAlgorithms, paste_buffer2d_uint8)(benchmark::State& st)
BENCHMARK_F(BMAlgorithms, paste_ibuffer2d_rgb8_baseline)(benchmark::State& st)
{
mln::image2d<mln::rgb8> output_rgb8(m_input_rgb8, mln::init());
mln::image2d<mln::rgb8> output_rgb8(m_input_rgb8, mln::image_build_params{});
while (st.KeepRunning())
paste_baseline(m_input_rgb8, output_rgb8);
st.SetBytesProcessed(st.iterations() * m_pixel_count);
......@@ -261,7 +261,7 @@ BENCHMARK_F(BMAlgorithms, paste_ibuffer2d_rgb8_baseline)(benchmark::State& st)
BENCHMARK_F(BMAlgorithms, paste_ibuffer2d_rgb8)(benchmark::State& st)
{
mln::image2d<mln::rgb8> output_rgb8(m_input_rgb8, mln::init());
mln::image2d<mln::rgb8> output_rgb8(m_input_rgb8, mln::image_build_params{});
while (st.KeepRunning())
paste(m_input_rgb8, output_rgb8);
st.SetBytesProcessed(st.iterations() * m_pixel_count);
......@@ -271,7 +271,7 @@ BENCHMARK_F(BMAlgorithms, paste_ibuffer2d_rgb8)(benchmark::State& st)
BENCHMARK_F(BMAlgorithms, transform_buffer2d_uint8_baseline)(benchmark::State& st)
{
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::init());
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::image_build_params{});
while (st.KeepRunning())
transform_baseline(m_input_uint8, output_uint8);
st.SetBytesProcessed(st.iterations() * m_pixel_count);
......@@ -279,7 +279,7 @@ BENCHMARK_F(BMAlgorithms, transform_buffer2d_uint8_baseline)(benchmark::State& s
BENCHMARK_F(BMAlgorithms, transform_buffer2d_uint8)(benchmark::State& st)
{
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::init());
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::image_build_params{});
while (st.KeepRunning())
transform(m_input_uint8, output_uint8);
st.SetBytesProcessed(st.iterations() * m_pixel_count);
......@@ -287,7 +287,7 @@ BENCHMARK_F(BMAlgorithms, transform_buffer2d_uint8)(benchmark::State& st)
BENCHMARK_F(BMAlgorithms, transform_ibuffer2d_rgb8_baseline)(benchmark::State& st)
{
mln::image2d<mln::rgb8> output_rgb8(m_input_rgb8, mln::init());
mln::image2d<mln::rgb8> output_rgb8(m_input_rgb8, mln::image_build_params{});
while (st.KeepRunning())
transform_baseline(m_input_rgb8, output_rgb8);
st.SetBytesProcessed(st.iterations() * m_pixel_count);
......@@ -295,7 +295,7 @@ BENCHMARK_F(BMAlgorithms, transform_ibuffer2d_rgb8_baseline)(benchmark::State& s
BENCHMARK_F(BMAlgorithms, transform_ibuffer2d_rgb8)(benchmark::State& st)
{
mln::image2d<mln::rgb8> output_rgb8(m_input_rgb8, mln::init());
mln::image2d<mln::rgb8> output_rgb8(m_input_rgb8, mln::image_build_params{});
while (st.KeepRunning())
transform(m_input_rgb8, output_rgb8);
st.SetBytesProcessed(st.iterations() * m_pixel_count);
......@@ -337,7 +337,7 @@ BENCHMARK_F(BMAlgorithms, for_each_ibuffer2d_rgb8)(benchmark::State& st)
BENCHMARK_F(BMAlgorithms, generate_buffer2d_uint8_baseline)(benchmark::State& st)
{
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::init());
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::image_build_params{});
while (st.KeepRunning())
generate_baseline(output_uint8);
st.SetBytesProcessed(st.iterations() * m_pixel_count);
......@@ -345,7 +345,7 @@ BENCHMARK_F(BMAlgorithms, generate_buffer2d_uint8_baseline)(benchmark::State& st
BENCHMARK_F(BMAlgorithms, generate_buffer2d_uint8)(benchmark::State& st)
{
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::init());
mln::image2d<mln::uint8> output_uint8(m_input_uint8, mln::image_build_params{});
while (st.KeepRunning())
generate(output_uint8);
st.SetBytesProcessed(st.iterations() * m_pixel_count);
......
......@@ -31,7 +31,17 @@ See :doc:`core/images` for a description of the image concepts and image basics.
.. topic:: Utilities
TODO
.. table::
:widths: auto
:class: full
+-------------------------------------------------+------------------------------------------------------------------------------------------+
| :cpp:func:`imconcretize(f) <mln::imconcretize>` | Creates a new writable image with the *geometry* of `f`. |
+-------------------------------------------------+------------------------------------------------------------------------------------------+
| :cpp:func:`imchvalue(f) <mln::imchvalue>` | Creates a new writable image with the *geomerty* of `f` able to store values of type `U` |
+-------------------------------------------------+------------------------------------------------------------------------------------------+
| :cpp:func:`resize(g,f) <mln::resize>` | Resize `g` to the *geometry* of `f` |
+-------------------------------------------------+------------------------------------------------------------------------------------------+
.. topic:: Fundamental image types
......
Image Builder
#############
Image Builder Objects
=====================
*image builders* follow the `Named parameter Idiom <https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Named_Parameter>`_ and provides additional init parameters. Note that
it may fail to fulfill the requirements, so a status code may be queried to check if everything succeeded.
.. doxygenstruct:: mln::image_build_params
:members:
.. doxygenclass:: mln::image_builder
:members:
.. doxygenclass:: mln::image_resizer
:members:
.. doxygenenum:: mln::image_build_error_code
Free functions
==============
.. doxygenfunction:: mln::imconcretize
.. doxygenfunction:: mln::imchvalue
.. doxygenfunction:: mln::resize
Usage
=====
This example shows how to create a temporary image with sufficient border to perform a stencil pattern (accessing the neighbors of a point).
.. code::
auto myfunction(I f)
{
// Try to adjust the border of the image to hold `nbh`
// and initialize this image with the value `42`
mln::image_build_error_code st;
mln::concrete_t<I> g = imconcretize(f).adjust(nbh).set_init_value(42).get_status(st);
if (st == mln::IMAGE_BUILD_OK)
{
mln_foreach(auto p, g.pixels())
for (auto nx : nbh(px))
// Process safely nx
}
else
{
// `g` has not a border large enough to hold the neighborhood.
// You have to check that the access is valid when accessing the neighbors
// of a point.
}
}
\ No newline at end of file
......@@ -172,34 +172,42 @@ Two methods enable to create a new image `g` from a prototype `f`. The second al
Because the syntax of a call to a template method is quite cumbersome, free functions can be used::
I f = ...;
mln::concrete_t<I> g1 = mln::concretize(f);
mln::ch_value_t<I, OtherType> g2 = mln::ch_value<OtherType>(f);
mln::concrete_t<I> g1 = mln::imconcretize(f);
mln::ch_value_t<I, OtherType> g2 = mln::imchvalue<OtherType>(f);
.. warning:: The type returned by `concretize` et al. are not images but *image initializers* that support advanced
parameterization of the initialization. So you should not use ``auto`` type deduction for variables.
.. warning:: The type returned by `concretize` et al. are not images but *image builders* that support advanced
parameterization of the initialization. So you should not use ``auto`` type deduction for variables (or by calling explicitly ``build()`` - see below)::
I f = ...;
auto g1 = mln::imconcretize(f).build();
auto g2 = mln::imchvalue<OtherType>(f).build();
.. rubric:: Advanced initialization
.. rubric:: Advanced initialization with image builders
*image initializers* follow the `Named parameter Idiom
*image builders* (see :doc:`image_builder`) follow the `Named parameter Idiom
<https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Named_Parameter>`_ and provides additional init parameters. Note that
it may fail to fulfill the requirements, so a status code may be queried to check if everything succeeded.
it may fail to fulfill the requirements, so a status code may be queried to check if everything succeeded.
+------------------------+---------------------------------------------------------------------------------------------+
| ``init(v)`` | Requires the image to be set to `v` |
+------------------------+---------------------------------------------------------------------------------------------+
| ``adjust(nbh)`` | Requires the extension of the image to be wide enough to hold the :ref:`neighborhood` `nbh` |
+------------------------+---------------------------------------------------------------------------------------------+
| ``get_status(status)`` | Get the status code |
+------------------------+---------------------------------------------------------------------------------------------+
+-------------------------+----------------------------------------------------------------------------------------------------------+
| ``set_init_value(v)`` | Requires the image to be set to `v` |
+-------------------------+----------------------------------------------------------------------------------------------------------+
| ``set_border(k)`` | Requires the image to have border of size `k`. |
+-------------------------+----------------------------------------------------------------------------------------------------------+
| ``adjust(se)`` | Requires the extension of the image to be wide enough to hold the :cpp:concept:`StructuringElement` `se` |
+-------------------------+----------------------------------------------------------------------------------------------------------+
| ``get_status(&status)`` | Get the status code |
+-------------------------+----------------------------------------------------------------------------------------------------------+
| ``build()`` | Build and return the new image. |
+-------------------------+----------------------------------------------------------------------------------------------------------+
Example::
I f = ...;
int st_code = 0;
mln::concrete_t<I> g1 = mln::concretize(f).adjust(mln::c4).get_status(st_code);
mln::image_build_error_code st_code;
mln::concrete_t<I> g1 = mln::imconcretize(f).adjust(mln::c4).get_status(&st_code);
if (st_code == 0)
// run with g1
else
......@@ -213,11 +221,8 @@ and deduces the initialization configuration from it.
It has the form:
``I(const I& other, mln::image_initializer_params_t params)``
Initialize from `other` but overrides init-parameters with those from `params`.
``I(const I& other, mln::image_build_params params)``
Initializes from `other` but overrides init-parameters with those from `params`.
......
......@@ -100,6 +100,12 @@ Structuring Element
| | | the pixel `px`. |
+------------+----------------+-------------------------------------------------------------+
For dynamic structuring elements:
+------------------------+-----+---------------------------------------------------------------------+
| ``se.radial_extent()`` | int | Returns the radial extent of the SE, the radius of 𝐿∞ disc (square) |
+------------------------+-----+---------------------------------------------------------------------+
.. rubric:: Type definitions and traits
......@@ -209,11 +215,11 @@ Structuring Element Properties
| Expression | Return Type | Sementics |
+==============+================+===========================================================+
| ``se.inc()`` | *impl-defined* | A SE equivalent to :math:`\Delta\mathcal{B}^+(p) = |
| | | \mathcal{B}(p) \setminus (\mathcal{B}(p) \cap |
| | | \mathcal{B}(p) (\mathcal{B}(p) |
| | | \mathcal{B}(\mathrm{prev}))` |
+--------------+----------------+-----------------------------------------------------------+
| ``se.dec()`` | *impl-defined* | A SE `s` equivalent to :math:`\Delta\mathcal{B}^-(p) = |
| | | \mathcal{B}(\mathrm{prev}) \setminus (\mathcal{B}(p) \cap |
| | | \mathcal{B}(\mathrm{prev}) (\mathcal{B}(p) |
| | | \mathcal{B}(\mathrm{prev}))` |
+--------------+----------------+-----------------------------------------------------------+
......@@ -243,6 +249,7 @@ Predefined Structuring Elements
se/disc
se/rectangle
se/periodic_lines
se/mask2d
Tools to build custom Neighborhoods and Structuring Elements
......
Mask 2D
=======
.. doxygenclass:: mln::se::experimental::mask2d
:members:
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment