URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2008-05-16 Matthieu Garrigues <garrigues(a)lrde.epita.fr>
* geraud/fllt.cc: FLLT : Finalize merge.
---
fllt.cc | 297 +++++++++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 211 insertions(+), 86 deletions(-)
Index: trunk/milena/sandbox/geraud/fllt.cc
===================================================================
--- trunk/milena/sandbox/geraud/fllt.cc (revision 1960)
+++ trunk/milena/sandbox/geraud/fllt.cc (revision 1961)
@@ -77,6 +77,7 @@
# define fllt_branch_iter_ind(P, V) mln::util::branch_iter_ind< fllt_node_elt<P,
V> >
# define fllt_branch_iter(P, V) mln::util::branch_iter< fllt_node_elt<P, V>
>
+# define stl_to_mln_iter(T) stl_iterator< T >
//Fwd declarations.
template <typename V> struct lower;
@@ -88,6 +89,7 @@
V value;
p_array<P> points;
p_array<P> holes;
+ std::vector<fllt_node(P, V)*> hole_shapes;
/// Tell if his parent if brighter or not. Nb : if the parent
/// if brighter, the node come from the lower level set
bool brighter;
@@ -238,12 +240,13 @@
}
- template <typename I, typename V>
- void blob(const I& is,
+ template <typename I, typename P, typename V, typename Set>
+ void blob(const Set&,
+ const I& is,
p_array<mln_point(I)>* N[256],
unsigned in_N,
const box2d& N_box,
- fllt_node(mln_point(I), V)* current_cc)
+ fllt_node(P, V)* current_cc)
{
typedef p_array<mln_point(I)> arr_t;
@@ -259,9 +262,8 @@
label++;
}
- typedef mln_psite(I) P;
P cur;
- mln_niter(neighb2d) n(c8(), cur);
+ mln_niter(neighb2d) n(Set::bdr_nbh(), cur);
p_queue_fast<P> qu;
p_array<P>& holes = current_cc->elt().holes;
@@ -296,6 +298,7 @@
for (unsigned i = 0; i < 256; ++i)
+ //for (int i = 255; i >= 0; --i)
{
mln_piter(arr_t) p(*N[i]);
for_all(p)
@@ -340,7 +343,8 @@
image2d< fllt_node(P, V)* >& smallest_shapes,
int in_R,
int in_N,
- const V& g)
+ const V& g,
+ unsigned& n_comps)
{
typedef p_array<P> arr_t;
@@ -349,9 +353,10 @@
{
mln_invariant(deja_vu(a) == in_N);
mln_invariant(smallest_shapes(a) != current_cc);
+// if (smallest_shapes(a) == current_cc)
+// continue;
deja_vu(a) = in_R;
- current_cc->elt().npoints++;
if (!smallest_shapes(a))
{
smallest_shapes(a) = current_cc;
@@ -363,22 +368,27 @@
{
fllt_node(P, V)* to_delete = smallest_shapes(a);
+// current_cc->elt().points.append(smallest_shapes(a)->elt().points);
+// A.append(smallest_shapes(a)->elt().points);
+
mln_piter(arr_t) p(smallest_shapes(a)->elt().points);
// Todo optimization here.
for_all(p)
+ {
smallest_shapes(p) = 0;
+ // deja_vu(p) = in_R;
+ //smallest_shapes(p) = current_cc;
+ }
while(!to_delete->children().empty())
current_cc->add_child(*to_delete->children().begin());
delete to_delete;
-
+ n_comps--;
smallest_shapes(a) = current_cc;
current_cc->elt().points.append(a);
}
else
smallest_shapes(a)->set_parent(current_cc);
- // N_box is not re-computed so that we save time;
- // N_box is always growing while looping from step 3.
}
}
@@ -449,7 +459,7 @@
mln_assertion(input.domain() == smallest_shapes.domain());
- unsigned l = 0, l_max;
+ unsigned l = 0, l_max = 0;
mln_ch_value(I, unsigned) reg_min = Set::regional_extremum(input, Set::reg_nbh(),
l_max);
std::vector<bool> tag(l_max + 1, false);
tag[0] = true;
@@ -476,7 +486,7 @@
accu::bbox<P> N_box;
bool touch_border_of_image = false;
- unsigned n_step_1 = 0, n_step_3 = 0, n_comps = 0, n_holes = 0;
+ unsigned n_step_1 = 0, n_step_3 = 0, n_step_4c = 0, n_comps = 0, n_holes = 0;
// Step 1.
step_1:
@@ -491,6 +501,7 @@
++n_step_1;
x0 = p;
g = input(x0);
+ ++n_comps;
current_cc = new node_type(Set::id);
current_cc->elt().value = g;
touch_border_of_image = false;
@@ -565,9 +576,9 @@
++n_comps;
if (touch_border_of_image)
- blob(deja_vu, N, in_N, N_box.to_result().to_larger(1), current_cc);
+ blob(Set(), deja_vu, N, in_N, N_box.to_result().to_larger(1), current_cc);
else
- blob(deja_vu, N, in_N, N_box, current_cc);
+ blob(Set(), deja_vu, N, in_N, N_box, current_cc);
n_holes += current_cc->elt().holes.npoints();
@@ -581,7 +592,7 @@
A = N[g];
N[g] = tmp;
N[g]->clear();
- move_A_to_R(*A, deja_vu, current_cc, smallest_shapes, in_R, in_N, g);
+ move_A_to_R(*A, deja_vu, current_cc, smallest_shapes, in_R, in_N, g, n_comps);
goto step_3;
}
// b)
@@ -591,13 +602,14 @@
A = N[g];
N[g] = tmp;
N[g]->clear();
- move_A_to_R(*A, deja_vu, current_cc, smallest_shapes, in_R, in_N, g);
+ move_A_to_R(*A, deja_vu, current_cc, smallest_shapes, in_R, in_N, g, n_comps);
goto step_3;
}
// c)
else
{
// FIXME: IDEA: this change might be performed while R is constructed(?)
+ n_step_4c++;
mln_piter(I) r(N_box);
for_all(r)
if (deja_vu(r) == in_R)
@@ -608,7 +620,7 @@
}
the_end:
- std::cout << n_step_1 << ' ' << n_step_3 <<
std::endl;
+ std::cout << " n_step1 : " << n_step_1 << "
n_step3 : " << n_step_3 << " n_step4c : " << n_step_4c
<< std::endl;
std::cout << "n comps = " << n_comps << " n holes
= " << n_holes << std::endl;
return *new tree_type(current_cc);
@@ -637,34 +649,42 @@
}
template <typename P, typename V>
- bool shape_is_included(fllt_branch_iter_ind(P, V) A,
- fllt_branch_iter_ind(P, V) B)
+ bool shape_is_included(fllt_node(P, V)* A,
+ fllt_node(P, V)* B)
+ {
+ return A->parent() == B || A == B;
+ }
+
+ template <typename P, typename V>
+ void find_all_holes(fllt_tree(P, V)& lower_tree,
+ fllt_tree(P, V)& upper_tree,
+ const image2d<fllt_node(P, V)*>& low_reg,
+ const image2d<fllt_node(P, V)*>& upp_reg)
{
- // TODO: optimize : take the smalest shape first.
typedef p_array<P> arr_t;
+ typedef fllt_node(P, V) node_type;
- for_all(A)
{
- bool found = false;
- mln_piter(arr_t) pA((*A).elt().points);
- for_all(pA)
- for_all(B)
- {
- found = false;
- mln_piter(arr_t) pB((*B).elt().points);
- for_all(pB)
- if (pA == pB)
+ fllt_branch_iter_ind(P, V) node_(lower_tree.main_branch());
+ for_all(node_)
{
- found = true;
- break;
+ node_type& node = *node_;
+ mln_piter(arr_t) hole(node.elt().holes);
+ for_all(hole)
+ node.elt().hole_shapes.push_back(find_hole<P,V,upper<V> >(node, P(hole),
upp_reg));
}
- if (found)
- break;
}
- if (!found)
- return false;
+
+ {
+ fllt_branch_iter_ind(P, V) node_(upper_tree.main_branch());
+ for_all(node_)
+ {
+ node_type& node = *node_;
+ mln_piter(arr_t) hole(node.elt().holes);
+ for_all(hole)
+ node.elt().hole_shapes.push_back(find_hole<P,V,lower<V> >(node, P(hole),
low_reg));
+ }
}
- return true;
}
template <typename I>
@@ -684,6 +704,8 @@
typedef fllt_tree(P, V) tree_type;
typedef p_array<P> arr_t;
+
+ find_all_holes(lower_tree, upper_tree, low_reg, upp_reg);
std::vector<node_type*> to_fill;
fllt_branch_iter_ind(P, V) node_(lower_tree.main_branch());
@@ -694,26 +716,27 @@
continue;
// std::cout << "Fill " << &node << std::endl;
-
- mln_piter(arr_t) hole_p(node.elt().holes);
- for_all(hole_p)
+ typename std::vector<fllt_node(P, V)*>::iterator hole_;
+ for (hole_ = node.elt().hole_shapes.begin();
+ hole_ != node.elt().hole_shapes.end();
+ hole_++)
{
- fllt_node(P, V)* hole;
- hole = find_hole<P,V,upper<V> >(node, P(hole_p), upp_reg);
+ fllt_node(P, V)* hole = *hole_;
bool child_has_bigger_hole = false;
typename fllt_node(P, V)::children_t::iterator it;
for (it = node.children().begin(); it != node.children().end() &&
!child_has_bigger_hole; it++)
{
// Browse the holes of each child.
- mln_piter(arr_t) q((*it)->elt().holes);
- for_all(q)
+ typename std::vector<fllt_node(P, V)*>::iterator child_hole_;
+ for (child_hole_ = (*it)->elt().hole_shapes.begin();
+ child_hole_ != (*it)->elt().hole_shapes.end();
+ child_hole_++)
{
- fllt_node(P, V)* child_hole = find_hole<P,V,upper<V> >((**it),
point2d(q), upp_reg);
+ fllt_node(P, V)* child_hole = *child_hole_;
// std::cout << "hole : " << hole << "
" << hole->elt().points << " " << std::endl;
// std::cout << "child hole : " << child_hole
<< " " << child_hole->elt().points << std::endl;
- if (shape_is_included(fllt_branch_iter_ind(P, V)(fllt_branch(P, V)(upper_tree,
*hole)),
- fllt_branch_iter_ind(P, V)(fllt_branch(P, V)(upper_tree, *child_hole))))
+ if (shape_is_included(hole, child_hole))
{
child_has_bigger_hole = true;
break;
@@ -743,24 +766,26 @@
if (node.elt().set_id != upper<V>::id)
continue;
- mln_piter(arr_t) hole_p(node.elt().holes);
- for_all(hole_p)
+ typename std::vector<fllt_node(P, V)*>::iterator hole_;
+ for (hole_ = node.elt().hole_shapes.begin();
+ hole_ != node.elt().hole_shapes.end();
+ hole_++)
{
- fllt_node(P, V)* hole;
- hole = find_hole<P,V,lower<V> >(node, P(hole_p), low_reg);
+ fllt_node(P, V)* hole = *hole_;
bool child_has_bigger_hole = false;
typename fllt_node(P, V)::children_t::iterator it;
for (it = node.children().begin(); it != node.children().end() &&
!child_has_bigger_hole; it++)
{
// Browse the holes of each child.
- mln_piter(arr_t) q((*it)->elt().holes);
- for_all(q)
+ typename std::vector<fllt_node(P, V)*>::iterator child_hole_;
+ for (child_hole_ = (*it)->elt().hole_shapes.begin();
+ child_hole_ != (*it)->elt().hole_shapes.end();
+ child_hole_++)
{
- fllt_node(P, V)* child_hole = find_hole<P,V,lower<V> >((**it),
point2d(q), low_reg);
+ fllt_node(P, V)* child_hole = *child_hole_;
//if (hole->elt().points <= child_hole->elt().points)
- if (shape_is_included(fllt_branch_iter_ind(P, V)(fllt_branch(P, V)(lower_tree,
*hole)),
- fllt_branch_iter_ind(P, V)(fllt_branch(P, V)(lower_tree, *child_hole))))
+ if (shape_is_included(hole, child_hole))
{
child_has_bigger_hole = true;
break;
@@ -796,7 +821,7 @@
std::cout << "1/ Compute the lower level
set.----------------------------------------" << std::endl;
lower_tree = level_set<I, lower<V> >(input, low_reg);
- draw_tree(input, lower_tree);
+// draw_tree(input, lower_tree);
std::cout << "2/ Compute the upper level
set.----------------------------------------" << std::endl;
upper_tree = level_set<I, upper<V> >(input, upp_reg);
@@ -843,6 +868,92 @@
}
}
+
+ template <typename P, typename V, typename I>
+ unsigned
+ compute_area_rec(fllt_node(P, V)* node, I& ima)
+ {
+
+ if (!node)
+ return 0;
+
+ int area = 0;
+
+ for (int i = 0; i < node->children().size();i++)
+ area += compute_area_rec(node->children()[i], ima);
+
+ mln_piter(p_array<P>) p(node->elt().points);
+ for_all(p)
+ if (!ima(P(p)))
+ {
+ ++area;
+ ima(p) = true;
+ }
+
+ node->elt().npoints = area;
+ return area;
+ }
+
+ template <typename P, typename V, typename I>
+ void
+ compute_area(const Image<I>& input_, fllt_tree(P, V)& tree)
+ {
+ const I& input = exact(input_);
+
+ image2d<bool> ima(input.domain());
+ level::fill(ima, false);
+ compute_area_rec(tree.root(), ima);
+ }
+
+ void draw_shape(image2d<value::int_u8>& output,
+ fllt_node(point2d, value::int_u8)* node)
+ {
+ typedef point2d P ;
+ typedef value::int_u8 V;
+
+ fllt_tree(P, V) subtree(node);
+ fllt_branch_iter_ind(P, V) s(fllt_branch(P, V)(subtree, *node));
+ for_all(s)
+ level::fill(inplace(output | (*s).elt().points), (*s).elt().value);
+ }
+
+ void area_filter(image2d<value::int_u8>& output,
+ fllt_node(point2d, value::int_u8)* node,
+ unsigned min_area,
+ unsigned max_area,
+ value::int_u8 bg)
+ {
+ typedef point2d P ;
+ typedef value::int_u8 V;
+
+ level::fill(output, bg);
+ fllt_tree(P, V) subtree(node);
+ fllt_branch_iter_ind(P, V) s(fllt_branch(P, V)(subtree, *node));
+ for_all(s)
+ if ((*s).elt().npoints > min_area && (*s).elt().npoints < max_area)
+ draw_shape(output, &*s);
+ }
+
+ void area_filter_min(image2d<value::int_u8>& output,
+ fllt_node(point2d, value::int_u8)* node,
+ unsigned min_area,
+ value::int_u8 g,
+ unsigned accu)
+ {
+// if ((*node).elt().npoints >= min_area)
+ if (accu > min_area)
+ {
+ accu = 0;
+ g = (*node).elt().value;
+ }
+
+ accu += (*node).elt().npoints;
+ level::fill(inplace(output | (*node).elt().points), g);
+
+ for (int i = 0; i < node->children().size();i++)
+ area_filter_min(output, node->children()[i], min_area, g, accu);
+ }
+
} // end of namespace mln::my
} // end of namespace mln
@@ -864,8 +975,8 @@
// return 1;
// }
-// image2d<int_u8> lena;
-// io::pgm::load(lena, argv[1]);
+ image2d<int_u8> lena;
+ io::pgm::load(lena, argv[1]);
// int vs[8][9] = { {0,0,0,0,0,0,0,0,0},
@@ -877,45 +988,59 @@
// {0,1,1,1,1,1,1,1,0},
// {0,0,0,0,0,0,0,0,0} };
-// int vs[8][9] = { {2,2,2,2,2,2,2,2,2},
-// {2,2,2,2,2,2,2,2,2},
-// {2,1,1,1,1,1,1,1,2},
-// {2,1,2,2,1,0,0,1,2},
-// {2,1,2,2,1,0,0,1,2},
-// {2,1,2,2,1,0,0,1,2},
-// {2,1,1,1,1,1,1,1,2},
-// {2,2,2,2,2,2,2,2,2} };
+// int vs[8][9] = { {6,6,6,6,6,6,6,6,6},
+// {6,6,6,6,6,6,6,6,6},
+// {6,5,5,5,5,5,5,5,6},
+// {6,5,6,6,5,3,3,5,6},
+// {6,5,6,6,5,3,0,5,6},
+// {6,5,6,6,5,3,3,5,6},
+// {6,5,5,5,5,5,5,5,6},
+// {6,6,6,6,6,6,6,6,6} };
+
// int vs[8][9] = { {2,2,2,2,2,2,2,2,2},
// {2,2,2,2,2,2,2,2,2},
// {2,1,1,1,1,1,1,1,2},
// {2,1,2,2,1,0,0,1,2},
-// {2,1,2,2,1,0,4,1,2},
+// {2,1,2,2,1,0,0,1,2},
// {2,1,2,2,1,0,0,1,2},
// {2,1,1,1,1,1,1,1,2},
// {2,2,2,2,2,2,2,2,2} };
- int vs[10][13] = { {1,1,1,1, 1,1,1,1, 1,1,1,1,1},
- {1,2,2,2,2,2,2,2,2,2,2,2,1},
- {1,2,2,2,2,2,2,2,2,2,2,2,1},
- {1,2,2,2,3,3,3,3,3,3,3,2,1},
- {1,2,2,2,3,3,3,2,2,2,3,2,1},
- {1,2,2,2,3,4,3,2,4,4,3,2,1},
-
- {1,2,2,2,3,3,3,2,2,2,3,2,1},
- {1,2,2,2,3,3,3,3,3,3,3,2,1},
- {1,2,2,2,2,2,2,2,2,2,2,2,1},
- {1,1,1,1,1,1,1,1,1,1,1,1,1}};
-
-
- image2d<int> lena_(make::image2d(vs));
- image2d<int_u8> lena(lena_.domain());
- level::fill(lena, lena_);
+
+ int vs[8][9] = { {2,2,2,2,2,2,2,2,2},
+ {2,2,2,2,2,2,2,2,2},
+ {2,1,1,1,1,1,1,1,2},
+ {2,1,2,2,1,0,0,1,2},
+ {2,1,2,2,1,0,4,1,2},
+ {2,1,2,2,1,0,0,1,2},
+ {2,1,1,1,1,1,1,1,2},
+ {2,2,2,2,2,2,2,2,2} };
+
+// int vs[10][13] = { {1,1,1,1, 1,1,1,1, 1,1,1,1,1},
+// {1,2,2,2,2,2,2,2,2,2,2,2,1},
+// {1,2,2,2,2,2,2,2,2,2,2,2,1},
+// {1,2,2,2,3,3,3,3,3,3,3,2,1},
+// {1,2,2,2,3,3,3,2,2,2,3,2,1},
+// {1,2,2,2,3,4,3,2,4,4,3,2,1},
+
+// {1,2,2,2,3,3,3,2,2,2,3,2,1},
+// {1,2,2,2,3,3,3,3,3,3,3,2,1},
+// {1,2,2,2,2,2,2,2,2,2,2,2,1},
+// {1,1,1,1,1,1,1,1,1,1,1,1,1}};
+
+
+// image2d<int> lena_(make::image2d(vs));
+// image2d<int_u8> lena(lena_.domain());
+// level::fill(lena, lena_);
tree_type tree = my::fllt(lena);
+ compute_area(lena, tree);
- draw_tree(lena, tree);
+ image2d<value::int_u8> output (lena.domain ());
+ area_filter(output, tree.root(), atoi(argv[2]), atoi(argv[3]), atoi(argv[4]));
+ io::pgm::save(output, "out.pgm");
- io::pgm::save(lena, "./out.pgm");
+ // draw_tree(lena, tree);
}