Olena-patches
Threads by month
- ----- 2025 -----
- 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

03 May '11
* tests/binarization/Makefile.am: Add new targets.
* tests/binarization/sauvola.cc,
* tests/binarization/sauvola_ms.cc: New.
* tests/binarization/sauvola.ref.pbm,
* tests/binarization/sauvola_ms.ref.pbm: New test data.
* tests/data.hh.in: Add a new path.
---
scribo/ChangeLog | 14 +++++++++
scribo/tests/binarization/Makefile.am | 6 +++-
.../tests/binarization/sauvola.cc | 29 ++++++++++---------
scribo/tests/binarization/sauvola.ref.pbm | Bin 0 -> 32884 bytes
.../tests/binarization/sauvola_ms.cc | 30 ++++++++++---------
scribo/tests/binarization/sauvola_ms.ref.pbm | Bin 0 -> 32884 bytes
scribo/tests/data.hh.in | 3 ++
7 files changed, 53 insertions(+), 29 deletions(-)
copy milena/tests/labeling/fill_holes.cc => scribo/tests/binarization/sauvola.cc (74%)
create mode 100644 scribo/tests/binarization/sauvola.ref.pbm
copy milena/tests/labeling/fill_holes.cc => scribo/tests/binarization/sauvola_ms.cc (72%)
create mode 100644 scribo/tests/binarization/sauvola_ms.ref.pbm
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 0235162..423c9ac 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,17 @@
+2011-04-07 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add new tests for Sauvola algorithms.
+
+ * tests/binarization/Makefile.am: Add new targets.
+
+ * tests/binarization/sauvola.cc,
+ * tests/binarization/sauvola_ms.cc: New.
+
+ * tests/binarization/sauvola.ref.pbm,
+ * tests/binarization/sauvola_ms.ref.pbm: New test data.
+
+ * tests/data.hh.in: Add a new path.
+
2011-04-06 Guillaume Lazzara <z(a)lrde.epita.fr>
* scribo/filter/object_groups_size_ratio.hh: Fix compilation.
diff --git a/scribo/tests/binarization/Makefile.am b/scribo/tests/binarization/Makefile.am
index c845b43..b894f5a 100644
--- a/scribo/tests/binarization/Makefile.am
+++ b/scribo/tests/binarization/Makefile.am
@@ -21,10 +21,14 @@ include $(top_srcdir)/scribo/tests/tests.mk
check_PROGRAMS = \
global_threshold \
- local_threshold
+ local_threshold \
+ sauvola \
+ sauvola_ms
global_threshold_SOURCES = global_threshold.cc
local_threshold_SOURCES = local_threshold.cc
+sauvola_SOURCES = sauvola.cc
+sauvola_ms_SOURCES = sauvola_ms.cc
TESTS = $(check_PROGRAMS)
diff --git a/milena/tests/labeling/fill_holes.cc b/scribo/tests/binarization/sauvola.cc
similarity index 74%
copy from milena/tests/labeling/fill_holes.cc
copy to scribo/tests/binarization/sauvola.cc
index bbf55b8..33eb59f 100644
--- a/milena/tests/labeling/fill_holes.cc
+++ b/scribo/tests/binarization/sauvola.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -24,28 +24,29 @@
// executable file might be covered by the GNU General Public License.
/// \file
-///
-/// Test of labeling::fill_holes.
-///
-/// \fixme Write a Test!
#include <mln/core/image/image2d.hh>
+#include <mln/data/compare.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/io/pgm/load.hh>
#include <mln/io/pbm/load.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/labeling/fill_holes.hh>
-#include <mln/value/label_8.hh>
-
-#include <mln/debug/println.hh>
#include <mln/io/pbm/save.hh>
-#include "tests/data.hh"
+#include <scribo/binarization/sauvola.hh>
+#include "tests/data.hh"
int main()
{
using namespace mln;
- image2d<bool> pic = io::pbm::load(MLN_IMG_DIR "/picasso.pbm");
- value::label_8 n;
- image2d<bool> out = labeling::fill_holes(pic, c4(), n);
+ image2d<value::int_u8> input;
+ io::pgm::load(input, MILENA_IMG_DIR "/lena.pgm");
+
+ image2d<bool> bin = scribo::binarization::sauvola(input, 101);
+
+ image2d<bool> ref;
+ io::pbm::load(ref, SCRIBO_TESTS_DIR "binarization/sauvola.ref.pbm");
+
+ mln_assertion(bin == ref);
}
diff --git a/scribo/tests/binarization/sauvola.ref.pbm b/scribo/tests/binarization/sauvola.ref.pbm
new file mode 100644
index 0000000000000000000000000000000000000000..6730ad45546f12a6e4dd166c41395689594bc2d1
GIT binary patch
literal 32884
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
Yn;N{gq35|3-mI*f&idB>-Ut8x0P<7s-v9sr
literal 0
HcmV?d00001
diff --git a/milena/tests/labeling/fill_holes.cc b/scribo/tests/binarization/sauvola_ms.cc
similarity index 72%
copy from milena/tests/labeling/fill_holes.cc
copy to scribo/tests/binarization/sauvola_ms.cc
index bbf55b8..31d0f96 100644
--- a/milena/tests/labeling/fill_holes.cc
+++ b/scribo/tests/binarization/sauvola_ms.cc
@@ -1,4 +1,4 @@
-// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+// Copyright (C) 2011 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -24,28 +24,30 @@
// executable file might be covered by the GNU General Public License.
/// \file
-///
-/// Test of labeling::fill_holes.
-///
-/// \fixme Write a Test!
#include <mln/core/image/image2d.hh>
+#include <mln/data/compare.hh>
+#include <mln/value/int_u8.hh>
+#include <mln/io/pgm/load.hh>
#include <mln/io/pbm/load.hh>
-#include <mln/core/alias/neighb2d.hh>
-#include <mln/labeling/fill_holes.hh>
-#include <mln/value/label_8.hh>
-
-#include <mln/debug/println.hh>
#include <mln/io/pbm/save.hh>
-#include "tests/data.hh"
+#include <scribo/binarization/sauvola_ms.hh>
+#include "tests/data.hh"
int main()
{
using namespace mln;
- image2d<bool> pic = io::pbm::load(MLN_IMG_DIR "/picasso.pbm");
- value::label_8 n;
- image2d<bool> out = labeling::fill_holes(pic, c4(), n);
+ image2d<value::int_u8> input;
+ io::pgm::load(input, MILENA_IMG_DIR "/lena.pgm");
+
+ image2d<bool> bin = scribo::binarization::sauvola_ms(input, 101, 2);
+
+ io::pbm::save(bin, "res.pbm");
+ image2d<bool> ref;
+ io::pbm::load(ref, SCRIBO_TESTS_DIR "/binarization/sauvola_ms.ref.pbm");
+
+ mln_assertion(bin == ref);
}
diff --git a/scribo/tests/binarization/sauvola_ms.ref.pbm b/scribo/tests/binarization/sauvola_ms.ref.pbm
new file mode 100644
index 0000000000000000000000000000000000000000..685efe7175c19cbcabd696fe357bd4a69401db06
GIT binary patch
literal 32884
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
literal 0
HcmV?d00001
diff --git a/scribo/tests/data.hh.in b/scribo/tests/data.hh.in
index 501fbea..5966fba 100644
--- a/scribo/tests/data.hh.in
+++ b/scribo/tests/data.hh.in
@@ -40,4 +40,7 @@
/// \brief The absolute path to the test directory of Scribo.
# define SCRIBO_TESTS_DIR "@abs_top_srcdir@/scribo/tests/"
+/// \brief The absolute path to the img directory of Milena.
+# define MILENA_IMG_DIR "@abs_top_srcdir@/milena/img"
+
#endif // ! SCRIBO_TESTS_DATA_HH
--
1.5.6.5
1
0

03 May '11
scribo/tests/Makefile.am,
scribo/tests/binarization/Makefile.am,
scribo/tests/primitive/extract/Makefile.am: Here.
---
scribo/ChangeLog | 8 ++++++++
scribo/tests/Makefile.am | 5 +++++
scribo/tests/binarization/Makefile.am | 7 ++++++-
scribo/tests/primitive/extract/Makefile.am | 6 ++++++
4 files changed, 25 insertions(+), 1 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 423c9ac..8d95b3a 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,13 @@
2011-04-07 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add test data in EXTRA_DIST.
+
+ scribo/tests/Makefile.am,
+ scribo/tests/binarization/Makefile.am,
+ scribo/tests/primitive/extract/Makefile.am: Here.
+
+2011-04-07 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Add new tests for Sauvola algorithms.
* tests/binarization/Makefile.am: Add new targets.
diff --git a/scribo/tests/Makefile.am b/scribo/tests/Makefile.am
index 1f227b7..706338f 100644
--- a/scribo/tests/Makefile.am
+++ b/scribo/tests/Makefile.am
@@ -18,6 +18,11 @@
include $(srcdir)/tests.mk
EXTRA_DIST = \
+ img/alignment_1.pbm \
+ img/alignment_2.pbm \
+ img/alignment_3.pbm \
+ img/alignment_4.pbm \
+ img/phillip.ppm \
img/pixels.pbm \
img/table_to_be_repaired.pbm \
img/table_to_be_repaired2.pbm \
diff --git a/scribo/tests/binarization/Makefile.am b/scribo/tests/binarization/Makefile.am
index b894f5a..500d708 100644
--- a/scribo/tests/binarization/Makefile.am
+++ b/scribo/tests/binarization/Makefile.am
@@ -1,4 +1,5 @@
-# Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE).
+# Copyright (C) 2009, 2011 EPITA Research and Development Laboratory
+# (LRDE).
#
# This file is part of Olena.
#
@@ -19,6 +20,10 @@
include $(top_srcdir)/scribo/tests/tests.mk
+EXTRA_DIST = \
+ sauvola_ms.ref.pbm \
+ sauvola.ref.pbm
+
check_PROGRAMS = \
global_threshold \
local_threshold \
diff --git a/scribo/tests/primitive/extract/Makefile.am b/scribo/tests/primitive/extract/Makefile.am
index 97eb43f..33d3a96 100644
--- a/scribo/tests/primitive/extract/Makefile.am
+++ b/scribo/tests/primitive/extract/Makefile.am
@@ -16,6 +16,12 @@
include $(top_srcdir)/scribo/tests/tests.mk
+EXTRA_DIST = \
+ alignment_1.ref.png \
+ alignment_2.ref.png \
+ alignment_3.ref.png \
+ alignment_4.ref.png
+
check_PROGRAMS =
if HAVE_MAGICKXX
--
1.5.6.5
1
0

03 May '11
* tests/img/alignment_1.png,
* tests/img/alignment_2.png,
* tests/img/alignment_3.png,
* tests/img/alignment_4.png: Rename and convert as...
* tests/img/alignment_1.pbm,
* tests/img/alignment_2.pbm,
* tests/img/alignment_3.pbm,
* tests/img/alignment_4.pbm: ... this.
* tests/primitive/extract/alignments.cc: Update loaded image.
---
scribo/ChangeLog | 16 ++++++++++++++++
scribo/tests/img/alignment_1.pbm | Bin 0 -> 12167 bytes
scribo/tests/img/alignment_1.png | Bin 3145 -> 0 bytes
scribo/tests/img/alignment_2.pbm | Bin 0 -> 12167 bytes
scribo/tests/img/alignment_2.png | Bin 3147 -> 0 bytes
scribo/tests/img/alignment_3.pbm | Bin 0 -> 12167 bytes
scribo/tests/img/alignment_3.png | Bin 3145 -> 0 bytes
scribo/tests/img/alignment_4.pbm | Bin 0 -> 12167 bytes
scribo/tests/img/alignment_4.png | Bin 3155 -> 0 bytes
scribo/tests/primitive/extract/alignments.cc | 3 +--
10 files changed, 17 insertions(+), 2 deletions(-)
create mode 100644 scribo/tests/img/alignment_1.pbm
delete mode 100644 scribo/tests/img/alignment_1.png
create mode 100644 scribo/tests/img/alignment_2.pbm
delete mode 100644 scribo/tests/img/alignment_2.png
create mode 100644 scribo/tests/img/alignment_3.pbm
delete mode 100644 scribo/tests/img/alignment_3.png
create mode 100644 scribo/tests/img/alignment_4.pbm
delete mode 100644 scribo/tests/img/alignment_4.png
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index fa834fa..d223777 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,3 +1,19 @@
+2011-04-06 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Change test image format to pnm.
+
+ * tests/img/alignment_1.png,
+ * tests/img/alignment_2.png,
+ * tests/img/alignment_3.png,
+ * tests/img/alignment_4.png: Rename and convert as...
+
+ * tests/img/alignment_1.pbm,
+ * tests/img/alignment_2.pbm,
+ * tests/img/alignment_3.pbm,
+ * tests/img/alignment_4.pbm: ... this.
+
+ * tests/primitive/extract/alignments.cc: Update loaded image.
+
2011-04-05 Guillaume Lazzara <z(a)lrde.epita.fr>
Regen generated files.
diff --git a/scribo/tests/img/alignment_1.pbm b/scribo/tests/img/alignment_1.pbm
new file mode 100644
index 0000000000000000000000000000000000000000..41025b9771ec8522993011725fe9409858ef1bb8
GIT binary patch
literal 12167
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
SC7ApFgiE>0uuB1(A^sa0t#md3
literal 0
HcmV?d00001
diff --git a/scribo/tests/img/alignment_1.png b/scribo/tests/img/alignment_1.png
deleted file mode 100644
index f4592429963506e1c987e2b18b0969ad04a9bde0..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3145
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
diff --git a/scribo/tests/img/alignment_2.pbm b/scribo/tests/img/alignment_2.pbm
new file mode 100644
index 0000000000000000000000000000000000000000..98a3e78a54a0cb571ee129938b40aeddaa16a864
GIT binary patch
literal 12167
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
R8E-|qxp)-TD6VGm{{|v8XMX?y
literal 0
HcmV?d00001
diff --git a/scribo/tests/img/alignment_2.png b/scribo/tests/img/alignment_2.png
deleted file mode 100644
index 9c828bb44984051f862879836b2904a1176695c2..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3147
zcmV-R47Br!P)<h;3K|Lk000e1NJLTq00FcB007tl00000s}3uE00002VoOIv00G^K
z6QlqD010qNS#tmY07w7;07w8v$!k6U000Sga6xAP00FcB007tkdmpID000XJNkl<Z
zXx{DGPjBPK6#(!z9>e2<!SO9Vu%thNZe<WgbWc6DA3-_gmN3ns3}RTLDvg37-M#iu
zB>NG1EzrX#YO5TAY>zoD#tqOdP#_t@J<tdv_PrrxOQinTLXx7zPJ$Ip@y8+O?;BD8
z|BuPv(OvB5u6J}dYB!hf>hx}|)7$X|AMDsyvUZ1Sj>vdPA4fbdA#!{6fL&e95}jyt
zyj)#2tgKuz%KPB9K!CWhnN+y}3*4+O8$MJSefG8O@=H}YDgTy9W;*2b@;!1LUKY%P
zVA?sWjW5(0ZAu8`@6hQJmIGJIPUiBm5CzD&J408MpHu-?ndBPS7r+~3>ib+-DZpdK
zm4@vZU)HBo(m4g}Q!J!q7aehx1`Iqf+1z>6SD}_el?tJNe+CE4EV<M}7lR6*&JT<q
zR9^*Je2Mvy`w(+)IJ}M&#htTv4l6D5M49vVsGu88s5EoVU1y5<g{3=p+=E1?<iz_}
zzsvP*DZd4W`NelmxN^zF9`FKIJ61Vt8@^YSL3RrK&Y8Be{ZcKsc<wr4=p2?Eo?-d^
ztib)~ym`Gtj`_J`@{T0Ov~$pM+Gaw@1t)5EOnEuS6lcxy<T{On!fb0-#Dcl9vnP_u
z1&j%}=DguN=UjhK&iy0fL#SPe-$SBGdCkgY*YUWq*pgx9dM5sJZDB^=Fmr^3pJK0o
zQeLUX*cAEV4<<MOIA-4fIk?hQe@91!S~YUET<h2$qVQuQfA3CF)x*4^nAs;+H*(!@
z!iJ9(&u?At)^UAsm*1ulEvnn+gI%xT_7<Gk;4GEz?GZw8SHIOs?0R?7bl79TCR?5F
zoR~YQUov?7#a3611h=lACwQ=}I)7tyS(SQAZl3g3_agllQ*(F(*uR$(X>-rPy_`I5
zUBUg_2hBaL5oNXeu(eCy%e}XoYZo7m>n!Kc$JzbccYmF(b5-%lQgv`D1bujdH52Bc
z=^LCf`y<;tK2-ieViPlW!x_%VJeM=<zlo015ci&k?e5+;{jhIBQx97?AHkIoz8s7U
zjxcFN!)_EbCL>I?b5o9R1gc#oCd#IsCt;}3RWV8AwHz}i_I!j#$f~+hG1hs<7aj~T
z{Mg|1p^Zlr!p)sF7U!BHs&+mw!5YUk<S_<};MWfGNaI)>@~tlO7ah%<=su9kZc?^f
zjB%WRs5+yi|NU5~e(mI17h=4L?yM?LtO^Lug*$GOD>3+7a48&T`#~nAvqgt7#c9L+
zB?odU?bWWxl8?}thHI5e1~KKARwqo^B+s5@{3!!)^)4Tg<82pVd1`c>x*i6(xybnE
z)ZMAx<x_HlcD<9Ej<CJe^{#GAlJU<fhwbxcR4zl+aw)pkM_?8lmdj^?+><EkzKJCq
zJa0NMy(~soN98mvJNH*A4}tw}mSFe2=r<X>W1=icM%;9(dY8Bd-H_@l$psu7p*x6M
zE>xjOJ{FH{InVEH9bgGRao@p~B<8~ly0@Hjg}vR)H!=Zl8UNufch0Zf=)R6wp)Sd}
zzxd;7@5xpt(HRqYUhS$2jkh{s`9P-~uYR!bb@g$+{r*z8R<YrA4t1wnpI<WHIL2c`
z&GID>t#^whe!rRaMS6HT+|kK=H+LH|KQM9qzv0*q>^5BIK21Do4Vz39u6un5cw^cG
zHcKY?^(@hOQHCZQl<d;t-W&(EybLE#jl8yfD2Gi4g&f`FdB~m>U8(!y3vq*v&-hH(
zSvdS64PP<kz?fFUiG=*^KQk$YHWmZhi9Lz;Bt`<~+E{WE1)(xS-N{xs{%Pt7hKuom
zK8XW?PO?Yj#K1(pRA#D<S2~koJce$l52KjMFaVE@O(dAcA$WieRyfS2b~qo*U2x}=
z`6;Y&e2mUR$47JLgYO*I0XezaUC#4!j@n3!?h@~hq2sF^26Z>+0+-)!Aj%dUuU%=|
z`AHm~Gk2Y0ROV5%$~|toSYj)zop>*=?(fdg<2)n4p0}@)v&seZG^ui387#YWg~NKt
zuv|<)k9_KSKsUDJ;>wwe=G@X1Vr<SmLHSX9<W~;s-F5}GGanlc(qA+)?0T5rIkmG8
ziya-cGf#TlISRGWY5jK7z48$s>R<ke5ABa015MGcT?@SH;uTMPVTxq<Z}#Qzs@Wl4
zF8K4|b-}(e{tVvLk@zDz3<pQz>#IUeb&-rp=<}9~=qZ%7kXip6LWtNEI##ekJU7)N
zL1F3NUenDttY7`PVrc>^(ycRb^(SvS*zDHkxBAgi%kdrE_nhCngD_i{i)gvi6->^L
zN=Byoa|ZWGw`WhpgWQYs{iJf^x2#<Ih1m$#y~x9L>PELNGM5|H7Mq+0M?2=X*{yrQ
zDb(gypX>5tWwGX)GuQpvuCF4DeRNrkt3MuCb)*-*e$%oUu1ezbwky$%OG~-t$@9ES
zG_77(&gc>@PQ(oQ=GD)eE@Ts(h1J_VUdVwtm$(wAZSe?qWk-??OeblrAU&>hRzFAJ
z?+ZrJ0IlWuqXSx`rTYPl^+~t2WW|}!xOZn%s=q=*(FZ#5zDGOBaedf!fpg3~<`YBd
zoO0&~=puSvOv~fAHL6nNl6h5s5POp8Shz*8*mE;)uN!0KLd@5=OWH5MU1#M~l}Ayz
z)}&N9W-8~d(=A#>b!{?#wI|Ha*X75xS;&tnvv#3P%4wOeyFZK=<__<V8jq;1Ey4Sp
z>U>>(LfHkUs{H8K7(Xx^THz>&qIYtxENYkDmP>l*uXPyq)DFvqqNK`I^>9Ki?XGaj
zxxd%fNzsmTxM;xo=tUldLo3=Dw$BTUs-D;R<=v`qYj+xn0}O`}(Q<4&{-%J-vU1|{
z>u0VJ;Jwl#rk8W-NBY~=?1oK@-{eq!jN3`kmrpMXdWH;P!Rc6e2swsB`FYzN!s#)1
z^jtX16NW*$8-+r8*}Wlo3)@ny-rnZK;`SC7ENt^N+uQP6tfXzvvKAd%cv-<7kRMZb
zrLoN|&TI^Jb2Pu~mc)+kMS78bkhHh-S2^p?Fi=?)zG1Yn58NhG7r^BGX--RuJ*JXL
zIivsjgOZoJ^?)8nNe^TZPI7mWWMmTq^lP7Rax=@iSvTO5k<qQdRWjv4fRlislYE5}
zeBN;m=Z!4#VlNPCs(RHgj22QzKedUuaH~T;L1&LDhjB)H5FZ2*UWeCA(*<xALdI%`
zfykJCHX(<!*iVClU@!2nH(%<ei|HYB2DKaDG^6S2hfnZ2Q;*BNAiz;>rF&T|x(T^p
zbn4=vJ?B7N8fd!+C)?Vo+WFHCIeM`~E*ZC6cONok2XiND_tRr?TyY(Qr72tQfgmY$
zs{3VK59BEHjo%=ba_!t@*<QnUrM749^cV8`7tWE<8z)pQ%>2Xz0sAs<FP1UFFuhEQ
z0XgBWlWw_tM6PFhHt^VU-M&tGF4N0I<+#TBBbPdt_0nF7ZVKZSZeUI^*cjK>IUH+T
zny2x;b6J`Nl1*9Ld7SAEIbFGdrZ-pC-^V>^7H4rFhM%x@JqQYm{UiBW<-CcaH*6+8
z5SKc;h~v1+r(8^0jz1H+kWu2^T*yCreU%wt7_y1vlRTLv<&4c(`Lw+N%;nV#`>lIZ
z5*A(pp$2hNCevh?pFVkMb`BAo%FXLasp{$X_z+tjyL&dY<-xL0chmOLRJg_Q9UWWe
z;Nh-XP@X-+b?7s=hl6G3p6PV&<?h0ggx*xcasanJEjgFpLx1yoSl{1^^c|$V9Ub5C
z=^HP0bM!lk?=<}f&<GM-*MCcc0001FdQ@0+V{dJ3Wo~o;0C?I{a1L^H4Dk=LQiups
z2um$0&dkqKFxE3PNK{Y=N-eWeFf`IPvedUUQP2qRb5|%xEJ@B#Fw`^B<Wd--I^8{e
z0~7-Md==a>b4pT+;Kms08FB#ts=Y^%Mm;2{0000bbVXQnWMOn=I%9HWVRU5xGB7bQ
zEig1KFfmjyI65^lIy5&cFfuwYFmoFb=KufzC3HntbYx+4WjbwdWNBu305UK!F)c7O
lEif@uF*rIkGCDLjD=;!TFfal}sapU5002ovPDHLkV1l>w26q4e
diff --git a/scribo/tests/img/alignment_3.pbm b/scribo/tests/img/alignment_3.pbm
new file mode 100644
index 0000000000000000000000000000000000000000..89ec9782af0d7d02754c1fc66721cc647f53082c
GIT binary patch
literal 12167
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
PVa4sRhPq)Pe{bw}0KjK|
literal 0
HcmV?d00001
diff --git a/scribo/tests/img/alignment_3.png b/scribo/tests/img/alignment_3.png
deleted file mode 100644
index 67c20308a0693278a5c16af4f4f9f014f30a2f8b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3145
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
diff --git a/scribo/tests/img/alignment_4.pbm b/scribo/tests/img/alignment_4.pbm
new file mode 100644
index 0000000000000000000000000000000000000000..27eea1e317f882e0a39dcb83ac10330458ba2eee
GIT binary patch
literal 12167
zcmeI2&yVEBb;sFevJ_-xDCd_a$YN@QT<nXqBMHW=G3c@(*g_6g1R*ed^U8(*3kZ^x
zA_QY-J=K#5L>~gt27JiDP#^pU82JaZ-C<z*U}&yB7+KN`JU$4TqWZ8k*&0^9uUKR^
z+1)$ifi1v^YO%v&)%(<|-}U&aUwrn_zuJE8r7wN)Z~x|{&u@S2tJ`0F<@JAj^&kFz
z`<W+qZoIs`{n9J{^!e?br=NQI=2JJH-TusrFFe0}`{g&j`K|4pC!hZ8?=|}TUw`Gr
z?H6D8%J!FE{ku0_dA)7;&XYTjKKkr4pWA+V=W~ymD+RfR3fH8&<TaS~uY{?qVdlY=
zv^^X$W=-4vuVUO(7d5ThC0anfVn*_YQ>=+~pPimm0-06V!A`sK?ybS@(YxaK18pU}
z*r3d1FhR1sgPmBs|EHr(yWB->566xd%ey?5uEUDOj5gj>axIp(qKlDbtP0R2l@V4-
znQT$IjXO+w=5EFH=0N=TT|e8I+_*L{W+LRS_K24^xUT{aL+V0{O#&4t&)fBepPcMS
z%>rZIX4&TXgaor2!y7uBs^@x`IhxMOMD6YE?QXI3@J#a<0~i)RHMUFA?`bV~Qnp>(
zv@J>>B)PgXygp<sot|qEnu^D1=CG-%I8SG)uPsf>RH_5E#ol3Yey%wKmL?912)i2<
zcCHiJXiJaFR4Kv67Sjrt=4mQTLQ+v)R%{%vz)q(Tuy7oXp-rnH2bKV{;}+$Tutakz
z1fkVd`H|We(Y?q3tM=ak_QyxSY?s8P{Bw3MoY*C@h($6OdHW(krC3~={T~AJ{056k
z>9J!r@i;LEt+p(zv7#dEwO<HiQYD?X`={Xt?0i|<gd0>cH@U@jepX|u!Hfw%pyr}5
z3XQht5Q}^NP5A(AhqizJwLoT)s{2kG7X7c5vC}j@vlvDcU1EM@XK>oVurc+u0V|DC
zZ>n!&><~QyrcIQ}S<|+PNpa8aQ45tkjmG6zs&DI?dPrD`*{4kiEFr15oN2DasTA~v
z;M#T)kMrYP?d#nNSZ*;h1g4HiDk?D*lsRd7qQPW%d{`uEf4Di^yyi~?X)_}}$o8;+
zOyy7Rct#oJQyCN-FWJPGLAL2Vf`9&mpU|;5sRolRTA6rq-<%swW!T`bN=VFjV4GgM
zf+>I9q1x8AF6FX+KgO1N>f<i?jk~1X^}FOnJ=x7y%+cNCrpWtE1gGLWj!lZWjEk`o
zCrJ<0#4p0my4oI&+3m`SEXFU;Hfu`7b1~lE@D{`<x@c7_4#5T5?4In3T8uvw3#?V4
zg<&{Ohh$-#L0;UgmU>ceg;G>uMIEbri)Bm)qlvsuXPUefR@ZzP_O+=$2q#Pps%s=u
z+P0;!dhU^_v{s@FV*QB#CkaZm!Hrukc^sdWFb9k&l%Q^i6Qzbhjg=AX0d`#Uu>z(+
zTEdDLw-_r*#e>pndk_~&<80_-39zEj2Lf24ai|&tOmnBrgcd88Fq}_>8D>nXxy5o|
zQQb~pFvG%i7^mYB)(5pMbeJ9PFjo}|<qB=#bgDTHeiK=&@&>gwi=l0+uv8Dd0n82>
zTU3%nfmKw=8cSAUsMyyJ%@2ki<Q-;8!s-Dq$I(g*6~h?oJv!Wg*{KZktks6GUsXvm
z!hr44xFz~cTQTaAR6ekA%&S!xG{D}`yM{3Jrqx#1O3rNj{KT3$N}x6r+~g|M5JsB%
z4vkx(&PWtCE>-e@#Y|CSgix4cB0a9L@=Vc20ECA7tlkt7V9Rr|%s7uuq{iozQMvtC
ze=E#1i?aH|J@e%OgTW_I9tEdO{U;yM!r5oAegb?!z=-FQ8ykbs&>9t9Fxd@cm?7H+
zhw1A)<0>%T*rn6sXXZ4>ImIe31O^L)(HnxpYTNCuxn~oX{%FtYoTqoNd2%mSFQtXV
z7847JOHtj{%4M|}Uy@x&(DOa3PQ4sPCRrymub5m93#^_itw@6@)+VirjMns|?4|cu
z*)bRA<JJ?q=(VZjMRL9T|F@V5&4l{mu=Tr4UDrIcOIj@BPTZD)_#$@K<+YEgsW@J6
z@VF$}Gi+GI#xAXWBo4zzcpYph6n!X`UJd)5YKvV9+DD^}{1P^-Y+KaIyU2xY8<XI`
zO6&0OPzUx?EydO-g}yE}m<dCS;s&=OO;1*VFPX%*VK|-Wz&k7pl|bMpPgMLrn0icn
zH`2bJA8E37Y^VnSSP`B3z~26%`fx9pmDZy&fuRz|^1p>&=qFfGsBd&J{U_`=fqO$A
zaG#8rL|LO?ig#E!QUoQenKV~D=Yal878eF?lmmW5SPD$gxe5%%kbp&k(`Sk-TgA3*
zyY#UQH_9CxhM0n>x?N*KSUJFAi8DB*Q@Mi~%~*{I!lDQmBoa+n4sD9C*$OP|U|LYY
zg#8h8)L3F<Ut7hzj4BC7i`7<RX*GnElRFIFvi>Xq=B>iE`2XZ^9EED%u%CoWmBjj!
zHI^=F(?ggmqz&W2(j%A--7cxI+*T51MT$xa+cscU8)0N|EMet6II8Zz2|*bA6%7V!
z)M+DYY6;7aF-uy^G~;HHrjkc;1t#+2IMW9lERPChT_aOC^+XB`lgn%+t1zCN#@Rk5
z7X~LP%975(iPD@0D949aZR=mMWo=;`W#K>H5L?e>`{6+O)}wN5pguie6Seoq^YUQh
z+91=-7Up&?>1Uy2zGp_s<o3n@-ygI!2Jp3IVs!hl4Olb&h7Xgb+a=Oh=<=d4MMCRy
zRX8=~{&|zJxKG-&byNe?&m}DF=C67CZDCie<VTAguIYqsa=%L|`tG<m^f5TuFB6uq
z%RtROc{$kyso!^P?JA)*wFXVyz<Jx;uH^P>EK}^lp}X=x*YR53{heb@-kG=h8S}5a
z2n};`_Tz6(E?~8UtgQmQZ#YW}cb=R2!*(UcZE9B72TmrOzqx7V+FEUuu=29TO6;@|
zux8I$i&+S@sWIB1BUZLIHy2^GC*S0H&tj}8%{|>?-X%?Xqit8DOg24vexbHZpnxCe
zdRHV3CPOcmxA;idJSxA@rf*_^^_eLv>-+KZYE!%g%<kR_W(V$@w)k6&7=#9sn_GdA
zyW!}7EH8OBB`kE6tneY7e;+QDaXqMWEdTBSZZQ9CIOIP9R_YqdUE6p}*a2hB=G$m1
zevLUPe_p}r0XEY~^*DbkY_YJ+VM%TAK9**LO|*a!1xzK?CVM+58f`FkES4aXLZb~I
z|J<ky7@ddrC9oH^{M2E0f#GzlSRYFXGceF1(q<0Pwp+vN%?cRfBQw`w^@ly|ZWmJn
zVBe{jaN7QhlePh_pQucPx{}gQ)uJ}(PxU5zdbsqlQZ;s4z&TQf)mX-8PSRN0;WqC<
zn}pT422-wWSp|#}Q)_!)zypPG>tXO4*-AE8QI)_L24fK$h8JKb8fEh^o;oZu(Dpvx
zFiXQ-YpaL5I8~(<xHOt$IWV>%qE45zm8^$5Ih9Ho78X<2lXS(HXV*er_fRtcgdK3W
zfhtbkgTs?dzh<JaEZn9b%}9(Mzs*K<Q|Fj3?;uHv>*W1AR9@v9cvbzZ-nq_jU*+A@
z%gc0-Js#jPi;WK8{X41-%rTjUyv1CbnnyF0|Lm843M^wYGPcqtw|RDs14?YLM!-Ig
zJ8yV7&w44B!}O)FlU~`Tx)iqPl&?#;-79EiCC_?7#(b)mvJzYBICFFvtS7VLb)~iy
za=oOFv0jI?Q+Z+XdP9#nvGJ04li+$XvhVohg^PWT9op1UBfIc)SiMOrhUcM}H2H^y
zBl?(V-sjH_CTWYoX47QH7TdTGqiu1vgz=`B`O|5OZ3-ORbXVP+4<@#|>pOfd-ozX>
zw(k}@>thvfgy+u-urVYph7B;w#GnBkR*xI}4cKl>JsOaR@y}uUmKohT*b{iC;IMl4
zu$9Em6DR{Z(ooXCd>FunJ%jh-34OpR3&CRVg(sfGl^CoS?K=z(BR|Xt%Y4Lfl!Qmh
z4oHhlf*CNl=na!zMN<XiP*i^r8;X8_`y?1uoF&MoECj19nc;#%z*$r=d|=nu2@b~4
zVig=T_#p@|XG=9$Ix{CIDMfN24Xh{xcrp;7DEu-wsBp28l=hu+t+wMC>>k2UaE9Md
zP)4d2F#LweW2Dq(wOC;>x;-g!Gh~ECa14a?0I*02V7L|QV%P>B;1@g=Gv?g}6AKus
zN)6~}!|h3fVfO!!leUp}2ioek#W?C#U|C?!a@?GueK<>7Ow>~uzly1`yw{TxX3h)3
zDux06sUU4e-9aU-Hf}Lknmr85UKd!P)Fp=tSUks0H89l1mgoi`Ix`xJEH4cWz(m+Q
z1!H5}w9VXCf)yGQwGMXN#t%%D;!caS$>wKfvc-6$Oo?8Ei%)d0nW>(Ke~K^+k<A)o
z^2YaSZI~r6CWF!ZqrBEum@23QX35qqS_c&F<-m>|hHnnIRYw9XsY8w7HN?#sw0*%{
zCYqBY#c@vzDO3Ud)eROqJ|gVxFsm4T5m$fCVEt_k>=&uTk8!$?>q%OTV>97!5d{IZ
zE(-ARZeYnGNT2qKZm`<Ok1)o6siJP~+PAv>$R4j1S(P!z_^Rx6X)X31_4TDgi+yl4
e>{nOAW>>=$yL7`K*tSiJD`CG0w4m*y!TuK@ymU4I
literal 0
HcmV?d00001
diff --git a/scribo/tests/img/alignment_4.png b/scribo/tests/img/alignment_4.png
deleted file mode 100644
index df3d395baa7c9f0fa905c6e7d941b36ee3ab705e..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 3155
zcmV-Z46O5sP)<h;3K|Lk000e1NJLTq00FcB007tl00000s}3uE00002VoOIv00G^K
z6QlqD010qNS#tmY07w7;07w8v$!k6U000Sga6xAP00FcB007tkdmpID000XRNkl<Z
zXx{DG&2Hny9RTndkE_{(!to-9I4DcH=%H5yIfOx3(RqO)50Ha`9C|3wa?wK=RFy{Y
zBEDsxpxC}bZ#e|*5C-B)k$r<;ge~fRXWSGB-Lhi;{~1b_NqyKtK3a5V0WT%-ry0)Y
ze@GGX#U`^GW94p+@94<>7ku6S$4L=-N5Lfgp_&Lae~0VaIBuP};SM&FBYT!|`FYph
zL~iAzyS`<2cnins7k6;I<rjBw(K_ev=z`liT7aWO)-K%0L`9CNViz;{`fFwQaq{G9
zMo1#XIjiss#1mEWqJpMvxuoC)ud4GZ|3~t%V7egWfetVB68t!Pl0RXl&p&KsIP7=5
zn4g`UolkW%>M)f;LmK}TS1-{|7?UdYyq3$N{W#z!`O{qMsK3XgAylPNSi3%_N=04X
zu9wJ*1fS@sep9Ex9#a}z6xS|8cbxf5wp`DPIG1{09pm7biXuT`>jIDJLAuHv^fPc~
zU<TIZ3S0~>a896$nQA#&X8crUM;QS}Pu~Rh*C9At&eRis)JG=aEtiR6T%F1o%B53}
zoW2FFD(5cqM5TK=soMF4#yOv&d;dFlCGmBB_YTZ`y|*I2L=h-wKmzMNe%U!bcd*jj
z$4hRx5p>4Whhkq?_k$N|cW>^fesP66h|-RA(6mr5<c-iZ>ar87okuu-$lrrDgu`Ko
zqd$v8cYb}~<PmSS-$6F;27<rGK4Lk#$U|qq#m;q^;_^T=-C;TidI3LW=QPK1q9Zvt
zK6LE>eFEkT(X19>dLuvPr};&GaaAVLy0MytXE2@!Et8W9#&CNz6*?(J5nfcE!@n|7
zhq!Jgbe2pFx>=%1vPW3abW{rH|KKhvv;6+EW%pV7uTI{M?&gTw7S7yT9ED5AcXP{u
z0VlV0otyb>asHa)ZLYiKxHS(p(sJ;z+!EXJ3)dWPc7+W-U~Sc~;O2PT0U(cQ+p(z;
zk{XK5%uDM+&5Cg%p5mG(9vga93e$4@UnbFfMz8QB&t6}Y@((}n3wwQ{NZG#&SY}!k
zAyk@nJO~<~;<?0g)0p$TaL&shXwW^s<$MSrA`gO%!NO_Z<Erqi+fRMYVBKiB7@Y63
zi3Arj892vOogXpQd2I*F7doQh!kDry0GGLI1qUIUS?d&2c&soFQ#+Smz^OK3l{5W5
zQxF}H%sN`lmK<E)N*A%bnn8Gi4Hvomz|m_Lugg#UazuWVS7hOchpw)dUbfmn*`Na0
znIVgMA;D69&<WP%hwfb2c6jJH2N9vzx5v=M)?A;00m{w^I{wh+=i732?eX5BjfYy}
z&*wQrbo^axKc9E-TnLM?ocnGp`p&icSuUfVb6$tz+yDmKq2uO>7~G2f>4i#Vhl0Uo
zjPStj`rk1j(^=^50EDHOXb2CR<>cQ}V;o1P;8;O1-UwCl<Z?F7ZR}AM$$246s2h$w
zRiWYqsRm1LzDy2^K;aRs3^)i>nvP({B*$($*G{Y|$eK?S*^u1GTK&mJN5r~MHs`l?
z2Hfm0eA~sr;9v8>mX&S1u0BPv(FsGIrLQe<L+mzuw74PDzncr^E?ITjar2En>?sKL
z!Fi{^X{4P7%{SuO!Dha8>Q*k=(S6DJrR(xj=|-2`JwIE-nLT7?G-8F_>P0YR3dx?z
zOHGV{*1T*uT9iTy*j<`_!is9-`5gDPuYN++_ci}azMZkM42JBg?fh)71oz<A{JFED
z>)Bg02?R80D!wU8pM9cZpZ}ua*k5!nCRxBHs>Em~=5~qf!)pkKge*J=U!s6F?=!I9
z>C`6~1TbodE&?ZU<pl>}lQihEzSng095?N$&rV>qWau6_m*>`{0+#6r7w$%VGOeAH
z=&}r)n!5n<<LJ7poVnqcWVQP{<l<aRM9WcKh3HOixQONu4h6MKq@XKYwaQJ^Hv%8s
zDbcSQZ$*BvQdt)*JC;LOgZV+T=xFHC)h@94LG%%UbM*<%=7%m`>AWLwCy*aHF8SQ~
z-aNlxr3-r5k|Xo>Bk{bPL$S)qpqGZwKLD%D=k``hpPxWD1P=NcnZ_%fiVxE86#AJ!
z=Xrtc*G#DbzNicYo&GFb;Y^x^=I2l3^uzGf%y?;U(Ok{=9}=DLv(G;elgq1F$V|hD
zGBiS$6&c6LqstlWTyWeLnJ7Xze)QQTggxbD39(Phaj1FUCw?50)#(7XlY3-sipg#%
z`ikAI<@~DMXg5Zy9rL^Evz%w?w&}*8SwudqRL=p-{RiU~=4VqsW+6+DzM829bwtd5
zOMa?+gZnd^*5B7+?i7)_SEmG)Out_9H#(PJ==OWuF3|z0wmRxAML6fd6r6!8wz~NV
z&f(OZX>akwX#0J;xjVCNd%ZN>xs0@!*XQ1L7vgokjxL@%VX8npR%02;R&9O+EzLT_
zqxODM8PE&)4mf*#9HNu(Nj_EY=%y1F(}IX|GoE0JiB2D#sq@2qeDGtI>p|Ld!P^r<
z#1Hday<uCyxuCv2m7<$y-I`tf7odNN?^1}5;8mB!^i#Fuj2A%AHB~Jah3FC{Q|ow4
zFZ6@LpF4<(tZU7ZF~%l51cwXeJpt}l(=w{vF*sO0G4^TZXJZ<O<}%xUBe=fD`P2D$
z7{ER?V21v)>5gwYJ_GkIEc&(kw!-{otZF<c5oN@eohbY4LPF=H%kGhEt^!RLYV4ob
z=(gR-OW*_qnd=;%I|@!Aa``<kJ!sR3Zm&8woliY*7y~c6+-!4)48C2Nv|qar#*z2D
zx@@n;wR7$6A8-iDauZ#<0Gz&**?I@<9v=t{0FB?T>k}Vy2H}-artK!^pnrlJ9fs_E
zk{Qph=Ltc^a{TEdJ=RTEiW7KG$ftN~al|WHl0@?|bn{t<j8*j!TQP2D;ioWljrDj^
zNiw7p(!)qnE!?{Fr*Hka!1nH9VAiU&4e`}->a|?Bn`5_gt=}Th+qrJ*okzEF?dtp6
ztz5hMhPQIh($|%G*N0VJ>H2W6)wy|t;|+`@=VIpZ2IuB)uHpZYT-<yb5e0ugliQrY
zc_+AjT9sONx!vKk*KIkq-lfjrw6}jfDW`V&d~<^vT)R%w(H-1i?qFUFLpf`@o~uuE
zd)N1wQd@p^kLfWPKc1X5tLX4LKjs{q9T|c3^;`i_Z->kD6E?Y7<d@80C5(_zpRBAM
zH>5Nny0C;}-24wYx#^Ok3ocZ!mWYbFyIx(N{yw$K?R^dVUf6=`m@mR+m*Osop&Tic
z6E^D39eVh52M?+CVRc6*8ZPRRL%ab2@B4yGtczgfoICuv4%H_18b6!tbxGGc`09}4
z&haJ3Nmyyjw&8s1@R^MtklYp~;|zMMZ3mrk3C{SU`7_NS*@uwWIznEXJGtcGuWmV3
zE*$jfw`^sPs}nUZXS&9P1?dE|nn77%wOu$__s_Wtn)R7zvgf0t8d~}l*O~Z<tn*XW
zDa`MtgPDN&_)rzfI$Cn+wL4(on(dx-2#fIn9Km)-Y6mgNV19k%9+%o@jUhGICp2=;
z&Y&#y8Yvb|Wt@0WCwM#Wrt1>=fqQo5LsPl;peLtCi~a(^XEAPW?gu{X6RCv$GJP!S
zM>j_SxL)l%eAr!#Wh1N`#29F*4D$O;{Xml(4!JUkYX^VLj|h81bPr5O_0_C)FdnBf
zyQ>xDx`#G6JO?CE$$3!}^>2Zw5|^d@!K5fx-_CdUBnEf}&&XZV;Lf6UYB%?i+0EVG
z(Y?5%>+a}o_e<S&+Wdg?e>VLGPG|+C;6<XT0001FdQ@0+V{dJ3Wo~o;0C?I{a1L^H
z4Dk=LQiups2um$0&dkqKFxE3PNK{Y=N-eWeFf`IPvedUUQP2qRb5|%xEJ@B#Fw`^B
z<Wd--I^8{e0~7-Md==a>b4pT+;Kms08FB#ts=Y^%Mm;2{0000bbVXQnWMOn=I%9HW
zVRU5xGB7bQEig1KFfmjyI65^mIxsLRFfuwYFx@mttpET3C3HntbYx+4WjbwdWNBu3
t05UK!F)c7OEif@uF*rIkGdeIZD=;!TFfgoX@(}<4002ovPDHLkV1mIR9n=5-
diff --git a/scribo/tests/primitive/extract/alignments.cc b/scribo/tests/primitive/extract/alignments.cc
index 7bd82fb..a069149 100644
--- a/scribo/tests/primitive/extract/alignments.cc
+++ b/scribo/tests/primitive/extract/alignments.cc
@@ -47,7 +47,7 @@ int main()
for (unsigned i = 1; i < 5; ++i)
{
std::ostringstream os;
- os << SCRIBO_IMG_DIR << "/alignment_" << i << ".png";
+ os << SCRIBO_IMG_DIR << "/alignment_" << i << ".pbm";
document<L> doc(os.str().c_str());
doc.open();
@@ -67,7 +67,6 @@ int main()
os_out << SCRIBO_TESTS_DIR << "/primitive/extract/alignment_"
<< i << ".ref.pbm";
- io::pbm::save(res.second(), "res.pbm");
io::pbm::load(ref, os_out.str().c_str());
mln_assertion(ref == res.second());
--
1.5.6.5
1
0
* scribo/core/component_features_data.hh: Fix default
attributes initialization.
* scribo/core/line_info.hh: Compute color and boldness if
available in components data.
* scribo/filter/object_links_left_aligned.hh,
* scribo/filter/object_links_right_aligned.hh: Fix doc.
* scribo/preprocessing/rotate_90.hh: Disable preconditions.
* scribo/primitive/extract/alignments.hh: Avoid a warning.
* src/preprocessing/split_bg_fg.cc: Initialize Magick++.
---
scribo/ChangeLog | 19 +++++++++++++
scribo/scribo/core/component_features_data.hh | 8 +++++
scribo/scribo/core/line_info.hh | 28 +++++++++++--------
scribo/scribo/filter/object_links_left_aligned.hh | 19 ++++++-------
scribo/scribo/filter/object_links_right_aligned.hh | 19 ++++++-------
scribo/scribo/preprocessing/rotate_90.hh | 8 ++++-
scribo/scribo/primitive/extract/alignments.hh | 1 +
scribo/src/preprocessing/split_bg_fg.cc | 6 +++-
8 files changed, 72 insertions(+), 36 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index d223777..a0d4937 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,24 @@
2011-04-06 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Small fixes in Scribo.
+
+ * scribo/core/component_features_data.hh: Fix default
+ attributes initialization.
+
+ * scribo/core/line_info.hh: Compute color and boldness if
+ available in components data.
+
+ * scribo/filter/object_links_left_aligned.hh,
+ * scribo/filter/object_links_right_aligned.hh: Fix doc.
+
+ * scribo/preprocessing/rotate_90.hh: Disable preconditions.
+
+ * scribo/primitive/extract/alignments.hh: Avoid a warning.
+
+ * src/preprocessing/split_bg_fg.cc: Initialize Magick++.
+
+2011-04-06 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Change test image format to pnm.
* tests/img/alignment_1.png,
diff --git a/scribo/scribo/core/component_features_data.hh b/scribo/scribo/core/component_features_data.hh
index f5ba60f..07b3e4a 100644
--- a/scribo/scribo/core/component_features_data.hh
+++ b/scribo/scribo/core/component_features_data.hh
@@ -38,6 +38,8 @@ namespace scribo
struct component_features_data
{
+ component_features_data();
+
bool valid;
scribo::def::color_type color;
float boldness;
@@ -50,6 +52,12 @@ namespace scribo
# ifndef MLN_INCLUDE_ONLY
+ component_features_data::component_features_data()
+ : valid(false)
+ {
+ }
+
+
inline
std::ostream&
operator<<(std::ostream& ostr, const component_features_data& data)
diff --git a/scribo/scribo/core/line_info.hh b/scribo/scribo/core/line_info.hh
index 73d7856..e925db7 100644
--- a/scribo/scribo/core/line_info.hh
+++ b/scribo/scribo/core/line_info.hh
@@ -1040,19 +1040,23 @@ namespace scribo
// incremented.
++used_comps;
- // Compute boldness
- boldness.take(comp_set(c).features().boldness);
- sum2_boldness += mln::math::sqr<float>(comp_set(c).features().boldness);
-
- // Compute color
- color_red.take(comp_set(c).features().color.red());
- color_green.take(comp_set(c).features().color.green());
- color_blue.take(comp_set(c).features().color.blue());
-
- sum2_red += mln::math::sqr<unsigned>(comp_set(c).features().color.red());
- sum2_green += mln::math::sqr<unsigned>(comp_set(c).features().color.green());
- sum2_blue += mln::math::sqr<unsigned>(comp_set(c).features().color.blue());
+ // COMPUTE FEATURES DATA
+ if (comp_set(c).has_features())
+ {
+ // Compute boldness
+ boldness.take(comp_set(c).features().boldness);
+ sum2_boldness += mln::math::sqr<float>(comp_set(c).features().boldness);
+
+ // Compute color
+ color_red.take(comp_set(c).features().color.red());
+ color_green.take(comp_set(c).features().color.green());
+ color_blue.take(comp_set(c).features().color.blue());
+
+ sum2_red += mln::math::sqr<unsigned>(comp_set(c).features().color.red());
+ sum2_green += mln::math::sqr<unsigned>(comp_set(c).features().color.green());
+ sum2_blue += mln::math::sqr<unsigned>(comp_set(c).features().color.blue());
+ }
// FIXME: we must guaranty here that the relationship is from
// right to left, otherwise, the space size computed between
diff --git a/scribo/scribo/filter/object_links_left_aligned.hh b/scribo/scribo/filter/object_links_left_aligned.hh
index 82d4185..830678a 100644
--- a/scribo/scribo/filter/object_links_left_aligned.hh
+++ b/scribo/scribo/filter/object_links_left_aligned.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -58,15 +58,14 @@ namespace scribo
\verbatim
- ~
- ~ ^
- ~ |
- ~ |
+
+ ~ ^
+ ~ |
~------ | Alpha
- ~ | | |
- ~ | | |
- ~ | | v
- ------ ~ ~ ~ | ~ ~| ~
+ ~ | | |
+ ~ | | |
+ ~ | | v
+ ~----- ~ ~ ~ | ~ ~| ~
| | | |
| x------------x |
| | | |
diff --git a/scribo/scribo/filter/object_links_right_aligned.hh b/scribo/scribo/filter/object_links_right_aligned.hh
index 07ca309..4f854e2 100644
--- a/scribo/scribo/filter/object_links_right_aligned.hh
+++ b/scribo/scribo/filter/object_links_right_aligned.hh
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -58,15 +58,14 @@ namespace scribo
\verbatim
+
+
~
- ~ ^
- ~ |
- ~ |
- ~------ | Alpha
- ~ | | |
- ~ | | |
- ~ | | v
- ------ ~ ~ ~ | ~ ~| ~
+ -----~ ^
+ | ~ | | Alpha
+ ~| | |
+ ~ | | v
+ ------ ~ ~ ~ | ~ ~| ~ ~
| | | |
| x------------x |
| | | |
diff --git a/scribo/scribo/preprocessing/rotate_90.hh b/scribo/scribo/preprocessing/rotate_90.hh
index 8db703d..e6d68c8 100644
--- a/scribo/scribo/preprocessing/rotate_90.hh
+++ b/scribo/scribo/preprocessing/rotate_90.hh
@@ -80,8 +80,12 @@ namespace scribo
const I& input = exact(input_);
mln_precondition(input.is_valid());
- mln_precondition(input.domain().pmin().row() > 0);
- mln_precondition(input.domain().pmin().col() > 0);
+
+ // FIXME: Does this routine accept images with an origin
+ // different from (0,0) and with negative coordinates?
+ //
+ // mln_precondition(input.domain().pmin().row() > 0);
+ // mln_precondition(input.domain().pmin().col() > 0);
// Works only on one block images.
mlc_is(mln_trait_image_value_access(I),
diff --git a/scribo/scribo/primitive/extract/alignments.hh b/scribo/scribo/primitive/extract/alignments.hh
index 5314683..4bd925e 100644
--- a/scribo/scribo/primitive/extract/alignments.hh
+++ b/scribo/scribo/primitive/extract/alignments.hh
@@ -559,6 +559,7 @@ namespace scribo
const object_groups<L>& groups = doc.paragraphs().lines().groups();
const line_set<L>& lines = doc.lines();
+ (void) groups; // Avoid warnings when debug is disabled.
// 1. Construct an image of group bounding boxes.
//
diff --git a/scribo/src/preprocessing/split_bg_fg.cc b/scribo/src/preprocessing/split_bg_fg.cc
index 270093c..2b68b53 100644
--- a/scribo/src/preprocessing/split_bg_fg.cc
+++ b/scribo/src/preprocessing/split_bg_fg.cc
@@ -1,5 +1,5 @@
-// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-// (LRDE)
+// Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+// Laboratory (LRDE)
//
// This file is part of Olena.
//
@@ -49,6 +49,8 @@ int main(int argc, char *argv[])
mln::trace::entering("main");
using namespace mln;
+ Magick::InitializeMagick(0);
+
if (argc != 6)
return scribo::debug::usage(argv,
"Split background and foreground.",
--
1.5.6.5
1
0

03 May '11
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 safe-groups has been created
at 397d9adad2d9d3854bb9f6b43fd3b0530af973e3 (commit)
- Log -----------------------------------------------------------------
397d9ad tests/unit_test/unit-tests.mk: Regen.
25b4393 Add a test for object_groups.
ff536c8 scribo/primitive/extract/separators_nonvisible.hh: Update use of object_groups and object_links.
6404315 Several improvements related to low-level data structures in XML output.
2fbfae8 scribo/toolchain/internal/content_in_doc_functor.hh: Make use of component::extract::alignments.
41e2055 Small fixes.
3f50eb7 scribo/primitive/extract/alignments.hh: Fix several bugs.
7e736d6 Improve object_groups and object_links API.
3ac6dd8 Add test data in EXTRA_DIST.
1bcc175 Add new tests for Sauvola algorithms.
78b8020 scribo/filter/object_groups_size_ratio.hh: Fix compilation.
d82fdf6 Rename few routines.
52a1107 Add more tests.
5b660b4 Small fixes in Scribo.
52f8110 Change test image format to pnm.
-----------------------------------------------------------------------
hooks/post-receive
--
Olena, a generic and efficient image processing platform
1
0

03 May '11
* tests/core/Makefile.am: New target.
* tests/core/object_groups.cc: New.
---
scribo/ChangeLog | 8 ++
scribo/tests/core/Makefile.am | 8 ++-
.../object_groups.cc} | 70 +++++++++++++-------
3 files changed, 60 insertions(+), 26 deletions(-)
copy scribo/tests/{filter/object_groups_small.cc => core/object_groups.cc} (50%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 9395d2b..f139bb6 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,13 @@
2011-05-03 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ Add a test for object_groups.
+
+ * tests/core/Makefile.am: New target.
+
+ * tests/core/object_groups.cc: New.
+
+2011-05-03 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
* scribo/primitive/extract/separators_nonvisible.hh: Update use of
object_groups and object_links.
diff --git a/scribo/tests/core/Makefile.am b/scribo/tests/core/Makefile.am
index 356cc31..c9af42d 100644
--- a/scribo/tests/core/Makefile.am
+++ b/scribo/tests/core/Makefile.am
@@ -1,5 +1,5 @@
-# Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
-# (LRDE).
+# Copyright (C) 2009, 2010, 2011 EPITA Research and Development
+# Laboratory (LRDE).
#
# This file is part of Olena.
#
@@ -20,8 +20,10 @@
include $(top_srcdir)/scribo/tests/tests.mk
-check_PROGRAMS = line_info
+check_PROGRAMS = line_info \
+ object_groups
line_info_SOURCES = line_info.cc
+object_groups_SOURCES = object_groups.cc
TESTS = $(check_PROGRAMS)
diff --git a/scribo/tests/filter/object_groups_small.cc b/scribo/tests/core/object_groups.cc
similarity index 50%
copy from scribo/tests/filter/object_groups_small.cc
copy to scribo/tests/core/object_groups.cc
index 9812b70..33e408f 100644
--- a/scribo/tests/filter/object_groups_small.cc
+++ b/scribo/tests/core/object_groups.cc
@@ -25,55 +25,79 @@
/// \file
-#include <iostream>
-
#include <mln/core/image/image2d.hh>
#include <mln/core/alias/neighb2d.hh>
#include <mln/io/pbm/load.hh>
+
+#include <scribo/core/component_set.hh>
#include <scribo/core/def/lbl_type.hh>
+#include <scribo/core/object_links.hh>
+#include <scribo/core/object_groups.hh>
#include <scribo/primitive/extract/components.hh>
#include <scribo/primitive/link/with_single_left_link.hh>
-#include <scribo/primitive/group/from_single_link.hh>
-#include <scribo/filter/object_groups_small.hh>
#include "tests/data.hh"
-int main()
+int main(int argc, char *argv[])
{
- using namespace scribo;
using namespace mln;
+ using namespace scribo;
std::string img = SCRIBO_IMG_DIR "/the_valleys.pbm";
- const bool ref[] = { false, true, true, true, true };
- const bool filtered_ref[] = { false, false, true, false, false };
- const unsigned size_ref[] = { 0, 1, 7, 1, 3 };
-
+ static const int comp_to_group_ref[] = { 0, 1, 4, 2, 3, 2, 2, 4, 4, 2, 2, 2, 2 };
+ static const int pixel_area_ref[] = { 0, 3, 973, 39, 426 };
+ static const box2d bbox_ref[] = {
+ box2d(),
+ make::box2d(0,91, 1,92),
+ make::box2d(9,95, 45,224),
+ make::box2d(9,204, 20,209),
+ make::box2d(9,12, 36,64)
+ };
+
+ static const int comp_ids_count_ref[] = { 0, 1, 7, 1, 3 };
+ static const int comp_ids_ref[][7] = {
+ { 0, 0, 0, 0, 0, 0, 0 },
+ { 1, 0, 0, 0, 0, 0, 0 },
+ { 3, 9, 5, 6, 10, 11, 12 },
+ { 4, 0, 0, 0, 0, 0, 0 },
+ { 7, 2, 8, 0, 0, 0, 0 } };
image2d<bool> input;
io::pbm::load(input, img.c_str());
typedef scribo::def::lbl_type V;
+ V nlabels;
typedef image2d<V> L;
-
- V nbboxes;
component_set<L>
- text = primitive::extract::components(input, c8(), nbboxes);
- object_links<L> links = primitive::link::with_single_left_link(text, 30);
+ comps = scribo::primitive::extract::components(input, c8(), nlabels);
- object_groups<L> groups = primitive::group::from_single_link(links);
+ object_links<L> link
+ = primitive::link::with_single_left_link(comps, 30);
- mln_assertion(groups.nelements() == 5);
- for_all_groups(g, groups)
- mln_assertion(groups(g).is_valid() == ref[g]);
+ object_groups<L> group(link);
- object_groups<L> groups2 = filter::object_groups_small(groups, 4);
+ mln_assertion(group.nelements() == 5);
+ mln_assertion(group.comp_to_group().nelements() == 13);
- for_all_groups(g, groups2)
+ // Checking comp_to_group()
+ for (int i = 0; i < group.comp_to_group().nelements(); ++i)
+ mln_assertion(group.comp_to_group()[i] == comp_to_group_ref[i]);
+
+ // Checking group info data.
+ for_all_groups(g, group)
{
- mln_assertion(groups2(g).is_valid() == filtered_ref[g]);
- mln_assertion(groups2(g).card() == size_ref[g]);
+ mln_assertion(group(g).id() == g);
+ mln_assertion(group(g).is_valid());
+ mln_assertion(group(g).pixel_area() == pixel_area_ref[g]);
+ mln_assertion(group(g).bbox() == bbox_ref[g]);
+ mln_assertion(group(g).component_ids().nelements() == comp_ids_count_ref[g]);
+
+ for_all_elements(e, group(g).component_ids())
+ mln_assertion(group(g).component_ids()[e] == comp_ids_ref[g][e]);
}
-
+ // Checking group_of()
+ for_all_comps(c, comps)
+ mln_assertion(group.group_of(c).id() == comp_to_group_ref[c]);
}
--
1.5.6.5
1
0

03 May '11
---
scribo/ChangeLog | 4 ++++
scribo/tests/unit_test/unit-tests.mk | 16 ++++++++++++----
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index f139bb6..a6ef3f8 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,9 @@
2011-05-03 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ * tests/unit_test/unit-tests.mk: Regen.
+
+2011-05-03 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
Add a test for object_groups.
* tests/core/Makefile.am: New target.
diff --git a/scribo/tests/unit_test/unit-tests.mk b/scribo/tests/unit_test/unit-tests.mk
index c654084..309b482 100644
--- a/scribo/tests/unit_test/unit-tests.mk
+++ b/scribo/tests/unit_test/unit-tests.mk
@@ -38,6 +38,7 @@ check_PROGRAMS += \
scribo_convert_from_base64 \
scribo_convert_from_qimage \
scribo_io_xml_internal_full_xml_visitor \
+scribo_io_xml_internal_save_image_to_xml \
scribo_io_xml_load
scribo_convert_from_base64_CPPFLAGS= ${QT_CPPFLAGS} -DHAVE_QT ${AM_CPPFLAGS}
@@ -49,6 +50,9 @@ scribo_convert_from_qimage_SOURCES = scribo_convert_from_qimage.cc
scribo_io_xml_internal_full_xml_visitor_CPPFLAGS= ${QT_CPPFLAGS} -DHAVE_QT ${AM_CPPFLAGS}
scribo_io_xml_internal_full_xml_visitor_LDFLAGS= ${QT_LDFLAGS} ${AM_LDFLAGS}
scribo_io_xml_internal_full_xml_visitor_SOURCES = scribo_io_xml_internal_full_xml_visitor.cc
+scribo_io_xml_internal_save_image_to_xml_CPPFLAGS= ${QT_CPPFLAGS} -DHAVE_QT ${AM_CPPFLAGS}
+scribo_io_xml_internal_save_image_to_xml_LDFLAGS= ${QT_LDFLAGS} ${AM_LDFLAGS}
+scribo_io_xml_internal_save_image_to_xml_SOURCES = scribo_io_xml_internal_save_image_to_xml.cc
scribo_io_xml_load_CPPFLAGS= ${QT_CPPFLAGS} -DHAVE_QT ${AM_CPPFLAGS}
scribo_io_xml_load_LDFLAGS= ${QT_LDFLAGS} ${AM_LDFLAGS}
scribo_io_xml_load_SOURCES = scribo_io_xml_load.cc
@@ -117,8 +121,10 @@ scribo_core_def_color_type \
scribo_core_def_lbl_type \
scribo_core_document \
scribo_core_erase_objects \
+scribo_core_group_info \
scribo_core_init_integral_image \
scribo_core_internal_doc_serializer \
+scribo_core_internal_sort_comp_ids \
scribo_core_line_info \
scribo_core_line_links \
scribo_core_line_set \
@@ -158,16 +164,16 @@ scribo_estim_components_features \
scribo_estim_font_boldness \
scribo_estim_font_color \
scribo_estim_internal_compute_skeleton \
-scribo_estim_object_groups_v_thickness \
+scribo_estim_object_groups_mean_width \
scribo_filter_all \
scribo_filter_common_objects_photo \
scribo_filter_internal_alignment_angle \
scribo_filter_internal_component_aligned \
scribo_filter_internal_compute \
scribo_filter_line_links_x_height \
+scribo_filter_object_groups_mean_width \
scribo_filter_object_groups_size_ratio \
scribo_filter_object_groups_small \
-scribo_filter_object_groups_v_thickness \
scribo_filter_object_groups_with_holes \
scribo_filter_object_links_aligned \
scribo_filter_object_links_bbox_h_ratio \
@@ -361,8 +367,10 @@ scribo_core_def_color_type_SOURCES = scribo_core_def_color_type.cc
scribo_core_def_lbl_type_SOURCES = scribo_core_def_lbl_type.cc
scribo_core_document_SOURCES = scribo_core_document.cc
scribo_core_erase_objects_SOURCES = scribo_core_erase_objects.cc
+scribo_core_group_info_SOURCES = scribo_core_group_info.cc
scribo_core_init_integral_image_SOURCES = scribo_core_init_integral_image.cc
scribo_core_internal_doc_serializer_SOURCES = scribo_core_internal_doc_serializer.cc
+scribo_core_internal_sort_comp_ids_SOURCES = scribo_core_internal_sort_comp_ids.cc
scribo_core_line_info_SOURCES = scribo_core_line_info.cc
scribo_core_line_links_SOURCES = scribo_core_line_links.cc
scribo_core_line_set_SOURCES = scribo_core_line_set.cc
@@ -402,16 +410,16 @@ scribo_estim_components_features_SOURCES = scribo_estim_components_features.cc
scribo_estim_font_boldness_SOURCES = scribo_estim_font_boldness.cc
scribo_estim_font_color_SOURCES = scribo_estim_font_color.cc
scribo_estim_internal_compute_skeleton_SOURCES = scribo_estim_internal_compute_skeleton.cc
-scribo_estim_object_groups_v_thickness_SOURCES = scribo_estim_object_groups_v_thickness.cc
+scribo_estim_object_groups_mean_width_SOURCES = scribo_estim_object_groups_mean_width.cc
scribo_filter_all_SOURCES = scribo_filter_all.cc
scribo_filter_common_objects_photo_SOURCES = scribo_filter_common_objects_photo.cc
scribo_filter_internal_alignment_angle_SOURCES = scribo_filter_internal_alignment_angle.cc
scribo_filter_internal_component_aligned_SOURCES = scribo_filter_internal_component_aligned.cc
scribo_filter_internal_compute_SOURCES = scribo_filter_internal_compute.cc
scribo_filter_line_links_x_height_SOURCES = scribo_filter_line_links_x_height.cc
+scribo_filter_object_groups_mean_width_SOURCES = scribo_filter_object_groups_mean_width.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
scribo_filter_object_groups_with_holes_SOURCES = scribo_filter_object_groups_with_holes.cc
scribo_filter_object_links_aligned_SOURCES = scribo_filter_object_links_aligned.cc
scribo_filter_object_links_bbox_h_ratio_SOURCES = scribo_filter_object_links_bbox_h_ratio.cc
--
1.5.6.5
1
0

last-svn-commit-850-gff536c8 scribo/primitive/extract/separators_nonvisible.hh: Update use of object_groups and object_links.
by Guillaume Lazzara 03 May '11
by Guillaume Lazzara 03 May '11
03 May '11
---
scribo/ChangeLog | 5 +
.../primitive/extract/separators_nonvisible.hh | 229 +++++---------------
2 files changed, 60 insertions(+), 174 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 350b536..9395d2b 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,10 @@
2011-05-03 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ * scribo/primitive/extract/separators_nonvisible.hh: Update use of
+ object_groups and object_links.
+
+2011-05-03 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
Several improvements related to low-level data structures in XML
output.
diff --git a/scribo/scribo/primitive/extract/separators_nonvisible.hh b/scribo/scribo/primitive/extract/separators_nonvisible.hh
index c3e227c..5c26285 100644
--- a/scribo/scribo/primitive/extract/separators_nonvisible.hh
+++ b/scribo/scribo/primitive/extract/separators_nonvisible.hh
@@ -27,84 +27,56 @@
/// \file
///
/// \brief Find non visible separators (whitespaces)
-///
-/// \fixme To be cleaned up
+
#ifndef SCRIBO_PRIMITIVE_EXTRACT_SEPARATORS_NONVISIBLE_HH
# define SCRIBO_PRIMITIVE_EXTRACT_SEPARATORS_NONVISIBLE_HH
-#include <mln/core/concept/image.hh>
-#include <mln/core/image/dmorph/image_if.hh>
-#include <mln/pw/all.hh>
-
-#include <mln/draw/line.hh>
-
-#include <mln/data/wrap.hh>
-#include <mln/data/fill.hh>
-#include <mln/data/convert.hh>
-
+# include <mln/core/concept/image.hh>
+# include <mln/core/image/dmorph/image_if.hh>
+# include <mln/pw/all.hh>
-#include <mln/labeling/colorize.hh>
-#include <mln/labeling/relabel.hh>
-#include <mln/labeling/blobs.hh>
+# include <mln/accu/count_value.hh>
-#include <mln/morpho/closing/structural.hh>
-#include <mln/morpho/closing/area.hh>
-#include <mln/morpho/opening/structural.hh>
-#include <mln/win/rectangle2d.hh>
-#include <mln/win/vline2d.hh>
+# include <mln/draw/line.hh>
-#include <mln/logical/not.hh>
-#include <mln/io/pbm/all.hh>
-#include <mln/io/pgm/all.hh>
-#include <mln/io/ppm/save.hh>
+# include <mln/data/fill.hh>
+# include <mln/data/convert.hh>
-#include <mln/literal/colors.hh>
+# include <mln/labeling/relabel.hh>
+# include <mln/labeling/value.hh>
-#include <mln/value/label_16.hh>
-#include <mln/value/int_u8.hh>
-#include <mln/value/int_u12.hh>
-#include <mln/value/int_u16.hh>
-#include <mln/value/rgb8.hh>
+# include <mln/morpho/closing/structural.hh>
-#include <mln/draw/box_plain.hh>
+# include <mln/literal/colors.hh>
-#include <mln/transform/influence_zone_geodesic.hh>
+# include <mln/value/label_16.hh>
+# include <mln/value/int_u8.hh>
+# include <mln/value/rgb8.hh>
-#include <mln/data/stretch.hh>
+# include <mln/util/timer.hh>
-#include <mln/util/timer.hh>
+# include <scribo/core/object_groups.hh>
+# include <scribo/core/component_set.hh>
+# include <scribo/core/def/lbl_type.hh>
-#include <mln/norm/l1.hh>
+# include <scribo/debug/logger.hh>
-#include <scribo/debug/logger.hh>
-#include <scribo/core/object_groups.hh>
-#include <scribo/core/component_set.hh>
-#include <scribo/primitive/extract/components.hh>
+# include <scribo/filter/object_groups_small.hh>
+# include <scribo/filter/object_links_bottom_aligned.hh>
+# include <scribo/filter/object_links_top_aligned.hh>
-#include <scribo/primitive/extract/lines_h_pattern.hh>
-#include <scribo/primitive/remove/separators.hh>
+# include <scribo/preprocessing/rotate_90.hh>
-#include <scribo/preprocessing/denoise_fg.hh>
-#include <scribo/preprocessing/rotate_90.hh>
+# include <scribo/primitive/extract/components.hh>
-#include <scribo/primitive/link/internal/compute_anchor.hh>
+# include <scribo/primitive/link/internal/dmax_default.hh>
+# include <scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh>
+# include <scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh>
-#include <scribo/primitive/link/internal/dmax_default.hh>
+# include <scribo/primitive/group/from_double_link_any.hh>
-#include <scribo/primitive/link/with_single_right_link_dmax_ratio_aligned.hh>
-#include <scribo/primitive/link/with_single_left_link_dmax_ratio_aligned.hh>
-#include <scribo/primitive/group/from_double_link_any.hh>
-
-#include <scribo/filter/object_links_top_aligned.hh>
-#include <scribo/filter/object_groups_small.hh>
-#include <scribo/filter/object_links_bottom_aligned.hh>
-
-#include <scribo/core/def/lbl_type.hh>
-#include <scribo/core/line_set.hh>
-#include <scribo/text/extract_lines.hh>
-#include <mln/draw/box.hh>
namespace scribo
@@ -120,7 +92,8 @@ namespace scribo
using namespace scribo::debug;
- /// \brief Find non visible separators (whitespaces)
+ /// \brief Find non visible separators. Based on components
+ /// alignments.
//
template <typename I>
mln_concrete(I)
@@ -161,20 +134,9 @@ namespace scribo
// Closing structural - Connect characters.
t.start();
- // line_set<L> lines = text::extract_lines(in, c8());
-
- // mln_concrete(I) input_clo;
- // initialize(input_clo, in);
- // data::fill(input_clo, false);
-
- // for_all_lines(l, lines)
- // draw::box(input_clo, lines(l).bbox(), true);
-
win::hline2d vl(17);
mln_concrete(I) input_clo = morpho::closing::structural(in, vl);
-
-
float t_ = t;
std::cout << "closing_structural - " << t_ << std::endl;
@@ -320,23 +282,7 @@ namespace scribo
t_ = t;
std::cout << "small groups - " << t_ << std::endl;
-
// Compute group bboxes
- t.restart();
- util::array<accu::shape::bbox<point2d> >
- top_accu(top_groups.nelements()),
- bot_accu(bot_groups.nelements());
-
-
- for_all_groups(c, top_groups)
- {
- top_accu(top_groups(c)).take(components(c).bbox());
- bot_accu(bot_groups(c)).take(components(c).bbox());
- }
- t_ = t;
- std::cout << "groups to group bboxes - " << t_ << std::endl;
-
-
t.restart();
mln_concrete(I) separators;
@@ -350,26 +296,28 @@ namespace scribo
std::cout << "Initialize separators image - " << t_ << std::endl;
t.restart();
- for_all_comp_data(d, top_accu)
- {
- if (top_accu(d).is_valid())
+ for_all_groups(d, top_groups)
+ if (top_groups(d).is_valid())
{
mln::draw::line(separators,
- top_accu(d).to_result().pmin(),
- point2d(top_accu(d).to_result().pmin().row(),
- top_accu(d).to_result().pmax().col()),
+ top_groups(d).bbox().pmin(),
+ point2d(top_groups(d).bbox().pmin().row(),
+ top_groups(d).bbox().pmax().col()),
true);
}
- if (bot_accu(d).is_valid())
+
+
+ for_all_groups(d, bot_groups)
+ if (bot_groups(d).is_valid())
{
mln::draw::line(separators,
- point2d(bot_accu(d).to_result().pmax().row(),
- bot_accu(d).to_result().pmin().col()),
- bot_accu(d).to_result().pmax(),
+ point2d(bot_groups(d).bbox().pmax().row(),
+ bot_groups(d).bbox().pmin().col()),
+ bot_groups(d).bbox().pmax(),
true);
}
- }
+
t_ = t;
std::cout << "Drawing output image - " << t_ << std::endl;
@@ -379,94 +327,30 @@ namespace scribo
// Restore input orientation.
mln_concrete(I) input = scribo::preprocessing::rotate_90(in, false);
-
- // Debug group bboxes (includes all bboxes before filtering)
- util::array<accu::shape::bbox<point2d> >
- btop_accu(top_groups.nelements()),
- bbot_accu(bot_groups.nelements());
-
-
- for_all_groups(c, top_groups)
- {
- btop_accu(top_groups(c)).take(components(c).bbox());
- bbot_accu(bot_groups(c)).take(components(c).bbox());
- }
-
mln_ch_value(I, value::rgb8)
wo_filtering = data::convert(value::rgb8(), input);
- for_all_comp_data(d, btop_accu)
- {
- if (btop_accu(d).is_valid())
+ for_all_groups(d, top_groups)
+ if (top_groups(d).is_valid())
{
mln::draw::line(wo_filtering,
- btop_accu(d).to_result().pmin(),
- point2d(btop_accu(d).to_result().pmin().row(),
- btop_accu(d).to_result().pmax().col()),
+ top_groups(d).bbox().pmin(),
+ point2d(top_groups(d).bbox().pmin().row(),
+ top_groups(d).bbox().pmax().col()),
literal::green);
-
}
- }
- for_all_comp_data(d, bbot_accu)
- {
- if (bbot_accu(d).is_valid())
+ for_all_groups(d, bot_groups)
+ if (bot_groups(d).is_valid())
{
mln::draw::line(wo_filtering,
- point2d(bbot_accu(d).to_result().pmax().row(),
- bbot_accu(d).to_result().pmin().col()),
- bbot_accu(d).to_result().pmax(),
+ point2d(bot_groups(d).bbox().pmax().row(),
+ bot_groups(d).bbox().pmin().col()),
+ bot_groups(d).bbox().pmax(),
literal::green);
}
- }
- logger().log_image(AuxiliaryResults, wo_filtering, "wo_filtering");
- // mln_ch_value(I, value::rgb8) both = data::convert(value::rgb8(), input);
-
- // for_all_comp_data(d, top_accu)
- // {
- // if (top_accu(d).is_valid() || btop_accu(d).is_valid())
- // {
- // if (top_accu(d).is_valid())
- // {
- // mln::draw::line(both,
- // top_accu(d).to_result().pmin(),
- // point2d(top_accu(d).to_result().pmin().row(),
- // top_accu(d).to_result().pmax().col()),
- // literal::green);
- // }
- // else
- // if (btop_accu(d).is_valid())
- // mln::draw::line(both,
- // btop_accu(d).to_result().pmin(),
- // point2d(btop_accu(d).to_result().pmin().row(),
- // btop_accu(d).to_result().pmax().col()),
- // literal::yellow);
-
- // }
- // if (bot_accu(d).is_valid() || bbot_accu(d).is_valid())
- // {
- // if (bot_accu(d).is_valid())
- // {
- // mln::draw::line(both,
- // point2d(bot_accu(d).to_result().pmax().row(),
- // bot_accu(d).to_result().pmin().col()),
- // bot_accu(d).to_result().pmax(),
- // literal::green);
- // }
- // else
- // if (bbot_accu(d).is_valid())
- // mln::draw::line(both,
- // point2d(bbot_accu(d).to_result().pmax().row(),
- // bbot_accu(d).to_result().pmin().col()),
- // bbot_accu(d).to_result().pmax(),
- // literal::yellow);
- // }
-
- // }
-
- // logger().log_image(AuxiliaryResults,
- // both, "both");
+ logger().log_image(AuxiliaryResults, wo_filtering, "wo_filtering");
logger().log_image(AuxiliaryResults, separators, "separators");
}
@@ -500,9 +384,6 @@ namespace scribo
t_ = t;
std::cout << "* accu::transform_line - " << t_ << std::endl;
- // if (_debug_)
- // io::pgm::save(data::convert(value::int_u8(), tmp), "tmp.pgm");
-
t.restart();
value::int_u8 nlabels;
--
1.5.6.5
1
0

last-svn-commit-849-g6404315 Several improvements related to low-level data structures in XML output.
by Guillaume Lazzara 03 May '11
by Guillaume Lazzara 03 May '11
03 May '11
* scribo/core/component_features_data.hh,
* scribo/core/component_info.hh,
* scribo/core/component_set.hh,
* scribo/core/document.hh,
* scribo/core/line_links.hh,
* scribo/core/paragraph_info.hh,
* scribo/core/paragraph_set.hh: Add operator==().
* scribo/io/xml/internal/full_xml_visitor.hh: Save more data for
groups, separators and paragraphs.
* scribo/io/xml/internal/save_image_to_xml.hh: New.
* scribo/io/xml/load.hh: Load new saved data.
* tests/unit_test/cond_tests_qt: Add save_image_to_xml.hh.
---
scribo/ChangeLog | 22 +++
scribo/scribo/core/component_features_data.hh | 16 ++
scribo/scribo/core/component_info.hh | 17 ++
scribo/scribo/core/component_set.hh | 36 +++--
scribo/scribo/core/document.hh | 68 +++++++-
scribo/scribo/core/line_links.hh | 12 ++
scribo/scribo/core/paragraph_info.hh | 19 +++
scribo/scribo/core/paragraph_set.hh | 21 +++
scribo/scribo/io/xml/internal/full_xml_visitor.hh | 118 +++++++++------
...{print_image_coords.hh => save_image_to_xml.hh} | 70 +++++----
scribo/scribo/io/xml/load.hh | 164 ++++++++++++++++++--
scribo/tests/unit_test/cond_tests_qt | 1 +
12 files changed, 456 insertions(+), 108 deletions(-)
copy scribo/scribo/io/xml/internal/{print_image_coords.hh => save_image_to_xml.hh} (54%)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 637fca8..350b536 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,27 @@
2011-05-03 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ Several improvements related to low-level data structures in XML
+ output.
+
+ * scribo/core/component_features_data.hh,
+ * scribo/core/component_info.hh,
+ * scribo/core/component_set.hh,
+ * scribo/core/document.hh,
+ * scribo/core/line_links.hh,
+ * scribo/core/paragraph_info.hh,
+ * scribo/core/paragraph_set.hh: Add operator==().
+
+ * scribo/io/xml/internal/full_xml_visitor.hh: Save more data for
+ groups, separators and paragraphs.
+
+ * scribo/io/xml/internal/save_image_to_xml.hh: New.
+
+ * scribo/io/xml/load.hh: Load new saved data.
+
+ * tests/unit_test/cond_tests_qt: Add save_image_to_xml.hh.
+
+2011-05-03 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
* scribo/toolchain/internal/content_in_doc_functor.hh: Make use of
component::extract::alignments.
diff --git a/scribo/scribo/core/component_features_data.hh b/scribo/scribo/core/component_features_data.hh
index 07b3e4a..b0a4e47 100644
--- a/scribo/scribo/core/component_features_data.hh
+++ b/scribo/scribo/core/component_features_data.hh
@@ -49,9 +49,14 @@ namespace scribo
std::ostream&
operator<<(std::ostream& ostr, const component_features_data& data);
+ bool
+ operator==(const component_features_data& lhs,
+ const component_features_data& rhs);
+
# ifndef MLN_INCLUDE_ONLY
+ inline
component_features_data::component_features_data()
: valid(false)
{
@@ -69,6 +74,17 @@ namespace scribo
<< "]" << std::endl;
}
+
+ bool
+ operator==(const component_features_data& lhs,
+ const component_features_data& rhs)
+ {
+ return
+ lhs.valid == rhs.valid
+ && lhs.color == rhs.color
+ && lhs.boldness == rhs.boldness;
+ }
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo
diff --git a/scribo/scribo/core/component_info.hh b/scribo/scribo/core/component_info.hh
index 164a242..1f94076 100644
--- a/scribo/scribo/core/component_info.hh
+++ b/scribo/scribo/core/component_info.hh
@@ -97,6 +97,9 @@ namespace scribo
std::ostream&
operator<<(std::ostream& ostr, const component_info& info);
+ bool
+ operator==(const component_info& lhs, const component_info& rhs);
+
# ifndef MLN_INCLUDE_ONLY
@@ -230,6 +233,20 @@ namespace scribo
<< ")" << std::endl;
}
+ inline
+ bool
+ operator==(const component_info& lhs, const component_info& rhs)
+ {
+
+ return
+ lhs.id() == rhs.id()
+ && lhs.bbox() == rhs.bbox()
+ && lhs.mass_center() == rhs.mass_center()
+ && lhs.card() == rhs.card()
+ && lhs.features() == rhs.features()
+ && lhs.tag() == rhs.tag()
+ && lhs.type() == rhs.type();
+ }
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/scribo/core/component_set.hh b/scribo/scribo/core/component_set.hh
index d729802..3587302 100644
--- a/scribo/scribo/core/component_set.hh
+++ b/scribo/scribo/core/component_set.hh
@@ -459,22 +459,6 @@ namespace scribo
return data_->infos_[id];
}
-// template <typename L>
-// inline
-// const component_info&
-// component_set<L>::operator()(const mln_value(L)& id) const
-// {
-// return data_->infos_[id];
-// }
-
-// template <typename L>
-// inline
-// component_info&
-// component_set<L>::operator()(const mln_value(L)& id)
-// {
-// return data_->infos_[id];
-// }
-
template <typename L>
inline
const component_info&
@@ -650,7 +634,25 @@ namespace scribo
bool
operator==(const component_set<L>& lhs, const component_set<L>& rhs)
{
- return lhs.id_() == rhs.id_();
+ if (! (lhs.labeled_image() == rhs.labeled_image()))
+ std::cout << "comp.lbl" << std::endl;
+
+ if (! (lhs.separators() == rhs.separators()))
+ std::cout << "comp.seps" << std::endl;
+
+ if (! (lhs.nelements() == rhs.nelements()
+ && lhs.labeled_image() == rhs.labeled_image()
+ && lhs.separators() == rhs.separators()))
+ return false;
+
+ for_all_comps(c, lhs)
+ if (! (lhs(c) == rhs(c)))
+ {
+ std::cout << "comp.info" << std::endl;
+ return false;
+ }
+
+ return true;
}
template <typename L>
diff --git a/scribo/scribo/core/document.hh b/scribo/scribo/core/document.hh
index f38b20b..e287c1d 100644
--- a/scribo/scribo/core/document.hh
+++ b/scribo/scribo/core/document.hh
@@ -88,19 +88,27 @@ namespace scribo
bool has_whitespace_seps() const;
const mln::image2d<bool>& whitespace_seps() const;
const component_set<L>& whitespace_seps_comps() const;
- void set_whitespace_separators(const image2d<bool>& whitespace_seps);
+ void set_whitespace_separators(const image2d<bool>& whitespace_seps,
+ const component_set<L>& whitespace_seps_comps);
// Horizontal separators
bool has_hline_seps() const;
const mln::image2d<bool>& hline_seps() const;
const component_set<L>& hline_seps_comps() const;
+ // Set vline separators image. The component is automatically computed.
void set_hline_separators(const image2d<bool>& line_seps);
+ void set_hline_separators(const image2d<bool>& line_seps,
+ const component_set<L>& hline_seps_comps);
// Vertical separators
bool has_vline_seps() const;
const mln::image2d<bool>& vline_seps() const;
const component_set<L>& vline_seps_comps() const;
- void set_vline_separators(const image2d<bool>& line_seps);
+
+ // Set vline separators image. The component is automatically computed.
+ void set_vline_separators(const image2d<bool>& vline_seps);
+ void set_vline_separators(const image2d<bool>& vline_seps,
+ const component_set<L>& vline_seps_comps);
const mln::image2d<value::rgb8>& image() const;
void set_image(const mln::image2d<value::rgb8>& image);
@@ -128,6 +136,9 @@ namespace scribo
};
+ template <typename L>
+ bool operator==(const document<L>& lhs, const document<L>& rhs);
+
# ifndef MLN_INCLUDE_ONLY
@@ -291,14 +302,11 @@ namespace scribo
template <typename L>
void
- document<L>::set_whitespace_separators(const image2d<bool>& whitespace_seps)
+ document<L>::set_whitespace_separators(const image2d<bool>& whitespace_seps,
+ const component_set<L>& whitespace_seps_comps)
{
whitespace_seps_ = whitespace_seps;
-
- mln_value(L) ncomps;
- whitespace_seps_comps_ = primitive::extract::components(whitespace_seps,
- mln::c8(), ncomps,
- component::WhitespaceSeparator);
+ whitespace_seps_comps_ = whitespace_seps_comps;
}
@@ -340,6 +348,16 @@ namespace scribo
template <typename L>
+ void
+ document<L>::set_hline_separators(const image2d<bool>& hline_seps,
+ const component_set<L>& hline_seps_comps)
+ {
+ hline_seps_ = hline_seps;
+ hline_seps_comps_ = hline_seps_comps;
+ }
+
+
+ template <typename L>
bool
document<L>::has_vline_seps() const
{
@@ -377,6 +395,16 @@ namespace scribo
template <typename L>
+ void
+ document<L>::set_vline_separators(const image2d<bool>& vline_seps,
+ const component_set<L>& vline_seps_comps)
+ {
+ vline_seps_ = vline_seps;
+ vline_seps_comps_ = vline_seps_comps;
+ }
+
+
+ template <typename L>
const mln::image2d<value::rgb8>&
document<L>::image() const
{
@@ -408,6 +436,30 @@ namespace scribo
}
+ template <typename L>
+ bool operator==(const document<L>& lhs, const document<L>& rhs)
+ {
+
+
+ return
+ lhs.filename() == rhs.filename()
+ && lhs.image() == rhs.image()
+ && lhs.binary_image() == rhs.binary_image()
+ && lhs.has_text() == rhs.has_text()
+ && lhs.paragraphs() == rhs.paragraphs()
+ && lhs.has_elements() == rhs.has_elements()
+ && lhs.elements() == rhs.elements()
+ && lhs.has_whitespace_seps() == rhs.has_whitespace_seps()
+ && lhs.whitespace_seps() == rhs.whitespace_seps()
+ && lhs.whitespace_seps_comps() == rhs.whitespace_seps_comps()
+ && lhs.has_hline_seps() == rhs.has_hline_seps()
+ && lhs.hline_seps() == rhs.hline_seps()
+ && lhs.hline_seps_comps() == rhs.hline_seps_comps()
+ && lhs.has_vline_seps() == rhs.has_vline_seps()
+ && lhs.vline_seps() == rhs.vline_seps()
+ && lhs.vline_seps_comps() == rhs.vline_seps_comps();
+ }
+
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/scribo/core/line_links.hh b/scribo/scribo/core/line_links.hh
index ab36a73..b7b438c 100644
--- a/scribo/scribo/core/line_links.hh
+++ b/scribo/scribo/core/line_links.hh
@@ -103,6 +103,10 @@ namespace scribo
std::ostream&
operator<<(std::ostream& ostr, const line_links<L>& links);
+ template <typename L>
+ bool
+ operator==(const line_links<L>& lhs, const line_links<L>& rhs);
+
# ifndef MLN_INCLUDE_ONLY
@@ -254,6 +258,14 @@ namespace scribo
}
+ template <typename L>
+ bool
+ operator==(const line_links<L>& lhs, const line_links<L>& rhs)
+ {
+ return lhs.lines() == rhs.lines()
+ && lhs.line_to_link() == rhs.line_to_link();
+ }
+
# endif // ! MLN_INCLUDE_ONLY
diff --git a/scribo/scribo/core/paragraph_info.hh b/scribo/scribo/core/paragraph_info.hh
index 557ded7..52068a7 100644
--- a/scribo/scribo/core/paragraph_info.hh
+++ b/scribo/scribo/core/paragraph_info.hh
@@ -89,6 +89,8 @@ namespace scribo
template <typename L>
std::ostream& operator<<(std::ostream& ostr, const paragraph_info<L>& info);
+ template <typename L>
+ bool operator==(const paragraph_info<L>& lhs, const paragraph_info<L>& rhs);
# ifndef MLN_INCLUDE_ONLY
@@ -248,6 +250,22 @@ namespace scribo
}
template <typename L>
+ bool
+ operator==(const paragraph_info<L>& lhs, const paragraph_info<L>& rhs)
+ {
+
+
+
+ return
+ lhs.line_ids() == rhs.line_ids()
+ && lhs.bbox() == rhs.bbox()
+ && lhs.llinks() == rhs.llinks()
+ && lhs.color() == rhs.color()
+ && lhs.color_reliability() == rhs.color_reliability()
+ && lhs.needs_stats_update() == rhs.needs_stats_update();
+ }
+
+ template <typename L>
std::ostream&
operator<<(std::ostream& ostr, const paragraph_info<L>& info)
{
@@ -259,6 +277,7 @@ namespace scribo
<< ")" << std::endl;
}
+
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace scribo
diff --git a/scribo/scribo/core/paragraph_set.hh b/scribo/scribo/core/paragraph_set.hh
index ec9f51b..242501d 100644
--- a/scribo/scribo/core/paragraph_set.hh
+++ b/scribo/scribo/core/paragraph_set.hh
@@ -86,6 +86,8 @@ namespace scribo
};
+ template <typename L>
+ bool operator==(const paragraph_set<L>& lhs, const paragraph_set<L>& rhs);
namespace make
{
@@ -200,6 +202,25 @@ namespace scribo
}
+ template <typename L>
+ bool operator==(const paragraph_set<L>& lhs, const paragraph_set<L>& rhs)
+ {
+ if (! (lhs.lines() == rhs.lines() && lhs.nelements() == rhs.nelements()))
+ {
+ return false;
+ }
+
+ for_all_paragraphs(p, lhs)
+ if (!(lhs(p) == rhs(p)))
+ {
+ std::cout << "paragraph.info" << std::endl;
+ return false;
+ }
+
+ return true;
+ }
+
+
namespace make
{
diff --git a/scribo/scribo/io/xml/internal/full_xml_visitor.hh b/scribo/scribo/io/xml/internal/full_xml_visitor.hh
index bba7691..c294bbc 100644
--- a/scribo/scribo/io/xml/internal/full_xml_visitor.hh
+++ b/scribo/scribo/io/xml/internal/full_xml_visitor.hh
@@ -43,13 +43,10 @@
# include <scribo/core/line_links.hh>
# include <scribo/core/line_info.hh>
+# include <scribo/io/xml/internal/save_image_to_xml.hh>
# include <scribo/io/xml/internal/print_box_coords.hh>
# include <scribo/io/xml/internal/print_page_preambule.hh>
-// Compression level 0-9. 9 is the best but is slow.
-// 5 seems to be a good compromise.
-# define COMPRESSION_LEVEL 5
-
namespace scribo
{
@@ -157,20 +154,46 @@ namespace scribo
if (doc.has_elements())
{
const component_set<L>& elts = doc.elements();
+
+ output << " <elements>" << std::endl;
+ elts.accept(*this);
+
for_all_comps(e, elts)
if (elts(e).is_valid())
elts(e).accept(*this);
+
+ output << " </elements>" << std::endl;
}
// line seraparators
if (doc.has_hline_seps())
+ {
+ output << " <hlines_separators>" << std::endl;
+ doc.hline_seps_comps().accept(*this);
+
for_all_comps(c, doc.hline_seps_comps())
doc.hline_seps_comps()(c).accept(*this);
+
+ save_image_to_xml(output, doc.hline_seps(),
+ "hlines_separators_image");
+
+ output << " </hlines_separators>" << std::endl;
+ }
if (doc.has_vline_seps())
+ {
+ output << " <vlines_separators>" << std::endl;
+ doc.vline_seps_comps().accept(*this);
+
for_all_comps(c, doc.vline_seps_comps())
doc.vline_seps_comps()(c).accept(*this);
+ save_image_to_xml(output, doc.vline_seps(),
+ "vlines_separators_image");
+
+ output << " </vlines_separators>" << std::endl;
+ }
+
// Whitespace seraparators
if (doc.has_whitespace_seps())
@@ -178,8 +201,16 @@ namespace scribo
const component_set<L>&
whitespace_seps_comps = doc.whitespace_seps_comps();
+ output << " <whitespaces_delimitors>" << std::endl;
+ whitespace_seps_comps.accept(*this);
+
for_all_comps(c, whitespace_seps_comps)
whitespace_seps_comps(c).accept(*this);
+
+ save_image_to_xml(output, doc.whitespace_seps(),
+ "whitespaces_delimitors_image");
+
+ output << " </whitespaces_delimitors>" << std::endl;
}
output << " </page>" << std::endl;
@@ -212,13 +243,26 @@ namespace scribo
void
full_xml_visitor::visit(const object_groups<L>& groups) const
{
- output << " <object_groups>" << std::endl;
+ output << " <object_groups ngroups=\"" << groups.nelements()
+ << "\">" << std::endl;
+
for_all_groups(g, groups)
{
- output << " <group "
- << " object_id=\"" << g
- << "\" group_id=\"" << groups(g)
- << "\"/>" << std::endl;
+ output << " <group id=\"" << groups(g).id()
+ << "\" valid=\"" << groups(g).is_valid()
+ << "\" pixel_area=\"" << groups(g).pixel_area()
+ << "\" pmin_x=\"" << groups(g).bbox().pmin().row()
+ << "\" pmin_y=\"" << groups(g).bbox().pmin().col()
+ << "\" pmax_x=\"" << groups(g).bbox().pmax().row()
+ << "\" pmax_y=\"" << groups(g).bbox().pmax().col()
+ << "\">" << std::endl;
+
+ for_all_elements(e, groups(g).component_ids())
+ output << " <group_member comp_id=\""
+ << groups(g).component_ids()(e)
+ << "\"/>" << std::endl;
+
+ output << " </group>" << std::endl;
}
output << " </object_groups>" << std::endl;
}
@@ -263,51 +307,36 @@ namespace scribo
<< "\" pmin_x=\"" << comp_set(c).bbox().pmin().col()
<< "\" pmin_y=\"" << comp_set(c).bbox().pmin().row()
<< "\" pmax_x=\"" << comp_set(c).bbox().pmax().col()
- << "\" pmax_y=\"" << comp_set(c).bbox().pmax().row()
- << "\"/>" << std::endl;
+ << "\" pmax_y=\"" << comp_set(c).bbox().pmax().row();
+
+ if (comp_set(c).has_features())
+ {
+ output << "\">" << std::endl;
+
+ output << " <component_features"
+ << " valid=\"" << comp_set(c).features().valid
+ << "\" color=\"" << comp_set(c).features().color
+ << "\" boldness=\"" << comp_set(c).features().boldness
+ << "\"/>" << std::endl;
+
+ output << " </component_info>" << std::endl;
+ }
+ else
+ output << "\"/>" << std::endl;
}
// Save labeled image
{
const L& lbl = comp_set.labeled_image();
- output << "<labeled_image "
- << " height=\"" << lbl.domain().height()
- << "\" width=\"" << lbl.domain().width() << "\">"
- << "<![CDATA[";
-
- // FIXME: Try to avoid that!
- border::resize(lbl, 0);
- QByteArray
- lbl64 = QByteArray::fromRawData((const char *)lbl.buffer(),
- lbl.nelements() * sizeof(mln_value(L)));
- lbl64 = qCompress(lbl64, COMPRESSION_LEVEL);
- lbl64 = lbl64.toBase64();
-
- output.write(lbl64.data(), lbl64.size());
-
- output << "]]></labeled_image>" << std::endl;
+ save_image_to_xml(output, lbl, "labeled_image");
}
// Save separators image
if (comp_set.has_separators())
{
const mln_ch_value(L,bool)& seps = comp_set.separators();
- output << "<separators_image "
- << " height=\"" << seps.domain().height()
- << "\" width=\"" << seps.domain().width() << "\">"
- << "<![CDATA[";
-
- border::resize(seps, 0);
- QByteArray
- seps64 = QByteArray::fromRawData((const char *)seps.buffer(),
- seps.nelements() * sizeof(bool));
- seps64 = qCompress(seps64, COMPRESSION_LEVEL);
- seps64 = seps64.toBase64();
-
- output.write(seps64.data(), seps64.size());
-
- output << "]]></separators_image>" << std::endl;
+ save_image_to_xml(output, seps, "separators_image");
}
output << "</component_set>" << std::endl;
@@ -394,7 +423,9 @@ namespace scribo
<< "\" x_height=\"" << lines(fid).x_height()
<< "\" d_height=\"" << lines(fid).d_height()
<< "\" a_height=\"" << lines(fid).a_height()
- << "\" char_width=\"" << lines(fid).char_width();
+ << "\" char_width=\"" << lines(fid).char_width()
+ << "\" color=\"" << parset(p).color()
+ << "\" color_reliability=\"" << parset(p).color_reliability();
// End of EXTENSIONS
output << "\">"
<< std::endl;
@@ -469,6 +500,5 @@ namespace scribo
} // end of namespace scribo
-# undef COMPRESSION_LEVEL
#endif // SCRIBO_IO_XML_INTERNAL_FULL_XML_VISITOR_HH
diff --git a/scribo/scribo/io/xml/internal/print_image_coords.hh b/scribo/scribo/io/xml/internal/save_image_to_xml.hh
similarity index 54%
copy from scribo/scribo/io/xml/internal/print_image_coords.hh
copy to scribo/scribo/io/xml/internal/save_image_to_xml.hh
index ebfe402..3f38337 100644
--- a/scribo/scribo/io/xml/internal/print_image_coords.hh
+++ b/scribo/scribo/io/xml/internal/save_image_to_xml.hh
@@ -23,15 +23,24 @@
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
-#ifndef SCRIBO_IO_XML_INTERNAL_PRINT_IMAGE_COORDS_HH
-# define SCRIBO_IO_XML_INTERNAL_PRINT_IMAGE_COORDS_HH
+#ifndef SCRIBO_IO_XML_INTERNAL_SAVE_IMAGE_TO_XML_HH
+# define SCRIBO_IO_XML_INTERNAL_SAVE_IMAGE_TO_XML_HH
/// \file
///
-/// \brief Prints box2d coordinates to XML data.
+/// Save an image as XML data.
-# include <fstream>
-# include <mln/core/concept/site_set.hh>
+# include <iostream>
+
+# include <QtXml>
+
+# include <mln/core/concept/image.hh>
+# include <mln/border/resize.hh>
+
+
+// Compression level 0-9. 9 is the best but is slow.
+// 5 seems to be a good compromise.
+# define COMPRESSION_LEVEL 5
namespace scribo
{
@@ -44,42 +53,43 @@ namespace scribo
namespace internal
{
-
using namespace mln;
- /*! \brief Prints box2d coordinates to XML data.
- */
- template <typename S>
+ template <typename I>
void
- print_image_coords(std::ofstream& ostr, const mln::Site_Set<S>& b,
- const char *space);
-
+ save_image_to_xml(std::ostream& output, const Image<I>& ima,
+ const char *qname);
# ifndef MLN_INCLUDE_ONLY
-
- template <typename S>
+ template <typename I>
void
- print_image_coords(std::ofstream& ostr, const mln::Site_Set<S>& b_,
- const char *space)
+ save_image_to_xml(std::ostream& output, const Image<I>& ima_,
+ const char *qname)
{
- std::string sc = space;
- std::string sp = sc + " ";
+ trace::entering("scribo::io::xml::internal::save_image");
- const S& b = exact(b_);
- mln_precondition(b.is_valid());
+ mln_precondition(exact(ima_).is_valid());
+ const I& ima = exact(ima_);
- ostr << sc << "<coords>" << std::endl;
+ output << "<" << qname
+ << " height=\"" << ima.domain().height()
+ << "\" width=\"" << ima.domain().width() << "\">"
+ << "<![CDATA[";
- mln_piter(S) p(b);
- for_all(p)
- ostr << sp << "<point x=\"" << p.col()
- << "\" y=\"" << p.row() << "\"/>"
- << std::endl;
+ mln::border::resize(ima, 0);
+ QByteArray
+ seps64 = QByteArray::fromRawData((const char *)ima.buffer(),
+ ima.nelements() * sizeof(mln_value(I)));
+ seps64 = qCompress(seps64, COMPRESSION_LEVEL);
+ seps64 = seps64.toBase64();
- ostr << sc << "</coords>" << std::endl;
- }
+ output.write(seps64.data(), seps64.size());
+ output << "]]></" << qname << ">" << std::endl;
+
+ trace::exiting("scribo::io::xml::internal::save_image");
+ }
# endif // ! MLN_INCLUDE_ONLY
@@ -91,4 +101,6 @@ namespace scribo
} // end of namespace scribo
-#endif // ! SCRIBO_IO_XML_INTERNAL_PRINT_IMAGE_COORDS_HH
+# undef COMPRESSION_LEVEL
+
+#endif // ! SCRIBO_IO_XML_INTERNAL_SAVE_IMAGE_TO_XML_HH
diff --git a/scribo/scribo/io/xml/load.hh b/scribo/scribo/io/xml/load.hh
index 8042c75..8d89085 100644
--- a/scribo/scribo/io/xml/load.hh
+++ b/scribo/scribo/io/xml/load.hh
@@ -88,6 +88,8 @@ namespace scribo
None,
ComponentSet,
ComponentInfo,
+ ComponentFeatures,
+ Elements,
LabeledImage,
SeparatorsImage,
ObjectLinks,
@@ -95,6 +97,7 @@ namespace scribo
Point,
Link,
Group,
+ GroupMember,
Line,
LineLinks,
LineLink,
@@ -102,7 +105,13 @@ namespace scribo
TextRegion,
CompIdList,
CompId,
- Page
+ Page,
+ WhitespacesDelimitors,
+ HLineSeparators,
+ VLineSeparators,
+ WhitespacesDelimitorsImage,
+ HLineSeparatorsImage,
+ VLineSeparatorsImage,
};
@@ -116,6 +125,8 @@ namespace scribo
static const ModeData mode_data[] = {
{ "component_set", ComponentSet },
{ "component_info", ComponentInfo },
+ { "component_features", ComponentFeatures },
+ { "elements", Elements },
{ "labeled_image", LabeledImage },
{ "separators_image", SeparatorsImage },
{ "object_links", ObjectLinks },
@@ -123,6 +134,7 @@ namespace scribo
{ "point", Point },
{ "link", Link },
{ "group", Group },
+ { "group_member", GroupMember },
{ "line", Line },
{ "line_links", LineLinks },
{ "line_link", LineLink },
@@ -131,10 +143,34 @@ namespace scribo
{ "compid_list", CompIdList },
{ "compid", CompId },
{ "page", Page },
+ { "whitespaces_delimitors", WhitespacesDelimitors },
+ { "hlines_separators", HLineSeparators },
+ { "vlines_separators", VLineSeparators },
+ { "whitespaces_delimitors_image", WhitespacesDelimitorsImage },
+ { "hlines_separators_image", HLineSeparatorsImage },
+ { "vlines_separators_image", VLineSeparatorsImage },
{ 0, None }
};
+ namespace internal
+ {
+
+ value::rgb8 parse_color(const QString& color_str)
+ {
+ QString color = color_str;
+ color.chop(1);
+ color = color.remove(0, 1);
+ QStringList rgb = color.split(',');
+
+ return
+ value::rgb8(rgb.at(0).toInt(),
+ rgb.at(1).toInt(),
+ rgb.at(2).toInt());
+ }
+
+ }
+
template <typename L>
class xml_handler : public QXmlDefaultHandler
{
@@ -142,7 +178,8 @@ namespace scribo
typedef mln_ch_value(L,bool) B;
public:
- xml_handler() : current_paragraph_id(1) { lines_data.append(line_info<L>()); } // line info id starts from 1.
+ xml_handler(document<L>& doc_) : current_paragraph_id(1), doc(doc_)
+ { lines_data.append(line_info<L>()); } // line info id starts from 1.
virtual
bool
@@ -185,6 +222,20 @@ namespace scribo
break;
+ case ComponentFeatures:
+ {
+ if (atts.value("valid").toInt())
+ {
+ component_features_data comp_features;
+ comp_features.valid = true;
+ comp_features.color = internal::parse_color(atts.value("color"));
+ comp_features.boldness = atts.value("boldness").toFloat();
+
+ comp_set_data->infos_.last().update_features(comp_features);
+ }
+ }
+ break;
+
// Object links
case ObjectLinks:
{
@@ -197,8 +248,9 @@ namespace scribo
// Object groups
case ObjectGroups:
{
- // qDebug() << "object_groups created";
- groups = object_groups<L>(links);
+ //qDebug() << "Processing object_groups";
+ group_info_.reserve(atts.value("ngroups").toInt());
+ group_info_.resize(1);
}
break;
@@ -225,6 +277,8 @@ namespace scribo
// qDebug() << "TextRegion";
current_paragraph = paragraph_info<L>(llinks);
+ current_paragraph.set_color_(internal::parse_color(atts.value("color")));
+ current_paragraph.set_color_reliability_(atts.value("color_reliability").toFloat());
}
break;
@@ -257,6 +311,7 @@ namespace scribo
line_data->a_height_ = atts.value("a_height").toInt();
line_data->char_space_ = atts.value("kerning").toInt();
line_data->char_width_ = atts.value("char_width").toInt();
+ line_data->char_width_ = atts.value("char_width").toInt();
line_data->word_space_ = 0;
line_data->reading_direction_ = line::LeftToRight;
@@ -266,6 +321,13 @@ namespace scribo
line_data->reading_orientation_ = atts.value("txt_reading_orientation").toInt();
line_data->indented_ = (atts.value("txt_indented") == "false" ? false : true);
+
+ line_data->boldness_ = atts.value("boldness").toFloat();
+ line_data->boldness_reliability_ = atts.value("boldness_reliability").toFloat();
+ line_data->color_ = internal::parse_color(atts.value("color"));
+
+ line_data->color_reliability_ = atts.value("color_reliability").toFloat();
+
bbox.init();
}
break;
@@ -282,7 +344,7 @@ namespace scribo
// CompId
case CompId:
{
- line_data->components_.append(atts.value("value").toInt());
+ line_data->component_ids_.append(atts.value("value").toInt());
}
break;
@@ -316,10 +378,21 @@ namespace scribo
break;
+ // Separators/delimitor images
+ case WhitespacesDelimitorsImage:
+ case HLineSeparatorsImage:
+ case VLineSeparatorsImage:
+ {
+ width = atts.value("width").toInt();
+ height = atts.value("height").toInt();
+ seps = B(mln::make::box2d(height, width), 0); // No border
+ }
+ break;
+
// Link
case Link:
{
- links(atts.value("from").toInt()) = atts.value("to").toInt();
+ links.update(atts.value("from").toInt(), atts.value("to").toInt());
}
break;
@@ -327,7 +400,20 @@ namespace scribo
// Group
case Group:
{
- groups(atts.value("object_id").toInt()) = atts.value("group_id").toInt();
+ group_info_.append(group_info(atts.value("id").toInt(),
+ atts.value("pixel_area").toInt(),
+ mln::make::box2d(atts.value("pmin_x").toInt(),
+ atts.value("pmin_y").toInt(),
+ atts.value("pmax_x").toInt(),
+ atts.value("pmax_y").toInt()),
+ atts.value("valid").toInt()));
+ }
+ break;
+
+ // GroupMember
+ case GroupMember:
+ {
+ component_ids.append(atts.value("comp_id").toInt());
}
break;
@@ -352,6 +438,7 @@ namespace scribo
{
// qDebug() << "Component set done";
components = component_set<L>(comp_set_data);
+
}
break;
@@ -382,6 +469,46 @@ namespace scribo
// qDebug() << "Page done";
lines.update_line_data_(lines_data);
parset = paragraph_set<L>(par_data);
+ doc.set_paragraphs(parset);
+ }
+ break;
+
+ // ObjectGroups
+ case ObjectGroups:
+ {
+ groups = object_groups<L>(links, group_info_);
+ }
+ break;
+
+ // Group
+ case Group:
+ {
+ group_info_.last().component_ids_() = component_ids;
+ component_ids.clear();
+ }
+ break;
+
+ case Elements:
+ {
+ doc.set_elements(components);
+ }
+ break;
+
+ case WhitespacesDelimitors:
+ {
+ doc.set_whitespace_separators(seps, components);
+ }
+ break;
+
+ case HLineSeparators:
+ {
+ doc.set_hline_separators(seps, components);
+ }
+ break;
+
+ case VLineSeparators:
+ {
+ doc.set_vline_separators(seps, components);
}
break;
@@ -419,6 +546,17 @@ namespace scribo
}
break;
+ case WhitespacesDelimitorsImage:
+ case HLineSeparatorsImage:
+ case VLineSeparatorsImage:
+ {
+ QByteArray data = ch.toAscii();
+ data = QByteArray::fromBase64(data);
+ data = qUncompress(data);
+ memcpy((char *) seps.buffer(), data.data(), data.size());
+ }
+ break;
+
default:
;
}
@@ -453,7 +591,10 @@ namespace scribo
component_set<L> components;
object_links<L> links;
+
object_groups<L> groups;
+ mln::util::array<component_id_t> component_ids;
+ mln::util::array<group_info> group_info_;
// Lines
unsigned current_line_id;
@@ -468,6 +609,11 @@ namespace scribo
mln::util::array<line_info<L> > lines_data;
line_set<L> lines;
+
+ // Delimitors/separators
+ B seps; // Temporary image.
+
+ document<L>& doc;
};
@@ -484,7 +630,7 @@ namespace scribo
load_extended(document<L>& doc,
const std::string& output_name)
{
- xml_handler<L> handler;
+ xml_handler<L> handler(doc);
QXmlSimpleReader reader;
reader.setContentHandler(&handler);
@@ -498,8 +644,6 @@ namespace scribo
QXmlInputSource xmlInputSource(&file);
if (reader.parse(xmlInputSource))
qDebug() << "Loaded successfuly";
-
- doc.set_paragraphs(handler.parset);
}
} // end of namespace scribo::io::xml::internal
diff --git a/scribo/tests/unit_test/cond_tests_qt b/scribo/tests/unit_test/cond_tests_qt
index f7bc42e..4f4b667 100644
--- a/scribo/tests/unit_test/cond_tests_qt
+++ b/scribo/tests/unit_test/cond_tests_qt
@@ -1,4 +1,5 @@
scribo/convert/from_base64.hh
scribo/convert/from_qimage.hh
scribo/io/xml/internal/full_xml_visitor.hh
+scribo/io/xml/internal/save_image_to_xml.hh
scribo/io/xml/load.hh
--
1.5.6.5
1
0

last-svn-commit-848-g2fbfae8 scribo/toolchain/internal/content_in_doc_functor.hh: Make use of component::extract::alignments.
by Guillaume Lazzara 03 May '11
by Guillaume Lazzara 03 May '11
03 May '11
---
scribo/ChangeLog | 10 +++-
.../toolchain/internal/content_in_doc_functor.hh | 54 +++++++++++---------
2 files changed, 37 insertions(+), 27 deletions(-)
diff --git a/scribo/ChangeLog b/scribo/ChangeLog
index 570a3c1..637fca8 100644
--- a/scribo/ChangeLog
+++ b/scribo/ChangeLog
@@ -1,5 +1,10 @@
2011-05-03 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+ * scribo/toolchain/internal/content_in_doc_functor.hh: Make use of
+ component::extract::alignments.
+
+2011-05-03 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
+
Small fixes.
* scribo/core/paragraph_info.hh: Add color information.
@@ -10,8 +15,9 @@
* scribo/make/text_components_image.hh: Fix wrong domain inclusions.
- * scribo/toolchain/text_in_picture.hh: Make use of
- component::extract::alignments.
+ * scribo/toolchain/text_in_picture.hh: Fix wrong include.
+
+ * src/debug/show_paragraph_blocks.cc: Add missing curly brackets.
2011-05-03 Guillaume Lazzara <lazzara(a)lrde.epita.fr>
diff --git a/scribo/scribo/toolchain/internal/content_in_doc_functor.hh b/scribo/scribo/toolchain/internal/content_in_doc_functor.hh
index 0a920a6..25b328b 100644
--- a/scribo/scribo/toolchain/internal/content_in_doc_functor.hh
+++ b/scribo/scribo/toolchain/internal/content_in_doc_functor.hh
@@ -37,7 +37,8 @@
# include <scribo/primitive/extract/separators.hh>
# include <scribo/primitive/extract/vertical_separators.hh>
# include <scribo/primitive/extract/horizontal_separators.hh>
-# include <scribo/primitive/extract/separators_nonvisible.hh>
+
+# include <scribo/primitive/extract/alignments.hh>
# include <scribo/primitive/identify.hh>
@@ -197,24 +198,8 @@ namespace scribo
on_progress();
}
- mln_ch_value(I,bool) whitespaces;
- if (enable_whitespace_seps)
- {
- // Whitespace separators
- on_new_progress_label("Find whitespace separators...");
-
- whitespaces = primitive::extract::separators_nonvisible(input_cleaned);
-
- on_progress();
- }
-
- // Debug
# ifndef SCRIBO_NDEBUG
- if (enable_whitespace_seps)
- debug::logger().log_image(debug::AuxiliaryResults,
- whitespaces, "whitespaces");
-
// Debug
if (enable_line_seps)
{
@@ -264,11 +249,6 @@ namespace scribo
/// Set separator components.
if (enable_line_seps)
components.add_separators(separators);
- if (enable_whitespace_seps)
- {
- components.add_separators(whitespaces);
- doc.set_whitespace_separators(whitespaces);
- }
// Debug
# ifndef SCRIBO_NDEBUG
@@ -291,13 +271,14 @@ namespace scribo
object_links<L> left_link
= primitive::link::with_single_left_link_dmax_ratio(
components,
- primitive::link::internal::dmax_width_and_height(1),
+ primitive::link::internal::dmax_default(1),
anchor::MassCenter);
+
object_links<L> right_link
= primitive::link::with_single_right_link_dmax_ratio(
components,
- primitive::link::internal::dmax_width_and_height(1),
+ primitive::link::internal::dmax_default(1),
anchor::MassCenter);
// Debug
@@ -318,7 +299,6 @@ namespace scribo
}
# endif // ! SCRIBO_NDEBUG
-
// Validating left and right links.
object_links<L>
merged_links = primitive::link::merge_double_link(left_link,
@@ -364,10 +344,34 @@ namespace scribo
lines = scribo::make::line_set(groups);
+ // Extract whitespace to improve text merging results afterwards.
+ mln_ch_value(L,bool) whitespaces;
+ if (enable_whitespace_seps)
+ {
+ scribo::paragraph_set<L> parset = scribo::make::paragraph(lines);
+ doc.set_paragraphs(parset);
+
+ // Whitespace separators
+ on_new_progress_label("Find whitespace separators...");
+
+ mln::util::couple<component_set<L>, mln_ch_value(L,bool)>
+ res = primitive::extract::alignments(doc, 3, 3);
+ whitespaces = res.second();
+
+ on_progress();
+
+ components.add_separators(res.second());
+ doc.set_whitespace_separators(res.second(), res.first());
+ }
+
+
//===== DEBUG =====
# ifndef SCRIBO_NDEBUG
if (debug::logger().is_enabled())
{
+ if (enable_whitespace_seps)
+ debug::logger().log_image(debug::AuxiliaryResults,
+ whitespaces, "whitespaces");
// Bboxes image.
debug::logger().log_image(
--
1.5.6.5
1
0