
* scribo/src/contest/table-2013/src/new.cc: Here. --- scribo/src/contest/table-2013/src/new.cc | 165 ++++++++++++++++++++++++++++++ 1 files changed, 165 insertions(+), 0 deletions(-) diff --git a/scribo/src/contest/table-2013/src/new.cc b/scribo/src/contest/table-2013/src/new.cc index 962bf22..8949e15 100644 --- a/scribo/src/contest/table-2013/src/new.cc +++ b/scribo/src/contest/table-2013/src/new.cc @@ -21,6 +21,8 @@ #include <mln/value/all.hh> +#include <mln/util/adjacency_matrix.hh> + // INCLUDE TESSERACT #include <tesseract/baseapi.h> @@ -337,6 +339,68 @@ void draw_links_rl(const scribo::object_groups< image2d<unsigned> >& groups, } } + +// Alignment predicates. + +// Maximum alignment threshold at normal resoution (72 dpi) +const float align_eps = 1.5; + +inline +bool +left_aligned(const box2d& b1, const box2d& b2, float scale_factor) +{ + return + math::abs(b1.pmin().col() - b2.pmin().col()) + < align_eps * scale_factor; +} + +inline +bool +vcenter_aligned(const box2d& b1, const box2d& b2, float scale_factor) +{ + return + math::abs(b1.pcenter().col() - b2.pcenter().col()) + < align_eps * scale_factor; +} + +inline +bool +right_aligned(const box2d& b1, const box2d& b2, float scale_factor) +{ + return + math::abs(b1.pmax().col() - b2.pmax().col()) + < align_eps * scale_factor; +} + + +inline +bool +top_aligned(const box2d& b1, const box2d& b2, float scale_factor) +{ + return + math::abs(b1.pmin().row() - b2.pmin().row()) + < align_eps * scale_factor; +} + +inline +bool +hcenter_aligned(const box2d& b1, const box2d& b2, float scale_factor) +{ + return + math::abs(b1.pcenter().row() - b2.pcenter().row()) + < align_eps * scale_factor; +} + +inline +bool +bottom_aligned(const box2d& b1, const box2d& b2, float scale_factor) +{ + return + math::abs(b1.pmax().row() - b2.pmax().row()) + < align_eps * scale_factor; +} + + /******************************** MAIN ****************************************/ int main(int argc, char** argv) { @@ -638,6 +702,106 @@ int main(int argc, char** argv) } } + /* FIXME: We could factor a lot by grouping these matrices and + arrays into a structure and giving them a number. */ + // Compute alignments. + typedef util::adjacency_matrix<unsigned> align_matrix; + align_matrix left_aligned_groups(groups.nelements()); + align_matrix vcenter_aligned_groups(groups.nelements()); + align_matrix right_aligned_groups(groups.nelements()); + align_matrix top_aligned_groups(groups.nelements()); + align_matrix hcenter_aligned_groups(groups.nelements()); + align_matrix bottom_aligned_groups(groups.nelements()); + // We rely on the fact that group (text boxes) are numbered in the + // raster order to determine whether an alignment has been set + // between two groups. + std::vector<bool> group_has_left_alignment(groups.nelements(), false); + std::vector<bool> group_has_vcenter_alignment(groups.nelements(), false); + std::vector<bool> group_has_right_alignment(groups.nelements(), false); + std::vector<bool> group_has_top_alignment(groups.nelements(), false); + std::vector<bool> group_has_hcenter_alignment(groups.nelements(), false); + std::vector<bool> group_has_bottom_alignment(groups.nelements(), false); + for (unsigned i = 1; i < groups.nelements(); ++i) + for (unsigned j = i + 1; j < groups.nelements(); ++j) + { + const box2d& b1 = groups(i).bbox(); + const box2d& b2 = groups(j).bbox(); + + if (!group_has_left_alignment[i] + && left_aligned(b1, b2, scale_factor)) + { + left_aligned_groups.add(i, j); + group_has_left_alignment[i] = true; + } + if (!group_has_vcenter_alignment[i] + && vcenter_aligned(b1, b2, scale_factor)) + { + vcenter_aligned_groups.add(i, j); + group_has_vcenter_alignment[i] = true; + } + if (!group_has_right_alignment[i] + && right_aligned(b1, b2, scale_factor)) + { + right_aligned_groups.add(i, j); + group_has_right_alignment[i] = true; + } + if (!group_has_top_alignment[i] && + top_aligned(b1, b2, scale_factor)) + { + top_aligned_groups.add(i, j); + group_has_top_alignment[i] = true; + } + if (!group_has_hcenter_alignment[i] && + hcenter_aligned(b1, b2, scale_factor)) + { + hcenter_aligned_groups.add(i, j); + group_has_hcenter_alignment[i] = true; + } + if (!group_has_bottom_alignment[i] && + bottom_aligned(b1, b2, scale_factor)) + { + bottom_aligned_groups.add(i, j); + group_has_bottom_alignment[i] = true; + } + } + // Visualization: alignments. + image2d<value::rgb8> alignments = + data::convert(value::rgb8(), bin_merged); + for (unsigned i = 1; i < groups.nelements(); ++i) + draw::box(alignments, groups(i).bbox(), literal::medium_gray); + for (unsigned i = 1; i < groups.nelements(); ++i) + for (unsigned j = i + 1; j < groups.nelements(); ++j) + { + const box2d& b1 = groups(i).bbox(); + const box2d& b2 = groups(j).bbox(); + + if (left_aligned_groups.are_adjacent(i, j)) + draw::line(alignments, + point2d(b1.pcenter().row(), b1.pmin().col()), + point2d(b2.pcenter().row(), b2.pmin().col()), + literal::red); + if (vcenter_aligned_groups.are_adjacent(i, j)) + draw::line(alignments, b1.pcenter(), b2.pcenter(), literal::orange); + if (right_aligned_groups.are_adjacent(i, j)) + draw::line(alignments, + point2d(b1.pcenter().row(), b1.pmax().col()), + point2d(b2.pcenter().row(), b2.pmax().col()), + literal::green); + + if (top_aligned_groups.are_adjacent(i, j)) + draw::line(alignments, + point2d(b1.pmin().row(), b1.pcenter().col()), + point2d(b2.pmin().row(), b2.pcenter().col()), + literal::cyan); + if (hcenter_aligned_groups.are_adjacent(i, j)) + draw::line(alignments, b1.pcenter(), b2.pcenter(), literal::yellow); + if (top_aligned_groups.are_adjacent(i, j)) + draw::line(alignments, + point2d(b1.pmax().row(), b1.pcenter().col()), + point2d(b2.pmax().row(), b2.pcenter().col()), + literal::magenta); + } + // Write images and close XML unsigned number = 0; write_image(bin, prefix, "bin", page, number); @@ -651,5 +815,6 @@ int main(int argc, char** argv) write_image(ima_groups, prefix, "groups", page, number); write_image(ima_valid, prefix, "valid", page, number); write_image(ima_cols_rows, prefix, "cols_rows", page, number); + write_image(alignments, prefix, "alignments", page, number); } } -- 1.7.2.5