Commit aa695cfd authored by Edwin Carlinet's avatar Edwin Carlinet

Update documentation

parent bf3c2ff1
......@@ -36,7 +36,7 @@ windows-debug:
stage: build
script:
- mkdir build; cd build
- conan install .. -s build_type=Debug --build missing
- conan install .. -s build_type=Debug --build missing -s compiler.cppstd=20
- cmake .. -G Ninja -DCMAKE_BUILD_TYPE=debug -D CMAKE_TOOLCHAIN_FILE="C:\vcpkg\scripts\buildsystems\vcpkg.cmake"
- cmake --build . --target build-tests
- ctest -L UnitTests --schedule-random --output-on-failure
......@@ -59,7 +59,7 @@ windows-debug:
stage: build
script:
- mkdir build && cd build
- conan install .. --build missing -e CXXFLAGS="" -e CCFLAGS="" -pr $CONAN_PROFILE
- conan install .. --build missing -s compiler.cppstd=20 -e CXXFLAGS="" -e CCFLAGS="" -pr $CONAN_PROFILE
- cmake -G Ninja .. -DCMAKE_BUILD_TYPE=$PYLENE_CONFIGURATION -DSANITIZE_ADDRESS=$ASAN -DSANITIZE_MEMORY=$MSAN -DSANITIZE_UNDEFINED=$UBSAN
- cmake --build . --target Pylene
- cmake --build . --target build-tests
......@@ -177,7 +177,7 @@ distcheck-linux-coverage:
stage: bench
script:
- mkdir build && cd build
- conan install .. -pr gcc-9 --build missing
- conan install .. -pr gcc-9 --build missing -s compiler.cppstd=20
- cmake -G Ninja .. -DCMAKE_BUILD_TYPE=Release
- cmake --build . --target fetch-external-data
- cmake --build . --target build-bench
......@@ -210,7 +210,7 @@ distbench-linux-gcc9-release:
stage: build
script:
- mkdir build && cd build
- conan install -u .. -pr gcc-9 --build missing
- conan install -u .. -pr gcc-9 --build missing -s compiler.cppstd=20
- cmake -G Ninja .. -DCMAKE_BUILD_TYPE=Release
- cmake --build . --target build-doc
- mkdir ../public && mv doc/sphinx/* ../public/
......@@ -243,7 +243,7 @@ package:
script:
- mkdir build && cd build
- conan user carlinet -r lrde-public -p $CONAN_LRDE_API_KEY
- conan create .. $CONAN_USER/$PACKAGE_TAG -pr gcc-9 --build missing -e CXX=g++ -e CC=gcc
- conan create .. $CONAN_USER/$PACKAGE_TAG -pr gcc-9 --build missing -s compiler.cppstd=20 -e CXX=g++ -e CC=gcc
- conan upload -r lrde-public --all $PACKAGE_NAME/$PACKAGE_VERSION@$CONAN_USER/$PACKAGE_TAG
rules:
- if: $CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "development/cpp20"
Main authors
============
Edwin Carlinet (maintainer)
Michaël Roynard
Contributions
=============
Célian Gossec
Virgile Hirtz
Main past authors from Milena having influenced the library
===========================================================
Thierry Géraud
Roland Levillain
Guillaume Lazzara
This diff is collapsed.
......@@ -45,10 +45,10 @@ library by other means, refer to the [documentation](http://olena.pages.lrde.epi
conan remote add lrde-public https://artifactory.lrde.epita.fr/artifactory/api/conan/lrde-public
```
1. Install the library with Conan:
1. Install the library with Conan (with C++20 standard)
```
conan install pylene/head@lrde/stable -g cmake_find_package
conan install pylene/head@lrde/stable -g cmake_find_package -s compiler.cppstd=20
```
2. Edit your ``CMakeLists.txt`` to include the paths to the library:
......
......@@ -25,17 +25,19 @@ class Pylene(ConanFile):
build_requires = [
"gtest/[>=1.10]",
"benchmark/[>=1.5.0]",
# For now boost is too heavy and is not based on components
# Such a dependancy brings linktime overhead because too many libraries are linked
# "boost/1.73.0"
]
requires = [
"range-v3/0.10.0",
"fmt/6.0.0",
"boost/1.73.0"
]
def configure(self):
self.settings.compiler.cppstd = "20"
tools.check_min_cppstd(self, "20")
def build(self):
......@@ -54,6 +56,8 @@ class Pylene(ConanFile):
self.cpp_info.names["cmake_find_package"] = "Pylene"
self.cpp_info.names["cmake_find_package_multi"] = "Pylene"
self.cpp_info.libs = [ "Pylene" ]
self.cpp_info.cxxflags.append(tools.cppstd_flag(self.settings))
......
Community guidelines
====================
Report issues or problems with the software
-------------------------------------------
If you have any trouble with the library, any question and so on; you may open an issue on gitlab:
https://gitlab.lrde.epita.fr/olena/pylene/-/issues
Contributing to the software
----------------------------
To submit a patch, a feature, you have to:
1. Create a user account on https://gitlab.lrde.epita.fr
2. Fork the project
3. Create a pull request
......@@ -46,7 +46,7 @@ master_doc = 'index'
# General information about the project.
project = u'Pylene'
copyright = u'2018, LRDE'
copyright = u'2020, LRDE'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
......
Core Module
===========
.. cpp:namespace:: mln
.. toctree::
:hidden:
core/core_types
core/images
core/ranges
core/neighborhood
......@@ -52,19 +52,22 @@ See :doc:`core/images` for a description of the image concepts and image basics.
.. topic:: Fundamental image types
.. table::
:class: full
:widths: auto
+--------------+-------------------------+
| `image2d<T>` | Buffer-encoded 2D image |
+--------------+-------------------------+
| `image3d<T>` | Buffer-encoded 3D image |
+--------------+-------------------------+
| `ndimage<T>` | Buffer-encoded nD image |
+--------------+-------------------------+
+-----------------------------------------+-------------------------+
| :cpp:any:`image2d` | Buffer-encoded 2D image |
+-----------------------------------------+-------------------------+
| :cpp:any:`image3d` | Buffer-encoded 3D image |
+-----------------------------------------+-------------------------+
| :cpp:any:`ndimage` | Buffer-encoded nD image |
+-----------------------------------------+-------------------------+
.. topic:: Functional image views
......
......@@ -5,8 +5,7 @@ Include :file:`<mln/core/algorithm/accumulate.hpp>`
.. cpp:namespace:: mln
#. .. cpp:function:: template <class V, class BinaryFunction> V accumulate(InputImage in, V init, BinaryFunction op)
#. .. cpp:function:: template <class V, class BinaryFunction> V accumulate(InputImage in, V init, BinaryFunction op)
#. .. cpp:function:: template <class Accumulator> auto accumulate(InputImage in, Accumulator accu)
......@@ -57,10 +56,9 @@ Examples
mln::image2d<uint8_t> ima = { {1, 2, 3}, {4, 5, 6} };
int s = mln::accumulate(ima, mln::accu::features::sum<>());
Complexity
----------
Linear in the number of pixels.
\ No newline at end of file
......@@ -7,15 +7,15 @@ All_of, any_of, none_of
.. cpp:namespace:: mln
#. .. cpp:function:: bool all_of(InputImage ima, UnaryPredicate p)
#. .. cpp:function:: bool all_of(InputImage ima, std::UnaryPredicate p)
#. .. cpp:function:: bool all_of(InputImage ima)
#. .. cpp:function:: bool any_of(InputImage ima, UnaryPredicate p)
#. .. cpp:function:: bool any_of(InputImage ima, std::UnaryPredicate p)
#. .. cpp:function:: bool any_of(InputImage ima)
#. .. cpp:function:: bool none_of(InputImage ima, UnaryPredicate p)
#. .. cpp:function:: bool none_of(InputImage ima, std::UnaryPredicate p)
#. .. cpp:function:: bool none_of(InputImage ima)
......@@ -26,7 +26,7 @@ All_of, any_of, none_of
:param ima: The image to test
:param p: The unary predicate that will be applied on values
:tparam InputImage: A model of :cpp:concept:`InputImage`
:tparam UnaryPredicate: A model of :cpp:concept:`stl::UnaryPredicate`
:tparam std::UnaryPredicate: A model of :cpp:concept:`std::UnaryPredicate`
:return: True or false
......
......@@ -5,7 +5,7 @@ Include :file:`<mln/core/algorithm/clone.hpp>`
.. cpp:namespace:: mln
.. cpp:function:: image_concrete_t<InputImage> clone(InputImage src)
.. cpp:function:: InputImage{I} image_concrete_t<I> clone(I src)
Clone the values from the source image `src` to a destination image which is automatically deduced as the concrete type of the input.
This primitive is directed at:
......@@ -25,7 +25,6 @@ Include :file:`<mln/core/algorithm/clone.hpp>`
:tparam OutputImage: A model of :cpp:concept:`OutputImage`
:return: The concrete image of `src` with the same values
Examples
--------
......
......@@ -5,14 +5,14 @@ Include :file:`<mln/core/algorithm/count_if.hpp>`
.. cpp:namespace:: mln
.. cpp:function:: std::ptrdiff_t count_if(InputImage ima, UnaryPredicate p)
.. cpp:function:: std::ptrdiff_t count_if(InputImage ima, std::UnaryPredicate p)
Count the number of pixel whose value verify the predicate `p` in `ima`.
:param ima: The image to be trasversed
:param p: The predicate to verify
:tparam InputImage: A model of :cpp:concept:`InputImage`
:tparam UnaryPredicate: A model of :cpp:concept:`stl::UnaryPredicate`
:tparam std::UnaryPredicate: A model of :cpp:concept:`std::UnaryPredicate`
:return: number of pixels whose value verifies `p` in `ima`
......
......@@ -5,7 +5,7 @@ Include :file:`<mln/core/algorithm/equal.hpp>`
.. cpp:namespace:: mln
.. cpp:function:: bool equal(LhsImage lhs, RhsImage rhs)
.. cpp:function:: Image{A} Image{B} bool equal(A lhs, B rhs)
Compare the pixels of `lhs` and `rhs`.
The result is true if and only if rhs's values equal lhs's values.
......@@ -32,4 +32,4 @@ Complexity
----------
Linear in the number of pixels.
\ No newline at end of file
......@@ -5,7 +5,7 @@ Include :file:`<mln/core/algorithm/for_each.hpp>`
.. cpp:namespace:: mln
.. cpp:function:: void for_each(InputImage in, UnaryFunction f)
.. cpp:function:: void for_each(InputImage in, std::UnaryFunction f)
Applies the function `f` to every value of `in`. It can be used for in-place transformation.
......
......@@ -5,9 +5,9 @@ Include :file:`<mln/core/algorithm/transform.hpp>`
.. cpp:namespace:: mln
#. .. cpp:function:: void transform(InputImage in, OutputImage out, UnaryFunction f)
#. .. cpp:function:: void transform(InputImage in, OutputImage out, std::UnaryFunction f)
#. .. cpp:function:: image_ch_value_t<InputImage, R> transform(InputImage in, UnaryFunction f)
#. .. cpp:function:: image_ch_value_t<InputImage, R> transform(InputImage in, std::UnaryFunction f)
1) Applies the function `f` to every value of `in` and stores the result in `out`.
......
Core Types
==========
Enumerated types
----------------
.. doxygenenum:: sample_type_id
......@@ -10,6 +10,7 @@ Forsee to add pdim (point) and vdim (value) for dimension constant in iamge conc
.. contents::
:local:
.. cpp:namespace:: mln
Description & Design Overview
=============================
......@@ -231,11 +232,14 @@ Image Concepts
Image-related Concepts
^^^^^^^^^^^^^^^^^^^^^^
Concepts are defined in the namespace :cpp:expr:`mln::concepts`.
In the introduction, we have seen that an image *f* is function associating **points** to **values**. **Values** are
simple :cpp:concept:`std::Regular` types. **Points** are also :cpp:concept:`std::Regular` but are also
:cpp:concept:`StrictTotallyOrdered` because they are the basis of *domains*.
.. cpp:namespace:: mln::concepts
.. cpp:namespace:: mln
.. cpp:concept:: template <typename D> Domain
A *domain* is a :cpp:concept:`std::Range` of *points* which is totally ordered (this ensures a traversal order of
......@@ -330,9 +334,9 @@ The figure below illustrates image properties and some of the image concept.
Image Concept
^^^^^^^^^^^^^
#. .. cpp:concept:: template <class I> Image
#. .. cpp:concept:: template <class I> InputImage
#. .. cpp:concept:: template <class I> ForwardImage
#. .. cpp:concept:: template <typename I> Image
#. .. cpp:concept:: template <typename I> InputImage
#. .. cpp:concept:: template <typename I> ForwardImage
**Image** (also **ForwardImage** and **InputImage**) is the minimal concept for modeling images. It provides *read*
......@@ -611,6 +615,34 @@ Indexable Image Concept
| ``cima.delta_index(dp)`` | `index_type` | | Get the index difference for a shift of *dp* |
+----------------------------+--------------+--------------+----------------------------------------------------+
Image Traits
============
.. cpp:namespace:: mln
.. cpp:type:: template <class I> image_concrete_t = I::concrete_type
template <class I, class V> image_ch_value_t = I::ch_value_type<V>
Get the concrete of an image (a type that is writable and can be resized). In the second, it requests an
image whose value type is `V`.
.. cpp:type:: template <class I> image_value_t = I::value_type
template <class I> image_reference_t = I::reference
Get the type of the values of an image. *Value type* is the naked type, *reference* is the type returned
by the expression `ima(p)` which is generally `T&`.
.. cpp:type:: template <class I> image_domain_t = I::domain_type
template <class I> image_point_t = I::point_type
Get the type of the domain and the type of the points (*points* being the domain values)
.. cpp:type:: template <class I> image_index_t = I::index_type
Get the type of the index of :cpp:concept:`Indexable` images.
Image Views
===========
......
This diff is collapsed.
......@@ -23,25 +23,24 @@ Class hierarchy diagrams for ndpoints. They all implement the :cpp:class:`__Poin
Default constructor.
.. cpp:function:: ndpoint(const P& other)
.. cpp:function:: template <class P> ndpoint(const P& other)
Converting constructor from any point implementing the :cpp:class:`__PointInterface`. This overload is enabled
only if `P` is compatible with ``ndpoint`` i.e. if ``P::value_type`` is convertible to ``T`` and ``ndim == (-1
|| other.ndim)``.
Converting constructor from any point implementing the :cpp:class:`__PointInterface`. This overload is enabled only if `P` is compatible with ``ndpoint`` i.e. if ``P::value_type`` is convertible to ``T`` and
``ndim == (-1 || other.ndim)``.
.. cpp:function:: ndpoint(int dim)
Construction with the number of dimensions given dynamically. Only available when ``ndim == -1``.
.. cpp:class:: template <int ndim, class T> ndpointref
`ndpointref` represents a n-dimensional points (coordinates) over a grid. The number of dimensions can be known at
compile time or dynamic ``ndim = -1``. It has a reference semantic and should be used as a function parameter only.
1. .. cpp:function:: ndpointref(P& other)
2. .. cpp:function:: ndpointref(const P& other)
1. .. cpp:function:: template <class P> ndpointref(P& other)
2. .. cpp:function:: template <class P> ndpointref(const P& other)
Converting constructor from any point implementing the :cpp:class:`__PointInterface`. This overload is enabled only if `P` is compatible with ``ndpointref``, i.e. if ``P::value_type*`` is convertible to ``T*`` and ``ndim == (-1 || other.ndim)``.
......@@ -119,7 +118,7 @@ Any two points p₁ and p₂ of types P₁ and P₂ are said *compatible* if the
* Comparison
Two *compatible* points are comparable and totally ordered (:cpp:concept:`std::StrictTotallyOrdered`) using the lexicographical ordering.
Two *compatible* points are comparable and totally ordered (:cpp:concept:`std::totally_ordered`) using the lexicographical ordering.
* Arithmetics
......
......@@ -25,7 +25,7 @@ Arithmetical
.. code::
mln::image2d<mln::rgb8> ima1 = ...;
mln::image2d<mln::rgb8> ima2 = ...;
auto g1 = ima1 + ima2;
......@@ -383,10 +383,12 @@ Conditional
3. .. cpp:function:: auto ifelse(Image ima, Scalar s_if, Image ima2)
4. .. cpp:function:: auto ifelse(Image ima, Scalar s_if, Scalar s_else)
1. Makes a view where for each pixel value evals to :cpp:expr:`out(p) = ima(p) ? ima1(p) : ima2(p)`.
2. Makes a view where for each pixel value evals to :cpp:expr:`out(p) = ima(p) ? ima1(p) : s_else`.
3. Makes a view where for each pixel value evals to :cpp:expr:`out(p) = ima(p) ? s_if : ima2(p)`.
4. Makes a view where for each pixel value evals to :cpp:expr:`out(p) = ima(p) ? s_if : s_else`.
.. Sphinx CPP domain with texpr does not support ternary ops
1. Makes a view where for each pixel value evals to ``out(p) = (ima(p) ? ima1(p) : ima2(p))``.
2. Makes a view where for each pixel value evals to ``out(p) = (ima(p) ? ima1(p) : s_else)``.
3. Makes a view where for each pixel value evals to ``out(p) = (ima(p) ? s_if : ima2(p))``.
4. Makes a view where for each pixel value evals to ``out(p) = (ima(p) ? s_if : s_else)``.
:param ima: Input range
......@@ -396,7 +398,7 @@ Conditional
.. code::
mln::image2d<int> ima = ...;
mln::image2d<int> ima1 = ...;
mln::image2d<int> ima2 = ...;
......
......@@ -5,7 +5,7 @@ Include :file:`<mln/core/image/view/transform.hpp>`
.. cpp:namespace:: mln::view
#. .. cpp:function:: auto transform(Image ima, UnaryFunction f)
#. .. cpp:function:: auto transform(Image ima, std::UnaryFunction f)
#. .. cpp:function:: auto transform(Image ima, Image ima2, BinaryFunction f)
1. Makes a view from `ima` where for each pixel value evals to :cpp:expr:`out(p) = f(ima(p))`
......
......@@ -3,16 +3,29 @@
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to Pylene's documentation!
==================================
Pylene : a modern C++ image processing library
==============================================
|Pylene| is an open-source image processing library that aims at proving a generic framework to develop IP algorithms
with safety, simplicity and performance in Mind. It is originated from Milena_ with the following objectives:
* Simplicity: simple modern C++ syntax with Python binding (in development)
* Efficiency: write algorithms in a simple way and run them as if they were written in C .We follow one guideline: zero-cost abstraction.
* Genericity: write algorithms that are able to run on many kind of images with, yet, zero-cost abstraction.
* Interoperability: run algorithms on image coming from and to external libraries (even on your own image type).
|Pylene| features ready-to-use image data structures (regular 2D, 3D images) and focus (but is not limited to
Mathematical Morphology Operators).
Contents:
.. toctree::
:maxdepth: 2
Introduction <intro>
Quick Start <tutorial>
tutorial
community
Reference Manual <reference>
Developer Manual <ruminations>
......
......@@ -80,6 +80,8 @@ Example with the 5-7-11 weights::
CDT with 5-7-11 :cpp:ref:`mln::wmask2d` (5-7-11 distance)
-
References
----------
......
......@@ -39,7 +39,7 @@ Segmentation
Component Trees & Hierarchical Representations
*********************************************
**********************************************
.. toctree::
:maxdepth: 1
......
......@@ -6,8 +6,8 @@ Include :file:`<mln/morpho/area_filter.hpp>`
.. cpp:namespace:: mln::morpho
.. cpp:function:: \
Image{I} concrete_t<I> area_opening(I f, Neighborhood nbh, int area, Compare cmp)
Image{I} concrete_t<I> area_closing(I f, Neighborhood nbh, int area)
Image{I} image_concrete_t<I> area_opening(I f, Neighborhood nbh, int area, Compare cmp)
Image{I} image_concrete_t<I> area_closing(I f, Neighborhood nbh, int area)
On binary images, the area connected opening that preserves connected
......
......@@ -6,8 +6,8 @@ Include :file:`<mln/morpho/structural/closing.hpp>`
.. cpp:namespace:: mln::morpho
.. cpp:function:: \
Image{I} concrete_t<I> closing(I image, StructuringElement se)
Image{I} concrete_t<I> closing(I image, StructuringElement se, BorderManager bm)
Image{I} image_concrete_t<I> closing(I image, StructuringElement se)
Image{I} image_concrete_t<I> closing(I image, StructuringElement se, BorderManager bm)
void closing(Image image, StructuringElement se, OutputImage out)
void closing(Image image, StructuringElement se, BorderManager bm, OutputImage out)
......
......@@ -9,8 +9,8 @@ Include :file:`<mln/morpho/dilation.hpp>`
.. cpp:function:: \
Image{I} concrete_t<I> dilation(I image, StructuringElement se)
Image{I} concrete_t<I> dilation(I image, StructuringElement se, BorderManager bm)
Image{I} image_concrete_t<I> dilation(I image, StructuringElement se)
Image{I} image_concrete_t<I> dilation(I image, StructuringElement se, BorderManager bm)
void dilation(Image image, StructuringElement se, OutputImage out)
void dilation(Image image, StructuringElement se, BorderManager bm, OutputImage out)
......
......@@ -6,8 +6,8 @@ Include :file:`<mln/morpho/area_filter.hpp>`
.. cpp:namespace:: mln::morpho
.. cpp:function:: \
Image{I} concrete_t<I> dynamic_opening(I f, Neighborhood nbh, int h)
Image{I} concrete_t<I> dynamic_closing(I f, Neighborhood nbh, int h)
Image{I} image_concrete_t<I> dynamic_opening(I f, Neighborhood nbh, int h)
Image{I} image_concrete_t<I> dynamic_closing(I f, Neighborhood nbh, int h)
On grayscale images, the dynamic connected opening removes maxima whose
......
......@@ -3,10 +3,11 @@ Erosion
Include :file:`<mln/morpho/erosion.hpp>`
.. cpp:namespace:: mln::morpho
.. cpp:function:: \
Image{I} concrete_t<I> erosion(I image, StructuringElement se)
Image{I} concrete_t<I> erosion(I image, StructuringElement se, BorderManager bm)
Image{I} image_concrete_t<I> erosion(I image, StructuringElement se)
Image{I} image_concrete_t<I> erosion(I image, StructuringElement se, BorderManager bm)
void erosion(Image image, StructuringElement se, OutputImage out)
void erosion(Image image, StructuringElement se, BorderManager bm, OutputImage out)
......
......@@ -6,8 +6,8 @@ Include :file:`<mln/morpho/extinction_transform.hpp>`
.. cpp:namespace:: mln::morpho
.. cpp:function:: \
Image{I} concrete_t<I> minima_extinction_transform(I ima, Neighborhood nbh)
Image{I} concrete_t<I> maxima_extinction_transform(I ima, Neighborhood nbh)
Image{I} image_concrete_t<I> minima_extinction_transform(I ima, Neighborhood nbh)
Image{I} image_concrete_t<I> maxima_extinction_transform(I ima, Neighborhood nbh)
The notion of *extinction* of a local extremum is based on the h-extrema (see. :doc:`dynamic_filter`).
The extinction value of a bassin corresponds its *dynamic* when it merges with another basin.
......
......@@ -6,7 +6,7 @@ Include :file:`<mln/morpho/fill_hole.hpp>`
.. cpp:namespace:: mln::morpho
.. cpp:function:: \
Image{I} concrete_t<I> fill_hole(I f, Neighborhood nbh, image_point_t<I> marker)
Image{I} image_concrete_t<I> fill_hole(I f, Neighborhood nbh, image_point_t<I> marker)
Image{I} void fill_hole(I f, Neighborhood nbh, image_point_t<I> marker, Image out)
The holes of a binary image correspond to the set of its regional minima which
......
......@@ -6,9 +6,9 @@ Include :file:`<mln/morpho/gradient.hpp>`
.. cpp:namespace:: mln::morpho
.. cpp:function:: \
Image{I} concrete_t<I> gradient(I f, StructuringElement se)
Image{I} concrete_t<I> external_gradient(I f, StructuringElement se)
Image{I} concrete_t<I> internal_gradient(I f, StructuringElement se)
Image{I} image_concrete_t<I> gradient(I f, StructuringElement se)
Image{I} image_concrete_t<I> external_gradient(I f, StructuringElement se)
Image{I} image_concrete_t<I> internal_gradient(I f, StructuringElement se)
Compute the morphological gradients. Morphological gradients are
operators enhancing variations of pixel intensity in a neighborhood
......
......@@ -8,7 +8,7 @@ Include :file:`<mln/morpho/hit_or_miss.hpp>`
.. cpp:namespace:: mln::morpho
.. cpp:function:: \
Image{I} concrete_t<I> hit_or_miss(I image, StructuringElement se_hit, StructuringElement se_miss)
Image{I} image_concrete_t<I> hit_or_miss(I image, StructuringElement se_hit, StructuringElement se_miss)
void hit_or_miss(Image image, StructuringElement se_hit, StructuringElement se_miss, OutputImage out)