* milena/mln/accu/center.hh: Add nsites() member.
* milena/mln/accu/pair.hh: Provide access to the underlying accus.
* milena/mln/accu/stat/variance.hh: Use literal::zero.
* milena/mln/core/internal/labeled_image_base.hh: Indent.
* milena/mln/core/site_set/box.hh: Rename center() as pcenter().
* milena/mln/labeling/blobs_and_compute.hh: Return the array of
accumulators.
* milena/mln/labeling/colorize.hh: Make sure a color is not used
twice in the same image.
* milena/mln/labeling/compute.hh: Add a new overload.
* milena/mln/transform/influence_zone_geodesic.hh: Fix a
segmentation fault when an image had a border.
---
milena/ChangeLog | 25 +++++
milena/mln/accu/center.hh | 14 +++-
milena/mln/accu/pair.hh | 26 ++++++
milena/mln/accu/stat/variance.hh | 4 +-
milena/mln/core/internal/labeled_image_base.hh | 2 +-
milena/mln/core/site_set/box.hh | 4 +-
milena/mln/labeling/blobs_and_compute.hh | 14 ++-
milena/mln/labeling/colorize.hh | 51 ++++++++---
milena/mln/labeling/compute.hh | 111 +++++++++++++++++++----
milena/mln/transform/influence_zone_geodesic.hh | 13 +--
10 files changed, 214 insertions(+), 50 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 73b9647..ec2ef35 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,28 @@
+2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Small fixes in Milena.
+
+ * milena/mln/accu/center.hh: Add nsites() member.
+
+ * milena/mln/accu/pair.hh: Provide access to the underlying accus.
+
+ * milena/mln/accu/stat/variance.hh: Use literal::zero.
+
+ * milena/mln/core/internal/labeled_image_base.hh: Indent.
+
+ * milena/mln/core/site_set/box.hh: Rename center() as pcenter().
+
+ * milena/mln/labeling/blobs_and_compute.hh: Return the array of
+ accumulators.
+
+ * milena/mln/labeling/colorize.hh: Make sure a color is not used
+ twice in the same image.
+
+ * milena/mln/labeling/compute.hh: Add a new overload.
+
+ * milena/mln/transform/influence_zone_geodesic.hh: Fix a
+ segmentation fault when an image had a border.
+
2009-12-14 Guillaume Lazzara <z(a)lrde.epita.fr>
Add rbg_to_int_u function.
diff --git a/milena/mln/accu/center.hh b/milena/mln/accu/center.hh
index 7cfbe78..a3622b3 100644
--- a/milena/mln/accu/center.hh
+++ b/milena/mln/accu/center.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009, 2010 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -73,6 +74,9 @@ namespace mln
/// Check whether this accu is able to return a result.
bool is_valid() const;
+ /// Return the number of sites taken in consideration.
+ unsigned nsites() const;
+
protected:
algebra::vec<P::dim, mln_sum(mln_coord(P))> center_;
unsigned nsites_;
@@ -158,6 +162,14 @@ namespace mln
return nsites_ > 0;
}
+ template <typename P, typename V>
+ inline
+ unsigned
+ center<P,V>::nsites() const
+ {
+ return nsites_;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/mln/accu/pair.hh b/milena/mln/accu/pair.hh
index bb0b691..11f4dc6 100644
--- a/milena/mln/accu/pair.hh
+++ b/milena/mln/accu/pair.hh
@@ -81,9 +81,16 @@ namespace mln
void get_result(result_1& r1, result_2& r2) const;
/// \}
+ /// Return the result of the first accumulator.
mln_result(A1) first() const;
+ /// Return the result of the second accumulator.
mln_result(A2) second() const;
+ /// Return the first accumulator.
+ A1 first_accu() const;
+ /// Return the second accumulator.
+ A2 second_accu() const;
+
/// Check whether this accu is able to return a result.
/// Always true here.
bool is_valid() const;
@@ -194,6 +201,25 @@ namespace mln
return a2_.to_result();
}
+
+
+ template <typename A1, typename A2, typename T>
+ inline
+ A1
+ pair<A1,A2,T>::first_accu() const
+ {
+ return a1_;
+ }
+
+ template <typename A1, typename A2, typename T>
+ inline
+ A2
+ pair<A1,A2,T>::second_accu() const
+ {
+ return a2_;
+ }
+
+
template <typename A1, typename A2, typename T>
inline
bool
diff --git a/milena/mln/accu/stat/variance.hh b/milena/mln/accu/stat/variance.hh
index 23e7731..c19761e 100644
--- a/milena/mln/accu/stat/variance.hh
+++ b/milena/mln/accu/stat/variance.hh
@@ -125,7 +125,7 @@ namespace mln
variance<T,S,R>::init()
{
n_ = 0;
- sum_ = sum2_ = 0;
+ sum_ = sum2_ = literal::zero;
}
template <typename T, typename S, typename R>
@@ -187,7 +187,7 @@ namespace mln
variance<T,S,R>::mean() const
{
if (n_ == 0u)
- return 0; // Safety.
+ return literal::zero; // Safety.
return sum_ / n_;
}
diff --git a/milena/mln/core/internal/labeled_image_base.hh
b/milena/mln/core/internal/labeled_image_base.hh
index 9e2d314..86bb077 100644
--- a/milena/mln/core/internal/labeled_image_base.hh
+++ b/milena/mln/core/internal/labeled_image_base.hh
@@ -310,7 +310,7 @@ namespace mln
const util::array<typename labeled_image_base<I,E>::bbox_t>&
labeled_image_base<I,E>::bboxes() const
{
- return this->data_->bboxes_;
+ return this->data_->bboxes_;
}
diff --git a/milena/mln/core/site_set/box.hh b/milena/mln/core/site_set/box.hh
index 75fb91c..077ac3d 100644
--- a/milena/mln/core/site_set/box.hh
+++ b/milena/mln/core/site_set/box.hh
@@ -143,7 +143,7 @@ namespace mln
box<P> to_larger(unsigned b) const;
/// Return the approximated central site of this box.
- P center() const;
+ P pcenter() const;
/// Test that the box owns valid data, i.e., is initialized and
/// with pmin being 'less-than' pmax.
@@ -390,7 +390,7 @@ namespace mln
template <typename P>
inline
P
- box<P>::center() const
+ box<P>::pcenter() const
{
mln_precondition(is_valid());
P center;
diff --git a/milena/mln/labeling/blobs_and_compute.hh
b/milena/mln/labeling/blobs_and_compute.hh
index 4d5d5d8..b76b62a 100644
--- a/milena/mln/labeling/blobs_and_compute.hh
+++ b/milena/mln/labeling/blobs_and_compute.hh
@@ -53,7 +53,9 @@ namespace mln
*/
template <typename I, typename N, typename L, typename A>
- util::couple<mln_ch_value(I, L), util::array<mln_result(A)> >
+ util::couple<mln_ch_value(I,L),
+ util::couple<util::array<mln_result(A)>,
+ util::array<A> > >
blobs_and_compute(const Image<I>& input, const Neighborhood<N>&
nbh,
L& nlabels, const Accumulator<A>& accu);
@@ -72,7 +74,8 @@ namespace mln
{
typedef mln_result(A) accu_result;
typedef mln_argument(A) accu_argument;
- typedef util::array<accu_result> result;
+ typedef util::couple<util::array<accu_result>,
+ util::array<A> > result;
void init()
{
@@ -133,7 +136,9 @@ namespace mln
template <typename I, typename N, typename L, typename A>
- util::couple<mln_ch_value(I,L), util::array<mln_result(A)> >
+ util::couple<mln_ch_value(I,L),
+ util::couple<util::array<mln_result(A)>,
+ util::array<A> > >
blobs_and_compute(const Image<I>& input, const Neighborhood<N>&
nbh,
L& nlabels, const Accumulator<A>& accu)
{
@@ -151,7 +156,8 @@ namespace mln
output = canvas::labeling::blobs(input, nbh, nlabels, functor);
util::couple<out_t, typename func_t::result>
- result = make::couple(output, functor.result_);
+ result = make::couple(output,
+ make::couple(functor.result_, functor.accus_));
trace::exiting("labeling::blobs_and_compute");
return result;
diff --git a/milena/mln/labeling/colorize.hh b/milena/mln/labeling/colorize.hh
index 26a78df..69493d5 100644
--- a/milena/mln/labeling/colorize.hh
+++ b/milena/mln/labeling/colorize.hh
@@ -103,11 +103,9 @@ namespace mln
unsigned random_number()
{
- static unsigned last = 1;
+ unsigned last = colorize_::min_value + (colorize_::max_value - colorize_::min_value + 1)
* rand();
- last = (323 * last + 6603) % 1025;
-
- return colorize_::min_value + last % colorize_::max_value;
+ return math::min(colorize_::min_value + last % colorize_::max_value,
colorize_::max_value);
}
@@ -120,17 +118,42 @@ namespace mln
mln::value::rgb<n>
random_color(const mln::value::rgb<n>&)
{
- // Make sure the numbers are generated in the same order
- // whatever the compiler used.
- // For instance, ICC does not compute function arguments in
- // the same order as GCC does.
- unsigned
- red = random_number(),
- green = random_number(),
+ static unsigned
+ nelements = colorize_::max_value - colorize_::min_value + 1;
+ static util::array<util::set<unsigned> >
+ red_(nelements),
+ green_(nelements);
+
+ unsigned red, green, blue;
+
+ unsigned ntries = 0;
+ do
+ {
+ red = random_number();
+ ++ntries;
+ }
+ while (red_[red - colorize_::min_value].nelements() == nelements
+ && ntries < nelements);
+
+ if (ntries == nelements)
+ {
+ trace::warning("labeling::colorize - Can't find a new unique color. Returning
black.");
+ return literal::black;
+ }
+
+
+ do
+ green = random_number();
+ while (red_[red - colorize_::min_value].has(green)
+ || green_[green - colorize_::min_value].nelements() == nelements);
+ red_[red - colorize_::min_value].insert(green);
+
+ do
blue = random_number();
- return mln::value::rgb<n>(red,
- green,
- blue);
+ while (green_[green - colorize_::min_value].has(blue));
+ green_[green - colorize_::min_value].insert(blue);
+
+ return mln::value::rgb<n>(red, green, blue);
}
}
diff --git a/milena/mln/labeling/compute.hh b/milena/mln/labeling/compute.hh
index d29242f..4f0d97d 100644
--- a/milena/mln/labeling/compute.hh
+++ b/milena/mln/labeling/compute.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -60,23 +61,6 @@ namespace mln
/// Compute an accumulator onto the pixel values of the image \p input.
/// for each component of the image \p label.
///
- /// \param[in] a An array of accumulator.
- /// \param[in] input The input image.
- /// \param[in] label The labeled image.
- /// \param[in] nlabels The number of labels in \p label.
- /// \return A mln::p_array of accumulator result (one result per label).
- //
- template <typename A, typename I, typename L>
- util::array<mln_result(A)>
- compute(util::array<A>& a,
- const Image<I>& input,
- const Image<L>& label,
- const mln_value(L)& nlabels);
-
-
- /// Compute an accumulator onto the pixel values of the image \p input.
- /// for each component of the image \p label.
- ///
/// \param[in] a An accumulator.
/// \param[in] input The input image.
/// \param[in] label The labeled image.
@@ -138,6 +122,23 @@ namespace mln
const mln_value(L)& nlabels);
+ /// Compute an accumulator onto the pixel values of the image \p input.
+ /// for each component of the image \p label.
+ ///
+ /// \param[in] a An array of accumulator.
+ /// \param[in] input The input image.
+ /// \param[in] label The labeled image.
+ /// \param[in] nlabels The number of labels in \p label.
+ /// \return A mln::p_array of accumulator result (one result per label).
+ //
+ template <typename A, typename I, typename L>
+ util::array<mln_result(A)>
+ compute(util::array<A>& a,
+ const Image<I>& input,
+ const Image<L>& label,
+ const mln_value(L)& nlabels);
+
+
# ifndef MLN_INCLUDE_ONLY
@@ -221,6 +222,49 @@ namespace mln
return res;
}
+ /// Generic implementation of labeling::compute.
+ ///
+ /// \param[in] accus_ An array of accumulators. If the size is
+ /// set to nlabels + 1, the accumulators are
+ /// considered as initialized. Otherwise,
+ /// the size is adjusted.
+ /// \param[in] label_ The labeled image.
+ /// \param[in] nlabels The number of labels in \p label.
+ ///
+ /// \return A mln::p_array of accumulator result (one result per label).
+ //
+ template <typename A, typename L>
+ inline
+ util::array<mln_result(A)>
+ compute(util::array<A>& accus,
+ const Image<L>& label_,
+ const mln_value(L)& nlabels)
+ {
+ trace::entering("labeling::impl::generic::compute");
+ internal::compute_tests(A(), label_, nlabels);
+
+ if (static_cast<unsigned>(nlabels) + 1 != accus.size())
+ {
+ accus.resize(0); // Make sure all the accumulators are
+ // re-initialized when resizing on next
+ // line.
+ accus.resize(static_cast<unsigned>(nlabels) + 1);
+ }
+
+ const L& label = exact(label_);
+
+ mln_piter(L) p(label.domain());
+ for_all(p)
+ accus[label(p)].take(p);
+
+ util::array<mln_result(A)> res;
+ convert::from_to(accus, res);
+
+ trace::exiting("labeling::impl::generic::compute");
+ return res;
+ }
+
+
/// Generic implementation of labeling::compute.
///
@@ -343,6 +387,15 @@ namespace mln
return impl::generic::compute(a, input, label, nlabels);
}
+ template <typename A, typename L>
+ inline
+ util::array<mln_result(A)>
+ compute_dispatch(util::array<A>& accus,
+ const Image<L>& label,
+ const mln_value(L)& nlabels)
+ {
+ return impl::generic::compute(accus, label, nlabels);
+ }
} // end of namespace mln::labeling::internal
@@ -406,6 +459,28 @@ namespace mln
template <typename A, typename L>
inline
util::array<mln_result(A)>
+ compute(util::array<A>& accus,
+ const Image<L>& label,
+ const mln_value(L)& nlabels)
+ {
+ trace::entering("labeling::compute");
+
+ internal::compute_tests(A(), label, nlabels);
+
+ typedef util::array<mln_result(A)> R;
+ R res = internal::compute_dispatch(accus, label, nlabels);
+
+ mln_postcondition(res.nelements() == static_cast<unsigned>(nlabels) + 1);
+
+ trace::exiting("labeling::compute");
+ return res;
+ }
+
+
+
+ template <typename A, typename L>
+ inline
+ util::array<mln_result(A)>
compute(const Accumulator<A>& a,
const Image<L>& label,
const mln_value(L)& nlabels)
diff --git a/milena/mln/transform/influence_zone_geodesic.hh
b/milena/mln/transform/influence_zone_geodesic.hh
index 4d7255a..b9a763f 100644
--- a/milena/mln/transform/influence_zone_geodesic.hh
+++ b/milena/mln/transform/influence_zone_geodesic.hh
@@ -1,4 +1,5 @@
-// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory
+// (LRDE)
//
// This file is part of Olena.
//
@@ -104,16 +105,12 @@ namespace mln
const N& nbh = exact(nbh_);
internal::influence_zone_geodesic_tests(input, nbh);
- mln_precondition(input.domain().pmin() == literal::origin);
std::queue<mln_value(I)*> q;
mln_concrete(I) output;
util::array<int> dp = offsets_wrt(input, nbh);
const unsigned n_nbhs = dp.nelements();
- const unsigned
- ncols = input.ncols(),
- first_offset = input.border() * (ncols + 2 * input.border() + 1);
// Initialization.
{
@@ -124,9 +121,9 @@ namespace mln
extension::fill(output, 1); // in propagation
const unsigned nelts = input.nelements();
- const mln_value(I)* p_i = & input.at_(0, 0);
- mln_value(I)* p_o = & output.at_(0, 0);
- for (unsigned i = first_offset; i < nelts; ++i, ++p_i, ++p_o)
+ const mln_value(I)* p_i = input.buffer();
+ mln_value(I)* p_o = output.buffer();
+ for (unsigned i = 0; i < nelts; ++i, ++p_i, ++p_o)
{
if (*p_i == 0)
continue;
--
1.5.6.5