Olena-patches
Threads by month
- ----- 2025 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- 9625 discussions
02 Mar '10
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch copyright-headers has been deleted
was 1c31ba76b4a505703f466e7d91eecc87437526a2
-----------------------------------------------------------------------
1c31ba76b4a505703f466e7d91eecc87437526a2 Add missing copyright headers to M4 files.
-----------------------------------------------------------------------
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Olena, a generic and efficient image processing platform".
The branch next has been updated
via f9ac5d4d841e31df0aa208435d302202852a9a6b (commit)
via c81c18f8fda28be370e9d8a01f2b1162db514c8d (commit)
from 1c31ba76b4a505703f466e7d91eecc87437526a2 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
f9ac5d4 Regen SCRIBO's Makefile helpers.
c81c18f Regen Milena's Makefile helpers.
-----------------------------------------------------------------------
Summary of changes:
milena/ChangeLog | 6 +++
milena/headers.mk | 5 +++
milena/tests/unit_test/unit-tests.mk | 10 ++++++
scribo/ChangeLog | 6 +++
scribo/headers.mk | 36 ++++++++++++++++++++-
scribo/tests/unit_test/unit-tests.mk | 58 ++++++++++++++++++++++++++++++++++
6 files changed, 119 insertions(+), 2 deletions(-)
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0
02 Mar '10
* headers.mk, tests/unit_test/unit-tests.mk: Here.
---
scribo/ChangeLog | 6 +++
scribo/headers.mk | 36 ++++++++++++++++++++-
scribo/tests/unit_test/unit-tests.mk | 58 ++++++++++++++++++++++++++++++++++
3 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 4fed85c..33307f4 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,9 @@
+2010-03-02 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Regen SCRIBO's Makefile helpers.
+
+ * headers.mk, tests/unit_test/unit-tests.mk: Here.
+
2009-11-03 Guillaume Lazzara <z(a)lrde.epita.fr>
Add a new example in Scribo.
diff --git a/scribo/headers.mk b/scribo/headers.mk
index 15d9b2a..4127a31 100644
--- a/scribo/headers.mk
+++ b/scribo/headers.mk
@@ -2,21 +2,29 @@
scribodir = $(includedir)/scribo
nobase_scribo_HEADERS = \
./all.hh \
+./binarization/binarize.hh \
./binarization/sauvola.hh \
+./binarization/sauvola_threshold.hh \
./binarization/simple.hh \
./core/all.hh \
./core/central_sites.hh \
+./core/concept/link_functor.hh \
./core/erase_objects.hh \
+./core/internal/link_functor_base.hh \
./core/macros.hh \
./core/object_groups.hh \
./core/object_image.hh \
./core/object_links.hh \
+./debug/alignment_decision_image.hh \
./debug/all.hh \
./debug/decision_image.hh \
+./debug/links_decision_image.hh \
./debug/save_bboxes_image.hh \
./debug/save_label_image.hh \
./debug/save_linked_bboxes_image.hh \
+./debug/save_object_diff.hh \
./debug/save_table_image.hh \
+./debug/several_links_decision_image.hh \
./debug/usage.hh \
./demo/src/mainwindow.hh \
./draw/all.hh \
@@ -24,9 +32,9 @@ nobase_scribo_HEADERS = \
./draw/bounding_boxes.hh \
./estim/object_groups_v_thickness.hh \
./filter/all.hh \
-./filter/common/object_groups_photo.hh \
-./filter/common/object_links_photo.hh \
./filter/common/objects_photo.hh \
+./filter/internal/compute.hh \
+./filter/object_groups_size_ratio.hh \
./filter/object_groups_small.hh \
./filter/object_groups_v_thickness.hh \
./filter/object_links_bbox_h_ratio.hh \
@@ -34,14 +42,21 @@ nobase_scribo_HEADERS = \
./filter/object_links_bbox_ratio.hh \
./filter/object_links_bbox_w_ratio.hh \
./filter/object_links_bottom_aligned.hh \
+./filter/object_links_center_aligned.hh \
./filter/object_links_non_aligned.hh \
./filter/object_links_non_aligned_simple.hh \
./filter/object_links_non_h_aligned.hh \
./filter/object_links_non_v_aligned.hh \
+./filter/object_links_top_aligned.hh \
+./filter/objects_h_thick.hh \
+./filter/objects_h_thin.hh \
./filter/objects_large.hh \
+./filter/objects_size_ratio.hh \
./filter/objects_small.hh \
./filter/objects_thick.hh \
./filter/objects_thin.hh \
+./filter/objects_v_thick.hh \
+./filter/objects_v_thin.hh \
./fun/v2b/objects_small_filter.hh \
./make/all.hh \
./make/debug_filename.hh \
@@ -80,18 +95,35 @@ nobase_scribo_HEADERS = \
./primitive/internal/find_root.hh \
./primitive/internal/have_link_valid.hh \
./primitive/internal/init_link_array.hh \
+./primitive/internal/is_invalid_link.hh \
./primitive/internal/is_link_valid.hh \
./primitive/internal/update_graph_link.hh \
./primitive/internal/update_link_array.hh \
./primitive/link/all.hh \
+./primitive/link/compute.hh \
+./primitive/link/compute_several.hh \
+./primitive/link/internal/anchors_3.hh \
+./primitive/link/internal/find_link.hh \
+./primitive/link/internal/find_several_links.hh \
+./primitive/link/internal/link_center_dmax_base.hh \
+./primitive/link/internal/link_center_dmax_ratio_base.hh \
+./primitive/link/internal/link_functor_base.hh \
+./primitive/link/internal/link_ms_dmax_base.hh \
+./primitive/link/internal/link_ms_dmax_ratio_base.hh \
./primitive/link/merge_double_link.hh \
./primitive/link/with_graph.hh \
./primitive/link/with_rag.hh \
./primitive/link/with_several_graphes.hh \
./primitive/link/with_several_left_links.hh \
+./primitive/link/with_several_right_closest_links.hh \
./primitive/link/with_several_right_links.hh \
+./primitive/link/with_several_right_links_overlap.hh \
./primitive/link/with_single_left_link.hh \
+./primitive/link/with_single_left_link_dmax_ratio.hh \
./primitive/link/with_single_right_link.hh \
+./primitive/link/with_single_right_link_bottom.hh \
+./primitive/link/with_single_right_link_dmax_ratio.hh \
+./primitive/link/with_single_right_link_top.hh \
./table/align_lines_horizontaly.hh \
./table/align_lines_verticaly.hh \
./table/all.hh \
diff --git a/scribo/tests/unit_test/unit-tests.mk b/scribo/tests/unit_test/unit-tests.mk
index 63998b0..2467334 100644
--- a/scribo/tests/unit_test/unit-tests.mk
+++ b/scribo/tests/unit_test/unit-tests.mk
@@ -2,21 +2,29 @@
check_PROGRAMS = \
scribo_all \
+scribo_binarization_binarize \
scribo_binarization_sauvola \
+scribo_binarization_sauvola_threshold \
scribo_binarization_simple \
scribo_core_all \
scribo_core_central_sites \
+scribo_core_concept_link_functor \
scribo_core_erase_objects \
+scribo_core_internal_link_functor_base \
scribo_core_macros \
scribo_core_object_groups \
scribo_core_object_image \
scribo_core_object_links \
+scribo_debug_alignment_decision_image \
scribo_debug_all \
scribo_debug_decision_image \
+scribo_debug_links_decision_image \
scribo_debug_save_bboxes_image \
scribo_debug_save_label_image \
scribo_debug_save_linked_bboxes_image \
+scribo_debug_save_object_diff \
scribo_debug_save_table_image \
+scribo_debug_several_links_decision_image \
scribo_debug_usage \
scribo_draw_all \
scribo_draw_bounding_box_links \
@@ -24,6 +32,7 @@ scribo_draw_bounding_boxes \
scribo_estim_object_groups_v_thickness \
scribo_filter_all \
scribo_filter_common_objects_photo \
+scribo_filter_internal_compute \
scribo_filter_object_groups_size_ratio \
scribo_filter_object_groups_small \
scribo_filter_object_groups_v_thickness \
@@ -32,16 +41,20 @@ scribo_filter_object_links_bbox_overlap \
scribo_filter_object_links_bbox_ratio \
scribo_filter_object_links_bbox_w_ratio \
scribo_filter_object_links_bottom_aligned \
+scribo_filter_object_links_center_aligned \
scribo_filter_object_links_non_aligned \
scribo_filter_object_links_non_aligned_simple \
scribo_filter_object_links_non_h_aligned \
scribo_filter_object_links_non_v_aligned \
+scribo_filter_object_links_top_aligned \
+scribo_filter_objects_h_thick \
scribo_filter_objects_h_thin \
scribo_filter_objects_large \
scribo_filter_objects_size_ratio \
scribo_filter_objects_small \
scribo_filter_objects_thick \
scribo_filter_objects_thin \
+scribo_filter_objects_v_thick \
scribo_filter_objects_v_thin \
scribo_fun_v2b_objects_small_filter \
scribo_make_all \
@@ -86,14 +99,30 @@ scribo_primitive_internal_is_link_valid \
scribo_primitive_internal_update_graph_link \
scribo_primitive_internal_update_link_array \
scribo_primitive_link_all \
+scribo_primitive_link_compute \
+scribo_primitive_link_compute_several \
+scribo_primitive_link_internal_anchors_3 \
+scribo_primitive_link_internal_find_link \
+scribo_primitive_link_internal_find_several_links \
+scribo_primitive_link_internal_link_center_dmax_base \
+scribo_primitive_link_internal_link_center_dmax_ratio_base \
+scribo_primitive_link_internal_link_functor_base \
+scribo_primitive_link_internal_link_ms_dmax_base \
+scribo_primitive_link_internal_link_ms_dmax_ratio_base \
scribo_primitive_link_merge_double_link \
scribo_primitive_link_with_graph \
scribo_primitive_link_with_rag \
scribo_primitive_link_with_several_graphes \
scribo_primitive_link_with_several_left_links \
+scribo_primitive_link_with_several_right_closest_links \
scribo_primitive_link_with_several_right_links \
+scribo_primitive_link_with_several_right_links_overlap \
scribo_primitive_link_with_single_left_link \
+scribo_primitive_link_with_single_left_link_dmax_ratio \
scribo_primitive_link_with_single_right_link \
+scribo_primitive_link_with_single_right_link_bottom \
+scribo_primitive_link_with_single_right_link_dmax_ratio \
+scribo_primitive_link_with_single_right_link_top \
scribo_table_align_lines_horizontaly \
scribo_table_align_lines_verticaly \
scribo_table_all \
@@ -115,21 +144,29 @@ scribo_util_all \
scribo_util_text
scribo_all_SOURCES = scribo_all.cc
+scribo_binarization_binarize_SOURCES = scribo_binarization_binarize.cc
scribo_binarization_sauvola_SOURCES = scribo_binarization_sauvola.cc
+scribo_binarization_sauvola_threshold_SOURCES = scribo_binarization_sauvola_threshold.cc
scribo_binarization_simple_SOURCES = scribo_binarization_simple.cc
scribo_core_all_SOURCES = scribo_core_all.cc
scribo_core_central_sites_SOURCES = scribo_core_central_sites.cc
+scribo_core_concept_link_functor_SOURCES = scribo_core_concept_link_functor.cc
scribo_core_erase_objects_SOURCES = scribo_core_erase_objects.cc
+scribo_core_internal_link_functor_base_SOURCES = scribo_core_internal_link_functor_base.cc
scribo_core_macros_SOURCES = scribo_core_macros.cc
scribo_core_object_groups_SOURCES = scribo_core_object_groups.cc
scribo_core_object_image_SOURCES = scribo_core_object_image.cc
scribo_core_object_links_SOURCES = scribo_core_object_links.cc
+scribo_debug_alignment_decision_image_SOURCES = scribo_debug_alignment_decision_image.cc
scribo_debug_all_SOURCES = scribo_debug_all.cc
scribo_debug_decision_image_SOURCES = scribo_debug_decision_image.cc
+scribo_debug_links_decision_image_SOURCES = scribo_debug_links_decision_image.cc
scribo_debug_save_bboxes_image_SOURCES = scribo_debug_save_bboxes_image.cc
scribo_debug_save_label_image_SOURCES = scribo_debug_save_label_image.cc
scribo_debug_save_linked_bboxes_image_SOURCES = scribo_debug_save_linked_bboxes_image.cc
+scribo_debug_save_object_diff_SOURCES = scribo_debug_save_object_diff.cc
scribo_debug_save_table_image_SOURCES = scribo_debug_save_table_image.cc
+scribo_debug_several_links_decision_image_SOURCES = scribo_debug_several_links_decision_image.cc
scribo_debug_usage_SOURCES = scribo_debug_usage.cc
scribo_draw_all_SOURCES = scribo_draw_all.cc
scribo_draw_bounding_box_links_SOURCES = scribo_draw_bounding_box_links.cc
@@ -137,6 +174,7 @@ scribo_draw_bounding_boxes_SOURCES = scribo_draw_bounding_boxes.cc
scribo_estim_object_groups_v_thickness_SOURCES = scribo_estim_object_groups_v_thickness.cc
scribo_filter_all_SOURCES = scribo_filter_all.cc
scribo_filter_common_objects_photo_SOURCES = scribo_filter_common_objects_photo.cc
+scribo_filter_internal_compute_SOURCES = scribo_filter_internal_compute.cc
scribo_filter_object_groups_size_ratio_SOURCES = scribo_filter_object_groups_size_ratio.cc
scribo_filter_object_groups_small_SOURCES = scribo_filter_object_groups_small.cc
scribo_filter_object_groups_v_thickness_SOURCES = scribo_filter_object_groups_v_thickness.cc
@@ -145,16 +183,20 @@ scribo_filter_object_links_bbox_overlap_SOURCES = scribo_filter_object_links_bbo
scribo_filter_object_links_bbox_ratio_SOURCES = scribo_filter_object_links_bbox_ratio.cc
scribo_filter_object_links_bbox_w_ratio_SOURCES = scribo_filter_object_links_bbox_w_ratio.cc
scribo_filter_object_links_bottom_aligned_SOURCES = scribo_filter_object_links_bottom_aligned.cc
+scribo_filter_object_links_center_aligned_SOURCES = scribo_filter_object_links_center_aligned.cc
scribo_filter_object_links_non_aligned_SOURCES = scribo_filter_object_links_non_aligned.cc
scribo_filter_object_links_non_aligned_simple_SOURCES = scribo_filter_object_links_non_aligned_simple.cc
scribo_filter_object_links_non_h_aligned_SOURCES = scribo_filter_object_links_non_h_aligned.cc
scribo_filter_object_links_non_v_aligned_SOURCES = scribo_filter_object_links_non_v_aligned.cc
+scribo_filter_object_links_top_aligned_SOURCES = scribo_filter_object_links_top_aligned.cc
+scribo_filter_objects_h_thick_SOURCES = scribo_filter_objects_h_thick.cc
scribo_filter_objects_h_thin_SOURCES = scribo_filter_objects_h_thin.cc
scribo_filter_objects_large_SOURCES = scribo_filter_objects_large.cc
scribo_filter_objects_size_ratio_SOURCES = scribo_filter_objects_size_ratio.cc
scribo_filter_objects_small_SOURCES = scribo_filter_objects_small.cc
scribo_filter_objects_thick_SOURCES = scribo_filter_objects_thick.cc
scribo_filter_objects_thin_SOURCES = scribo_filter_objects_thin.cc
+scribo_filter_objects_v_thick_SOURCES = scribo_filter_objects_v_thick.cc
scribo_filter_objects_v_thin_SOURCES = scribo_filter_objects_v_thin.cc
scribo_fun_v2b_objects_small_filter_SOURCES = scribo_fun_v2b_objects_small_filter.cc
scribo_make_all_SOURCES = scribo_make_all.cc
@@ -199,14 +241,30 @@ scribo_primitive_internal_is_link_valid_SOURCES = scribo_primitive_internal_is_l
scribo_primitive_internal_update_graph_link_SOURCES = scribo_primitive_internal_update_graph_link.cc
scribo_primitive_internal_update_link_array_SOURCES = scribo_primitive_internal_update_link_array.cc
scribo_primitive_link_all_SOURCES = scribo_primitive_link_all.cc
+scribo_primitive_link_compute_SOURCES = scribo_primitive_link_compute.cc
+scribo_primitive_link_compute_several_SOURCES = scribo_primitive_link_compute_several.cc
+scribo_primitive_link_internal_anchors_3_SOURCES = scribo_primitive_link_internal_anchors_3.cc
+scribo_primitive_link_internal_find_link_SOURCES = scribo_primitive_link_internal_find_link.cc
+scribo_primitive_link_internal_find_several_links_SOURCES = scribo_primitive_link_internal_find_several_links.cc
+scribo_primitive_link_internal_link_center_dmax_base_SOURCES = scribo_primitive_link_internal_link_center_dmax_base.cc
+scribo_primitive_link_internal_link_center_dmax_ratio_base_SOURCES = scribo_primitive_link_internal_link_center_dmax_ratio_base.cc
+scribo_primitive_link_internal_link_functor_base_SOURCES = scribo_primitive_link_internal_link_functor_base.cc
+scribo_primitive_link_internal_link_ms_dmax_base_SOURCES = scribo_primitive_link_internal_link_ms_dmax_base.cc
+scribo_primitive_link_internal_link_ms_dmax_ratio_base_SOURCES = scribo_primitive_link_internal_link_ms_dmax_ratio_base.cc
scribo_primitive_link_merge_double_link_SOURCES = scribo_primitive_link_merge_double_link.cc
scribo_primitive_link_with_graph_SOURCES = scribo_primitive_link_with_graph.cc
scribo_primitive_link_with_rag_SOURCES = scribo_primitive_link_with_rag.cc
scribo_primitive_link_with_several_graphes_SOURCES = scribo_primitive_link_with_several_graphes.cc
scribo_primitive_link_with_several_left_links_SOURCES = scribo_primitive_link_with_several_left_links.cc
+scribo_primitive_link_with_several_right_closest_links_SOURCES = scribo_primitive_link_with_several_right_closest_links.cc
scribo_primitive_link_with_several_right_links_SOURCES = scribo_primitive_link_with_several_right_links.cc
+scribo_primitive_link_with_several_right_links_overlap_SOURCES = scribo_primitive_link_with_several_right_links_overlap.cc
scribo_primitive_link_with_single_left_link_SOURCES = scribo_primitive_link_with_single_left_link.cc
+scribo_primitive_link_with_single_left_link_dmax_ratio_SOURCES = scribo_primitive_link_with_single_left_link_dmax_ratio.cc
scribo_primitive_link_with_single_right_link_SOURCES = scribo_primitive_link_with_single_right_link.cc
+scribo_primitive_link_with_single_right_link_bottom_SOURCES = scribo_primitive_link_with_single_right_link_bottom.cc
+scribo_primitive_link_with_single_right_link_dmax_ratio_SOURCES = scribo_primitive_link_with_single_right_link_dmax_ratio.cc
+scribo_primitive_link_with_single_right_link_top_SOURCES = scribo_primitive_link_with_single_right_link_top.cc
scribo_table_align_lines_horizontaly_SOURCES = scribo_table_align_lines_horizontaly.cc
scribo_table_align_lines_verticaly_SOURCES = scribo_table_align_lines_verticaly.cc
scribo_table_all_SOURCES = scribo_table_all.cc
--
1.5.6.5
1
0
02 Mar '10
* headers.mk, tests/unit_test/unit-tests.mk: Here.
---
milena/ChangeLog | 6 ++++++
milena/headers.mk | 5 +++++
milena/tests/unit_test/unit-tests.mk | 10 ++++++++++
3 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/milena/ChangeLog b/milena/ChangeLog
index b3cd42e..2c40c47 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,9 @@
+2010-03-02 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Regen Milena's Makefile helpers.
+
+ * headers.mk, tests/unit_test/unit-tests.mk: Here.
+
2009-11-18 Guillaume Lazzara <z(a)lrde.epita.fr>
* doc/white_paper/white_paper.tex: Fix an invalid URL.
diff --git a/milena/headers.mk b/milena/headers.mk
index eb27c99..110caa6 100644
--- a/milena/headers.mk
+++ b/milena/headers.mk
@@ -194,6 +194,7 @@ mln/core/alias/window1d.hh \
mln/core/alias/window2d.hh \
mln/core/alias/window3d.hh \
mln/core/all.hh \
+mln/core/box_runend_piter.hh \
mln/core/box_runstart_piter.hh \
mln/core/category.hh \
mln/core/concept/accumulator.hh \
@@ -332,6 +333,7 @@ mln/core/internal/image_morpher.hh \
mln/core/internal/image_primary.hh \
mln/core/internal/image_value_morpher.hh \
mln/core/internal/is_masked_impl_selector.hh \
+mln/core/internal/labeled_image_base.hh \
mln/core/internal/morpher_lvalue.hh \
mln/core/internal/neighb_base.hh \
mln/core/internal/neighb_niter_base.hh \
@@ -451,6 +453,7 @@ mln/data/transform.hh \
mln/data/transform.spe.hh \
mln/data/transform_inplace.hh \
mln/data/update.hh \
+mln/data/wrap.hh \
mln/debug/all.hh \
mln/debug/draw_graph.hh \
mln/debug/essential.hh \
@@ -1088,6 +1091,7 @@ mln/transform/essential.hh \
mln/transform/hough.hh \
mln/transform/influence_zone_front.hh \
mln/transform/influence_zone_geodesic.hh \
+mln/transform/influence_zone_geodesic_saturated.hh \
mln/transform/internal/all.hh \
mln/transform/internal/closest_point_functor.hh \
mln/transform/internal/distance_functor.hh \
@@ -1198,6 +1202,7 @@ mln/value/internal/value_like.hh \
mln/value/interval.hh \
mln/value/label.hh \
mln/value/label_16.hh \
+mln/value/label_32.hh \
mln/value/label_8.hh \
mln/value/lut_vec.hh \
mln/value/mixin.hh \
diff --git a/milena/tests/unit_test/unit-tests.mk b/milena/tests/unit_test/unit-tests.mk
index d9d29aa..6a9d5d5 100644
--- a/milena/tests/unit_test/unit-tests.mk
+++ b/milena/tests/unit_test/unit-tests.mk
@@ -191,6 +191,7 @@ mln_core_alias_window1d \
mln_core_alias_window2d \
mln_core_alias_window3d \
mln_core_all \
+mln_core_box_runend_piter \
mln_core_box_runstart_piter \
mln_core_category \
mln_core_concept_accumulator \
@@ -313,6 +314,7 @@ mln_core_internal_image_morpher \
mln_core_internal_image_primary \
mln_core_internal_image_value_morpher \
mln_core_internal_is_masked_impl_selector \
+mln_core_internal_labeled_image_base \
mln_core_internal_morpher_lvalue \
mln_core_internal_neighb_base \
mln_core_internal_neighb_niter_base \
@@ -427,6 +429,7 @@ mln_data_transform \
mln_data_transform_inplace \
mln_data_update \
mln_data_was_median \
+mln_data_wrap \
mln_debug_all \
mln_debug_draw_graph \
mln_debug_essential \
@@ -1123,6 +1126,7 @@ mln_transform_essential \
mln_transform_hough \
mln_transform_influence_zone_front \
mln_transform_influence_zone_geodesic \
+mln_transform_influence_zone_geodesic_saturated \
mln_transform_internal_all \
mln_transform_internal_closest_point_functor \
mln_transform_internal_distance_functor \
@@ -1235,6 +1239,7 @@ mln_value_internal_value_like \
mln_value_interval \
mln_value_label \
mln_value_label_16 \
+mln_value_label_32 \
mln_value_label_8 \
mln_value_lut_vec \
mln_value_mixin \
@@ -1484,6 +1489,7 @@ mln_core_alias_window1d_SOURCES = mln_core_alias_window1d.cc
mln_core_alias_window2d_SOURCES = mln_core_alias_window2d.cc
mln_core_alias_window3d_SOURCES = mln_core_alias_window3d.cc
mln_core_all_SOURCES = mln_core_all.cc
+mln_core_box_runend_piter_SOURCES = mln_core_box_runend_piter.cc
mln_core_box_runstart_piter_SOURCES = mln_core_box_runstart_piter.cc
mln_core_category_SOURCES = mln_core_category.cc
mln_core_concept_accumulator_SOURCES = mln_core_concept_accumulator.cc
@@ -1606,6 +1612,7 @@ mln_core_internal_image_morpher_SOURCES = mln_core_internal_image_morpher.cc
mln_core_internal_image_primary_SOURCES = mln_core_internal_image_primary.cc
mln_core_internal_image_value_morpher_SOURCES = mln_core_internal_image_value_morpher.cc
mln_core_internal_is_masked_impl_selector_SOURCES = mln_core_internal_is_masked_impl_selector.cc
+mln_core_internal_labeled_image_base_SOURCES = mln_core_internal_labeled_image_base.cc
mln_core_internal_morpher_lvalue_SOURCES = mln_core_internal_morpher_lvalue.cc
mln_core_internal_neighb_base_SOURCES = mln_core_internal_neighb_base.cc
mln_core_internal_neighb_niter_base_SOURCES = mln_core_internal_neighb_niter_base.cc
@@ -1720,6 +1727,7 @@ mln_data_transform_SOURCES = mln_data_transform.cc
mln_data_transform_inplace_SOURCES = mln_data_transform_inplace.cc
mln_data_update_SOURCES = mln_data_update.cc
mln_data_was_median_SOURCES = mln_data_was_median.cc
+mln_data_wrap_SOURCES = mln_data_wrap.cc
mln_debug_all_SOURCES = mln_debug_all.cc
mln_debug_draw_graph_SOURCES = mln_debug_draw_graph.cc
mln_debug_essential_SOURCES = mln_debug_essential.cc
@@ -2416,6 +2424,7 @@ mln_transform_essential_SOURCES = mln_transform_essential.cc
mln_transform_hough_SOURCES = mln_transform_hough.cc
mln_transform_influence_zone_front_SOURCES = mln_transform_influence_zone_front.cc
mln_transform_influence_zone_geodesic_SOURCES = mln_transform_influence_zone_geodesic.cc
+mln_transform_influence_zone_geodesic_saturated_SOURCES = mln_transform_influence_zone_geodesic_saturated.cc
mln_transform_internal_all_SOURCES = mln_transform_internal_all.cc
mln_transform_internal_closest_point_functor_SOURCES = mln_transform_internal_closest_point_functor.cc
mln_transform_internal_distance_functor_SOURCES = mln_transform_internal_distance_functor.cc
@@ -2528,6 +2537,7 @@ mln_value_internal_value_like_SOURCES = mln_value_internal_value_like.cc
mln_value_interval_SOURCES = mln_value_interval.cc
mln_value_label_SOURCES = mln_value_label.cc
mln_value_label_16_SOURCES = mln_value_label_16.cc
+mln_value_label_32_SOURCES = mln_value_label_32.cc
mln_value_label_8_SOURCES = mln_value_label_8.cc
mln_value_lut_vec_SOURCES = mln_value_lut_vec.cc
mln_value_mixin_SOURCES = mln_value_mixin.cc
--
1.5.6.5
1
0
last-svn-commit-53-g5fe933b text/merging.hh (scribo): Update code with lastest Theo's changes.
by Guillaume Lazzara 02 Mar '10
by Guillaume Lazzara 02 Mar '10
02 Mar '10
---
scribo/ChangeLog | 5 +
scribo/text/merging.hh | 857 +++++++++++++++++++++++++-----------------------
2 files changed, 446 insertions(+), 416 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index b29f31e..ee26d66 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,8 @@
+2010-03-02 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ * text/merging.hh (scribo): Update code with lastest Theo's
+ changes.
+
2010-02-19 Guillaume Lazzara <z(a)lrde.epita.fr>
Add a small tool to recognize text in a binary image.
diff --git a/scribo/text/merging.hh b/scribo/text/merging.hh
index d0fcfff..2dba26c 100644
--- a/scribo/text/merging.hh
+++ b/scribo/text/merging.hh
@@ -2,6 +2,7 @@
#include <fstream>
#include <sstream>
#include <vector>
+#include <set>
#include <algorithm>
#include <mln/core/image/image2d.hh>
@@ -13,6 +14,8 @@
#include <mln/data/fill.hh>
#include <mln/data/wrap.hh>
+#include <mln/make/box2d.hh>
+
#include <mln/util/timer.hh>
@@ -30,11 +33,82 @@ namespace scribo
using value::int_u8;
+ template <typename L>
+ inline
+ int delta_of_line(const scribo::line_info<L>& l)
+ {
+ return l.char_width() + l.char_space();
+ }
+
+
+ template <typename L>
+ inline
+ bool looks_like_a_text_line(const scribo::line_info<L>& l)
+ {
+ return
+ l.card() >= 3 // at least 3 components
+ && l.bbox().height() > 10 // and minimal height
+ && l.bbox().width() > l.bbox().height(); // and more horizontal-like than vertical
+ // FIXME: Later on, add a criterion based on the number
+ // of alignments (on top and bot).
+ }
+
+
+ /*!
+
+ */
+ template <typename L>
+ struct group_data_t
+ {
+ group_data_t()
+ : info(0)
+ {
+ }
+
+ group_data_t(const scribo::line_info<L>& info_)
+ : info(&info_)
+ {
+ finalize();
+ }
+
+ const scribo::line_info<L>* info;
+
+ // deduced:
+ int meanline;
+ bool looks_like_a_line;
+ unsigned delta;
+ box2d ebox;
+
+ void finalize()
+ {
+ if (info->x_height() == 0)
+ std::cerr << "oops" << std::endl;
+
+ meanline = info->baseline() - int(info->x_height()) + 1;
+
+ looks_like_a_line = looks_like_a_text_line(*info);
+
+ // delta = looks_like_a_line ? char_space + char_width : 0;
+ delta = delta_of_line(*info);
+ // FIXME: choose between:
+ // char_width + char_space
+ // 2 * char_width
+ // char_width + 2 * char_space
+
+ int A = info->a_height() - info->x_height(), D = - info->d_height();
+ if (A <= 2 && D > 2)
+ A = D;
+ if (D <= 2 && A > 2)
+ D = A;
+ ebox = mln::make::box2d(meanline - A, info->bbox().pmin().col() - delta,
+ info->baseline() + D, info->bbox().pmax().col() + delta);
+ }
+
+ };
template <typename T, typename T2>
void draw_box(image2d<T>& input, const box2d& b, T2 l)
{
-// data::fill((input | b).rw(), l);
const unsigned
delta = input.delta_index(dpoint2d(1,0)),
nrows = b.nrows(),
@@ -114,40 +188,40 @@ namespace scribo
template <typename L>
- unsigned do_union(scribo::line_set<L>& lines,
+ unsigned do_union(util::array<group_data_t<L> >& dta,
+ scribo::line_set<L>& lines,
unsigned l1,
unsigned l2,
util::array<unsigned>& parent)
{
- unsigned
- l1r = my_find_root(parent, l1),
- l2r = my_find_root(parent, l2);
- if (l1r == l2r)
- {
- std::cout << '.' << std::endl;
- return l1r;
- }
-
-// swap_ordering(l1, l2);
-
-// parent[l2] = l1; // The smallest label value is root.
-// lines(l1).fast_merge(lines(l2));
+ l1 = my_find_root(parent, l1);
+ l2 = my_find_root(parent, l2);
+ if (l1 == l2)
+ return l1;
- if (lines(l1).card() < lines(l2).card())
- std::swap(l1, l2);
+ swap_ordering(l1, l2);
+ parent[l2] = l1; // The smallest label value is root.
- parent[l2] = l1; // The text line with the most component count is root.
- lines(l1).fast_merge(lines(l2));
-
-// looks_like_a_text_line_[l1] = looks_like_a_text_line(lines(l1));
+ if (lines(l2).card() > lines(l1).card())
+ {
+ // we transfer data from the largest item to the root one.
+ scribo::line_info<L> tmp = lines(l1);
+ lines(l1) = lines(l2);
+ lines(l1).fast_merge(tmp);
+
+ // We must set manually the tag for lines(l2) since it is
+ // not used directly in merge process so its tag cannot be
+ // updated automatically.
+ lines(l2).update_tag(line::Merged);
+ }
+ else
+ lines(l1).fast_merge(lines(l2));
+ dta[l1].finalize();
// l1's tag is automatically set to line::Needs_Precise_Stats_Update
// l2's tag is automatically set to line::Merged
- // looks_like_txt_line[l1] = looks_like_txt_line[l1] || looks_like_txt_line[l2];
- // merge of "approximate stats": (n, (n x sum)) => useful for computing the enlarging delta
-
return l1;
}
@@ -160,168 +234,252 @@ namespace scribo
}
- void compute_data(// in
- unsigned tl, unsigned tr, unsigned bl, unsigned br,
- // out
- unsigned& l1, unsigned& l2, unsigned& l3, unsigned& l4,
- unsigned& count_non_zero,
- unsigned& count_different_labels)
+ template <typename L>
+ void draw_enlarged_box(image2d<unsigned>& output,
+ const util::array<group_data_t<L> >& dta,
+ unsigned l)
{
- l1 = l2 = l3 = l4 = 0;
- count_non_zero = 0;
- if (tl)
- {
- l1 = tl;
- ++count_non_zero;
- }
- if (tr)
- {
- if (! l1) l1 = tr;
- else if (tr != l1) l2 = tr;
- ++count_non_zero;
- }
- if (bl)
+ box2d b = dta[l].ebox;
+ b.crop_wrt(output.domain());
+ draw_box(output, b, l);
+ }
+
+
+ /*! \brief Check whether two lines can merge.
+
+ Criterions:
+ - Height ratio must be <= 1.7
+ - Baselines delta must be <= 3
+ - Boxes must not overlap too much.
+
+ */
+ template <typename L>
+ bool lines_can_merge(const scribo::line_info<L>& l1,
+ const scribo::line_info<L>& l2)
+ {
+ // Parameters.
+ const float x_ratio_max = 1.7, baseline_delta_max = 3;
+
+ // Similarity of x_height.
{
- if (! l1) l1 = bl;
- else if (! l2) { if (bl != l1) l2 = bl; }
- else if (bl != l1 && bl != l2) l3 = bl;
- ++count_non_zero;
+ float x1 = l1.x_height(), x2 = l2.x_height();
+ float x_ratio = std::max(x1, x2) / std::min(x1, x2);
+ if (x_ratio > x_ratio_max)
+ return false;
}
- if (br)
+
+ // Same baseline.
{
- if (! l1) l1 = br;
- else if (! l2) { if (br != l1) l2 = br; }
- else if (! l3) { if (br != l1 && br != l2) l3 = br; }
- else if (br != l1 && br != l2 && br != l3) l4 = br;
- ++count_non_zero;
+ if (std::abs(l1.baseline() - l2.baseline()) > baseline_delta_max)
+ return false;
}
- if (l1 == 0)
- count_different_labels = 0;
- else if (l2 == 0)
- count_different_labels = 1;
- else if (l3 == 0)
- count_different_labels = 2;
- else if (l4 == 0)
- count_different_labels = 3;
+ // left / right
+ unsigned
+ col1 = l1.bbox().pcenter().col(),
+ col2 = l2.bbox().pcenter().col();
+ if (col1 < col2)
+ return col1 + l1.bbox().width() / 4 < col2 - l2.bbox().width() / 4;
else
- count_different_labels = 4;
-
- if (count_different_labels == 0)
- std::cerr << "bug 0" << std::endl;
+ return col2 + l2.bbox().width() / 4 < col1 - l1.bbox().width() / 4;
}
template <typename L>
- bool looks_like_a_text_line(const scribo::line_info<L>& l)
+ int horizontal_distance(const scribo::line_info<L>& l1,
+ const scribo::line_info<L>& l2)
{
- return
- /*l.card() > 2 // suffisient cardinality
- && */l.bbox().height() > 20 // and suffisient height
- && l.bbox().width() > 50 // and suffisient width
- && l.bbox().width() > 2 * l.bbox().height(); // and horizontal-like.
-
- // FIXME:
- // if (n_comps > 2)
- // return true;
- // FIXME: Refine?
+ if (l1.bbox().pcenter().col() < l2.bbox().pcenter().col())
+ return l2.bbox().pmin().col() - l1.bbox().pmax().col();
+ else
+ return l1.bbox().pmin().col() - l2.bbox().pmax().col();
}
- template <typename L>
- int delta_of_line(const scribo::line_info<L>& l)
- {
- return l.char_width() /* / 2 */ + l.char_space();
- }
+ /*! \brief Check whether a non line component and a line can merge.
+ Criterions:
+ - Small height (c.height < l.x_height)
+ - Character width mean in 'c' must be lower than the character
+ width median of 'l'. (c.width / c.ncomps < l.char_width)
- template <typename L>
- void draw_enlarged_box(image2d<unsigned>& output,
- const scribo::line_info<L>& l)
- {
- if (looks_like_a_text_line(l))
- draw_box(output, enlarge(l.bbox(), delta_of_line(l)), l.id());
- else
- draw_box(output, l.bbox(), l.id());
- }
+ OR
+ - Small height (c.height < l.x_height)
+ - Not so long width (c.width < 5 * l.char_width)
+ - Aligned with the 'x' center ((l.baseline + l.meanline / 2) - c.center.row < 7)
+ - tiny spacing (horizontal distance < 5)
+ */
template <typename L>
- bool lines_can_merge(const scribo::line_info<L>& l1, const scribo::line_info<L>& l2)
+ bool non_line_and_line_can_merge(const scribo::line_info<L>& l_cur,
+ const group_data_t<L>& dta_cur, // current
+ const scribo::line_info<L>& l_ted,
+ const group_data_t<L>& dta_ted) // touched
{
- float hratio = float(l1.bbox().height()) / float(l2.bbox().height());
- float xhratio = float(l1.x_height()) / float(l2.x_height());
- if ((hratio < 0.5 || hratio > 2.) && (xhratio < 0.8 || xhratio > 1.25)) // too different heights
+ if (dta_cur.looks_like_a_line || ! dta_ted.looks_like_a_line)
return false;
+ // the current object is a NON-textline
+ // the background (touched) object is a textline
+
+
+ // FIXME: THERE IS A BUG
+ // The second condition should be replaced by the commented one.
+ //
+ // General case (for tiny components like --> ',:."; <--):
+ if (l_cur.bbox().height() < l_ted.x_height()
+ && float(l_cur.char_width()) / float(l_cur.card()) < l_ted.char_width())
+// && float(l_cur.bbox().width()) / float(l_cur.card()) < l_ted.char_width())
+ return true;
+
+
+ // Special case for '---':
+ if (// small height:
+ l_cur.bbox().height() < l_ted.x_height()
+ // // not so long width:
+ && l_cur.bbox().width() < 5 * l_ted.char_width()
+ // align with the 'x' center:
+ && std::abs((l_ted.baseline() + dta_ted.meanline) / 2 - l_cur.bbox().pcenter().row()) < 7
+ // tiny spacing:
+ && horizontal_distance(l_cur, l_ted) < 5
+ )
+ {
+ return true;
+ }
- unsigned
- col1 = l1.bbox().pcenter().col(),
- col2 = l2.bbox().pcenter().col();
- if (col1 < col2)
- return col1 + l1.bbox().width() / 4 < col2 - l2.bbox().width() / 4;
- else
- return col2 + l2.bbox().width() / 4 < col1 - l1.bbox().width() / 4;
- }
+ // Special case
+// // FIXME: Box are aligned; the main problem is that we can have multiple valid box
+// // depending on the presence of descent and/or ascent!
+// if (std::abs(dta_cur.box.pmin().row() - dta_ted.box.pmin().row()) < 5 // top
+// && std::abs(dta_cur.box.pmax().row() - dta_ted.box.pmax().row()) < 5 // bot
+// && ((dta_ted.box.pcenter().col() < dta_cur.box.pcenter().col() && dta_cur.box.pmin().col() - dta_ted.box.pmax().col() < 10) // small distance when cur is at right
+// || (dta_cur.box.pcenter().col() < dta_ted.box.pcenter().col() && dta_ted.box.pmin().col() - dta_cur.box.pmax().col() < 10)) // or when is at left.
+// )
+// return true;
-// struct line_info<L>
-// {
-// bool looks_like_a_text_line; // pre-computed
-// int delta_of_line; // pre-computed before each merging pass
-// // FIXME:
-// //
-// // Important note: after merging two lines, we draw the
-// // merged line over the existing one; we have to ensure that we
-// // cover the previous rectangle (otherwise we have a label in
-// // 'output' that is not used anymore! and it can mix up the
-// // detection of upcoming merges...) so this delta has to remain
-// // the same during one pass. Another solution (yet more costly)
-// // could be of erasing the previous rectangle before re-drawing...
-// };
+ return false;
+
+ // The unused criterion below is too restrictive; it does not work
+ // for ending '-', and neither for ',' when there's no descent.
+ // dta_ted.box.has(dta_cur.box.pcenter())
+ }
+ /*! \brief Merge text lines.
+
+ This algorithm iterates over all the components ordered by size.
+ It uses a 2d labeled image, tmp_box, to draw component bounding
+ boxes and uses that image to check bounding box collisions.
+ Depending on that collisions and whether the component looks like
+ a text line or not, bounding boxes are merged.
+
+ \verbatim
+ ALGORITHM:
+ for each component 'cur' in decreasing order
+ if already merged
+ continue
+
+ ///
+ /// x-----------x
+ /// | |
+ /// x x x
+ /// | |
+ /// x-----------x
+ ///
+
+ Set labels <- Every labels corresponding to the colliding bounding
+ boxes (uses only the 7 sites detailled above).
+
+ If label.card == 1
+ l = label.get(0);
+ If l != background
+ If looks_like_a_line(cur)
+ If looks_like_a_line(l)
+ // Error case: a line is included in a line.
+ else
+ // Line cur is included in a frame or a drawing.
+ draw_enlarged_box(l)
+ end
+ else
+ If looks_like_a_line(l)
+ // Component cur is a punctuation overlapping with line l.
+ l_ <- do_union(cur, l)
+ draw_enlarged_box(l_)
+ end
+ end
+ else
+ If looks_like_a_line(cur)
+ // Component cur is a new line.
+ draw_enlarged_box(l)
+ end
+ end
+ else
+ for each label l in labels
+ If l == background
+ continue
+ end
+
+ If lines_can_merge(cur, l)
+ l_ <- do_union(cur, l)
+ draw_enlarged_box(l_)
+ continue
+ end
+
+ If !looks_like_a_line(cur) and looks_like_a_line(l)
+ If non_line_and_line_can_merge(cur, l)
+ // A punctuation merge with a line
+ l_ <- do_union(cur, l)
+ draw_enlarged_box(l_)
+ continue
+ else
+ // None
+ end
+ else
+ // Error case
+ end
+ end
+
+ \endverbatim
+ */
+ // FIXME:
+ //
+ // Important note: after merging two lines, we draw the
+ // merged line over the existing one; we have to ensure that we
+ // cover the previous rectangle (otherwise we have a label in
+ // 'output' that is not used anymore! and it can mix up the
+ // detection of upcoming merges...) so this delta has to remain
+ // the same during one pass. Another solution (yet more costly)
+ // could be of erasing the previous rectangle before re-drawing...
+ //
template <typename L>
image2d<unsigned>
one_merge_pass(unsigned ith_pass,
const box2d& domain,
std::vector<scribo::line_id_t>& v,
scribo::line_set<L>& lines,
- util::array<unsigned>& parent,
- util::array<bool>& looks_like_a_text_line_,
- bool last_pass = false)
+ util::array<group_data_t<L> >& dta,
+ util::array<unsigned>& parent)
{
- image2d<unsigned> canvas(domain);
- data::fill(canvas, 0);
+ image2d<unsigned> output(domain);
+ data::fill(output, 0);
image2d<value::int_u8> log(domain);
data::fill(log, 0);
- unsigned
- count_new = 0,
- count_include = 0,
- count_merge = 0,
- count_grow = 0,
- count_bad_3 = 0,
- count_bad_4 = 0;
+ const unsigned n = dta.nelements() - 1;
+ unsigned l_;
unsigned
-
- count_1_grow_ok = 0,
- count_1_grow_KO = 0,
- count_1_merge_ok = 0,
- count_1_merge_KO = 0,
- count_1_other = 0,
-
- count_2_merge_hyphen_ok = 0,
- count_2_merge_hyphen_KO = 0,
- count_2_merge_all_ok = 0,
- count_2_merge_all_KO = 0,
- count_2_merge_other = 0;
-
- const unsigned n = lines.nelements();
- unsigned l_;
+ count_txtline_IN_txtline = 0,
+ count_txtline_IN_junk = 0,
+ count_two_lines_merge = 0,
+ count_new_txtline = 0,
+ count_comp_IN_txtline = 0,
+ count_comp_HITS_txtline = 0,
+ count_WTF = 0;
for (int i = n - 1; i >= 0; --i)
{
@@ -332,324 +490,191 @@ namespace scribo
box2d b = lines(l).bbox();
- unsigned tl, tr, bl, br;
+ unsigned tl, tr, ml, mc, mr, bl, br;
{
- box2d b_ =
- looks_like_a_text_line_(lines(l).id()) ?
- enlarge(b, delta_of_line(lines(l))) :
- b;
- tl = canvas(b_.pmin());
- tr = canvas.at_(b_.pmin().row(), b_.pmax().col());
- bl = canvas.at_(b_.pmax().row(), b_.pmin().col());
- br = canvas(b_.pmax());
- }
+ box2d b_;
-// {
-// tl = canvas(b.pmin());
-// tr = canvas.at_(b.pmin().row(), b.pmax().col());
-// bl = canvas.at_(b.pmax().row(), b.pmin().col());
-// br = canvas(b.pmax());
-// }
+ b_ = enlarge(lines(l).bbox(), dta[l].delta);
+ b_.crop_wrt(output.domain());
- if (tl == tr && bl == br && tl == bl) // Same behavior for all corners.
- {
- if (tl != 0)
- {
- // Main case: it is an "included" box (falling in an already drawn box)
- ++count_include;
- // Merge lines #tl and #l.
- l_ = do_union(lines, tl, l, parent);
- // We have to re-draw the original largest line since
- // it may change of label (take the one of the included line).
- draw_enlarged_box(canvas, lines(l_));
-
- // Log:
- draw_box(log, b, 128);
- }
- else
- {
- // Main case: it is a "new" box, to be drawn in the background.
- ++count_new;
-
- // Extra test:
- if (canvas(b.pcenter()) == 0)
- // confirmation that we are not in this rare pathological case:
- //
- // o---o
- // +----|---|---------+
- // | | ? | |
- // +----|---|---------+
- // o---o
- {
- draw_enlarged_box(canvas, lines(l));
- // Log:
- draw_box(log, b, 127);
- }
- else
- {
- // FIXME:
- // We have to tag as pathological the line l.
- if (last_pass)
- lines(l).update_tag(scribo::line::Pathological);
- std::cout << "pathological ''new box''" << std::endl;
- }
- }
- }
- else
- {
- // Particular cases.
- unsigned
- l1, l2, l3, l4,
- count_non_zero, count_different_labels;
-
- compute_data(// in
- tl, tr, bl, br,
- // out
- l1, l2, l3, l4,
- count_non_zero, count_different_labels);
+ /*
+ tl tr
+ x---------------x
+ | |
+ | mc |
+ ml x x x mr
+ | |
+ | |
+ x---------------x
+ bl br
+ */
- if (count_different_labels == 0)
- std::cout << "bug 0000" << std::endl;
+ tl = output(b_.pmin());
+ tr = output.at_(b_.pmin().row(), b_.pmax().col());
+ ml = output.at_(b_.pcenter().row(), b_.pmin().col());
+ mc = output.at_(b_.pcenter().row(), b_.pcenter().col());
+ mr = output.at_(b_.pcenter().row(), b_.pmax().col());
+ bl = output.at_(b_.pmax().row(), b_.pmin().col());
+ br = output(b_.pmax());
+ }
- if (count_different_labels == 1 && count_non_zero == 3)
- {
- // +----------+
- // | x--x |
- // | | | |
- // | x--0 !! |
- // +----------+
- std::cout << "bug 1-3" << std::endl;
- }
-
- // FIXME: Handle the case where count_different_labels ==
- // 2 && count_non_zero == 3?
-
-
- if (count_different_labels == 4)
- {
- ++count_bad_4;
-
- // FIXME:
- // We have to tag as pathological the line l.
- if (last_pass)
- lines(l).update_tag(scribo::line::Pathological);
-
- // Log:
- draw_box(log, b, 254);
- }
-
-
- if (count_different_labels == 3)
- {
- ++count_bad_3;
-
- // FIXME:
- // We have to tag as pathological the line l.
- if (last_pass)
- lines(l).update_tag(scribo::line::Pathological);
-
- // Log:
- draw_box(log, b, 253);
- }
+ typedef std::set<unsigned> set_t;
+ std::set<unsigned> labels;
+ labels.insert(tl);
+ labels.insert(tl);
+ labels.insert(tr);
+ labels.insert(ml);
+ labels.insert(mc);
+ labels.insert(mr);
+ labels.insert(bl);
+ labels.insert(br);
- if (count_different_labels == 1) // Usually a "grow" case thanks to comma, hyphen, etc.
+ if (labels.size() == 1) // Same behavior for all ancors.
+ {
+ if (mc != 0)
{
- ++count_grow;
-
- if (count_non_zero == 0 || count_non_zero == 4)
- std::cerr << "bug 1-04" << std::endl;
-
- // We have to test if we shall merge!
-
- bool
- l_is_line = looks_like_a_text_line_(lines(l).id()),
- l1_is_line = looks_like_a_text_line_(lines(l1).id());
+ // Main case: it is an "included" box (falling in an already drawn box)
- if (! l_is_line && l1_is_line)
+ if (dta[l].looks_like_a_line)
{
- // This is the classical "grow" case: a small component
- // makes a larger one grow.
-
- // l should be a comma, hyphen, etc. of the line l1
- // so we try to make line l1 grow.
- if (lines(l).bbox().height() < lines(l1).bbox().height()
- && lines(l).bbox().width() < lines(l1).bbox().width())
+ if (dta[mc].looks_like_a_line)
{
- // line l height and width are resp. smaller than line l1 height and width.
- ++count_1_grow_ok;
- l_ = do_union(lines, l, l1, parent);
- draw_enlarged_box(canvas, lines(l_));
- // Log:
- draw_box(log, b, 100);
+ ++count_txtline_IN_txtline;
+ std::cout << "weird: inclusion of a txt_line in a txt_line!" << std::endl;
}
else
{
- ++count_1_grow_KO;
-
- // ,-.
- // | | l etait une fois...
- // | |
- // | | bla bla bla.
- // | |
- // | | bla bla bla
- // `-'
- //
- // It is usually the case of a dropped initial...
- //
- // FIXME: Do we want to set this line as pathological?
-
- if (last_pass)
- lines(l).update_tag(scribo::line::Pathological);
-
- draw_box(canvas, b, l);
+ ++count_txtline_IN_junk;
+ // a non-line (probably a drawing or a frame) includes a line
+ draw_enlarged_box(output, dta, l);
// Log:
- draw_box(log, b, 101);
+ draw_box(log, b, 100);
}
- // It seems better to distinguish between the
- // different cases : if the height of line l is
- // larger than the width, I can be a comma so I
- // only merge if my location is at the bottom of
- // line l1, and so on.
}
-
- else if (l_is_line && l1_is_line)
+ else // the current object is NOT a line
{
- // Less common case than the above "grow" one:
- // two lines merge.
-
- if (lines_can_merge(lines(l), lines(l1)))
- {
- ++count_1_merge_ok;
- l_ = do_union(lines, l, l1, parent);
- draw_enlarged_box(canvas, lines(l_));
- // Log:
- draw_box(log, b, 110);
- }
- else
+ if (dta[mc].looks_like_a_line)
{
- ++count_1_merge_KO;
- if (last_pass)
- lines(l).update_tag(scribo::line::Pathological);
+ ++count_comp_IN_txtline;
+ // FIXME: critere petouille a ajouter ici
+
+ // Merge non-line #l into line #mc.
+ l_ = do_union(dta, lines, mc, l, parent);
+ // We have to re-draw the original largest line since
+ // it may change of label (take the one of the included line).
+ draw_enlarged_box(output, dta, l_);
// Log:
- draw_box(log, b, 111);
+ draw_box(log, b, 128);
}
}
- else
+ }
+ else
+ {
+ // Main case: it is a "new" box, that might be drawn in the background.
+
+ // we only draw this box if it is a text-line!!!
+ if (dta[l].looks_like_a_line)
{
- ++count_1_other;
+ ++count_new_txtline;
+ draw_enlarged_box(output, dta, l);
// Log:
- draw_box(log, b, 120);
+ draw_box(log, b, 127);
}
+ else
+ draw_box(log, b, 1);
}
-
-
- if (count_different_labels == 2)
+ }
+ else
+ {
+ // Particular cases.
+ for (set_t::const_iterator it = labels.begin();
+ it != labels.end();
+ ++it)
{
+ unsigned lcand = *it;
- bool
- l_is_line = looks_like_a_text_line_(lines(l).id()),
- l1_is_line = looks_like_a_text_line_(lines(l1).id()),
- l2_is_line = looks_like_a_text_line_(lines(l2).id());
+ if (lcand == 0) // Skip background.
+ continue;
- if (! l_is_line && l1_is_line && l2_is_line)
+ if (lines_can_merge(lines(l), lines(lcand)))
{
- // Typically an hyphen joins two tines (two chunks of the same line).
- if (lines_can_merge(lines(l1), lines(l2)))
- {
- ++count_2_merge_hyphen_ok;
- do_union(lines, l1, l2, parent);
- l_ = do_union(lines, l, l2, parent);
- draw_enlarged_box(canvas, lines(l_));
- // Log:
- draw_box(log, b, 80);
- }
- else
- {
- ++count_2_merge_hyphen_KO;
- if (last_pass)
- lines(l).update_tag(scribo::line::Pathological);
- // Log:
- draw_box(log, b, 81);
- }
+ ++count_two_lines_merge;
+ l_ = do_union(dta, lines, l, lcand, parent);
+ draw_enlarged_box(output, dta, l_);
+ // Log:
+ draw_box(log, b, 151);
+ continue;
}
- else if (l_is_line && l1_is_line && l2_is_line)
+
+
+ if (! dta[l].looks_like_a_line && dta[lcand].looks_like_a_line)
{
- // Typically three chunks of the same line.
- if (lines_can_merge(lines(l1), lines(l2))
- && lines_can_merge(lines(l), lines(l1))
- && lines_can_merge(lines(l), lines(l2)))
+ ++count_comp_HITS_txtline;
+ if (non_line_and_line_can_merge(lines(l), dta[l], lines(lcand), dta[lcand]))
+ // a petouille merges with a text line?
{
- ++count_2_merge_all_ok;
- do_union(lines, l1, l2, parent);
- l_ = do_union(lines, l, l2, parent);
- draw_enlarged_box(canvas, lines(l_));
+ ++count_comp_HITS_txtline;
+ l_ = do_union(dta, lines, l, lcand, parent);
+ draw_enlarged_box(output, dta, l_);
// Log:
- draw_box(log, b, 90);
+ draw_box(log, b, 169);
+ continue;
}
else
{
- ++count_2_merge_all_KO;
- if (last_pass)
- lines(l).update_tag(scribo::line::Pathological);
// Log:
- draw_box(log, b, 91);
+ draw_box(log, b, 254);
}
}
else
{
- ++count_2_merge_other;
- if (last_pass)
- lines(l).update_tag(scribo::line::Pathological);
+ ++count_WTF;
// Log:
draw_box(log, b, 255);
}
- // FIXME: Perhaps there is only one merge...
-
}
-
}
+
}
- std::cout
- << "new = " << count_new << std::endl
- << "inc = " << count_include << std::endl
- << "mrg = " << count_merge << std::endl
- << "grw = " << count_grow << std::endl
- << "bd3 = " << count_bad_3 << std::endl
- << "bd4 = " << count_bad_4 << std::endl;
std::cout
- << std::endl
- << "#1 grow ok = " << count_1_grow_ok << std::endl
- << "#1 grow KO = " << count_1_grow_KO << std::endl
- << "#1 merge ok = " << count_1_merge_ok << std::endl
- << "#1 merge KO = " << count_1_merge_KO << std::endl
- << "#1 other = " << count_1_other << std::endl;
+ << " new txtline = " << count_new_txtline << std::endl
+ << " comp IN txtline = " << count_comp_IN_txtline << std::endl
+ << " 2 lines merge = " << count_two_lines_merge << std::endl
+ << " comp HITS txtline = " << count_comp_HITS_txtline << std::endl
+ << " txtline IN junk = " << count_txtline_IN_junk << std::endl
+ << " txtline IN txtline = " << count_txtline_IN_txtline << std::endl
+ << " WTF! = " << count_WTF << std::endl;
+
+
+ (void) ith_pass;
+// if (ith_pass == 1)
+// {
+// mln::io::pgm::save(log, "log_1.pgm");
+// mln::io::pgm::save(data::wrap(int_u8(), output), "log_1e.pgm");
+// }
+// else if (ith_pass == 2)
+// {
+// mln::io::pgm::save(log, "log_2.pgm");
+// mln::io::pgm::save(data::wrap(int_u8(), output), "log_2e.pgm");
+// }
+// else if (ith_pass == 3)
+// {
+// mln::io::pgm::save(log, "log_3.pgm");
+// mln::io::pgm::save(data::wrap(int_u8(), output), "log_3e.pgm");
+// }
+
+ return output;
- std::cout
- << std::endl
- << "#2 merge hyphen ok = " << count_2_merge_hyphen_ok << std::endl
- << "#2 merge hyphen KO = " << count_2_merge_hyphen_KO << std::endl
- << "#2 merge all ok = " << count_2_merge_all_ok << std::endl
- << "#2 merge all KO = " << count_2_merge_all_KO << std::endl
- << "#2 merge other = " << count_2_merge_other << std::endl;
-
- if (ith_pass == 1)
- mln::io::pgm::save(log, "log_1.pgm");
- else if (ith_pass == 2)
- mln::io::pgm::save(log, "log_2.pgm");
- else if (ith_pass == 3)
- mln::io::pgm::save(log, "log_3.pgm");
-
- return canvas;
}
@@ -672,6 +697,8 @@ namespace scribo
scribo::line_set<L> lines_;
};
+
+
template <typename L>
scribo::line_set<L>
draw_boxes(const box2d& input_domain,
@@ -702,34 +729,32 @@ namespace scribo
util::timer t;
- // Caching whether a line looks like a text line.
- util::array<bool>
- looks_like_a_text_line_(unsigned(lines.nelements()) + 1);
+ // Caching line temporary data.
+ util::array<group_data_t<L> >
+ dta;
+ dta.reserve(unsigned(lines.nelements()) + 1);
+ dta.append(group_data_t<L>());
for_all_lines(l, lines)
- looks_like_a_text_line_[l] = looks_like_a_text_line(lines(l));
-
+ dta.append(group_data_t<L>(lines(l)));
// First pass
t.start();
- one_merge_pass(1, input_domain, v, lines,
- parent, looks_like_a_text_line_);
+ one_merge_pass(1, input_domain, v, lines, dta, parent);
float ts = t.stop();
std::cout << "time " << ts << std::endl;
// Second pass
t.start();
- canvas = one_merge_pass(2, input_domain, v, lines,
- parent, looks_like_a_text_line_,
- true); // <- last pass
+ canvas = one_merge_pass(2, input_domain, v, lines, dta, parent); // <- last pass
ts = t.stop();
std::cout << "time " << ts << std::endl;
- using value::int_u8;
+// using value::int_u8;
//io::pgm::save(data::wrap(int_u8(), canvas), "merge_result.pgm");
- mln::io::ppm::save(labeling::colorize(value::rgb8(), canvas),
- "merge_result.ppm");
+// mln::io::ppm::save(labeling::colorize(value::rgb8(), canvas),
+// "merge_result.ppm");
return lines;
--
1.5.6.5
1
0
last-svn-commit-23-g34f317b Split the regional maxima binary in small atomic binaries.
by green 24 Feb '10
by green 24 Feb '10
24 Feb '10
* green/tools/annotating/histo: New directory.
* green/tools/annotating/histo/Makefile.am: New Makefile.
* green/tools/annotating/histo/histo.cc: New source file.
* green/tools/annotating/opening: New directory.
* green/tools/annotating/opening/Makefile.am: New Makefile.
* green/tools/annotating/opening/opening.cc: New source file.
* green/tools/annotating/regmax: New directory.
* green/tools/annotating/regmax/Makefile.am: New Makefile.
* green/tools/annotating/regmax/regmax.cc: New source file.
---
milena/sandbox/ChangeLog | 14 ++
.../annotating/histo}/Makefile.am | 9 +-
.../sandbox/green/tools/annotating/histo/histo.cc | 121 ++++++++++++++++++
.../annotating/opening}/Makefile.am | 9 +-
.../green/tools/annotating/opening/opening.cc | 79 ++++++++++++
.../annotating/regmax}/Makefile.am | 9 +-
.../green/tools/annotating/regmax/regmax.cc | 133 ++++++++++++++++++++
7 files changed, 359 insertions(+), 15 deletions(-)
copy milena/sandbox/green/{exp/annotating/nb_color => tools/annotating/histo}/Makefile.am (96%)
create mode 100644 milena/sandbox/green/tools/annotating/histo/histo.cc
copy milena/sandbox/green/{exp/annotating/nb_color => tools/annotating/opening}/Makefile.am (96%)
create mode 100644 milena/sandbox/green/tools/annotating/opening/opening.cc
copy milena/sandbox/green/{exp/annotating/nb_color => tools/annotating/regmax}/Makefile.am (96%)
create mode 100644 milena/sandbox/green/tools/annotating/regmax/regmax.cc
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 0947048..cbd9cdc 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,3 +1,17 @@
+2010-01-05 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
+ Split the regional maxima binary in small atomic binaries.
+
+ * green/tools/annotating/histo: New directory.
+ * green/tools/annotating/histo/Makefile.am: New Makefile.
+ * green/tools/annotating/histo/histo.cc: New source file.
+ * green/tools/annotating/opening: New directory.
+ * green/tools/annotating/opening/Makefile.am: New Makefile.
+ * green/tools/annotating/opening/opening.cc: New source file.
+ * green/tools/annotating/regmax: New directory.
+ * green/tools/annotating/regmax/Makefile.am: New Makefile.
+ * green/tools/annotating/regmax/regmax.cc: New source file.
+
2009-12-23 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
Write the opening volume thresholds for the scribo image mp00082c.ppm.
diff --git a/milena/sandbox/green/exp/annotating/nb_color/Makefile.am b/milena/sandbox/green/tools/annotating/histo/Makefile.am
similarity index 96%
copy from milena/sandbox/green/exp/annotating/nb_color/Makefile.am
copy to milena/sandbox/green/tools/annotating/histo/Makefile.am
index 8e204c6..8cd7511 100644
--- a/milena/sandbox/green/exp/annotating/nb_color/Makefile.am
+++ b/milena/sandbox/green/tools/annotating/histo/Makefile.am
@@ -6,7 +6,6 @@
# TOOLS #
#########
-LOADLIBES= -lboost_filesystem
INCLUDES= -I$(HOME)/svn/oln/trunk/milena/sandbox/green
#CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES)
#CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES)
@@ -16,17 +15,17 @@ RM= rm
MKDIR= mkdir -p
CP= cp
-SOURCE_PATTERN= green/exp
-BUILD__PATTERN= green/build/exp
+SOURCE_PATTERN= green/tools
+BUILD__PATTERN= green/build/tools
ifeq ($(findstring $(BUILD__PATTERN),$(PWD)), $(BUILD__PATTERN))
# Case where make is done from build directory.
SOURCE_DIR= $(subst $(BUILD__PATTERN),$(SOURCE_PATTERN),$(PWD))
-BUILD__DIR= $(PWD)/
+BUILD__DIR= $(PWD)
else
# Case where make is done from source directory.
-SOURCE_DIR= $(PWD)/
+SOURCE_DIR= $(PWD)
BUILD__DIR= $(subst $(SOURCE_PATTERN),$(BUILD__PATTERN),$(PWD))
endif
diff --git a/milena/sandbox/green/tools/annotating/histo/histo.cc b/milena/sandbox/green/tools/annotating/histo/histo.cc
new file mode 100644
index 0000000..ab0b8af
--- /dev/null
+++ b/milena/sandbox/green/tools/annotating/histo/histo.cc
@@ -0,0 +1,121 @@
+// TOOLS ==> Color histogram
+
+#include <iostream>
+
+#include <mln/accu/stat/histo3d_rgb.hh>
+
+#include <mln/core/macros.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+#include <mln/core/image/dmorph/image_if.hh>
+
+#include <mln/data/compute.hh>
+#include <mln/data/transform.hh>
+
+#include <mln/display/display_histo.hh>
+
+#include <mln/fun/v2v/rgb8_to_rgbn.hh>
+
+#include <mln/io/dump/save.hh>
+#include <mln/io/pbm/load.hh>
+#include <mln/io/pbm/save.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/ppm/load.hh>
+#include <mln/io/ppm/save.hh>
+
+#include <mln/opt/at.hh>
+
+#include <mln/pw/value.hh>
+
+#include <mln/value/rgb8.hh>
+#include <mln/value/rgb.hh>
+
+
+template <unsigned n>
+void mk_histo(const std::string& input,
+ const std::string& output,
+ const std::string& histo,
+ const std::string& mask)
+{
+ typedef mln::value::int_u8 t_int_u8;
+ typedef mln::value::rgb8 t_rgb8;
+ typedef mln::value::rgb<n> t_rgbn;
+ typedef mln::image2d<t_int_u8> t_image2d_int_u8;
+ typedef mln::image2d<t_rgb8> t_image2d_rgb8;
+ typedef mln::image2d<t_rgbn> t_image2d_rgbn;
+ typedef mln::image2d<bool> t_image2d_bool;
+ typedef mln::image3d<unsigned> t_histo3d;
+ typedef mln::fun::v2v::rgb8_to_rgbn<n> t_rgb8_to_rgbn;
+ typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun;
+
+ // START OF IMAGE PROCESSING CHAIN
+ t_image2d_rgb8 i0_input; // input rgb8
+ t_image2d_rgbn i1_input; // input rgbn
+ t_image2d_bool m0_input; // mask input
+ t_histo3d h1_input; // histo input
+ t_image2d_int_u8 p1_histo; // histo proj
+
+ mln::io::ppm::load(i0_input, input.c_str());
+ i1_input = mln::data::transform(i0_input, t_rgb8_to_rgbn());
+
+ if (0 < mask.size())
+ {
+ mln::io::pbm::load(m0_input, mask.c_str());
+ h1_input = mln::data::compute(t_histo3d_fun(),
+ (i1_input | mln::pw::value(m0_input)).rw());
+ }
+ else
+ {
+ h1_input = mln::data::compute(t_histo3d_fun(), i1_input);
+ }
+ // END OF IMAGE PROCESSING CHAIN
+
+ // BEGIN DUMPING
+ p1_histo = mln::display::display_histo3d_unsigned(h1_input);
+ mln::io::dump::save(h1_input, histo.c_str());
+ mln::io::pgm::save(p1_histo, output.c_str());
+ // END DUMPING
+}
+
+
+void usage()
+{
+ std::cout << std::endl;
+ std::cout << "histo input.ppm q out.ppm histo.dump [msk.pbm]" << std::endl;
+ std::cout << "where" << std::endl;
+ std::cout << "input.ppm is the 8 bits color ppm image" << std::endl;
+ std::cout << "q is the degree of quanification {2,3,4,5,6,7,8}" << std::endl;
+ std::cout << "out.pgm is the r/g projection of the histogram" << std::endl;
+ std::cout << "out.dump is the quantified color histogram" << std::endl;
+ std::cout << "msk.pbm is the mask which select the pixels" << std::endl;
+ std::cout << std::endl;
+}
+
+int main(int argc, char* args[])
+{
+ if (5 == argc || 6 == argc)
+ {
+ const std::string input(args[1]);
+ const char q = args[2][0];
+ const std::string output(args[3]);
+ const std::string histo(args[4]);
+ const std::string mask(6 == argc? args[5] : "");
+
+ switch(q)
+ {
+ case '2': mk_histo<2>(input, output, histo, mask); break;
+ case '3': mk_histo<3>(input, output, histo, mask); break;
+ case '4': mk_histo<4>(input, output, histo, mask); break;
+ case '5': mk_histo<5>(input, output, histo, mask); break;
+ case '6': mk_histo<6>(input, output, histo, mask); break;
+ case '7': mk_histo<7>(input, output, histo, mask); break;
+ case '8': mk_histo<8>(input, output, histo, mask); break;
+ default: usage(); break;
+ }
+ }
+ else
+ usage();
+
+ return 0;
+}
diff --git a/milena/sandbox/green/exp/annotating/nb_color/Makefile.am b/milena/sandbox/green/tools/annotating/opening/Makefile.am
similarity index 96%
copy from milena/sandbox/green/exp/annotating/nb_color/Makefile.am
copy to milena/sandbox/green/tools/annotating/opening/Makefile.am
index 8e204c6..8cd7511 100644
--- a/milena/sandbox/green/exp/annotating/nb_color/Makefile.am
+++ b/milena/sandbox/green/tools/annotating/opening/Makefile.am
@@ -6,7 +6,6 @@
# TOOLS #
#########
-LOADLIBES= -lboost_filesystem
INCLUDES= -I$(HOME)/svn/oln/trunk/milena/sandbox/green
#CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES)
#CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES)
@@ -16,17 +15,17 @@ RM= rm
MKDIR= mkdir -p
CP= cp
-SOURCE_PATTERN= green/exp
-BUILD__PATTERN= green/build/exp
+SOURCE_PATTERN= green/tools
+BUILD__PATTERN= green/build/tools
ifeq ($(findstring $(BUILD__PATTERN),$(PWD)), $(BUILD__PATTERN))
# Case where make is done from build directory.
SOURCE_DIR= $(subst $(BUILD__PATTERN),$(SOURCE_PATTERN),$(PWD))
-BUILD__DIR= $(PWD)/
+BUILD__DIR= $(PWD)
else
# Case where make is done from source directory.
-SOURCE_DIR= $(PWD)/
+SOURCE_DIR= $(PWD)
BUILD__DIR= $(subst $(SOURCE_PATTERN),$(BUILD__PATTERN),$(PWD))
endif
diff --git a/milena/sandbox/green/tools/annotating/opening/opening.cc b/milena/sandbox/green/tools/annotating/opening/opening.cc
new file mode 100644
index 0000000..3e1dbf2
--- /dev/null
+++ b/milena/sandbox/green/tools/annotating/opening/opening.cc
@@ -0,0 +1,79 @@
+// TOOLS ==> histogram filtering
+
+#include <iostream>
+
+#include <mln/accu/stat/histo3d_rgb.hh>
+
+#include <mln/core/macros.hh>
+#include <mln/core/alias/neighb3d.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+
+#include <mln/data/compute.hh>
+
+#include <mln/display/display_histo.hh>
+
+#include <mln/io/dump/load.hh>
+#include <mln/io/dump/save.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+
+#include <mln/morpho/opening/volume.hh>
+
+#include <mln/value/int_u8.hh>
+
+void mk_opening(const std::string& input,
+ const unsigned min_vol,
+ const std::string& output,
+ const std::string& opened)
+{
+ typedef mln::value::int_u8 t_int_u8;
+ typedef mln::image2d<t_int_u8> t_image2d_int_u8;
+ typedef mln::image3d<unsigned> t_histo3d;
+ typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun;
+
+ // START OF IMAGE PROCESSING CHAIN
+ t_histo3d h1_input; // histo input
+ t_histo3d h2_input; // histo input
+ t_image2d_int_u8 p1_histo; // histo proj
+
+ mln::io::dump::load(h1_input, input.c_str());
+ h2_input = mln::morpho::opening::volume(h1_input, mln::c6(), min_vol);
+ // END OF IMAGE PROCESSING CHAIN
+
+ // BEGIN DUMPING
+ p1_histo = mln::display::display_histo3d_unsigned(h2_input);
+ mln::io::dump::save(h2_input, opened.c_str());
+ mln::io::pgm::save(p1_histo, output.c_str());
+ // END DUMPING
+}
+
+
+void usage()
+{
+ std::cout << std::endl;
+ std::cout << "opening input.dump v out.dump out.ppm" << std::endl;
+ std::cout << "where" << std::endl;
+ std::cout << "input.dump is the 3d color input histo" << std::endl;
+ std::cout << "v is the minimum size of each composant" << std::endl;
+ std::cout << "out.pgm is the r/g proj of the opened histogram" << std::endl;
+ std::cout << "out.dump is the opened histogram" << std::endl;
+ std::cout << std::endl;
+}
+
+int main(int argc, char* args[])
+{
+ if (5 == argc)
+ {
+ const std::string input(args[1]);
+ const unsigned min_vol = atoi(args[2]);
+ const std::string output(args[3]);
+ const std::string opened(args[4]);
+
+ mk_opening(input, min_vol, output, opened);
+ }
+ else
+ usage();
+
+ return 0;
+}
diff --git a/milena/sandbox/green/exp/annotating/nb_color/Makefile.am b/milena/sandbox/green/tools/annotating/regmax/Makefile.am
similarity index 96%
copy from milena/sandbox/green/exp/annotating/nb_color/Makefile.am
copy to milena/sandbox/green/tools/annotating/regmax/Makefile.am
index 8e204c6..8cd7511 100644
--- a/milena/sandbox/green/exp/annotating/nb_color/Makefile.am
+++ b/milena/sandbox/green/tools/annotating/regmax/Makefile.am
@@ -6,7 +6,6 @@
# TOOLS #
#########
-LOADLIBES= -lboost_filesystem
INCLUDES= -I$(HOME)/svn/oln/trunk/milena/sandbox/green
#CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES)
#CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES)
@@ -16,17 +15,17 @@ RM= rm
MKDIR= mkdir -p
CP= cp
-SOURCE_PATTERN= green/exp
-BUILD__PATTERN= green/build/exp
+SOURCE_PATTERN= green/tools
+BUILD__PATTERN= green/build/tools
ifeq ($(findstring $(BUILD__PATTERN),$(PWD)), $(BUILD__PATTERN))
# Case where make is done from build directory.
SOURCE_DIR= $(subst $(BUILD__PATTERN),$(SOURCE_PATTERN),$(PWD))
-BUILD__DIR= $(PWD)/
+BUILD__DIR= $(PWD)
else
# Case where make is done from source directory.
-SOURCE_DIR= $(PWD)/
+SOURCE_DIR= $(PWD)
BUILD__DIR= $(subst $(SOURCE_PATTERN),$(BUILD__PATTERN),$(PWD))
endif
diff --git a/milena/sandbox/green/tools/annotating/regmax/regmax.cc b/milena/sandbox/green/tools/annotating/regmax/regmax.cc
new file mode 100644
index 0000000..2079bc4
--- /dev/null
+++ b/milena/sandbox/green/tools/annotating/regmax/regmax.cc
@@ -0,0 +1,133 @@
+// TOOLS ==> regmax on histo
+
+#include <iostream>
+
+#include <mln/accu/stat/histo3d_rgb.hh>
+
+#include <mln/core/macros.hh>
+#include <mln/core/alias/neighb3d.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+
+#include <mln/data/compute.hh>
+
+#include <mln/debug/println.hh>
+#include <mln/display/display_histo.hh>
+
+#include <mln/io/dump/load.hh>
+#include <mln/io/dump/save.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/ppm/save.hh>
+
+#include <mln/labeling/regional_maxima.hh>
+
+#include <mln/morpho/opening/volume.hh>
+
+#include <mln/value/label_8.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/value/rgb8.hh>
+
+template <unsigned n>
+struct t_labeling_rgbn : mln::Function_v2v< t_labeling_rgbn<n> >
+{
+ typedef mln::value::rgb<n> t_rgbn;
+ typedef mln::value::label_8 t_lbl8;
+ typedef t_rgbn argument;
+ typedef t_lbl8 result;
+ typedef mln::image3d<t_lbl8> t_label;
+
+ const t_label& _label;
+
+ t_labeling_rgbn(const t_label& label) : _label(label) {}
+
+ result operator()(const argument& c) const
+ {
+ t_lbl8 tmp = mln::opt::at(_label, c.blue(), c.red(), c.green());
+
+ return tmp;
+ }
+};
+
+void mk_regmax(const std::string& input,
+ const std::string& quant,
+ const std::string& histo,
+ const std::string& label,
+ const std::string& output)
+{
+ typedef mln::value::label_8 t_lbl8;
+ typedef mln::value::rgb8 t_rgb8;
+ typedef mln::value::rgbn t_rgbn;
+ typedef mln::value::int_u8 t_int_u8;
+ typedef mln::algebra::vec<3,float> t_v3f;
+ typedef mln::image2d<t_int_u8> t_image2d_int_u8;
+ typedef mln::image2d<t_rgb8> t_image2d_rgb8;
+ typedef mln::image3d<t_lbl8> t_image3d_lbl8;
+ typedef mln::image2d<t_lbl8> t_image2d_lbl8;
+ typedef mln::image3d<unsigned> t_histo3d;
+ typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun;
+ typedef mln::accu::stat::mean<t_v3f,t_v3f,t_v3f> t_mean;
+ typedef mln::util::array<t_v3f> t_mean_array;
+
+ t_image2d_rgb8 i0_input; // input img
+ t_image2d_rgbn i1_input; // quant img
+ t_histo3d h2_input; // opened histo
+// t_image2d_int_u8 p2_label; // histo proj
+ t_image2d_lbl8 p2_label; // histo proj
+// t_image2d_rgb8 p2_label; // histo proj
+ t_image3d_lbl8 l2_histo; // label histo
+ t_mean_array m2_label; // palette
+
+ t_lbl8 n_lbl; // nb class
+
+ // BEGIN LOADING
+ mln::io::ppm::load(i0_input, input.c_str());
+ mln::io::ppm::load(i1_input, quant.c_str());
+ mln::io::dump::load(h2_input, histo.c_str());
+ // END LOADING
+
+ // BEGIN IMAGE PROCESSING
+ l2_histo = mln::labeling::regional_maxima(h2_input, mln::c6(), n_lbl);
+ // END IMAGE PROCESSING
+
+ // BEGIN SAVING
+ mln::debug::println(h2_input);
+ mln::io::dump::save(l2_histo, labeled.c_str());
+
+ l2_input = mln::data::transform(i1_input, t_labeling_rgbn<n>(l2_histo));
+ m2_label = mln::labeling::compute(t_mean(), i0_input, l2_input, n_labels);
+ p2_label =mln::display::display3_histo3d_unsigned(h2_input,l2_histo,m2_label);
+
+// mln::io::pgm::save(p2_label, output.c_str());
+ mln::io::ppm::save(p2_label, output.c_str());
+ std::cout << "Nb classes : " << n_lbl << std::endl;
+ // END SAVING
+}
+
+
+void usage()
+{
+ std::cout << std::endl;
+ std::cout << "regmax input.dump out.dump out.ppm" << std::endl;
+ std::cout << "where" << std::endl;
+ std::cout << "input.dump is opened histo" << std::endl;
+ std::cout << "out.pgm is the r/g proj of the opened histogram" << std::endl;
+ std::cout << "out.dump is the labeled histogram" << std::endl;
+ std::cout << std::endl;
+}
+
+int main(int argc, char* args[])
+{
+ if (4 == argc)
+ {
+ const std::string input(args[1]);
+ const std::string output(args[2]);
+ const std::string labeled(args[3]);
+
+ mk_regmax(input, output, labeled);
+ }
+ else
+ usage();
+
+ return 0;
+}
--
1.5.6.5
1
0
last-svn-commit-24-g9028f28 Build translation table between number of pixels and percentage of pixels in image for the scribo database.
by green 24 Feb '10
by green 24 Feb '10
24 Feb '10
* green/demo/labeling/regional_maxima/threshold.txt: New translation
table.
---
milena/sandbox/ChangeLog | 8 ++++++++
.../demo/labeling/regional_maxima/thresholds.txt | 15 +++++++++++++++
2 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index cbd9cdc..f34508b 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,5 +1,13 @@
2010-01-05 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+ Build translation table between number of pixels and percentage of
+ pixels in image for the scribo database.
+
+ * green/demo/labeling/regional_maxima/threshold.txt: New translation
+ table.
+
+2010-01-05 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
Split the regional maxima binary in small atomic binaries.
* green/tools/annotating/histo: New directory.
diff --git a/milena/sandbox/green/demo/labeling/regional_maxima/thresholds.txt b/milena/sandbox/green/demo/labeling/regional_maxima/thresholds.txt
index ddf5ca7..58f3e6a 100644
--- a/milena/sandbox/green/demo/labeling/regional_maxima/thresholds.txt
+++ b/milena/sandbox/green/demo/labeling/regional_maxima/thresholds.txt
@@ -5,9 +5,24 @@ image = 1169 x 1567 = 1831823
-----------------------
0.05 % | 1000.00
1.00 % | 18318.23
+ 2.00 % | 36636.46
+ 3.00 % | 54954.69
+ 4.00 % | 73272.92
5.00 % | 91591.15
+ 6.00 % | 109909.38
+ 7.00 % | 128227.61
+ 8.00 % | 146545.84
+ 9.00 % | 164864.07
10.00 % | 183182.30
+ 11.00 % | 201500.53
+ 12.00 % | 219818.76
+ 13.00 % | 238136.99
+ 14.00 % | 256455.22
15.00 % | 274773.45
+ 16.00 % | 293091.68
+ 17.00 % | 311409.91
+ 18.00 % | 329728.14
+ 19.00 % | 348046.37
20.00 % | 366364.60
25.00 % | 457955.75
30.00 % | 549546.90
--
1.5.6.5
1
0
last-svn-commit-25-gd3e640b Extend the histogram visualization tools for new projection concept.
by green 24 Feb '10
by green 24 Feb '10
24 Feb '10
* green/mln/display/project_histo.hh (project2_histo): New functions
that keep the max of the histogram or the class associate to it while
projecting along a direction.
* green/mln/display/project_histo.hh (project3_histo): New functions
that keep the color of the class associate to the histogram maximum
while projecting along a direction.
* green/mln/display/display_histo.hh: New interface functions for
project2_histo and project3_histo.
---
milena/sandbox/ChangeLog | 13 +
milena/sandbox/green/mln/display/display_histo.hh | 50 +++
milena/sandbox/green/mln/display/project_histo.hh | 344 +++++++++++++++++++++
3 files changed, 407 insertions(+), 0 deletions(-)
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index f34508b..b9d40cb 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,5 +1,18 @@
2010-01-05 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+ Extend the histogram visualization tools for new projection concept.
+
+ * green/mln/display/project_histo.hh (project2_histo): New functions
+ that keep the max of the histogram or the class associate to it while
+ projecting along a direction.
+ * green/mln/display/project_histo.hh (project3_histo): New functions
+ that keep the color of the class associate to the histogram maximum
+ while projecting along a direction.
+ * green/mln/display/display_histo.hh: New interface functions for
+ project2_histo and project3_histo.
+
+2010-01-05 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
Build translation table between number of pixels and percentage of
pixels in image for the scribo database.
diff --git a/milena/sandbox/green/mln/display/display_histo.hh b/milena/sandbox/green/mln/display/display_histo.hh
index 1fd5da4..2ba0b61 100644
--- a/milena/sandbox/green/mln/display/display_histo.hh
+++ b/milena/sandbox/green/mln/display/display_histo.hh
@@ -33,6 +33,8 @@
# include <mln/display/project_histo.hh>
# include <mln/fun/v2v/log.hh>
# include <mln/value/int_u8.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/value/label_8.hh>
/// \file
@@ -55,6 +57,20 @@ namespace mln
image2d<value::int_u8>
display_histo3d_unsigned(const image3d<unsigned>& histo);
+ image2d<value::int_u8>
+ display2_histo3d_unsigned(const image3d<unsigned>& histo);
+
+ image2d<value::label_8>
+ display2_histo3d_unsigned(const image3d<unsigned>& histo,
+ const image3d<value::label_8>& label);
+
+ image2d<value::rgb8>
+ display3_histo3d_unsigned(const image3d<unsigned>& histo);
+
+ image2d<value::rgb8>
+ display3_histo3d_unsigned(const image3d<unsigned>& histo,
+ const image3d<value::label_8>& label);
+
#ifndef MLN_INCLUDE_ONLY
/// \brief Allow the visualization of a 3d histogram by projection.
@@ -86,6 +102,40 @@ namespace mln
return proj_int;
}
+ image2d<value::int_u8>
+ display2_histo3d_unsigned(const image3d<unsigned>& histo)
+ {
+ image2d<value::int_u8> proj = project2_histo<0>(histo);
+
+ return proj;
+ }
+
+ image2d<value::label_8>
+ display2_histo3d_unsigned(const image3d<unsigned>& histo,
+ const image3d<value::label_8>& label)
+ {
+ image2d<value::label_8> proj = project2_histo<0>(histo, label);
+
+ return proj;
+ }
+
+ image2d<value::rgb8>
+ display3_histo3d_unsigned(const image3d<unsigned>& histo)
+ {
+ image2d<value::rgb8> proj = project3_histo<0>(histo);
+
+ return proj;
+ }
+
+ image2d<value::rgb8>
+ display3_histo3d_unsigned(const image3d<unsigned>& histo,
+ const image3d<value::label_8>& label)
+ {
+ image2d<value::rgb8> proj = project3_histo<0>(histo, label);
+
+ return proj;
+ }
+
#endif // ! MLN_INCLUDE_ONLY
diff --git a/milena/sandbox/green/mln/display/project_histo.hh b/milena/sandbox/green/mln/display/project_histo.hh
index f0e6858..d842c70 100644
--- a/milena/sandbox/green/mln/display/project_histo.hh
+++ b/milena/sandbox/green/mln/display/project_histo.hh
@@ -37,6 +37,12 @@
# include <mln/accu/image/take.hh>
# include <mln/accu/image/to_result.hh>
+# include <mln/opt/at.hh>
+
+# include <mln/value/int_u8.hh>
+# include <mln/value/rgb8.hh>
+# include <mln/value/label_8.hh>
+
/// \file
///
/// \brief Allow the visualization of 3d histogram.
@@ -54,6 +60,10 @@ namespace mln
image2d<mln_result(A)>
project_histo(const image3d<V>& histo);
+ template <typename A, unsigned direction, typename V>
+ image2d<mln_result(A)>
+ project2_histo(const image3d<V>& histo);
+
# ifndef MLN_INCLUDE_ONLY
/// \brief Allow the visualization of 3d histogram.
@@ -86,6 +96,340 @@ namespace mln
return accu::image::to_result(histo_accu);
}
+ template <unsigned direction>
+ image2d<value::int_u8>
+ project2_histo(const image3d<unsigned>& histo)
+ {
+ image2d<value::int_u8> result;
+
+ if (0 == direction) // blue
+ {
+ image2d<value::int_u8> arg_max(histo.ncols(), histo.nslices());
+
+ for (unsigned j = 0; j < histo.ncols(); ++j)
+ for (unsigned i = 0; i < histo.nslices(); ++i)
+ {
+ unsigned max = 0; // minimum as possible
+ signed pos = -1;
+
+ for (unsigned k = 0; k < histo.nrows(); ++k)
+ {
+ if (max <= opt::at(histo,i,j,k))
+ {
+ max = opt::at(histo,i,j,k);
+ pos = k;
+ }
+ }
+
+ opt::at(arg_max,i,j) = pos;
+ }
+
+ result = arg_max;
+ }
+ else if (1 == direction) // red
+ {
+ image2d<value::int_u8> arg_max(histo.nrows(), histo.nslices());
+
+ for (unsigned j = 0; j < histo.nslices(); ++j)
+ for (unsigned i = 0; i < histo.nrows(); ++i)
+ {
+ unsigned max = 0; // minimum as possible
+ signed pos = -1;
+
+ for (unsigned k = 0; k < histo.ncols(); ++k)
+ {
+ if (max <= opt::at(histo,i,j,k))
+ {
+ max = opt::at(histo,i,j,k);
+ pos = k;
+ }
+ }
+
+ opt::at(arg_max,i,j) = pos;
+ }
+
+ result = arg_max;
+ }
+ else // 2 == direction // green
+ {
+ image2d<value::int_u8> arg_max(histo.nrows(), histo.ncols());
+
+ for (unsigned j = 0; j < histo.ncols(); ++j)
+ for (unsigned i = 0; i < histo.nrows(); ++i)
+ {
+ unsigned max = 0; // minimum as possible
+ signed pos = -1;
+
+ for (unsigned k = 0; k < histo.nslices(); ++k)
+ {
+ if (max <= opt::at(histo,i,j,k))
+ {
+ max = opt::at(histo,i,j,k);
+ pos = k;
+ }
+ }
+
+ opt::at(arg_max,i,j) = pos;
+ }
+
+ result = arg_max;
+ }
+
+ return result;
+ }
+
+ template <unsigned direction>
+ image2d<value::label_8>
+ project2_histo(const image3d<unsigned>& histo,
+ const image3d<value::label_8>& label)
+ {
+ image2d<value::label_8> result;
+
+ if (0 == direction) // blue
+ {
+ image2d<value::label_8> arg_max(histo.ncols(), histo.nslices());
+
+ for (unsigned j = 0; j < histo.ncols(); ++j)
+ for (unsigned i = 0; i < histo.nslices(); ++i)
+ {
+ unsigned max = 0; // minimum as possible
+ signed pos = -1;
+
+ for (unsigned k = 0; k < histo.nrows(); ++k)
+ {
+ if (max <= opt::at(histo,i,j,k))
+ {
+ max = opt::at(histo,i,j,k);
+ pos = k;
+ }
+ }
+
+ opt::at(arg_max,i,j) = opt::at(label,i,j,pos);
+ }
+
+ result = arg_max;
+ }
+ else if (1 == direction) // red
+ {
+ image2d<value::label_8> arg_max(histo.nrows(), histo.nslices());
+
+ for (unsigned j = 0; j < histo.nslices(); ++j)
+ for (unsigned i = 0; i < histo.nrows(); ++i)
+ {
+ unsigned max = 0; // minimum as possible
+ signed pos = -1;
+
+ for (unsigned k = 0; k < histo.ncols(); ++k)
+ {
+ if (max <= opt::at(histo,i,j,k))
+ {
+ max = opt::at(histo,i,j,k);
+ pos = k;
+ }
+ }
+
+ opt::at(arg_max,i,j) = opt::at(label,pos,i,j);
+ }
+
+ result = arg_max;
+ }
+ else // 2 == direction // green
+ {
+ image2d<value::label_8> arg_max(histo.nrows(), histo.ncols());
+
+ for (unsigned j = 0; j < histo.ncols(); ++j)
+ for (unsigned i = 0; i < histo.nrows(); ++i)
+ {
+ unsigned max = 0; // minimum as possible
+ signed pos = -1;
+
+ for (unsigned k = 0; k < histo.nslices(); ++k)
+ {
+ if (max <= opt::at(histo,i,j,k))
+ {
+ max = opt::at(histo,i,j,k);
+ pos = k;
+ }
+ }
+
+ opt::at(arg_max,i,j) = opt::at(label,i,pos,j);
+ }
+
+ result = arg_max;
+ }
+
+ return result;
+ }
+
+
+ // FIXME ... determine the color of each class.
+ template <unsigned direction>
+ image2d<value::rgb8>
+ project3_histo(const image3d<unsigned>& histo,
+ const image3d<value::label_8>& label)
+ {
+ image2d<value::rgb8> result;
+
+ if (0 == direction) // blue
+ {
+ image2d<value::rgb8> arg_max(histo.ncols(), histo.nslices());
+
+ for (unsigned j = 0; j < histo.ncols(); ++j)
+ for (unsigned i = 0; i < histo.nslices(); ++i)
+ {
+ unsigned max = 0; // minimum as possible
+ signed pos = -1;
+
+ for (unsigned k = 0; k < histo.nrows(); ++k)
+ {
+ if (max <= opt::at(histo,i,j,k))
+ {
+ max = opt::at(histo,i,j,k);
+ pos = k;
+ }
+ }
+
+ opt::at(arg_max,i,j) = value::rgb8(i,j,pos);
+ }
+
+ result = arg_max;
+ }
+ else if (1 == direction) // red
+ {
+ image2d<value::rgb8> arg_max(histo.nrows(), histo.nslices());
+
+ for (unsigned j = 0; j < histo.nslices(); ++j)
+ for (unsigned i = 0; i < histo.nrows(); ++i)
+ {
+ unsigned max = 0; // minimum as possible
+ signed pos = -1;
+
+ for (unsigned k = 0; k < histo.ncols(); ++k)
+ {
+ if (max <= opt::at(histo,i,j,k))
+ {
+ max = opt::at(histo,i,j,k);
+ pos = k;
+ }
+ }
+
+ opt::at(arg_max,i,j) = value::rgb8(pos,i,j);
+ }
+
+ result = arg_max;
+ }
+ else // 2 == direction // green
+ {
+ image2d<value::rgb8> arg_max(histo.nrows(), histo.ncols());
+
+ for (unsigned j = 0; j < histo.ncols(); ++j)
+ for (unsigned i = 0; i < histo.nrows(); ++i)
+ {
+ unsigned max = 0; // minimum as possible
+ signed pos = -1;
+
+ for (unsigned k = 0; k < histo.nslices(); ++k)
+ {
+ if (max <= opt::at(histo,i,j,k))
+ {
+ max = opt::at(histo,i,j,k);
+ pos = k;
+ }
+ }
+
+ // FIXME ... how to fix the n of rgb
+ opt::at(arg_max,i,j) = value::rgb8(i,pos,j);
+ }
+
+ result = arg_max;
+ }
+
+ return result;
+ }
+
+ template <unsigned direction>
+ image2d<value::rgb8>
+ project3_histo(const image3d<unsigned>& histo)
+ {
+ image2d<value::rgb8> result;
+
+ if (0 == direction) // blue
+ {
+ image2d<value::rgb8> arg_max(histo.ncols(), histo.nslices());
+
+ for (unsigned j = 0; j < histo.ncols(); ++j)
+ for (unsigned i = 0; i < histo.nslices(); ++i)
+ {
+ unsigned max = 0; // minimum as possible
+ signed pos = -1;
+
+ for (unsigned k = 0; k < histo.nrows(); ++k)
+ {
+ if (max <= opt::at(histo,i,j,k))
+ {
+ max = opt::at(histo,i,j,k);
+ pos = k;
+ }
+ }
+
+ opt::at(arg_max,i,j) = value::rgb8(i,j,pos);
+ }
+
+ result = arg_max;
+ }
+ else if (1 == direction) // red
+ {
+ image2d<value::rgb8> arg_max(histo.nrows(), histo.nslices());
+
+ for (unsigned j = 0; j < histo.nslices(); ++j)
+ for (unsigned i = 0; i < histo.nrows(); ++i)
+ {
+ unsigned max = 0; // minimum as possible
+ signed pos = -1;
+
+ for (unsigned k = 0; k < histo.ncols(); ++k)
+ {
+ if (max <= opt::at(histo,i,j,k))
+ {
+ max = opt::at(histo,i,j,k);
+ pos = k;
+ }
+ }
+
+ opt::at(arg_max,i,j) = value::rgb8(pos,i,j);
+ }
+
+ result = arg_max;
+ }
+ else // 2 == direction // green
+ {
+ image2d<value::rgb8> arg_max(histo.nrows(), histo.ncols());
+
+ for (unsigned j = 0; j < histo.ncols(); ++j)
+ for (unsigned i = 0; i < histo.nrows(); ++i)
+ {
+ unsigned max = 0; // minimum as possible
+ signed pos = -1;
+
+ for (unsigned k = 0; k < histo.nslices(); ++k)
+ {
+ if (max <= opt::at(histo,i,j,k))
+ {
+ max = opt::at(histo,i,j,k);
+ pos = k;
+ }
+ }
+
+ // FIXME ... how to fix the n of rgb
+ opt::at(arg_max,i,j) = value::rgb8(i,pos,j);
+ }
+
+ result = arg_max;
+ }
+
+ return result;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
--
1.5.6.5
1
0
* green/doc/annotating: New directory.
* green/doc/annotating/class.txt: New hierarchy description.
* green/doc/annotating/testMillet2008.txt: New result interpretations.
* green/doc/annotating/syntheseMillet2008.txt: New feature extractions.
* green/demo/annotating/class.txt: Remove this obsolete file.
---
milena/sandbox/ChangeLog | 10 +
milena/sandbox/green/demo/annotating/class.txt | 33 ---
milena/sandbox/green/doc/annotating/class.txt | 42 +++
.../green/doc/annotating/syntheseMillet2008.txt | 283 ++++++++++++++++++++
milena/sandbox/green/doc/annotating/testMillet2008 | 69 +++++
5 files changed, 404 insertions(+), 33 deletions(-)
delete mode 100644 milena/sandbox/green/demo/annotating/class.txt
create mode 100644 milena/sandbox/green/doc/annotating/class.txt
create mode 100644 milena/sandbox/green/doc/annotating/syntheseMillet2008.txt
create mode 100644 milena/sandbox/green/doc/annotating/testMillet2008
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index ffbc6e3..2fecbe3 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,3 +1,13 @@
+2009-12-16 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
+ Group Millet2008 documentation files.
+
+ * green/doc/annotating: New directory.
+ * green/doc/annotating/class.txt: New hierarchy description.
+ * green/doc/annotating/testMillet2008.txt: New result interpretations.
+ * green/doc/annotating/syntheseMillet2008.txt: New feature extractions.
+ * green/demo/annotating/class.txt: Remove this obsolete file.
+
2009-12-16 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
Correct typo into directories.
diff --git a/milena/sandbox/green/demo/annotating/class.txt b/milena/sandbox/green/demo/annotating/class.txt
deleted file mode 100644
index ec7e92e..0000000
--- a/milena/sandbox/green/demo/annotating/class.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-Dans scribo les classes de documents sont:
-
-- image seule (photo)
-- courrier manuscrit
-- courrier dactylographié
-- facture ou feuille organisée sous forme de tableau
-- article de journal
-- document composite
-- infographie (logo, carte, dessin vectoriel)
-- slide (copie d'écran ou sauvegarde au format image)
-
-
-Où se situent les faxes ?
-
-
-Description d'un fax:
-- ratio l/L assimilable à du A4 ou US Letter
-- nombre de couleurs très petit, < 1000
-- plutôt du N & B, mais quelques faxes sont en couleurs
-- généralement un % élevé de blanc (la page vierge)
-
-
-Description d'un article de journal:
-- nombre élevés de couleurs (> 10 000) en général
-- quelques articles de conférences autour de 5000
-
-
-Description des photos:
-- un nombre très élevé de couleurs
-- ratio non A4, non US Letter
-
-
-
diff --git a/milena/sandbox/green/doc/annotating/class.txt b/milena/sandbox/green/doc/annotating/class.txt
new file mode 100644
index 0000000..0fa5cf9
--- /dev/null
+++ b/milena/sandbox/green/doc/annotating/class.txt
@@ -0,0 +1,42 @@
+Dans scribo les classes de documents sont:
+
+- image seule (photo)
+- courrier manuscrit
+- courrier dactylographié
+- facture ou feuille organisée sous forme de tableau
+- article de journal
+- document composite
+- infographie (logo, carte, dessin vectoriel)
+- slide (copie d'écran ou sauvegarde au format image)
+
+Le problème avec cette hiérarchie c'est quelle induit une connaissance
+fonctionnelle des images traitées et que les extracteurs de primitives font
+plutôt ressortir des informations relatives à la nature de l'image.
+
+Par exemple, les slides peuvent contenir aussi bien du texte, que des photos
+ou des cliparts. C'est une forme de "composite" par définition.
+
+Où se situent les faxes ?
+
+
+Description d'un fax:
+- ratio l/L assimilable à du A4 ou US Letter
+- nombre de couleurs très petit, < 1000
+- plutôt du N & B, mais quelques faxes sont en couleurs
+- généralement un % élevé de blanc (la page vierge)
+
+
+Description d'un article de journal:
+- nombre élevés de couleurs (> 10 000) en général
+- quelques articles de conférences autour de 5000
+
+
+Description des photos:
+- un nombre très élevé de couleurs
+- ratio non A4, non US Letter
+
+
+Google hiérarchie:
+- line drawing
+- clipart
+- photo
diff --git a/milena/sandbox/green/doc/annotating/syntheseMillet2008.txt b/milena/sandbox/green/doc/annotating/syntheseMillet2008.txt
new file mode 100644
index 0000000..b7b3648
--- /dev/null
+++ b/milena/sandbox/green/doc/annotating/syntheseMillet2008.txt
@@ -0,0 +1,283 @@
+
+Millet utilise un certain nombre de descripteurs (p 65, Chapitre 3)
+pour l'annotation automatique. Son objectif est de formuler une
+annotation automatique simple à partir de descripteurs de bas niveaux
+qui permettent de réaliser l'opération en moins de 10 secondes.
+
+L'auteur présente dans le chapitre 4, p 77 l'arbre de classification
+et l'utilisation précise qu'il fait de ces descripteurs.
+
+
+Reconnaissance des images de clipart versus photographies
+Reconnaissance des images Noir & Blanc versus Couleur
+Reconnaissance Interieur versus Exterieur
+Autre reconnaissance cartes, photos, peintures.
+
+
+ /---------Image------------\
+ | |
+ v v
+ /-------+------+-------\ /-------+----------\
+ | | | | | | |
+ v v | v v v v
+Carte Clipart | Peinture Couleur N&B N&B colorisé
+ |
+ v
+ /----Photo----------\
+ | |
+ v |
+ /----------\ |
+ | | |
+ v | v
+Intérieur | Visages
+ |
+ v
+ /-----Extérieur------\
+ | |
+ v v
+ /-----\ /-----\
+ | | | |
+ v v v v
+Jour Nuit Nature Urbain
+
+
+Note:
+-----
+Lorsque d'un concept, on part de sa droite et de sa gauche, il s'agit en fait
+de tests différents effectués en parallèles (ex.: Image, Photo, Extérieur).
+
+Lorsqu'on aboutit à une bifurcation et qu'il ne s'agit pas d'un concept, cela
+correspond à un seul test dont les résultats sont répartis dans des classes
+différentes.
+
+Fax
+Magazine
+
+
+
+ANNEXE 1 : SYNTHESE DESCRIPTEURS MILLET
+=======================================
+
+* RGB-64
+--------
+Chaque composante est quantifiée sur 4 valeurs (4x4x4 = 64), puis on construit
+l'histogramme à 64 composantes.
+
+
+* TSVal
+-------
+A partir de l'espace RGB d'origine, on effectue
+la transformation. Attention les composantes ne sont pas quantifiées
+de la même manière (18 valeurs pour la teinte [17 + 1 pour le
+négatif], Val et S sont quantifiées sur 3 valeurs
+chacunes. L'histogramme obtenu dans cet espace contiendra 162
+composantes.
+
+Val = max(R,G,B)
+S = [max(R,G,B) - min(R,G,B)] / max(R,G,B)
+
+Si R = max(R,G,B)
+Alors T = 60 * (G-B) / [max(R,G,B) - min(R,G,B)]
+
+Si G = max(R,G,B)
+Alors T = 60 * (2 + (B-R) / [max(R,G,B) - min(R,G,B)])
+
+Si B = max(R,G,B)
+Alors T = 60 * (4 + (R-G) / [max(R,G,B) - min(R,G,B)])
+
+
+* RGB-64-9
+----------
+L'image est décomposée en 9 sous images identiques, puis on applique le
+descripteur RGB-64. L'histogramme obtenu est la concaténation des 9
+histogrammes soit un histogramme résultant à 576 composantes.
+
+
+* BIC
+-----
+L'image est quantifiée en 216 couleurs (RGB-216) 6 valeurs par couleur. On
+distingue ensuite les pixels du bord des pixels intérieurs. Les pixels
+intérieurs ont la même couleur que leurs 4-voisins. Un histogramme est crée
+pour chaque groupe de pixels. Puis on concatène
+les histogrammes en un seul de 432 composantes.
+
+
+* LEP
+-----
+On construit une image de gradient avec un sobel 3x3, puis cette image est
+seuillée à 100 et devient donc binaire. On étiquette les configurations
+obtenues avec un masque 3x3 classique (convolution). Il existe 2^9
+configurations possibles. On construit alors un histogramme à 512 composantes.
+
+masque de convolution pour l'identification de la configuration:
+001 002 004
+008 256 016
+032 064 128
+
+
+* GABOR
+-------
+Très coûteux, la réponse de 24 filtres sur une image 300x300 est de l'ordre de
+ 1s. On utilise ici des filtres de taille 8x8.
+
+F(x,y) = [1 / (2 PI sigma_x sigma_y)]
+ * exp[(-1/2)(x^2/sigma_x^2 + y^2/sigma_y^2)] * exp[j2 PI Wx]
+
+sigma_x et sigma_y sont des paramètres d'échelles.
+W permet de changer l'orientation.
+
+Il existe une formule pour trouver les coefficients des filtres une fois que
+l'on a déterminé le nombre d'orientations et d'échelles utilisées. On ne
+retiendra, en sortie de filtre, que la variance et l'énergie. L'auteur
+préconise d'utiliser 6 directions et 4 échelles.
+
+
+--------------GABOR---------MATLAB----------------------------------------------
+function gb=gabor_fn(sigma,theta,lambda,psi,gamma)
+
+sigma_x = sigma;
+sigma_y = sigma/gamma;
+
+% Bounding box
+nstds = 3;
+xmax = max(abs(nstds*sigma_x*cos(theta)),abs(nstds*sigma_y*sin(theta)));
+xmax = ceil(max(1,xmax));
+ymax = max(abs(nstds*sigma_x*sin(theta)),abs(nstds*sigma_y*cos(theta)));
+ymax = ceil(max(1,ymax));
+xmin = -xmax; ymin = -ymax;
+[x,y] = meshgrid(xmin:xmax,ymin:ymax);
+
+% Rotation
+x_theta=x*cos(theta)+y*sin(theta);
+y_theta=-x*sin(theta)+y*cos(theta);
+
+gb=exp(-.5*(x_theta.^2/sigma_x^2+y_theta.^2/sigma_y^2)).*cos(2*pi/lambda*x_theta+psi);
+
+http://matlabserver.cs.rug.nl/cgi-bin/matweb.exe
+Gabor Filters. Tech. rep., 2002.
+--------------GABOR---------MATLAB----------------------------------------------
+
+
+* PROJECTION
+------------
+L'image est redimentionnée en 100x100. Un coup de Sobel 3x3, puis une
+binarisation avec s=100. On considère les moitiées verticales puis
+horizontales. Pour les moitiées verticales, on réalise la somme sur chacune
+des lignes, on obtient alors un vecteur de taille 100.
+Pour les moitiées horizontales, on réalise les sommes des colonnes. On obtient
+alors un vecteur taille 100. Les 4 sous vecteurs obtenus peuvent être
+concaténés pour former un unique descipteur de 400 composantes.
+
+
+
+ANNEXE 2 : SYNTHESE CLASSIFICATION MILLET
+=========================================
+
+
+* Reconnaissance des images de clipart versus photographies
+-----------------------------------------------------------
+
+Construire l'histogramme de l'image, éliminer toutes les couleurs peu
+représentées et ensuite les comptées. Moins de 50 couleurs / 256, c'est un
+clipart, plus de 150 / 256 c'est une photographie. Entre les deux, indécision.
+D'après l'auteur, le test n'est pas complètement fiable et peu être évincé, tout
+dépend de la qualité de la compression des cliparts.
+
+Diviser l'image en 16 imagettes (4x4), calculer la suite pour chaque imagette.
+Trouver le maxima de l'histogramme (noté p)/ p = argmax H(x), x in [0,255].
+Puis on calcule un sigma autour du pic.
+
+sigma^2 = Sum(p-1,p-5) r(x) pour p > 250
+sigma^2 = Sum(p+1,p+5) r(x) pour p < 005
+sigma^2 = (1/2) (Sum(p-1,p-5) r(x) + Sum(p+1,p+5) r(x)) pour les autres p
+
+r(x) = ((H(x)/H(p)) * (x-p))^2
+
+
+Le descripteur de l'image entière est alors le maximum des 16 sigma^2. Si le
+pic est resseré, c'est plutôt un clipart (< 5), sinon plutôt une photographie
+(> 40). Le seuil est fixé à 15.
+
+
+
+* Reconnaissance des images Noir & Blanc versus Couleur
+-------------------------------------------------------
+
+Achromatisme (en passant par TSVal)
+
+si |R - G| < s
+et si |R - B| < s alors R ~ G ~ B
+et si |G - B| < s
+
+==> T = -1
+==> Val = (R + G + B)/3
+
+L'auteur propose s = 0,03
+
+Une image est dite Noir & Blanc (donc Achromatique) si + de 99% des pixels le
+sont. Le test peut être appliqué aux images étiquetées comme des cliparts, ou
+des photographies.
+
+
+Faible saturation:
+
+On établit l'histogramme de la saturation de l'image (0 à 255). Si plus de 95%
+des pixels sont inférieurs à une saturation de 100, alors l'image est faiblement
+saturée. Ce test ne s'applique sur les photographies, surtout pas aux cliparts.
+
+
+Dominance de la teinte (image jaunie):
+
+On construit l'histogramme de la teinte (0 à 255). On localise le maximum de
+l'histogramme. Si + de 95% des pixels ont une distance < 20 du maximum, alors
+l'image est considérée comme Noir & Blanc et on peut donner sa teinte dominante.
+De plus il faut qu'au moins 50% des pixels soient faiblement saturés.
+
+T = -1 Achromatisme
+ 0 <= T < 14 Rouge
+ 14 <= T < 29 Orange
+ 29 <= T < 45 Jaune
+ 45 <= T < 113 Vert
+113 <= T < 149 Cyan
+149 <= T < 205 Bleu
+205 <= T < 235 Violet
+235 <= T < 242 Rose, Magenta
+242 <= T < 255 Rouge
+
+
+ 0 <= V < 82 Noir
+ 82 <= V < 179 Gris
+179 <= V < 255 Blanc
+
+
+Pour un pixel (S, Val)
+si |184 - S| + |65 - Val| < |255 - S| + |125 - Val| alors marron sinon orange.
+
+Et encore
+si la teinte est jaune et Val < 80 alors vert sinon jaune.
+
+
+
+* Reconnaissance Interieur versus Exterieur
+-------------------------------------------
+
+Utilisation des descripteurs LEP et RGB-64. Expérience avec un kpp ~ 80%. Puis
+expérimentation avec un SVM ~ 90% de réussite. Finalement, inclusion dans le SVM
+de LEP, RGB-64, TSVal-125, projection, Bic, Gabor.
+
+
+
+
+* Localisation des visages
+--------------------------
+
+Une semaine d'apprentissage, 5 secondes pour leur localisation. Je ne suis pas
+sûr que cette méthode soit pertinente pour notre contexte applicatif.
+
+
+
+* Autre classification
+----------------------
+
+Utilisation de SVM et de tous les descripteurs possibles comme pour Interieur
+versus Exterieur.
diff --git a/milena/sandbox/green/doc/annotating/testMillet2008 b/milena/sandbox/green/doc/annotating/testMillet2008
new file mode 100644
index 0000000..a5cf22d
--- /dev/null
+++ b/milena/sandbox/green/doc/annotating/testMillet2008
@@ -0,0 +1,69 @@
+Dans le cadre de nos recherches, nous testons le classifieur de
+Millet2008 pour la classification des images en clipart ou en
+photographies. Deux tests sont proposés, le premier est basé sur le
+nombre de couleurs de l'image après un seuillage de l'histogramme de
+façon à éliminer les couleurs de faible contribution; le second test
+consiste à extraire le pic de l'histogramme et à mesurer une
+"variance" normalisée autour de ce pic. Le premier test part du
+principe que les photographies possèdent de très nombreuses couleurs,
+tandis que les cliparts n'en ont que quelques unes. Le test n'est pas
+toujours vérifié. Le second test s'intéresse à la nature de
+l'histogramme. L'idée étant de montrer qu'un histogramme continu, donc
+avec une "variance" élevé autour du pic principal est plutôt
+représentatif des phtotographies, alors qu'une "variance" faible tient
+d'avantage du clipart (peu de couleurs, couleurs isolées). Selon
+l'auteur, ce second test donne de très bon résultats. Il peut être
+affiné en divisant l'image en 16 sous parties et en analysant chacune
+des imagettes avec la technique décrite ci-dessus. Dans ce cas, la
+"variance" de l'image est le max des "variances" des imagettes. Les
+repères suivnt sont donnés par l'auteur, "variance" < 5 pour les
+clipart et "variance" ~ 40 pour les photographies (seuil fixé à 15).
+
+
+Test A (Nombre de couleurs dans l'histogramme):
+-----------------------------------------------
+
+
+Test B ("Variance" autour du pic principal):
+--------------------------------------------
+
+bill: Les images de factures contiennent un ensemble d'informations
+groupés sous forme de tableau. Il peut y avoir plusieurs tableaux,
+visibles ou non. Pour la pupart des histogrammes observés,
+l'information en niveau de gris montre un grand pic blanc sans
+voisinage ou avec un voisinage de taille insignifiante. Toutes les
+factures devraient être classées comme des cliparts sauf exception.
+
+deux images sortent du lot:
+- bill17.ppm => 12.7828
+- bill23.ppm => 17.2565
+
+bill17 contient des dégradés qui viennent épaissir le pic blanc, du
+coup le voisinage autour du pic devient plus important.
+
+bill23 contient un logo et une image de fond en transparence sur le
+tableau. Par ailleurs, certains textes sont sur un fond
+composite. Tous ces éléments viennent épaissir le pic blanc.
+
+Résultat : 29 images / 30 passent le test
+
+
+photo: Les images de l'AFP ont la particularité d'être cadré serré
+pour faire ressortir un élément clé de la scène photographiée. On
+s'attend, d'après l'auteur à obtenir une "variance" proche de 40 (seuil ~ 15).
+
+5 vrai positifs:
+- photo01 ==> 42.9224
+- photo10 ==> 48.0298
+- photo25 ==> 33.6833
+- photo27 ==> 42.9025
+- photo28 ==> 43.5689
+
+des scores faibles:
+-
+
+
+
+
+Test C ("Variance" sur les 16 imagettes):
+-----------------------------------------
\ No newline at end of file
--
1.5.6.5
1
0
last-svn-commit-15-g047c908 Introduce the local deviation operator (Millet2008) which subdivise the image in 16 parts.
by green 24 Feb '10
by green 24 Feb '10
24 Feb '10
* green/demo/annotating/stddev_color_16: New directory.
* green/demo/annotating/stddev_color_16/Makefile.am: New Makefile.
* green/demo/annotating/stddev_color_16/stddev_color_16.cc: New demo.
---
milena/sandbox/ChangeLog | 9 +
.../{bic => stddev_color_16}/Makefile.am | 0
.../annotating/stddev_color_16/stddev_color_16.cc | 178 ++++++++++++++++++++
3 files changed, 187 insertions(+), 0 deletions(-)
copy milena/sandbox/green/demo/annotating/{bic => stddev_color_16}/Makefile.am (100%)
create mode 100644 milena/sandbox/green/demo/annotating/stddev_color_16/stddev_color_16.cc
diff --git a/milena/sandbox/ChangeLog b/milena/sandbox/ChangeLog
index 2fecbe3..bc8efb2 100644
--- a/milena/sandbox/ChangeLog
+++ b/milena/sandbox/ChangeLog
@@ -1,5 +1,14 @@
2009-12-16 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+ Introduce the local deviation operator (Millet2008) which
+ subdivise the image in 16 parts.
+
+ * green/demo/annotating/stddev_color_16: New directory.
+ * green/demo/annotating/stddev_color_16/Makefile.am: New Makefile.
+ * green/demo/annotating/stddev_color_16/stddev_color_16.cc: New demo.
+
+2009-12-16 Yann Jacquelet <jacquelet(a)lrde.epita.fr>
+
Group Millet2008 documentation files.
* green/doc/annotating: New directory.
diff --git a/milena/sandbox/green/demo/annotating/bic/Makefile.am b/milena/sandbox/green/demo/annotating/stddev_color_16/Makefile.am
similarity index 100%
copy from milena/sandbox/green/demo/annotating/bic/Makefile.am
copy to milena/sandbox/green/demo/annotating/stddev_color_16/Makefile.am
diff --git a/milena/sandbox/green/demo/annotating/stddev_color_16/stddev_color_16.cc b/milena/sandbox/green/demo/annotating/stddev_color_16/stddev_color_16.cc
new file mode 100644
index 0000000..5e95c76
--- /dev/null
+++ b/milena/sandbox/green/demo/annotating/stddev_color_16/stddev_color_16.cc
@@ -0,0 +1,178 @@
+// COMPUTING THE STDEV OF THE COLORS
+
+#include <iostream>
+#include <sstream>
+
+#include <mln/img_path.hh>
+
+#include <mln/accu/max_site.hh>
+#include <mln/accu/stat/histo1d.hh>
+
+#include <mln/core/macros.hh>
+#include <mln/core/image/image1d.hh>
+#include <mln/core/image/image2d.hh>
+#include <mln/core/image/image3d.hh>
+
+#include <mln/debug/println.hh>
+
+#include <mln/data/compute.hh>
+#include <mln/data/fill.hh>
+#include <mln/data/transform.hh>
+#include <mln/data/paste.hh>
+
+#include <mln/fun/v2v/rgb8_to_int_u8.hh>
+
+#include <mln/io/ppm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/plot/save_image_sh.hh>
+
+#include <mln/math/sqr.hh>
+
+#include <mln/opt/at.hh>
+
+#include <mln/value/rgb8.hh>
+#include <mln/value/int_u.hh>
+
+
+float r(short p, unsigned histo_p, short x, unsigned histo_x)
+{
+ float result = mln::math::sqr(((float)histo_x / histo_p) * (x-p));
+
+ return result;
+}
+
+unsigned stddev_color(mln::image2d<mln::value::int_u8> input_int_u8,
+ const char *name_histo,
+ const char *name_image)
+{
+ typedef mln::point1d t_point1d;
+ typedef mln::value::rgb8 t_rgb8;
+ typedef mln::value::int_u8 t_int_u8;
+ typedef mln::image2d<t_rgb8> t_image2d_rgb8;
+ typedef mln::image2d<t_int_u8> t_image2d_int_u8;
+ typedef mln::image1d<unsigned> t_histo1d;
+ typedef mln::fun::v2v::rgb8_to_int_u8 t_rgb8_to_int_u8;
+ typedef mln::accu::meta::stat::histo1d t_histo1d_fun;
+ typedef mln::accu::max_site<t_histo1d> t_max_site_fun;
+
+ t_histo1d histo;
+
+ std::cout << "histo : " << name_histo << std::endl;
+ std::cout << "image : " << name_image << std::endl;
+
+ histo = mln::data::compute(t_histo1d_fun(), input_int_u8);
+
+ mln::io::pgm::save(input_int_u8, name_image);
+ mln::io::plot::save_image_sh(histo, name_histo);
+ mln::debug::println(histo);
+
+ // Find the peak of the histogram
+ unsigned v_max = mln::opt::at(histo, 0);
+ short p_max = 0;
+
+ mln_piter_(t_histo1d) p(histo.domain());
+
+ for_all(p)
+ {
+ if (v_max < histo(p))
+ {
+ v_max = histo(p);
+ p_max = p.ind();
+ }
+ }
+
+ // Compute the specific stddev
+
+ float stddev_low = 0.0;
+ float stddev_up = 0.0;
+ float stddev = 0.0;
+
+ if (250 > p_max)
+ for (short i = p_max+1; i < p_max+6; ++i)
+ stddev_up += r(p_max, mln::opt::at(histo,p_max),
+ i, mln::opt::at(histo,i));
+
+ if (5 < p_max)
+ for (short i = p_max-1; i > p_max-6; --i)
+ stddev_low += r(p_max, mln::opt::at(histo,p_max),
+ i, mln::opt::at(histo,i));
+
+ stddev = (250 < p_max)? stddev_low : (5 > p_max)? stddev_up :
+ (stddev_low + stddev_up)/2;
+
+ std::cout << "max_site : " << p_max << std::endl;
+ std::cout << "h(max_site) : " << v_max << std::endl;
+ std::cout << "stddev_up : " << stddev_up << std::endl;
+ std::cout << "stddev_low : " << stddev_low << std::endl;
+ std::cout << "stddev : " << stddev << std::endl;
+
+ return 0;
+}
+
+unsigned stddev_color_16(const std::string& image)
+{
+ typedef mln::point1d t_point1d;
+ typedef mln::value::rgb8 t_rgb8;
+ typedef mln::value::int_u8 t_int_u8;
+ typedef mln::image2d<t_rgb8> t_image2d_rgb8;
+ typedef mln::image2d<t_int_u8> t_image2d_int_u8;
+ typedef mln::image1d<unsigned> t_histo1d;
+ typedef mln::fun::v2v::rgb8_to_int_u8 t_rgb8_to_int_u8;
+ typedef mln::accu::meta::stat::histo1d t_histo1d_fun;
+ typedef mln::accu::max_site<t_histo1d> t_max_site_fun;
+
+ t_image2d_rgb8 input_rgb8;
+ t_image2d_int_u8 input_int_u8;
+
+ mln::io::ppm::load(input_rgb8, image.c_str());
+ input_int_u8 = mln::data::transform(input_rgb8, t_rgb8_to_int_u8());
+
+ // IMAGE SPLITTING PHASE
+ mln::box2d domain = input_int_u8.domain();
+ mln::point2d pmin = domain.pmin();
+ mln::point2d pmax = domain.pmax();
+
+ unsigned sz_row = (pmax.row() - pmin.row())/ 4;
+ unsigned sz_col = (pmax.col() - pmin.col())/ 4;
+
+ std::cout << domain << std::endl;
+
+ // Divide the domain in nine sub-domains.
+ for (unsigned i = 0; i < 4; ++i)
+ for (unsigned j = 0; j < 4; ++j)
+ {
+ mln::point2d min(pmin.row()+sz_row*i,pmin.col()+sz_col*j);
+ mln::point2d max(pmin.row()+sz_row*(i+1),pmin.col()+sz_col*(j+1));
+ mln::box2d dom(min,max);
+
+ std::cout << dom << std::endl;
+
+ // Save it
+ t_image2d_int_u8 input_1o16_int_u8(dom);
+ std::ostringstream name_histo("");
+ std::ostringstream name_image("");
+
+ name_histo << "histo" << i << "_" << j << ".sh";
+ name_image << "image" << i << "_" << j << ".ppm";
+
+ mln::data::paste(input_int_u8 | dom, input_1o16_int_u8);
+
+ stddev_color(input_1o16_int_u8,
+ name_histo.str().c_str(),
+ name_image.str().c_str());
+ }
+
+ return 0;
+}
+
+
+int main()
+{
+// unsigned val = stddev_color_16(ANNOTATING_PHOTO_IMG_PATH "/photo01.ppm");
+ unsigned val = stddev_color_16(ANNOTATING_LOGO_IMG_PATH "/logo06.ppm");
+
+// std::cout << "nb color : " << val << std::endl;
+
+ return 0;
+}
+
--
1.5.6.5
1
0