https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Nicolas Ballas <ballas(a)lrde.epita.fr>
Sandbox: Add a document which describes the images types in milena.
* ballas/doc/image_types,
* ballas/doc/image_types/include: New repository.
* ballas/doc/image_types/include/image_tour.tex,
* ballas/doc/image_types/doc.tex: New document describing the images.
* ballas/doc/image_tours.txt: update.
image_tours.txt | 5
image_types/doc.tex | 28 ++
image_types/include/image_tour.tex | 480 +++++++++++++++++++++++++++++++++++++
3 files changed, 510 insertions(+), 3 deletions(-)
Index: ballas/doc/image_types/include/image_tour.tex
--- ballas/doc/image_types/include/image_tour.tex (revision 0)
+++ ballas/doc/image_types/include/image_tour.tex (revision 0)
@@ -0,0 +1,480 @@
+\chapter{Images Tour}
+
+This chapter intends to give a global overview of the image types present in
+Milena.
+
+
+
+\section{Primary Image}
+
+Primitive image are images which are not based on another image.
+They don't lie on an underlying image.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Image nD %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\subsection{Image $n$D}
+
+\begin{itemize}
+\item{Short Description:}
+
+Image based on a regular grid (aligned and orthogonal) .
+The grid nodes are points.
+Milena provides three types of image $n$D: \verb+image1d+, \verb+image2d+ and
+\verb+image3d+.
+Depends on the dimension, the grid (so the image) can ether be linear
+(in $1$D), rectangular (in $2$D) or cubic (in $3$D).
+
+\item{Type Parameters:}
+
+\begin{itemize}
+\item \verb+T+: the image value type.
+\end{itemize}
+
+
+\item{Memory management:}
+
+All the image values are stored in a linear buffer in the RAM.
+
+\item{Data access:}
+
+ As these image types are based on a regular grid, and have their values
+stored in a linear buffer in RAM, we can directly access to the image
+values from the image points.
+The read access at the point $p$ is
+
+$ima(p) \rightarrow data[p]$ and write access is
+
+$ima(p) \leftarrow data[p]$ \footnote{$data$ represents the image
+values buffer, $p$ represents a point.}.\\
+
+
+But depends on the image dimension, $p$ canb be in $1$D, $2$D or $3$D.
+
+
+\begin{itemize}
+\item {$1$D:}
+
+$ima(p) \rightarrow data[p.row]$
+
+$ima(p) \leftarrow data[p.row]$
+\item {$2$D:}
+
+$ima(p) \rightarrow data[p.row][p.col]$
+
+$ima(p) \leftarrow data[p.row][p.col]$
+\item {$3$D:}
+
+$ima(p) \rightarrow data[p.row][p.col][p.sli]$
+
+$ima(p) \leftarrow data[p.row][p.col][p.sli]$
+\end{itemize}
+
+
+\item{Associated properties:}
+
+In order to increase access performance, an extended domain is added to the
+images $n$D.
+An extended domain add dummy values on the images borders.
+This way, an user doesn't have to check if a neighbour of a point is inside the
+image domain.
+An extended domain speed up algorithms which use structuring elements.
+Furthermore, the image values type have a pointer semantics.
+(there are stored in a linear buffer).
+So images $n$D provide access to pixter (iterator over image pixels).
+
+\end{itemize}
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Image based on function %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\subsection{Image based on function}
+
+\subsubsection{Fun\_Image}
+
+\begin{itemize}
+
+\item{Short Description:}
+
+\verb+Fun_Image+ has been designed to define an image from a function site to
+value (called $p2v$).
+
+The definition of a $p2v$ function f is:
+
+\begin{eqnarray*}
+Psite\_Type & \rightarrow & Value\_Type \\
+ p & \rightarrow & f(p)
+\end{eqnarray*}
+
+
+
+\item{Type Parameters:}
+
+\begin{itemize}
+\item \verb+F+: $p2v$ function.
+\item \verb+S+: Site Set type.
+\end{itemize}
+
+\item{Memory management:}
+
+No data are stored in memory, since all the values are computed by the
+function.
+
+\item{Data access:}
+
+$ima(p) \rightarrow f(p)$ where $f$ is the image associated function.
+
+\item{Associated properties:}
+
+\verb+Fun_Image+ are constant images since we can't modify the
+\verb+Fun_Image+ values.
+Indeed all the values are computed on the fly by the function associated to the
+image.
+So, the image values doesn't have a write access.
+In addition the \verb+Fun_Image+ site set must be include in the domain of
+the function associated to the image.
+
+\end{itemize}
+
+\subsubsection{Flat\_Image}
+
+\begin{itemize}
+
+\item{Short Description:}
+
+\verb+Flat_Image+ is a specialized version of the \verb+Fun_image+.
+All the sites in the image share the same value.
+So \verb+Flat_Image+ can be seen as a \verb+Fun_image+ which a constant
+function.
+
+\begin{eqnarray*}
+Psite\_Type & \rightarrow & Value\_Type \\
+ p & \rightarrow & v
+\end{eqnarray*} where $v$ is a constant value.
+
+\item{Type Parameters:}
+
+\begin{itemize}
+
+\item \verb+T+: Value type.
+\item \verb+S+: Site Set type.
+
+\end{itemize}
+
+\item{Memory management:}
+
+The flat value $v$ is stored in the memory.
+
+\item{Data access:}
+
+$ima(p) \rightarrow v$
+
+$ima(p) \leftarrow v$
+where v is the flat value associated to the image.
+
+\end{itemize}
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Image encoded by runs %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{Images encoded by run}
+
+\subsubsection{Definition of a run}
+
+A run is a ``continuous'' succession of points.
+It is encoded by a point representing the beginning of the run
+and an integer which is the length of the run.
+
+Example:
+The run \verb+((1, 2), 4)+ represents the site \verb+(1, 2)+, \verb+(1, 3)+,
+\verb+(1, 4)+ and \verb+(1, 5)+.
+
+
+\subsubsection{rle\_image}
+
+\begin{itemize}
+\item{Short Description:}
+
+A \verb+rle_image+ can be defined as couples $(r, v)$ where $r$ is a run of
+point \verb+P+ and $v$ is a value of type \verb+T+.
+A \verb+rle_image+ associates one value for all the points in the run $r$.
+
+\item{Type Parameters:}
+
+\begin{itemize}
+\item \verb+P+: Point type.
+\item \verb+T+: Value type.
+\end{itemize}
+
+\item{Memory management:}
+
+\begin{itemize}
+\item \verb+runs+: a vector of run.
+\item \verb+values+: a vector values.
+\end{itemize}
+
+A run at the index i of the \verb+runs+ vector is associated to the value at
+the index i of the \verb+values+ vector.
+
+
+\item{Data access:}
+
+Due to the run encoding, we cannot access directly to the image values with
+a point.
+We need to handle the image implementation details.
+That's why we use a psite (which is different from a point) to access to
+the image values.
+The psite type is just a wrapper of two integer which are the position of
+the run (\verb+out_run_index+) inside the \verb+runs+ vector, and the position
+of the point (\verb+in_run_index+) inside the run.\\
+
+
+Here is how we access to the image data.
+
+$ima(psite) \rightarrow values[psite.out\_run\_index]$
+
+$ima(psite) \leftarrow values[psite.out\_run\_index]$
+
+
+\item{Associated properties:}
+
+Implementation details are necessary to access to the image value.
+So this image type has its psite type different to site type.
+This image type is ``one shot''.
+We cannot add new points to the image once we created it.
+\end{itemize}
+
+
+\subsubsection{compact\_rle}
+\begin{itemize}
+\item{Short Description:}
+
+\verb+compact_rle+ type is similar to the \verb+rle_image+ type.
+But \verb+compact_rle+ also encode the 0 values of the original image into
+the encoded image (the \verb+rle_image+ just ignores the 0).
+FIXME Can't we use \verb+rle_image+ (with a different encoding functions)?
+
+\end{itemize}
+
+
+\subsubsection{sparse\_image}
+\begin{itemize}
+\item{Short Description:}
+
+A \verb+sparse_image+ can be defined as couples $(r, [v])$ where $r$ is a run
+of points \verb+P+ and $v$ a vector of values of type \verb+T+.
+A \verb+sparse_image+ associates a value to each points of the run $r$.
+
+\item{Type Parameters:}
+
+\begin{itemize}
+\item \verb+P+: Point type.
+\item \verb+T+: Value type.
+\end{itemize}
+
+
+\item{Memory management:}
+\begin{itemize}
+\item \verb+runs+: a vector of run.
+\item \verb+values+: a vector of vector of values.
+\end{itemize}
+
+\item{Data access:}
+
+We use the same psite to access to \verb+sparse_image+ data than
+\verb+rle_image+.
+
+$ima(psite) \rightarrow values[psite.out\_run\_index][psite.in\_run\_index]$
+
+$ima(psite) \leftarrow values[psite.out\_run\_index][psite.in\_run\_index]$
+
+
+\item{Associated properties:}
+
+\verb+sparse_image+ has the same property than \verb+rle_image+.
+
+\end{itemize}
+
+
+\subsubsection{value\_encoded\_image}
+\begin{itemize}
+\item{Short Description:}
+
+
+In a \verb+value_encoded_image+ a value is associated to a set of runs.
+A \verb+value_encoded_image+ can be seen as couples $(v, \{runs\})$ where
+v is a value and $\{runs\}$ is a set of runs.
+With this structure, all the runs (so, all the points) which have the same
+value can be easily get (in a $O(1)$ complexity).
+
+
+\item{Type Parameters:}
+
+\begin{itemize}
+\item \verb+T+ Value type.
+\item \verb+P+ Point type.
+\end{itemize}
+
+\item{Memory management:}
+
+\begin{itemize}
+\item \verb+runs_array+ a vector which contains a set of run at each index.
+\item \verb+values+ values vector.
+\end{itemize}
+
+All the runs in a set at an index i, have \verb+values[i]+ as value.
+
+\item{Data access:}
+
+$ima(p) \rightarrow values[psite.index]$
+
+$ima(p) \leftarrow values[psite.index]$ where $index$ represents the position
+of the psite in the $runs\_array$ vector.
+
+
+\item{Associated properties:}
+
+This image type is ``one shot''.
+The psite type is different from the site type of the image.
+Furthermore, in \verb+value_encoded_image+ it is possible to retrieve
+the set of runs corresponding to a value.
+
+$ima.sites(v) \rightarrow runs\_array[v.index]$
+
+$ima.sites(v) \leftarrow runs\_array[v.index]$ where $v$ is an image value
+and $v.index$ the corresponding index in the $values$ vector.
+
+It is also possible to change all the values of a set of runs in the image.
+
+$ima.cell(v) \rightarrow values[v.index]$ FIXME: does it has any sens?
+
+$ima.cell(v) \leftarrow values[v.index]$ where $v$ is an image values
+and $v.index$ the corresponding index in the $values$ vector.
+
+
+
+\end{itemize}
+
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% map_image by runs %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\subsection{map\_image}
+
+\begin{itemize}
+
+\item{Short Description:}
+ A \verb+map_image+ have it values stored in a std::map.
+
+\item{Type Parameters:}
+
+\begin{itemize}
+\item \verb+T+: Value type.
+\item \verb+P+: Site type.
+\end{itemize}
+
+\item{Memory management:}
+
+ A std::map $m$ which use \verb+P+ as key type and \verb+V+ as value type.
+
+\item{Data access:}
+
+$ima(p) \rightarrow m[p]$
+
+$ima(p) \leftarrow m[p]$
+where m is std::map associated to the image.
+
+
+\item{Associated properties:}
+
+The data access are not in $O(1)$ since the image uses an underlying std::map.
+So this image is \verb+slow+.
+
+\end{itemize}
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Image based on a lut %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+\subsection{lut\_image}
+
+\begin{itemize}
+\item{Short Description:}
+
+A \verb+lut_image+ uses a look up table to retrieve a value
+associated to an image site.
+
+
+\item{Type Parameters:}
+
+\begin{itemize}
+\item \verb+P+: Point type.
+\item \verb+T+: Value type.
+\end{itemize}
+
+\item{Memory management:}
+
+\begin{itemize}
+\item \verb+pset+: set of site composing the image.
+\item \verb+values+: container associated a lut\_value to each site of the
+image.
+\item \verb+lut+: table translating the lut\_values to their real values.
+\end{itemize}
+
+\item{Data access:}
+
+$ima(p) \rightarrow lut[value[p]]$
+
+$ima(p) \leftarrow lut[value[p]]$
+
+\item{Associated properties:}
+
+
+It is possible to change all the values of a set of runs in the image.
+
+$ima.cell(v) \rightarrow lut[v.index]$ FIXME: does it has any sens?
+
+$ima.cell(v) \leftarrow lut[v.index]$ where $v$ is an image values
+and $v.index$ the corresponding index in the $lut$.
+
+
+\end{itemize}
+
+
+
+
+\section{Morpher}
+
+
+
+%%% TEMPLATE
+\begin{itemize}
+\item{Short Description:}
+
+
+
+\item{Type Parameters:}
+
+
+\item{Memory management:}
+
+
+\item{Data access:}
+
+
+\item{Associated properties:}
+
+\end{itemize}
Index: ballas/doc/image_types/doc.tex
--- ballas/doc/image_types/doc.tex (revision 0)
+++ ballas/doc/image_types/doc.tex (revision 0)
@@ -0,0 +1,28 @@
+\documentclass[8 pt,a4paper]{report}
+\usepackage[english]{babel}
+\usepackage{enumerate}
+\usepackage{fancyhdr}
+\usepackage{listings}
+\usepackage{graphicx}
+\usepackage[latin1]{inputenc}
+\usepackage[linkcolor=black,colorlinks,pdftex]{hyperref}
+
+% \setlength{\oddsidemargin}{0.5cm} % Marge gauche sur pages impaires
+% \setlength{\evensidemargin}{0.5cm} % Marge gauche sur pages paires
+% \setlength{\textwidth}{15.5cm}
+
+
+
+
+\title{
+ Milena Documentation
+}
+
+
+\begin{document}
+
+\maketitle{}
+
+\include{include/image_tour}
+
+\end{document}
Index: ballas/doc/image_tours.txt
--- ballas/doc/image_tours.txt (revision 1929)
+++ ballas/doc/image_tours.txt (working copy)
@@ -31,7 +31,6 @@
----------
/ \
- | |
| Image Type |
| and | automatic -----> Props
| associated|
@@ -48,7 +47,7 @@
Some operators are only defined in special cases. Properties provide a way to
check that the operator's input types respect the operator requirements.
-
+frf
*** Specialization of an Algorithm
Example:
@@ -598,7 +597,7 @@
*** Sparse Image
-A RLE image can be defined as the following:
+A Sparse image can be defined as the following:
{(p, [v])} where p is a run of P and v is a value of type T, and [v] is an
array of size p.length().
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Roland Levillain <roland(a)lrde.epita.fr>
Add a 3-D cuboid window type.
* mln/win/cuboid3d.hh: New.
* tests/win/cuboid3d.cc: New test.
* tests/win/Makefile.am (check_PROGRAMS): Add cuboid3d.
(cuboid3d_SOURCES): New.
mln/win/cuboid3d.hh | 266 ++++++++++++++++++++++++++++++++++++++++++++++++++
tests/win/Makefile.am | 2
tests/win/cuboid3d.cc | 67 ++++++++++++
3 files changed, 335 insertions(+)
Index: mln/win/cuboid3d.hh
--- mln/win/cuboid3d.hh (revision 0)
+++ mln/win/cuboid3d.hh (revision 0)
@@ -0,0 +1,266 @@
+// 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.
+
+#ifndef MLN_WIN_CUBOID3D_HH
+# define MLN_WIN_CUBOID3D_HH
+
+/// \file mln/win/cuboid3d.hh
+/// \brief Definition of the mln::win::cuboid3d window.
+
+# include <mln/core/concept/window.hh>
+# include <mln/core/internal/dpoints_base.hh>
+# include <mln/core/dpoint3d.hh>
+# include <mln/core/dpoints_piter.hh>
+
+
+namespace mln
+{
+
+ namespace win
+ {
+
+ /** \brief Cuboid defined on the 3-D square grid.
+
+ A cuboid3d is a 3-D window with cuboid (also known as
+ rectangular prism or rectangular parallelepiped) shape. It is
+ centered and symmetric.
+
+ For instance: \n
+
+ o o o o o o o\n
+ o o o o o o o\n
+ o o o o o o o\n
+ o o o o o o o\n
+ o o o o o o \on
+
+ o o o o o o o\n
+ o o o o o o o\n
+ o o o x o o o\n
+ o o o o o o o\n
+ o o o o o o \on
+
+ o o o o o o o\n
+ o o o o o o o\n
+ o o o o o o o\n
+ o o o o o o o\n
+ o o o o o o \on
+
+ is defined with depth = 3, height = 5 and width = 7.
+
+ Reference:
+ http://en.wikipedia.org/wiki/Cuboid
+ */
+ struct cuboid3d : public Window< cuboid3d >,
+ public internal::dpoints_base_< dpoint3d, cuboid3d >
+ {
+ /// Point Site associated type.
+ typedef point3d psite;
+
+ /// Point associated type.
+ typedef point3d point;
+
+ /// Dpoint associated type.
+ typedef dpoint3d dpoint;
+
+ /// \brief Point_Iterator type to browse a cuboid such as: "for
+ /// each slice (increasing), for each row (increasing), for each
+ /// column (increasing)."
+ typedef dpoints_fwd_piter<dpoint3d> fwd_qiter;
+
+ /// \brief Point_Iterator type to browse a cuboid such as: "for
+ /// each slice (decreasing), for each row (decreasing), for each
+ /// column (decreasing)."
+ typedef dpoints_bkd_piter<dpoint3d> bkd_qiter;
+
+
+ /// \brief Constructor.
+ ///
+ /// \param[in] depth The depth of the cuboid3d.
+ /// \param[in] height The height of the cuboid3d.
+ /// \param[in] width The width of the cuboid3d.
+ ///
+ /// \pre Argument \a depth, \a height and \a width must be odd.
+ cuboid3d(unsigned depth, unsigned height, unsigned width);
+
+
+ /// Properties of the window.
+ /// \{
+ /// \brief Test if the window is centered.
+ /// \return \c true (always).
+ bool is_centered() const;
+ /// \brief Test if the window is symmetric.
+ /// \return \c true (always).
+ bool is_symmetric() const;
+ /// \}
+
+ /// Accessors.
+ /// \{
+ /// \brief Return the depth of the cuboid.
+ unsigned depth() const;
+ /// \brief Return the height of the cuboid.
+ unsigned height() const;
+ /// \brief Return the width of the cuboid.
+ unsigned width() const;
+ /// \}
+
+ /// \brief Return the volume of the cuboid.
+ unsigned volume() const;
+
+ /// \brief Give the maximum coordinate gap between the center of
+ /// the window and a point of the window.
+ unsigned delta() const;
+
+ /// Apply a central symmetry to the target window.
+ cuboid3d& sym();
+
+ protected:
+ /// The depth of the cuboid (expressed as a number of slices).
+ unsigned depth_;
+ /// The height of the cuboid (expressed as a number of rows).
+ unsigned height_;
+ /// The width of the cuboid (expressed as a number of columns).
+ unsigned width_;
+ };
+
+
+ /// \brief Print a cuboid window \a win into the output stream \a ostr.
+ ///
+ /// \param[in,out] ostr An output stream.
+ /// \param[in] win A cuboid window.
+ ///
+ /// \return The modified output stream \a ostr.
+ ///
+ /// \relates mln::win::cuboid3d
+ std::ostream& operator<<(std::ostream& ostr, const cuboid3d& win);
+
+
+
+# ifndef MLN_INCLUDE_ONLY
+
+ inline
+ cuboid3d::cuboid3d(unsigned depth, unsigned height, unsigned width)
+ : depth_(depth),
+ height_(height),
+ width_(width)
+ {
+ mln_precondition(height % 2 == 1 && width % 2 == 1);
+ const int dsli = depth / 2;
+ const int drow = height / 2;
+ const int dcol = width / 2;
+ for (int sli = -dsli; sli <= dsli; ++sli)
+ for (int row = -drow; row <= drow; ++row)
+ for (int col = -dcol; col <= dcol; ++col)
+ insert(make::dpoint3d(sli, row, col));
+ }
+
+ inline
+ bool
+ cuboid3d::is_centered() const
+ {
+ return true;
+ }
+
+ inline
+ bool
+ cuboid3d::is_symmetric() const
+ {
+ return true;
+ }
+
+ inline
+ unsigned
+ cuboid3d::depth() const
+ {
+ return depth_;
+ }
+
+ inline
+ unsigned
+ cuboid3d::height() const
+ {
+ return height_;
+ }
+
+ inline
+ unsigned
+ cuboid3d::width() const
+ {
+ return width_;
+ }
+
+ inline
+ unsigned
+ cuboid3d::volume() const
+ {
+ return depth_ * width_ * height_;
+ }
+
+ inline
+ unsigned
+ cuboid3d::delta() const
+ {
+ if (depth_ > height_)
+ if (depth_ > width_)
+ // height_ < depth_ && width_ < depth_.
+ return depth_ / 2;
+ else
+ // height_ < depth_ <= width_.
+ return width_ / 2;
+ else
+ if (height_ > width_)
+ // depth_ <= height_ && width_ <= height_.
+ return height_ / 2;
+ else
+ // depth_ <= height_ <= width_.
+ return width_ / 2;
+ }
+
+ inline
+ cuboid3d&
+ cuboid3d::sym()
+ {
+ return *this;
+ }
+
+ inline
+ std::ostream&
+ operator<<(std::ostream& ostr, const cuboid3d& win)
+ {
+ ostr << "[cuboid3d: width=" << win.depth()
+ << ", depth=" << win.width()
+ << ", height=" << win.height() << ']';
+ return ostr;
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::win
+
+} // end of namespace mln
+
+
+#endif // ! MLN_WIN_CUBOID3D_HH
Index: tests/win/cuboid3d.cc
--- tests/win/cuboid3d.cc (revision 0)
+++ tests/win/cuboid3d.cc (revision 0)
@@ -0,0 +1,67 @@
+// 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/win/cuboid3d.cc
+ *
+ * \brief Tests on mln::win::cuboid3d.
+ */
+
+#include <cmath>
+#include <mln/win/cuboid3d.hh>
+#include <mln/geom/sym.hh>
+
+#include <mln/convert/to_image.hh>
+
+#include <mln/debug/println.hh>
+
+int main()
+{
+ using namespace mln;
+
+ const unsigned d = 7, h = 3, w = 5;
+ win::cuboid3d cuboid(d, h, w);
+
+ mln_assertion(cuboid.is_centered());
+ mln_assertion(cuboid.is_symmetric());
+ mln_assertion(cuboid == geom::sym(cuboid));
+ mln_assertion(cuboid.ndpoints() == d * h * w);
+
+ mln_assertion(cuboid.delta() == 3);
+
+ for (int s = -7; s <= 7; ++s)
+ for (int x = -7; x <= 7; ++x)
+ for (int y = -7; y <= 7; ++y)
+ {
+ mln_assertion(((abs(s) <= 3 && abs(x) <= 1 && abs(y) <= 2)) ||
+ !cuboid.has(dpoint3d(s, x, y)));
+ mln_assertion((abs(s) <= 3 && abs(x) <= 1 && abs(y) <= 2) ==
+ (cuboid.has(dpoint3d(s, x, y))));
+ }
+
+ debug::println(convert::to_image(cuboid));
+}
+
Index: tests/win/Makefile.am
--- tests/win/Makefile.am (revision 1926)
+++ tests/win/Makefile.am (working copy)
@@ -5,6 +5,7 @@
check_PROGRAMS = \
backdiag2d \
cube3d \
+ cuboid3d \
diag2d \
disk2d \
hline2d \
@@ -15,6 +16,7 @@
backdiag2d_SOURCES = backdiag2d.cc
cube3d_SOURCES = cube3d.cc
+cuboid3d_SOURCES = cuboid3d.cc
diag2d_SOURCES = diag2d.cc
disk2d_SOURCES = disk2d.cc
hline2d_SOURCES = hline2d.cc
https://svn.lrde.epita.fr/svn/oln/trunk/milena
Index: ChangeLog
from Alexandre Abraham <abraham(a)lrde.epita.fr>
Make Tikz output able to valuate pixels.
* sandbox/abraham/io/tikz/save_header.hh: New
(mln::io::tikz::save_header) Write the header of the LaTeX file.
* sandbox/abraham/io/tikz/save.hh:
(mln::io::tikz::save) Can now take another image in argument to put
values on pixels.
save.hh | 70 ++++++++++++++++++++++++++++++++++++++-------
save_header.hh | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 147 insertions(+), 11 deletions(-)
Index: sandbox/abraham/io/tikz/save_header.hh
--- sandbox/abraham/io/tikz/save_header.hh (revision 0)
+++ sandbox/abraham/io/tikz/save_header.hh (revision 0)
@@ -0,0 +1,88 @@
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 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.
+
+#ifndef MLN_IO_TIKZ_SAVE_HEADER_HH
+# define MLN_IO_TIKZ_SAVE_HEADER_HH
+
+/*!
+ * \file mln/io/tikz/save_header.hh
+ *
+ * \brief Define a function which saves header for TIKZ image.
+ *
+ */
+
+# include <iostream>
+# include <fstream>
+
+namespace mln
+{
+
+ namespace io
+ {
+
+# ifndef MLN_INCLUDE_ONLY
+
+ namespace tikz
+ {
+
+ template <typename I>
+ inline
+ void save_header(const I& ima,
+ const std::string& filename,
+ std::ofstream& file)
+ {
+ if (! file)
+ {
+ std::cerr << "error: cannot open file '" << filename
+ << "'!";
+ abort();
+ }
+
+ file << "% Generated by milena 1.0 http://olena.lrde.epita.fr" << std::endl;
+ file << "% EPITA Research and Development Laboratory (LRDE)" << std::endl;
+
+ file << "\\documentclass[12pt,a4paper]{article}" << std::endl;
+ file << "\\usepackage{tikz}" << std::endl;
+
+ file << "\\begin{document}" << std::endl;
+ file << "\\begin{tikzpicture}" << std::endl;
+ file << "\\tikzstyle{every node}=[transform shape, draw,shape=rectangle, minimum width=1cm, minimum height=1cm]" << std::endl;
+
+ }
+
+ } // end of namespace mln::io::tikz
+
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+
+#endif // ! MLN_IO_TIKZ_SAVE_HEADER_HH
Index: sandbox/abraham/io/tikz/save.hh
--- sandbox/abraham/io/tikz/save.hh (revision 1925)
+++ sandbox/abraham/io/tikz/save.hh (working copy)
@@ -49,8 +49,8 @@
# include <mln/metal/templated_by.hh>
-# include <mln/io/pnm/save_header.hh>
-# include <mln/io/pnm/macros.hh>
+// # include <mln/io/tikz/save_header.hh>
+# include "save_header.hh"
# include <mln/geom/size2d.hh>
@@ -71,6 +71,15 @@
template <typename I>
void save(const Image<I>& ima_, const std::string& filename);
+ /*! Save a milena image as a tikz image with values.
+ *
+ * \param[in] ima_ The image to save.
+ * \param[in,out] filename the destination.
+ * \param[in] val_ An Image containing values to print.
+ */
+ template <typename I, typename V>
+ void save(const Image<I>& ima_, const std::string& filename, const Image<V>& val_);
+
# ifndef MLN_INCLUDE_ONLY
@@ -157,12 +166,38 @@
{
file << "\\path (" << p.col() << "," << max_row - p.row() << ") node[fill=";
write_value(file, ima(p));
- file << "] (p_" << p.row() << "_" << p.col() << ") { \\scriptsize \\color{";
+ file << "] (p_" << p.row() << "_" << p.col() << ") { \\color{";
+ file << "black";
+ file << "}" << "};" << std::endl;
+ }
+ }
+
+ // Save data
+ template <typename I, typename V>
+ inline
+ void save_data_with_values_(std::ofstream& file,
+ const I& ima,
+ const V& val)
+ {
+ const int
+ min_row = geom::min_row(ima),
+ max_row = geom::max_row(ima),
+ min_col = geom::min_col(ima),
+ max_col = geom::max_col(ima);
+
+ point2d p;
+ for (p.row() = min_row; p.row() <= max_row; ++p.row())
+ for (p.col() = min_col; p.col() <= max_col; ++p.col())
+ {
+ file << "\\path (" << p.col() << "," << max_row - p.row() << ") node[fill=";
+ write_value(file, ima(p));
+ file << "] (p_" << p.row() << "_" << p.col() << ") { \\color{";
file << "black";
- file << "}" << ima(p) << "};" << std::endl;
+ file << "}" << val(p) << "};" << std::endl;
}
}
+
} // end of namespace mln::io::pnm::impl
@@ -174,14 +209,8 @@
{
const I& ima = exact(ima_);
std::ofstream file(filename.c_str());
- // io::tikz::save_header(ima, file);
-
- file << "\\documentclass[12pt,a4paper]{article}" << std::endl;
- file << "\\usepackage{tikz}" << std::endl;
- file << "\\begin{document}" << std::endl;
- file << "\\begin{tikzpicture}" << std::endl;
- file << "\\tikzstyle{every node}=[draw,shape=rectangle, minimum width=1cm, minimum height=1cm]" << std::endl;
+ io::tikz::save_header(ima, filename, file);
impl::save_data_(file,
ima);
@@ -190,6 +219,25 @@
file << "\\end{document}" << std::endl;
}
+ template <typename I, typename V>
+ inline
+ void save(const Image<I>& ima_, const std::string& filename, const Image<V>& val_)
+ {
+ const I& ima = exact(ima_);
+ const V& val = exact(val_);
+ std::ofstream file(filename.c_str());
+
+ io::tikz::save_header(ima, filename, file);
+
+ impl::save_data_with_values_(file,
+ ima,
+ val);
+
+ file << "\\end{tikzpicture}" << std::endl;
+ file << "\\end{document}" << std::endl;
+ }
+
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::io::tikz