https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
Index: ChangeLog
from Thierry Geraud <thierry.geraud(a)lrde.epita.fr>
Sample code for Roland.
* geraud/dmap.cc: New.
dmap.cc | 129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 129 insertions(+)
Index: geraud/dmap.cc
--- geraud/dmap.cc (revision 0)
+++ geraud/dmap.cc (revision 0)
@@ -0,0 +1,129 @@
+#include <vector>
+
+#include <mln/core/image2d.hh>
+#include <mln/core/w_window2d_int.hh>
+#include <mln/debug/println.hh>
+#include <mln/level/fill.hh>
+#include <mln/level/stretch.hh>
+#include <mln/accu/max.hh>
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+
+namespace mln
+{
+
+ template<typename I, typename W>
+ mln_ch_value(I, unsigned) dmap(const Image<I>& input_,
+ const Weighted_Window<W>& win_)
+ {
+ const I& input = exact(input_);
+ const W& win = exact(win_);
+ mln_precondition(input.has_data());
+
+ typedef std::vector<mln_point(I)> bucket_t;
+
+ // Initialization of distance.
+ mln_ch_value(I, unsigned) distance;
+ initialize(distance, input);
+
+ // Mod determination.
+ mln_accu_with_(accu::max, unsigned) max;
+ for (unsigned i = 0; i < win.ndpoints(); ++i)
+ max.take(win.w(i));
+ unsigned mod = unsigned(max) + 1;
+
+ // Aux data.
+ std::vector<bucket_t> bucket(mod);
+ unsigned bucket_size = 0;
+
+ // Initialization.
+ {
+ mln_piter(I) p(input.domain());
+ mln_qiter(W) q(win, p);
+ for_all(p)
+ if (input(p))
+ {
+ distance(p) = literal::zero;
+ for_all(q)
+ if (input.has(q) && ! input(q))
+ {
+ bucket[0].push_back(p);
+ ++bucket_size;
+ break;
+ }
+ }
+ else
+ distance(p) = mln_max(unsigned);
+ }
+
+ // Propagation.
+ {
+ mln_point(I) p;
+ mln_qiter(W) q(win, p);
+
+ for (unsigned d = 0; bucket_size != 0; ++d)
+ {
+ bucket_t& bucket_d = bucket[d % mod];
+ for (unsigned i = 0; i < bucket_d.size(); ++i)
+ {
+ p = bucket_d[i];
+
+ if (distance(p) < d)
+ // p has already been processed, having a distance less than d.
+ continue;
+
+ for_all(q)
+ if (distance.has(q) && distance(q) > d)
+ {
+ unsigned d_ = d + q.w();
+
+ if (d_ < distance(q))
+ {
+ distance(q) = d_;
+ bucket[d_ % mod].push_back(q);
+ ++bucket_size;
+ }
+ }
+ }
+ bucket_size -= bucket_d.size();
+ bucket_d.clear();
+ }
+
+ } // end of propagation.
+
+ return distance;
+ }
+
+} // end of namespace mln
+
+
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+
+ const unsigned n = 256;
+ image2d<bool> ima(n, n);
+ level::fill(ima, false);
+ ima.at(n / 2, n / 2) = true;
+
+ int ws[] = { 3, 2, 3,
+ 2, 0, 2,
+ 3, 2, 3 };
+
+// int ws[] = { 0, 9, 0, 9, 0,
+// 9, 6, 4, 6, 9,
+// 0, 4, 0, 4, 0,
+// 9, 6, 4, 6, 9,
+// 0, 9, 0, 9, 0 }; // coef = 4.1203
+
+ w_window2d_int win = make::w_window2d(ws);
+
+ image2d<unsigned> d = dmap(ima, win);
+
+ image2d<int_u8> out(d.domain());
+ level::stretch(d, out);
+ io::pgm::save(out, "out.pgm");
+}