milena r1655: Update and clean extract character example

URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena ChangeLog: 2008-01-11 Guillaume Duhamel <guillaume.duhamel@lrde.epita.fr> Update and clean extract character example. * sandbox/nivault/extract_character.cc: Clean and update. --- extract_character.cc | 287 +++++++++++++++++++++++++++------------------------ 1 file changed, 152 insertions(+), 135 deletions(-) Index: trunk/milena/sandbox/nivault/extract_character.cc =================================================================== --- trunk/milena/sandbox/nivault/extract_character.cc (revision 1654) +++ trunk/milena/sandbox/nivault/extract_character.cc (revision 1655) @@ -71,20 +71,125 @@ using namespace mln; +bool +is_character(box2d box, unsigned cardinality) +{ + unsigned rows = box.nrows(); + unsigned cols = box.ncols(); + unsigned size = rows * cols; + float ratio = (float) (rows * cols) / cardinality; + + /// Remove noise. + if ((rows < 5) && (cols < 5)) + return true; + +// if (rows < cols) +// ratio = cols / rows; +// else +// ratio = rows / cols; + +// if (ratio > 3) +// return true; + +// if (vec_card[i].to_result () /*rows * cols*/ < 200) + +// if (size / card < 0.3) +// return true; + +// if (((float)card / (float)size) > 0.7) +// return true; + +// if (((float)card / (float)size) < 0.3) +// return true; + +// if (cols > 20) +// return true; + +// if (cols < 10) +// return true; + + float min = 0.2; + float max = 0.7; + + if (cardinality < size * min) + return true; + + if (cardinality > size * max) + return true; + + return false; +} + +template <typename I> +void +draw_bbox(I& image, box2d box) +{ + point2d pmin = box.pmin(); + point2d pmax = box.pmax(); + + point2d p1 (pmin[0], pmin[1]); + point2d p2 (pmax[0], pmin[1]); + point2d p3 (pmin[0], pmax[1]); + point2d p4 (pmax[0], pmax[1]); + + draw::line (image, p1, p2, literal::red); + draw::line (image, p2, p4, literal::red); + draw::line (image, p4, p3, literal::red); + draw::line (image, p3, p1, literal::red); +} + +template <typename I> +void +check_with_ref(I& image, std::string path_ref, std::string path_output) +{ + image2d<bool> ref = io::pbm::load (path_ref); + image2d<value::rgb8> mask (image.domain()); + unsigned cpt = 0; + unsigned ok = 0; + + mln_piter(I) p (image.domain ()); + + for_all (p) + { + if (image(p)) + if (ref(p)) + mask(p) = literal::red; + else + { + mask(p) = literal::white; + ++ok; + } + else + if (ref(p)) + { + ++ok; + mask(p) = literal::black; + } + else + mask(p) = literal::green; + ++cpt; + } + io::ppm::save(mask, path_output + "check.ppm"); + std::cout << "Reussite : " << (float)ok / (float)cpt * 100 << "% (" + << ok << "/" << cpt << ")." << std::endl; +} + + int main(int argc, char** argv) { using value::int_u8; + using value::rgb8; + typedef point2d P; typedef image2d<bool> I; typedef image2d<unsigned> I_LABEL; typedef image2d<value::rgb8> O; - typedef point2d P; if (argc != 3) { std::cerr << "Usage : " << argv[0] - << " input.pbm output.pbm" << std::endl; + << " input.pbm output" << std::endl; exit(1); } @@ -103,195 +208,107 @@ // input2 = morpho::dilation(input, win); // io::pbm::save (output, path_output); -/// Labeling. + +/// Labeling the input image. unsigned nb_labels; I_LABEL label_image = labeling::blobs(input, c8(), nb_labels); std::cout << "nb_labels = " << nb_labels << std::endl; /// Extraction of informations in the image (BoundingBox, Cardinality, ... ). - -// std::vector< accu::mean_ <point2d> > vec_mean (nb_labels + 1); -// std::vector< accu::p<accu::mean<point2d> >::ret > vec_mean (nb_labels + 1); std::vector< accu::bbox <point2d> > vec_bbox (nb_labels + 1); std::vector< accu::count_<point2d> > vec_card (nb_labels + 1); - mln_piter_(I_LABEL) p (label_image.domain ()); for_all (p) { if (input(p)) output(p) = literal::white; -// vec_mean[label_image(p)].take (p); vec_bbox[label_image(p)].take (p); vec_card[label_image(p)].take (p); } - I_LABEL text_ima (label_image.domain()); + /// Generation of the text image (text_image). + I_LABEL text_image (label_image.domain()); for (unsigned i = 0; i <= nb_labels; ++i) { - float ratio = 0; - unsigned rows = vec_bbox[i].to_result().nrows(); - unsigned cols = vec_bbox[i].to_result().ncols(); - unsigned size = rows * cols; - unsigned card = vec_card[i].to_result(); - - /// Remove noise. - if ((rows < 5) && (cols < 5)) - continue; - - /// Evaluation of kind of data (character or not). - { -// if (rows < cols) -// ratio = cols / rows; -// else -// ratio = rows / cols; - -// if (ratio > 3) -// continue; - -// if (vec_card[i].to_result () /*rows * cols*/ < 200) - -// if (size / card < 0.3) -// continue; - -// if (((float)card / (float)size) > 0.7) -// continue; - -// if (((float)card / (float)size) < 0.3) -// continue; - -// if (cols > 20) -// continue; - - if (cols < 10) - continue; - } - - - float min = 0.2; - float max = 0.7; - - if (card < size * min) - continue; - - if (card > size * max) + if (is_character(vec_bbox[i].to_result(), vec_card[i].to_result())) continue; + /// Copy text in an image (text_image). { typedef sub_image<I_LABEL, box2d> I_SUB; typedef image_if_value<I_SUB> I_VAL; - I_SUB sub_ima = (label_image | vec_bbox[i].to_result()); - I_VAL val_ima = (sub_ima | i); + I_SUB sub_image = (label_image | vec_bbox[i].to_result()); + I_VAL val_image = (sub_image | i); - mln_piter_(I_VAL) p(val_ima.domain()); + mln_piter_(I_VAL) p(val_image.domain()); + + /// Hack : problem with traits in image_if. for_all (p) - text_ima(p) = val_ima(p); + text_image(p) = val_image(p); -// /// Hack + /// Here is the good way to do the previous action. // level::paste (val_ima, text_ima); } } - - - - - /// Generation of the graph. - I_LABEL zi_image = geom::seeds2tiling(text_ima, c4 ()); - mesh_p<point2d> m = make::voronoi(zi_image, text_ima, c4()); - + /// Generation of the graph from text image. + I_LABEL zi_image = geom::seeds2tiling(text_image, c4 ()); + mesh_p<point2d> m = make::voronoi(zi_image, text_image, c4()); I_LABEL gr_image (label_image.domain ()); I_LABEL gr_image2 (label_image.domain ()); draw::mesh(gr_image, m, 255, 128); draw::mesh(gr_image2, m, 255, 0); + + + /// Dilation of node of the graph. win::disk2d win (30); I_LABEL pr = morpho::dilation(gr_image2, win); I bool_ima (label_image.domain ()); level::paste(pr, bool_ima); + /// Labeling the dilated image. + unsigned nb_dilated_node_labels; + I_LABEL label_image2 = labeling::blobs(bool_ima, c8(), nb_dilated_node_labels); + std::cout << "nb_dilated_node_labels = " << nb_dilated_node_labels << std::endl; + std::vector< accu::bbox <point2d> > vec_bbox2 (nb_dilated_node_labels + 1); - - /// Labeling2. - unsigned nb_labels2; - I_LABEL label_image2 = labeling::blobs(bool_ima, c8(), nb_labels2); - std::cout << "nb_labels = " << nb_labels2 << std::endl; - std::vector< accu::bbox <point2d> > vec_bbox2 (nb_labels2 + 1); - + /// Extract area of text. mln_piter_(I_LABEL) pl (label_image.domain ()); for_all (pl) - { vec_bbox2[label_image2(pl)].take (pl); - } - for (unsigned i = 0; i <= nb_labels2; ++i) - { - P pmin = vec_bbox2[i].to_result().pmin(); - P pmax = vec_bbox2[i].to_result().pmax(); - point2d p1 (pmin[0], pmin[1]); - point2d p2 (pmax[0], pmin[1]); - point2d p3 (pmin[0], pmax[1]); - point2d p4 (pmax[0], pmax[1]); - - draw::line (output, p1, p2, literal::red); - draw::line (output, p2, p4, literal::red); - draw::line (output, p4, p3, literal::red); - draw::line (output, p3, p1, literal::red); - } + /// Draw the bounding box of area of text in output. + for (unsigned i = 0; i <= nb_dilated_node_labels; ++i) + draw_bbox(output, vec_bbox2[i].to_result()); + + image2d<int_u8> out (label_image.domain ()); + + /// Save the influence area of the node of the graphe (seed2tiling result). + level::stretch (zi_image, out); + io::pgm::save(out, path_output + ".text_area.approx.pgm"); + std::cout << path_output + ".text_area.approx.pgm" << " generated" << std::endl; + + /// Save the graph of the text. + level::stretch (gr_image, out); + io::pgm::save(out, path_output + ".text_graph.pgm"); + std::cout << path_output + ".text_graph.pgm" << " generated" << std::endl; + + + /// Save the output image (input image + bounding box text in red). + io::ppm::save(output, path_output + ".ppm"); + std::cout << path_output + ".ppm" << " generated" << std::endl; - io::ppm::save(output, "rgb.ppm"); - // image2d<int_u8> process (label_image.domain ()); // level::stretch (label_image2, process); // io::pgm::save(process, "process.pgm"); -// // I ref = io::pbm::load ("ref_text.pbm"); -// // image2d<value::rgb8> mask (ref.domain()); -// // mln_piter_(I_LABEL) p_out (text_ima.domain ()); - -// // unsigned cpt = 0; -// // unsigned ok = 0; - -// // for_all (p_out) -// // { -// // if (text_ima(p_out)) -// // if (ref(p_out)) -// // mask(p_out) = literal::red; -// // else -// // { -// // mask(p_out) = literal::white; -// // ++ok; -// // } -// // else -// // if (ref(p_out)) -// // { -// // ++ok; -// // mask(p_out) = literal::black; -// // } -// // else -// // mask(p_out) = literal::green; -// // ++cpt; -// // } -// // io::ppm::save(mask, "rgb.ppm"); -// // std::cout << "Reussite : " << (float)ok / (float)cpt * 100 << "% (" -// // << ok << "/" << cpt << ")." << std::endl; - -// image2d<int_u8> out (label_image.domain ()); - - -// level::stretch (zi_image, out); -// io::pgm::save(out, "out.text_area.approx.pgm"); - -// level::stretch (gr_image, out); -// io::pgm::save(out, "out.text_graph.pgm"); - -// std::cout << path_output << " generated" << std::endl; - }
participants (1)
-
Guillaume Duhamel