* mln/topo/center_only_iter.hh: New.
* tests/topo/complex.cc: Exercise this iterator.
---
milena/ChangeLog | 7 ++
milena/mln/topo/center_only_iter.hh | 134 +++++++++++++++++++++++++++++++++++
milena/tests/topo/complex.cc | 14 ++++
3 files changed, 155 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/topo/center_only_iter.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 5097f23..5375a7d 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,12 @@
2008-10-04 Roland Levillain <roland(a)lrde.epita.fr>
+ Add a complex relative iterator iterating on its center only.
+
+ * mln/topo/center_only_iter.hh: New.
+ * tests/topo/complex.cc: Exercise this iterator.
+
+2008-10-04 Roland Levillain <roland(a)lrde.epita.fr>
+
Fix initialization and access to values in mln::complex_image.
* mln/core/image/complex_image.hh
diff --git a/milena/mln/topo/center_only_iter.hh b/milena/mln/topo/center_only_iter.hh
new file mode 100644
index 0000000..d55ffca
--- /dev/null
+++ b/milena/mln/topo/center_only_iter.hh
@@ -0,0 +1,134 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_TOPO_CENTER_ONLY_ITER_HH
+# define MLN_TOPO_CENTER_ONLY_ITER_HH
+
+/// \file mln/topo/center_only_iter.hh
+///
+/// \brief Definition of a complex relative iterator iterating on its
+/// center (reference face) only.
+///
+/// \see mln/topo/centered_iter_adapter.hh
+
+# include <mln/topo/internal/complex_relative_iterator_base.hh>
+# include <mln/topo/face.hh>
+
+
+namespace mln
+{
+
+ namespace topo
+ {
+
+ // Forward declaration.
+ template <unsigned D> class face;
+
+
+ /*----------------------------.
+ | topo::center_only_iter<D>. |
+ `----------------------------*/
+
+ /** \brief Iterator on all the adjacent (n-1)-faces of the n-face
+ of an mln::complex<D>.
+
+ \arg \p D The dimension of the complex this iterator belongs to.
+
+ mln::topo::center_only_iter inherits from
+ mln::topo::internal::forward_complex_relative_iterator_base,
+ but it could inherit from
+ mln::topo::internal::backward_complex_relative_iterator_base
+ as well, since it always contains a single element, the
+ center/reference face (and the traversal order is
+ meaningless).
+
+ This iterator is essentially used to implement other iterators.
+ \see mln::topo::centered_iter_adapter
+ \see mln::complex_lower_window
+ \see mln::complex_higher_window
+ \see mln::complex_lower_higher_window */
+ template <unsigned D>
+ class center_only_iter
+ : public internal::forward_complex_relative_iterator_base< face<D>,
+ center_only_iter<D> >
+ {
+ private:
+ typedef center_only_iter<D> self_;
+ typedef internal::forward_complex_relative_iterator_base< face<D>,
+ self_ > super_;
+
+ public:
+ /// Construction.
+ /// \{
+ center_only_iter();
+ template <typename Fref>
+ center_only_iter(const Fref& f_ref);
+ /// \}
+
+ /// Compute the set of faces adjacent to the reference face.
+ void update_adj_faces_();
+ };
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ /*----------------------------.
+ | topo::center_only_iter<D>. |
+ `----------------------------*/
+
+ template <unsigned D>
+ inline
+ center_only_iter<D>::center_only_iter()
+ {
+ }
+
+ template <unsigned D>
+ template <typename Fref>
+ inline
+ center_only_iter<D>::center_only_iter(const Fref& f_ref)
+ : super_(f_ref)
+ {
+ }
+
+ template <unsigned D>
+ inline
+ void
+ center_only_iter<D>::update_adj_faces_()
+ {
+ mln_precondition(this->c_);
+ this->adj_faces_.clear();
+ this->adj_faces_.push_back(*this->c_);
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::topo
+
+} // end of namespace mln
+
+#endif // ! MLN_TOPO_CENTER_ONLY_ITER_HH
diff --git a/milena/tests/topo/complex.cc b/milena/tests/topo/complex.cc
index 9e559de..92d0398 100644
--- a/milena/tests/topo/complex.cc
+++ b/milena/tests/topo/complex.cc
@@ -33,6 +33,7 @@
#include <iostream>
#include <mln/topo/complex.hh>
+#include <mln/topo/center_only_iter.hh>
using namespace mln;
@@ -324,6 +325,19 @@ int main()
face<D>'s.
-----------------------------------------------------------------
*/
+
+ /*------------------.
+ | Other iterators. |
+ `------------------*/
+
+ // For each face, iterate on itself. (This iterator is not
+ // interesting as-is, but is useful when combined with others,
+ // e.g. in topo::centered_iter_adapter).
+ topo::center_only_iter<D> center(fwd_f);
+ for_all(fwd_f)
+ for_all(center)
+ std::cout << " " << center << std::endl;
+ std::cout << std::endl;
}
--
1.6.0.1
URL: https://svn.lrde.epita.fr/svn/oln/branches/cleanup-2008/milena
ChangeLog:
2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr>
Update tutorial..
* milena/doc/tutorial/tutorial.tex:
- Add a new section about sites
- Add new subsections about image domain and values.
- Talk about operator '/' used to create sub images.
---
tutorial.tex | 460 ++++++++++++++++++++++++++++++++++++++---------------------
1 file changed, 304 insertions(+), 156 deletions(-)
Index: branches/cleanup-2008/milena/doc/tutorial/tutorial.tex
===================================================================
--- branches/cleanup-2008/milena/doc/tutorial/tutorial.tex (revision 2502)
+++ branches/cleanup-2008/milena/doc/tutorial/tutorial.tex (revision 2503)
@@ -4,6 +4,7 @@
\usepackage{makeidx}
\usepackage{xcolor}
\usepackage{color}
+\usepackage{html}
\newcommand{\img}[4]{
\begin{figure}[ht!]
@@ -19,37 +20,66 @@
\author{LRDE}
\date{}
+\definecolor{ccomment}{rgb}{0.5,0,0}
+\definecolor{cstring}{rgb}{0,0.32,0.5}
+\definecolor{cidentifier}{rgb}{0,0.5,0}
+\definecolor{cbg}{rgb}{0.95,0.95,0.95}
+
%%%LISTINGS SETTINGS
\lstset{frameround=fttt}
\lstloadlanguages{C++}
\lstset{language=C++}
-\lstset{backgroundcolor=\color{black},
-basicstyle=\bfseries\color{white},
-identifierstyle=\color{green},
-stringstyle=\color{yellow},
-commentstyle=\color{red},
+
+%\lstset{backgroundcolor=\color{black},
+%basicstyle=\bfseries\color{white},
+%identifierstyle=\color{green},
+%stringstyle=\color{yellow},
+%commentstyle=\color{red},
+%showstringspaces=false,linewidth=14cm}
+
+\lstset{backgroundcolor=\color{cbg},
+basicstyle=\bfseries\color{black},
+identifierstyle=\color{black},
+stringstyle=\color{cstring},
+commentstyle=\color{ccomment},
showstringspaces=false,linewidth=14cm}
+\newenvironment{doxycode}
+{% This is the begin code
+\begin{latexonly}%
+\begin{lstlisting}[frame=single]%
+\end{latexonly}%
+\begin{htmlonly}%
+\backslash code%
+\end{htmlonly}%
+}
+{%
+\begin{htmlonly}%
+\backslash endcode%
+\end{htmlonly}%
+\begin{latexonly}%
+\end{lstlisting}%
+\end{latexonly}%
+}
+
+
+
\begin{document}
\tableofcontents
-ajouter dans => milena/doc/tutorial |
--------------------------------------------------
-
-\chapter{Foreword}
+\chapter*{Foreword}
-The following tutorial talks about 2D images. We chose that kind of images
-because it is easier to understand and this is the
-most used. \\
+The following tutorial explains the basic concepts behind Olena and how to use
+the most common objects and routines.
+This tutorial includes many code examples and figures. In order to make this
+tutorial easier to understand, we will mainly talk about 2D images. This is
+not so restrictive since 1D, 3D, $n$D images behave the same way.
-FIXME
-[dessin de grille 2d, colonnes/lignes numerotees + repere x/y]
-Intersection <=> point 2d <=> milieu d'un pixel \\
Since examples are based on 2D images pixels are actually "points" however we
-will call them "sites" which is the most generic name.\\
+will call them "sites" which is the most generic name.\newline
Here is also a list of common variable name conventions:
\begin{figure}[ht!]
@@ -63,21 +93,53 @@
\end{tabular}
\end{figure}
-Methods provided by the objects in the library are in constant time. If you need
-a specific method but you cannot find it, you may find an algorithm which can
-compute the information you need.
-
Olena is organized in a namespace hierarchy. Everything is declared by Olena
within the 'oln::' namespace, and possibly a sub-namespace such as
'oln::arith::' (arithmetic operations on images), 'oln::morpho::' (morphological
-operations), etc. For the sake of simplicity, we will neglect the 'oln::'
+operations), etc. Usually, the namespace hierarchy is mapped to the mln
+directory tree. For the sake of simplicity, we will neglect the 'oln::'
prefix in all the code examples.
+Methods provided by objects in the library are in constant time. If you need
+a specific method but you cannot find it, you may find an algorithm which can
+compute the information you need.
+
+\clearpage
+\newpage
+\chapter{Site}
+
+Usually, when talking about images, we think about common images composed of a
+set of pixels.
+Since Olena is generic, we want to support many kind of images, even images
+which are not composed of a set of pixels, such as images of images.
+
+In order to express this genericity, we have the ``site'' concept.
+This concept allows us to divide a pixel into two information:
+\begin{itemize}
+ \item The coordinates (the site itself).
+ \item The value.
+\end{itemize}
+
+Let's say we have 2D grid like this:
+
+//FIXME
+[dessin de grille 2d, colonnes/lignes numerotees + repere x/y]
+Intersection == point 2d == milieu d'un pixel \\
+
+On a regular grid like this, in 2D, we usually use a 2D point as a site which
+means we have the following equivalence:
+
+\begin{center}
+ Intersection $\equiv$ point2d (2D site) $\equiv$ center of a pixel
+\end{center}
+
+The site does not store any value but refer to an area where we will be able
+to read its value.
-\chapter{Concepts}
-//FIXME lister \underline{TOUS} les concepts (core/concepts)
-\section{Site set}
+\clearpage
+\newpage
+\chapter{Site set}
Site sets are used:
\begin{enumerate}
@@ -85,66 +147,67 @@
\item As Site container.
\end{enumerate}
+They do not actually store any image value. They only store site information.
+
Here is a list of all the site set concepts which can be found in
core/site\_set:
\begin{tabular}{|l|p{8cm}|}
\hline
-Site set & Description \\ \hline
+Site set & Description \\
+\hline
-p\_key & \\ \hline
-p\_priority & \\ \hline
-p\_box & \\ \hline
-p\_bgraph & \\ \hline
-p\_double & \\ \hline
-p\_if & \\ \hline
-p\_line\_graph & \\ \hline
-p\_queue\_fast & \\ \hline
-p\_set & \\ \hline
-p\_faces & \\ \hline
-p\_queue & \\ \hline
-p\_set\_of & \\ \hline
-line2d & \\ \hline
-p\_complex & \\ \hline
-p\_graph & \\ \hline
-p\_image & \\ \hline
-p\_mutable\_array\_of & \\ \hline
-p\_run & \\ \hline
-p\_vaccess & \\ \hline
+p\_array & site array. \\
+\hline
+p\_box & compact domain definde on a regular grid (in 2D, a rectangle). \\
+\hline
+p\_if & site set verifying a predicate. \\
+\hline
+p\_queue & site queue. \\
+\hline
+p\_run & site range. \\
+\hline
+p\_runs & site range set. \\
+\hline
+p\_set & mathematical site set. \\
+\hline
+p\_vaccess & site set ordered by value. \\
+\hline
+p\_edges & set of graph edges associated to sites. \\
+\hline
+p\_vertices & set of graph vertices associated to sites.\\
+\hline
\end{tabular}
-\subsection{Basic interface}
+\section{Basic interface}
Common basic interface:\\
\begin{tabular}{|l|l|l|l|p{4cm}|}
\hline
-Return Type & Name & Arguments & Const & Commor type automatically from the
-given container type
-passed as parameter. These macros can be used with any container like images or
-site sets.ents \\ \hline
+Return Type & Name & Arguments & Const & Comments \\ \hline
bool & is\_valid & - & X & Returns true if it has been initialized. The
-default constructor does not do it. \\ \hline
+default constructor does not initialize it. \\ \hline
bool & has & const P\& p & X & \\ \hline
\end{tabular} \\
-\subsection{Optional interface}
+\section{Optional interface}
Site sets may have other methods depending on their type: \\
\begin{tabular}{|l|l|l|l|p{4cm}|}
\hline
Return Type & Name & Arguments & Const & Comments \\ \hline
-size\_t & nsites & - & - & \\ \hline
+size\_t & nsites & - & - & Return the number of sites. \\ \hline
const Box\& & bbox & - & X & Bounding box. Available only on grid site sets.
\\ \hline
\end{tabular} \\
The previous methods are available depending on the site set. A box
will have the bbox() method since it can be retrived in constant time: a box
-is it's own bounding box (see \ref{fig:box_bbox}).
+is it's own bounding box.
\begin{lstlisting}[frame=single]
box2d b(2,3);
@@ -164,6 +227,7 @@
P\_array and box both have a nsites method since the internal structure allow a
constant time retrieval.
+%\begin{doxycode}
\begin{lstlisting}[frame=single]
p_array<point2d> arr;
@@ -175,13 +239,12 @@
// it can be retrieved in constant time.
std::cout << "nsites = " << arr.nsites() << std::endl;
\end{lstlisting}
-
-
+%\end{doxycode}
\clearpage
\newpage
-\section{Image}
+\chapter{Image}
An image is composed both of:
\begin{itemize}
@@ -196,31 +259,21 @@
\item A site set, also called the "domain".
\end{itemize}
-An image2d will always have its bouding box defined by a box2d whatever the
-site set used to define its domain.
-The Value set, which includes all the possible values a site can have, is also
-called "destination" set.
-
-An image has a virtual border which is defined thanks to its domain. The
- border is virtual since the image can have an extended domain as well.
-That one is optional, it defines sites outside the virtual border which is
-useful in algorithms when working with sites being part of the domain but close
-to the borders. The extended domain can be defined thanks to a function, an
-image or a site set.
-
-//FIXME: remove this line
-ici, site <=> Point2d
-
-
\section{About value, rvalue and lvalue}
+Since the values are of a specific type, it exists a set of all the possible
+site values. This set is called "destination" set. It may be iterable and
+printable if it is finite and not too huge.
+
Image types provide a method to access values, namely "operator() const".
Yet, its signature is NOT "value operator()(const site\& p) const"
but "rvalue operator()(const psite\& p) const"
For instance, with I being image2d$<$int\_u8$>$, we have :
+\begin{center}
I::value == int\_u8 but I::rvalue == const int\_u8\&
+\end{center}
so copying the value when the call "f(p)" returns is avoided.
In that case, it is a low-level implementation issue that makes rvalue
@@ -233,8 +286,48 @@
With I being image2d$<$int\_u8$>$, we have :
+\begin{center}
I::value == int\_u8 but I::lvalue == int\_u8\&
+\end{center}
+
+\section{Domain}
+The site set contains the sites which compose the image. Sites are based on a
+grid so the image depends on that grid as well.
+It means that an image 2D can only be defined by sites based on a 2D grid.
+Likewise, an image2d will always have its bouding box defined by a box2d.
+
+Being defined on a grid means that the image can be defined anywhere.
+For instance, defining a 2D image with a box2d starting from point (-20, -20)
+ to (-3, 5) is completely valid.
+
+The following example shows that the definition domain and the site set are
+exactly equivalent.
+
+\begin{lstlisting}[frame=single]
+ box2d b(-2,3, 3,-5); // Define a box2d from (-2,3) to (3,-5).
+ image2d<int> ima(b); // Define the domain of the image.
+
+ cout << b << std::endl; // Display b
+
+ cout << ima.domain() << std::endl; // Display b too
+\end{lstlisting}
+
+
+\section{Border and extension}
+// FIXME: COMPLETELY WRONG!!!
+// FIXME: Tell that the user can disable the border/extension: foo(ima | ima.domain())
+An image has a virtual border which is defined thanks to its domain. The
+ border is virtual since the image can have an extended domain as well.
+That one is optional, it defines sites outside the virtual border which is
+useful in algorithms when working with sites being part of the domain but close
+to the borders. The extended domain can be defined thanks to a function, an
+image or a site set.
+//FIXME ADD FIGURE
+
+\section{Morphed images}
+//FIXME: Write it!
+// Pas concrete, light, how to concrete
\section{Sample code}
In order to create a 2D image, you have two possibilites:
@@ -248,32 +341,24 @@
The empty image has no data and its definition domain is still unset. We do
not know yet the number of sites it contains. However, it is really useful to
have such an "empty image" because it is a placeholder for the result of some
-processing, or another image.
-
-Trying to access the site value from an empty image leads to an error at
-run-time.
-
+processing, or another image. Trying to access the site value from an empty
+image leads to an error at run-time.
-\begin{lstlisting}[frame=single]
- box2d b(2,3);
- image2d<int> ima(b); // Define the domain of the image.
-
- cout << b << std::endl; // Display b
-
- cout << ima.domain() << std::endl; // Display b too
-\end{lstlisting}
+The following example illustrates how to map data to a site throughout the
+image.
\begin{lstlisting}[frame=single]
box2d b(2,3);
image2d<int> ima(b);
point2d p(1, 2);
- ima.at(1,2) = 9; // The value is returned by reference
- // and can be changed.
+ // Associate '9' as value for the site/point2d (1,2).
+ // The value is returned by reference and can be changed.
+ ima.at(1,2) = 9;
cout << ima(p) << std::endl; // prints 9
ima(p) = 2; // The value is returned by reference
- // and can be changed.
+ // and can be changed as well.
cout << ima(p) << std::endl; // prints 2
\end{lstlisting}
@@ -287,7 +372,7 @@
std::cout << (imga.has(p) ? "true" : "false") << std::endl;
\end{lstlisting}
-Since the notion of point is independent from the image it applies on, we can
+Since the notion of site is independent from the image it applies on, we can
form expressions where p is used on several images:
\begin{lstlisting}[frame=single]
// At index (9, 9), both values change.
@@ -298,7 +383,7 @@
\end{lstlisting}
-Images do not actually store the data in the class. This is a pointer
+Images do not actually store the data in the class. Images store a pointer
to an allocated space which can be shared with other objects. Once an image is
assigned to another one, the two images share the same data so they have the
same ID and point to the same memory space.
@@ -338,7 +423,7 @@
In the Olena library, all image types behave like image2d:
\begin{itemize}
-\item An "empty" image actually is a mathematical variable.
+\item An "empty" image is actually a mathematical variable.
$\rightarrow$ just think in a mathemetical way when dealing with images;
@@ -357,7 +442,7 @@
-\subsection{Interface}
+\section{Interface}
\begin{tabular}{|l|l|l|l|p{4cm}|}
\hline
@@ -381,19 +466,16 @@
\end{tabular}
-
-\newpage
-\section{Neighborhood}
-
-
-
+\clearpage
\newpage
-\section{Window}
+\chapter{Window and Neighborhood}
-\chapter{Sites and psites}
+\clearpage
+\newpage
+\chapter{Sites, psites and dpoints}
\section{Need for site}
@@ -432,7 +514,7 @@
Let's have a small example. Define a function returning a value for a given
point:
-
+\clearpage
\begin{lstlisting}[frame=single]
unsigned my_values(const point2d& p)
{
@@ -471,13 +553,10 @@
+-+-+
\end{lstlisting}
-However, in memory, since it is based on a p\_array, values are stored in a
+However, in memory, since it is based on a p\_array, sites are stored in a
vector.
-The site x is the point (3, 7). The image values are stored in a
-vector where the index is the offset of the cell from the beginning of the
-vector. The site x thus corresponds to the cell 1.
-
+The site x is the point (3, 7) which corresponds to the cell 1 in the p\_array.
\begin{lstlisting}[frame=single]
arr[] = 0 1 2 3 4
@@ -486,9 +565,10 @@
+-+-+-+-+-+
\end{lstlisting}
-Obviously, from the site coordinates, we cannot access the associated data in
-constant-time. That's why we need a different mechanism in order to access
-this data: the psites.
+Obviously, we cannot check in constant time whether the site x, point2d here,
+is part of that image or not: knowing the point coordinates is not enough.
+That's why we need a different mechanism in order to access this information:
+the psites.
Here we have:
@@ -520,14 +600,18 @@
How it works: a psite inherits from internal::site\_impl$<$site$>$ which is
specialized for every site type; for instance, internal::site\_impl$<$point2d$>$
owns the method "coord row() const" which is defined as
-"return exact(this)->to\_site().row()"
+"return exact(this)-$>$to\_site().row()"
+\section{Need for dpoint}
+//FIXME
+\clearpage
+\newpage
\chapter{Iterators}
Each container object in Olena like site sets or images have iterators.
The iteration mechanism for images is directly derived from the mechanism
-for site set.
+for site sets.
There are usually three kinds:
\begin{itemize}
@@ -552,7 +636,7 @@
As you may have noticed, according to the data type, the word "iter" is prefixed
by the usual name variable used for that data type. Sites variables are usually
-called 'p' so the proper iterator is "piter".\\
+called 'p' so the proper iterator is "piter". (See the foreword)\\
An iterator has the following interface: \\
@@ -589,19 +673,32 @@
passed as parameter. These macros can be used with any container like images or
site sets.
-\begin{lstlisting}[frame=single]
- image2d<int> ima(box2d(2, 3));
+Here follow an example with the implemantions of the most basic routines which use the for\_all
+loop: fill and paste.
- mln_piter(box2d) p(ima.domain());
+\begin{lstlisting}[frame=single]
+template <typename I>
+void fill(I& ima, mln_value(I) v)
+{
+ mln_piter(I) p(ima.domain());
for_all(p)
- std::cout << p << std::endl;
-
- mln_viter(image2d<int>) v(ima.destination());
- for_all(v)
- std::cout << v << std::endl;
+ ima(p) = v;
+}
\end{lstlisting}
+\begin{lstlisting}[frame=single]
+template <typename I, typename J>
+void paste(const I& data, J& dest)
+{
+ mln_piter(I) p(data.domain());
+ for_all(p)
+ dest(p) = data(p);
+}
+\end{lstlisting}
+
+\clearpage
+\newpage
\chapter{Basic operations}
//FIXME : illustrer
@@ -620,8 +717,7 @@
\hline
\end{tabular} \\
-
-\section{Examples}
+\section{Fill}
First, create an image:
\begin{lstlisting}[frame=single]
image2d<char> imga(0, 0, 20, 20);
@@ -645,6 +741,7 @@
strictly map their C++ name; so oln::level::fill is defined in the file
"oln/level/fill.hh".
+\subsection*{Note}
Most algorithms in Olena are constructed following the classical scheme: "output
algo(input)", where the input image is only read. However some few algorithms
take an input image in order to modify it. To enforce this particular feature,
@@ -652,9 +749,10 @@
modified "inplace". The algorithm call shall be "level::fill(inplace(ima),
val)". When forgetting the "inplace(..)" statement it does not compile.
+
+\section{Paste}
We then define below a second image to play with. As you can see this image has
-data for the sites (5, 5) to (14, 14) (so it has 100 sites). The definition
-domain of a 2D image can start from any sites, even a negative one.
+data for the sites (5, 5) to (14, 14) (so it has 100 sites).
\begin{lstlisting}[frame=single]
image1d<char> imgb(5, 5, 14, 14);
@@ -677,6 +775,7 @@
//FIXME : ajouter des zolies zimages again.
+\subsection*{Note}
With this simple example we can see that images defined on different domains (or
set of sites) can interoperate. The set of sites of an image is defined and
can be accessed and printed. The following code:
@@ -701,37 +800,13 @@
(whose values are to be pasted) is a subset of the destination image.
-\begin{figure}[ht!]
- \begin{lstlisting}[frame=single]
-template <typename I>
-void fill(I& ima, mln_value(I) v)
-{
- mln_piter(I) p(ima.domain());
- for_all(p)
- ima(p) = v;
-}
- \end{lstlisting}
- \caption{Implementation of the fill routine.\label{fig:fill_impl}}
-\end{figure}
-
-
-\begin{figure}[ht!]
- \begin{lstlisting}[frame=single]
-template <typename I, typename J>
-void paste(const I& data, J& dest)
-{
- mln_piter(I) p(data.domain());
- for_all(p)
- dest(p) = data(p);
-}
- \end{lstlisting}
- \caption{Implementation of the paste routine.\label{fig:paste_impl}}
-\end{figure}
+\section{Blobs}
+//FIXME: write it!
\newpage
\section{Working with parts of an image}
-Sometime it may be interesting to work only on some part of the image or to
+Sometime it may be interesting to work only on some parts of the image or to
extract only a sub set of that image. Olena enables that thoughout out the
operator '$|$'.
@@ -751,14 +826,14 @@
A Sub Domain can be a site set, an image or any value returned by this
operator.
For a given site, Function\_p2v returns a Value and Function\_p2b returns a
-boolean. These functions. are actually a sort of predicate. You can easily get
-of function of function\_p2v kind thanks to pw::value(Image). It returns the
+boolean. These functions. are actually a sort of predicate. A common
+function\_p2v is pw::value(Image). It returns the
point to value function used in the given image. C functions can also be used as
predicate by passing the function pointer.
You can easily get a function\_p2b by comparing the value returned
by a function\_p2v to another Value.
-The following sample code illustrates this feature.
+The following sample codes illustrate this feature.
In order to use C functions as predicate, they must have one of the following
prototype if you work on 2D images:
@@ -773,7 +848,7 @@
Of course, you just need to change the point type if you use another image
type. For instance, you would use point3d with 3D images.
The returned value type V for function\_p2v depends on the image value type.
-With image2d<int>, V would be int.
+With image2d$<$int$>$, V would be int.
In this section, all along the examples, the image "ima" will refer to the
following declaration:
@@ -826,7 +901,7 @@
// Get the sub site set containing only the sites
// part of component 2.
- mln_VAR(lab_2, lab_2b.domain(1));
+ mln_VAR(lab_2, lab_2b.domain(true));
// Fill the sites of component 2 with red.
fill(lab_2, color::red);
@@ -861,9 +936,82 @@
...
}
\end{lstlisting}
+%
+%
+\medskip
+%
+%
+\subsection*{Important note}
+When writing:
+
+\begin{lstlisting}[frame=single]
+ ima | sub_D
+\end{lstlisting}
+
+sub\_D must be included in ima.domain().
+
+Let's have an image, \textit{imab}, like this:
+\begin{lstlisting}[frame=single]
+0 1 0
+1 1 1
+\end{lstlisting}
+
+Extract a sub image from \textit{imab} with sites having their value set to 1.
+\begin{lstlisting}[frame=single]
+mln_VAR(imab1, imab | (pw::value(imab) == 1u));
+\end{lstlisting}
+
+Then, \textit{imab1} looks like:
+\begin{lstlisting}[frame=single]
+ 1
+1 1 1
+\end{lstlisting}
+
+Now, if we want to extract a sub image it may fail, depending on the site set
+used:
+\begin{lstlisting}[frame=single]
+box2d b1(1,0, 1, 2);
+mln_VAR(imac, imab1 | b1);
+
+// Print:
+// 1 1 1
+debug::prinln(imac);
+
+box2d b2(0,0, 1, 1);
+// Will fail at runtime.
+// ima.domain().has((0,0)) is false.
+mln_VAR(imad, imab1 | b2);
+debug::prinln(imad);
+\end{lstlisting}
+
+If you do not want this constraint, you may want to use an alternative
+operator:
+\begin{lstlisting}[frame=single]
+ ima / sub_D
+\end{lstlisting}
+
+In that case there is no restriction on the domain at all and the following example will work.
+\begin{lstlisting}[frame=single]
+box2d b2(0,0, 1, 1);
+
+mln_VAR(imad, imab1 / b2);
+
+// Print
+// 1
+// 1 1
+debug::prinln(imad);
+\end{lstlisting}
+With this operator, an intersection is applied on the image domain and the
+site set.
+
+\newpage
+\clearpage
\chapter{Graphes and images}
+
+//FIXME: REWRITE
+
\section{Description}
Olena enables the possibility of using graphes with images.
Graphes can help you to handle directly parts of an image and represent their
---
ChangeLog | 81 ++++++++
milena/mln/core/site_set/p_edges.hh | 262 ++++++++++++++++++++++++++
milena/mln/util/internal/graph_edge_psite.hh | 126 ++++++++++++
milena/tests/core/site_set/Makefile.am | 2 +
milena/tests/core/site_set/p_edges.cc | 93 +++++++++
5 files changed, 564 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/core/site_set/p_edges.hh
create mode 100644 milena/mln/util/internal/graph_edge_psite.hh
create mode 100644 milena/tests/core/site_set/p_edges.cc
diff --git a/ChangeLog b/ChangeLog
index 0353d7e..e4e58c0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,84 @@
+2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add p_edges.
+
+ * milena/mln/core/site_set/p_edges.hh:
+ The site set p_edges.
+
+ * milena/mln/util/internal/graph_edge_psite.hh:
+ The associated psite.
+
+ * milena/tests/core/site_set/Makefile.am,
+ * milena/tests/core/site_set/p_edges.cc:
+ Add a basic test.
+
+2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Refactor graph_vertex_psite.
+
+ * milena/mln/util/internal/graph_vertex_psite.hh:
+ Refactor this class...
+ * milena/mln/util/internal/graph_psite_base.hh:
+ ... here.
+
+2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Fix util::graph<G>::is_subgraph_of().
+
+ * milena/mln/util/graph.hh: here.
+
+2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add missing methods to vertex and edge.
+
+ * milena/mln/util/internal/graph_edge.hh:
+ Add change_graph().
+ * milena/mln/util/internal/graph_vertex.hh:
+ Add invalidate().
+
+
+2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add p_vertices.
+
+ * milena/mln/core/site_set/p_vertices.hh:
+ The site set p_vertices.
+
+ * milena/mln/util/internal/graph_vertex_psite.hh:
+ The psite associated to p_vertices.
+
+ * milena/tests/core/site_set/p_vertices.cc,
+ * milena/tests/core/site_set/Makefile.am:
+ Add a small test.
+
+2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add a missing method to graph_vertex_iter.
+
+ * milena/mln/util/internal/graph_vertex_iter.hh:
+ Add a missing update_graph() method.
+
+2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Fix invalid compilation of graph_vertex.
+
+ * milena/mln/util/internal/graph_vertex.hh:
+ Remove useless const and a wrong precondition.
+
+2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Fix missing methods in graph_base.
+
+ * milena/mln/util/internal/graph_base.hh:
+ Add new has() overload for convenience.
+
+2008-10-03 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Update p_graph_piter.
+
+ * milena/mln/core/site_set/p_graph_piter.hh:
+ update in order to make it work with the new graph structure.
+
2008-09-30 Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Update reconstruction algorithms in theo's sandbox.
diff --git a/milena/mln/core/site_set/p_edges.hh b/milena/mln/core/site_set/p_edges.hh
new file mode 100644
index 0000000..3c94998
--- /dev/null
+++ b/milena/mln/core/site_set/p_edges.hh
@@ -0,0 +1,262 @@
+ // Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+ //
+ // This file is part of the Olena Library. This library is free
+ // software; you can redistribute it and/or modify it under the terms
+ // of the GNU General Public License version 2 as published by the
+ // Free Software Foundation.
+ //
+ // This library is distributed in the hope that it will be useful,
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ // General Public License for more details.
+ //
+ // You should have received a copy of the GNU General Public License
+ // along with this library; see the file COPYING. If not, write to
+ // the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ // Boston, MA 02111-1307, USA.
+ //
+ // As a special exception, you may use this file as part of a free
+ // software library without restriction. Specifically, if other files
+ // instantiate templates or use macros or inline functions from this
+ // file, or you compile this file and link it with other files to
+ // produce an executable, this file does not by itself cause the
+ // resulting executable to be covered by the GNU General Public
+ // License.
+ // reasons why the executable file might be covered by the GNU General
+ // Public License.
+
+#ifndef MLN_CORE_SITE_SET_P_EDGES_HH
+# define MLN_CORE_SITE_SET_P_EDGES_HH
+
+ /// \file mln/core/site_set/p_edges.hh
+ /// \brief Definition of a site set based on graph edges.
+
+# include <mln/core/internal/site_set_base.hh>
+# include <mln/core/site_set/p_graph_piter.hh>
+# include <mln/util/internal/graph_edge_psite.hh>
+# include <mln/util/graph.hh>
+
+
+namespace mln
+{
+ // Forward declaration.
+ template <typename G, typename F> struct p_edges;
+
+ namespace trait
+ {
+ template <typename G, typename F>
+ struct site_set_< p_edges<G, F> >
+ {
+ // FIXME: I don't know what to use yet!
+ typedef trait::site_set::nsites::known nsites;
+ typedef trait::site_set::bbox::unknown bbox;
+ typedef trait::site_set::contents::fixed contents;
+ typedef trait::site_set::arity::unique arity;
+ };
+ } // end of namespace mln::trait
+
+
+ template <typename G, typename F>
+ class p_edges
+ : public internal::site_set_base_< typename F::result, p_edges<G, F> >
+ {
+ typedef util::edge<G> edge_t;
+
+ typedef p_edges<G, F> self_;
+ typedef internal::site_set_base_< typename F::result, self_ > super_;
+
+ typedef G graph_t;
+
+ public:
+ /// \brief Construct a graph edge psite set from a graph and a function.
+ ///
+ /// \param gr The graph upon which the graph edge psite set is built.
+ /// \param f the function mapping edges and sites.
+ p_edges(const graph_t& gr, const F& f);
+
+ /// Associated types.
+ /// \{
+ /// Element associated type.
+ typedef mln_site(super_) element;
+ /// Point_Site associated type.
+ typedef internal::edge_psite<G, F> psite;
+
+ /// Forward Site_Iterator associated type.
+ typedef p_graph_piter< self_, mln_edge_fwd_iter(G) > fwd_piter;
+
+ /// Backward Site_Iterator associated type.
+ typedef p_graph_piter< self_, mln_edge_bkd_iter(G) > bkd_piter;
+
+ /// Site_Iterator associated type.
+ typedef fwd_piter piter;
+ /// \}
+
+ /// \brief Return The number of points (sites) of the set, i.e.,
+ /// the number of \em edges.
+ size_t nsites() const;
+
+ /// Return The number of edges in the graph.
+ std::size_t nedges() const;
+
+ /// Is this site set valid?
+ bool is_valid() const;
+ /// Invalidate this site set.
+ void invalidate();
+
+ /// Does this site set has site \a p?
+ bool has(const psite& p) const;
+
+ /// Does this site set has edge \a e?
+ template <typename G2>
+ bool has(const util::edge<G2>& e) const;
+
+ // FIXME: Dummy.
+ std::size_t memory_size() const;
+
+ /// Accessors.
+ /// \{
+ /// Return the graph associated to this site set
+ const graph_t& g() const;
+ /// Return the mapping function.
+ F function() const;
+ /// \}
+
+ private:
+ mlc_const(graph_t)* g_;
+ F f_;
+ };
+
+
+ /// \brief Comparison between two mln::p_edges's.
+ ///
+ /// Two mln::p_edges's are considered equal if they share the
+ /// same graph.
+ template <typename G, typename F>
+ bool
+ operator==(const p_edges<G, F>& lhs, const p_edges<G, F>& rhs);
+
+
+ /// \brief Inclusion of a mln::p_edges in another one.
+ ///
+ /// \todo Refine this later, when we are able to express subgraph
+ /// relations.
+ template <typename G, typename F>
+ bool
+ operator<=(const p_edges<G, F>& lhs, const p_edges<G, F>& rhs);
+
+} // end of mln
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+namespace mln
+{
+
+ template <typename G, typename F>
+ inline
+ p_edges<G, F>::p_edges(const graph_t& g, const F& f)
+ : g_ (&g), f_(f)
+ {
+ }
+
+ template <typename G, typename F>
+ inline
+ size_t
+ p_edges<G, F>::nsites() const
+ {
+ return nedges();
+ }
+
+ template <typename G, typename F>
+ inline
+ std::size_t
+ p_edges<G, F>::nedges() const
+ {
+ return this->g_->e_nmax();
+ }
+
+ template <typename G, typename F>
+ inline
+ bool
+ p_edges<G, F>::is_valid() const
+ {
+ return g_ != 0;
+ }
+
+ template <typename G, typename F>
+ inline
+ void
+ p_edges<G, F>::invalidate()
+ {
+ g_ = 0;
+ }
+
+ template <typename G, typename F>
+ inline
+ bool
+ p_edges<G, F>::has(const psite& p) const
+ {
+ mln_precondition(is_valid());
+ return has(p.e());
+ }
+
+ template <typename G, typename F>
+ template <typename G2>
+ inline
+ bool
+ p_edges<G, F>::has(const util::edge<G2>& e) const
+ {
+ mln_precondition(is_valid());
+ return e.g()->is_subgraph_of(*g_) && g_->has(e) && e.is_valid();
+ }
+
+ template <typename G, typename F>
+ inline
+ std::size_t
+ p_edges<G, F>::memory_size() const
+ {
+ // FIXME: Dummy; implement (see other site sets).
+ abort();
+ return 0;
+ }
+
+ template <typename G, typename F>
+ inline
+ const typename p_edges<G, F>::graph_t&
+ p_edges<G, F>::g() const
+ {
+ mln_precondition(is_valid());
+ return *g_;
+ }
+
+ template <typename G, typename F>
+ inline
+ F
+ p_edges<G, F>::function() const
+ {
+ return f_;
+ }
+
+ template <typename G, typename F>
+ bool
+ operator==(const p_edges<G, F>& lhs, const p_edges<G, F>& rhs)
+ {
+ /* FIXME: We should not rely on pointer equality here, as graph
+ will soon become shells using (shared) tracked pointers to
+ actual data. So, delegate the equality test to the graphs
+ themselves. */
+ return (*lhs.g_) == (*rhs.g_);
+ }
+
+ template <typename G, typename F>
+ bool
+ operator<=(const p_edges<G, F>& lhs, const p_edges<G, F>& rhs)
+ {
+ return lhs == rhs;
+ }
+
+} // end of mln
+
+# endif // ! MLN_INCLUDE_ONLY
+
+#endif // MLN_CORE_SITE_SET_P_EDGES_HH
diff --git a/milena/mln/util/internal/graph_edge_psite.hh b/milena/mln/util/internal/graph_edge_psite.hh
new file mode 100644
index 0000000..5e00d18
--- /dev/null
+++ b/milena/mln/util/internal/graph_edge_psite.hh
@@ -0,0 +1,126 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License.
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+#ifndef MLN_UTIL_INTERNAL_GRAPH_EDGE_PSITE_HH
+# define MLN_UTIL_INTERNAL_GRAPH_EDGE_PSITE_HH
+
+# include <mln/core/concept/pseudo_site.hh>
+# include <mln/util/internal/graph_psite_base.hh>
+
+namespace mln
+{
+
+ template <typename G, typename F> class p_edges;
+
+} // end of namespace mln
+
+/// \file mln/util/internal/edge_psite.hh
+/// \brief Implementation of p_edges psite.
+
+namespace mln
+{
+
+ namespace internal
+ {
+
+ template <typename G, typename F>
+ class edge_psite :
+ public graph_psite_base<util::edge<G>, typename F::result,
+ p_edges<G, F>,
+ edge_psite<G, F> >
+ {
+ typedef edge_psite<G, F> self_;
+ typedef p_edges<G, F> target_t;
+ typedef graph_psite_base<util::edge<G>, typename F::result, target_t, self_> super_;
+ typedef util::edge<G> edge_t;
+
+ public:
+ /// Associated Types
+ /// \{
+ /// Site type, the return type of the mapping function \p F here.
+ typedef typename F::result site;
+ /// \}
+
+ /// Constructors
+ /// \{
+ edge_psite();
+ edge_psite(const target_t& t);
+ /// \}
+
+ /// Accessors
+ /// \{
+ /// Return the underlying edge.
+ const edge_t& e() const;
+ /// \}
+
+ protected:
+ /// The underlying edge (inherited).
+ using super_::v_;
+ };
+
+ } // end of namespace internal
+
+} // end of namespace mln
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+namespace mln
+{
+
+ namespace internal
+ {
+
+ template <typename G, typename F>
+ inline
+ edge_psite<G, F>::edge_psite()
+ {
+ }
+
+ template <typename G, typename F>
+ inline
+ edge_psite<G, F>::edge_psite(const target_t& t)
+ {
+ this->change_target(t);
+ }
+
+ template <typename G, typename F>
+ inline
+ const typename edge_psite<G, F>::edge_t&
+ edge_psite<G, F>::e() const
+ {
+ return v_;
+ }
+
+ } // end of namespace internal
+
+} // end of namespace mln
+
+# endif // !MLN_INCLUDE_ONLY
+
+#endif // !MLN_UTIL_INTERNAL_GRAPH_EDGE_PSITE_HH
+
diff --git a/milena/tests/core/site_set/Makefile.am b/milena/tests/core/site_set/Makefile.am
index d1b2cf6..1b23c79 100644
--- a/milena/tests/core/site_set/Makefile.am
+++ b/milena/tests/core/site_set/Makefile.am
@@ -5,6 +5,7 @@ include $(top_srcdir)/milena/tests/tests.mk
check_PROGRAMS = \
p_array \
## p_bgraph \
+ p_edges \
p_image \
p_priority_queue \
p_queue \
@@ -22,5 +23,6 @@ p_queue_fast_SOURCES = p_queue_fast.cc
p_set_SOURCES = p_set.cc
pset_if_SOURCES = pset_if.cc
p_vertices_SOURCES = p_vertices.cc
+p_edges_SOURCES = p_edges.cc
TESTS = $(check_PROGRAMS)
diff --git a/milena/tests/core/site_set/p_edges.cc b/milena/tests/core/site_set/p_edges.cc
new file mode 100644
index 0000000..9ab01a1
--- /dev/null
+++ b/milena/tests/core/site_set/p_edges.cc
@@ -0,0 +1,93 @@
+// Copyright (C) 2008 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library without restriction. Specifically, if other files
+// instantiate templates or use macros or inline functions from this
+// file, or you compile this file and link it with other files to
+// produce an executable, this file does not by itself cause the
+// resulting executable to be covered by the GNU General Public
+// License. This exception does not however invalidate any other
+// reasons why the executable file might be covered by the GNU General
+// Public License.
+
+/*! \file tests/core/site_set/p_edges.cc
+ *
+ * \brief Tests on mln::p_edges.
+ */
+
+#include <mln/util/graph.hh>
+#include <mln/core/alias/point2d.hh>
+#include <mln/core/site_set/p_edges.hh>
+
+// Function mapping an edge to a specific site.
+template <typename G>
+struct my_fun
+{
+ typedef mln::point2d result;
+
+ const result& operator()(const mln::util::edge<G>& v) const
+ {
+ static mln::point2d res(0, 0);
+ res.row() = v.id();
+ return res;
+ }
+};
+
+int main()
+{
+ using namespace mln;
+
+ // Create a graph.
+ util::graph g;
+ g.add_vertex (); // 0
+ g.add_vertex (); // 1
+ g.add_vertex (); // 2
+ g.add_vertex (); // 3
+ g.add_vertex (); // 4
+ g.add_vertex (); // 5
+ g.add_edge (0, 1);
+ g.add_edge (0, 2);
+ g.add_edge (3, 4);
+ g.add_edge (4, 5);
+ g.add_edge (5, 4);
+ g.add_edge (1, 0);
+ g.add_edge (5, 3);
+ g.add_edge (2, 1);
+
+ typedef p_edges<util::graph, my_fun<util::graph> > p_edges;
+ p_edges pv(g, my_fun<util::graph>());
+
+ // Forward iterator
+ {
+ mln_fwd_piter_(p_edges) p(pv);
+ unsigned i = 0;
+ for_all(p)
+ mln_assertion(p.p_hook_().e().id() == i++);
+ mln_assertion(i == g.e_nmax());
+ }
+ // Backward iterator
+ {
+ mln_bkd_piter_(p_edges) p(pv);
+ unsigned i = g.e_nmax() - 1;
+ for_all(p)
+ mln_assertion(p.p_hook_().e().id() == i--);
+ mln_assertion(i == UINT_MAX);
+ }
+
+ return 0;
+}
--
1.5.6.5