Commit 56c80ae1 authored by Thierry Geraud's avatar Thierry Geraud
Browse files

New 2D window types in mln.

	* tests/median.cc: Clean up.
	* tests/hmedian.cc: New.
	* tests/erosion.cc: Clean up.
	* tests/rectangle2d.cc: Update.
	* mln/core/hline2d.hh: New.
	* mln/core/rectangle2d.hh
	(half_width_, half_height_): Change to...
	(width_, height_): ...these.
	Update.
	* mln/core/vline2d.hh: New.
	* mln/morpho/erosion.hh (erosion_wrt_win): New overload.
	* mln/level/was.median.hh: New.
	* mln/level/approx: New.
	* mln/level/approx/median.hh: New.
	* mln/level/median.hh (median_as_procedure): Move into...
	* mln/level/was.hmedian.hh: ...this new file.


git-svn-id: https://svn.lrde.epita.fr/svn/oln/trunk@1021 4aad255d-cdde-0310-9447-f3009e2ae8c0
parent 3920960f
2007-07-17 Thierry Geraud <thierry.geraud@lrde.epita.fr>
New 2D window types in mln.
* tests/median.cc: Clean up.
* tests/hmedian.cc: New.
* tests/erosion.cc: Clean up.
* tests/rectangle2d.cc: Update.
* mln/core/hline2d.hh: New.
* mln/core/rectangle2d.hh
(half_width_, half_height_): Change to...
(width_, height_): ...these.
Update.
* mln/core/vline2d.hh: New.
* mln/morpho/erosion.hh (erosion_wrt_win): New overload.
* mln/level/was.median.hh: New.
* mln/level/approx: New.
* mln/level/approx/median.hh: New.
* mln/level/median.hh (median_as_procedure): Move into...
* mln/level/was.hmedian.hh: ...this new file.
2007-07-17 Thierry Geraud <thierry.geraud@lrde.epita.fr>
Add delta to windows in mln.
......
// Copyright (C) 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_CORE_HLINE2D_HH
# define MLN_CORE_HLINE2D_HH
/*! \file mln/core/hline2d.hh
*
* \brief Definition of the mln::hline2d window.
*/
# include <mln/core/concept/window.hh>
# include <mln/core/internal/set_of.hh>
# include <mln/core/dpoint2d.hh>
# include <mln/core/dpoints_piter.hh>
namespace mln
{
/*! \brief Horizontal line window defined on the 2D square grid.
*
* An hline2d is centered and symmetrical; so its height is 1 and
* its width (length) is odd.
*
* For instance: \n
* o o x o o \n
* is defined with length = 5.
*/
struct hline2d : public Window< hline2d >,
public internal::set_of_<dpoint2d>
{
/// Point associated type.
typedef point2d point;
/// Dpoint associated type.
typedef dpoint2d dpoint;
/*! \brief Piter type to browse a hline such as: "for each row
* (increasing), for each column (increasing)."
*/
typedef dpoints_fwd_piter<dpoint2d> fwd_qiter;
/*! \brief Piter type to browse a hline such as: "for each row
* (decreasing), for each column (decreasing)."
*/
typedef dpoints_fwd_piter<dpoint2d> bkd_qiter; // FIXME: bkd!!!
/*! \brief Same as fwd_qiter.
*/
typedef fwd_qiter qiter;
/*! \brief Constructor.
*
* \param[in] length Length, thus width, of the horizontal line.
*
* \pre \p length is odd.
*/
hline2d(unsigned length);
/*! \brief Test if the window is centered.
*
* \return True.
*/
bool is_centered() const;
/*! \brief Test if the window is symmetric.
*
* \return true.
*/
bool is_symmetric() const;
/*! \brief Give the hline length, that is, its width.
*/
unsigned length() const;
/*! \brief Give the maximum coordinate gap between the window
* center and a window point.
*/
unsigned delta() const;
/// Get the symmetrical window.
hline2d sym_() const;
protected:
unsigned length_;
};
/*! \brief Print an horizontal 2D line window \p win into the output
* stream \p ostr.
*
* \param[in,out] ostr An output stream.
* \param[in] win An horizontal 2D line window.
*
* \return The modified output stream \p ostr.
*
* \relates mln::hline2d
*/
std::ostream& operator<<(std::ostream& ostr, const hline2d& win);
# ifndef MLN_INCLUDE_ONLY
hline2d::hline2d(unsigned length)
: length_(length)
{
mln_precondition(length % 2 == 1);
const int dcol = length / 2;
for (int col = - dcol; col <= dcol; ++col)
insert(make::dpoint2d(0, col));
}
bool hline2d::is_centered() const
{
return true;
}
bool hline2d::is_symmetric() const
{
return true;
}
unsigned hline2d::length() const
{
return length_;
}
unsigned hline2d::delta() const
{
return length_ / 2;
}
hline2d hline2d::sym_() const
{
return *this;
}
std::ostream& operator<<(std::ostream& ostr, const hline2d& win)
{
ostr << "[line2d: length=" << win.length() << ']';
return ostr;
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
#endif // ! MLN_CORE_HLINE2D_HH
......@@ -47,13 +47,11 @@ namespace mln
* A rectangle2d is a 2D window with rectangular shape. It is
* centered and symmetrical.
*
* For instance:
* o o o o o
* o o x o o
* o o o o o
* is defined with half_height = 1 and half_width = 2.
*
* \todo Consider width instead of half_width (same for height).
* For instance: \n
* o o o o o \n
* o o x o o \n
* o o o o o \n
* is defined with height = 3 and width = 5.
*/
struct rectangle2d : public Window< rectangle2d >,
public internal::set_of_<dpoint2d>
......@@ -80,12 +78,12 @@ namespace mln
/*! \brief Constructor.
*
* \param[in] half_height sic
* \param[in] half_width sic
* \param[in] height sic
* \param[in] width sic
*
* \pre half_height != 0 and half_width != 0
* \pre Height and width are odd.
*/
rectangle2d(unsigned half_height, unsigned half_width);
rectangle2d(unsigned height, unsigned width);
/*! \brief Test if the window is centered.
*
......@@ -116,7 +114,7 @@ namespace mln
rectangle2d sym_() const;
protected:
unsigned half_height_, half_width_;
unsigned height_, width_;
};
......@@ -136,12 +134,12 @@ namespace mln
# ifndef MLN_INCLUDE_ONLY
rectangle2d::rectangle2d(unsigned half_height, unsigned half_width)
: half_height_(half_height),
half_width_(half_width)
rectangle2d::rectangle2d(unsigned height, unsigned width)
: height_(height),
width_(width)
{
mln_precondition(half_height != 0 && half_width != 0);
const int drow = half_height, dcol = half_width;
mln_precondition(height % 2 == 1 && width % 2 == 1);
const int drow = height / 2, dcol = width / 2;
for (int row = - drow; row <= drow; ++row)
for (int col = - dcol; col <= dcol; ++col)
insert(make::dpoint2d(row, col));
......@@ -159,17 +157,17 @@ namespace mln
unsigned rectangle2d::height() const
{
return 2 * half_height_ + 1;
return height_;
}
unsigned rectangle2d::width() const
{
return 2 * half_width_ + 1;
return width_;
}
unsigned rectangle2d::delta() const
{
return half_width_ > half_height_ ? half_width_ : half_height_;
return width_ > height_ ? width_ / 2 : height_ / 2;
}
rectangle2d rectangle2d::sym_() const
......@@ -177,10 +175,9 @@ namespace mln
return *this;
}
std::ostream& operator<<(std::ostream& ostr,
const rectangle2d& win)
std::ostream& operator<<(std::ostream& ostr, const rectangle2d& win)
{
ostr << "[width=" << win.width() << ", height=" << win.height() << ']';
ostr << "[rectangle2d: width=" << win.width() << ", height=" << win.height() << ']';
return ostr;
}
......@@ -190,4 +187,9 @@ namespace mln
// when rectangle2d is involved, one surely also wants:
# include <mln/core/hline2d.hh>
# include <mln/core/vline2d.hh>
#endif // ! MLN_CORE_RECTANGLE2D_HH
// Copyright (C) 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_CORE_VLINE2D_HH
# define MLN_CORE_VLINE2D_HH
/*! \file mln/core/vline2d.hh
*
* \brief Definition of the mln::vline2d window.
*/
# include <mln/core/concept/window.hh>
# include <mln/core/internal/set_of.hh>
# include <mln/core/dpoint2d.hh>
# include <mln/core/dpoints_piter.hh>
namespace mln
{
/*! \brief Vertical line window defined on the 2D square grid.
*
* An vline2d is centered and symmetrical; so its width is 1 and
* its height (length) is odd.
*
* For instance: \n
* o \n
* x \n
* o \n
* is defined with length = 5.
*/
struct vline2d : public Window< vline2d >,
public internal::set_of_<dpoint2d>
{
/// Point associated type.
typedef point2d point;
/// Dpoint associated type.
typedef dpoint2d dpoint;
/*! \brief Piter type to browse a vline such as: "for each row
* (increasing), for each column (increasing)."
*/
typedef dpoints_fwd_piter<dpoint2d> fwd_qiter;
/*! \brief Piter type to browse a vline such as: "for each row
* (decreasing), for each column (decreasing)."
*/
typedef dpoints_fwd_piter<dpoint2d> bkd_qiter; // FIXME: bkd!!!
/*! \brief Same as fwd_qiter.
*/
typedef fwd_qiter qiter;
/*! \brief Constructor.
*
* \param[in] length Length, thus height, of the vertical line.
*
* \pre \p length is odd.
*/
vline2d(unsigned length);
/*! \brief Test if the window is centered.
*
* \return True.
*/
bool is_centered() const;
/*! \brief Test if the window is symmetric.
*
* \return true.
*/
bool is_symmetric() const;
/*! \brief Give the vline length, that is, its height.
*/
unsigned length() const;
/*! \brief Give the maximum coordinate gap between the window
* center and a window point.
*/
unsigned delta() const;
/// Get the symmetrical window.
vline2d sym_() const;
protected:
unsigned length_;
};
/*! \brief Print a vertical 2D line window \p win into the output
* stream \p ostr.
*
* \param[in,out] ostr An output stream.
* \param[in] win A vertical 2D line window.
*
* \return The modified output stream \p ostr.
*
* \relates mln::vline2d
*/
std::ostream& operator<<(std::ostream& ostr, const vline2d& win);
# ifndef MLN_INCLUDE_ONLY
vline2d::vline2d(unsigned length)
: length_(length)
{
mln_precondition(length % 2 == 1);
const int drow = length / 2;
for (int row = - drow; row <= drow; ++row)
insert(make::dpoint2d(row, 0));
}
bool vline2d::is_centered() const
{
return true;
}
bool vline2d::is_symmetric() const
{
return true;
}
unsigned vline2d::length() const
{
return length_;
}
unsigned vline2d::delta() const
{
return length_ / 2;
}
vline2d vline2d::sym_() const
{
return *this;
}
std::ostream& operator<<(std::ostream& ostr, const vline2d& win)
{
ostr << "[line2d: length=" << win.length() << ']';
return ostr;
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln
#endif // ! MLN_CORE_VLINE2D_HH
// Copyright (C) 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_LEVEL_APPROX_MEDIAN_HH
# define MLN_LEVEL_APPROX_MEDIAN_HH
/*! \file mln/level/median.hh
*
* \brief Approximates of some median filters of an image.
*/
# include <mln/level/median.hh>
# include <mln/core/rectangle2d.hh>
namespace mln
{
namespace level
{
namespace approx
{
/*! Compute in \p output an approximate of the median filter of
* image \p input by the 2D rectangle \p win.
*
* \param[in] input The image to be filtered.
* \param[in] win The rectangle.
* \param[in,out] output The output image.
*
* The approximation is based on a vertical median ran after
* an horizontal median.
*
* \pre \p input and \p output have to be initialized.
*/
template <typename I, typename O>
void median(const Image<I>& input, const rectangle2d& win,
Image<O>& output);
# ifndef MLN_INCLUDE_ONLY
template <typename I, typename O>
void median(const Image<I>& input_, const rectangle2d& win,
Image<O>& output_)
{
const I& input = exact(input_);
O& output = exact(output_);
mln_assertion(output.domain() == input.domain());
O tmp(output.domain());
level::median(input, hline2d(win.width()), tmp);
level::median(tmp, vline2d(win.height()), output);
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::level::approx
} // end of namespace mln::level
} // end of namespace mln
#endif // ! MLN_LEVEL_APPROX_MEDIAN_HH
......@@ -34,9 +34,11 @@
*/
# include <mln/core/concept/image.hh>
# include <mln/core/window2d.hh>
# include <mln/accu/median.hh>
# include <mln/core/hline2d.hh>
# include <mln/accu/median.hh>
# include <mln/canvas/sbrowsing.hh>
......@@ -66,88 +68,6 @@ namespace mln
namespace impl
{
template <typename I, typename W, typename O>
void median_as_procedure(const I& input,
const W& win,
O& output)
{
mln_precondition(input.has_data());
mln_precondition(output.has_data());
int
min_row = input.min_row(), max_row = input.max_row(),
min_col = input.min_col(), max_col = input.max_col();
window2d
win_fwd_plus = win - (win + left),
win_fwd_minus = (win + left) - win,
win_bkd_plus = win - (win + right),
win_bkd_minus = (win + right) - win,
win_bot = win - (win + up),
win_top = (win + up) - win;
point2d p;
mln_qiter(W)
q_fp(win_fwd_plus, p), q_fm(win_fwd_minus, p),
q_bp(win_bkd_plus, p), q_bm(win_bkd_minus, p),
q_top(win_top, p), q_bot(win_bot, p);
accu::median_on<mln_value(I)> med;
// initialization
p = input.domain().pmin() + up;
med.init();
{
mln_qiter(W) q(win, p);
for_all(q) if (input.has(q))
med.take(input(q));
}
int& row = p.row();
int& col = p.col();
bool fwd = true;