Commit 18a13882 authored by Guillaume Lazzara's avatar Guillaume Lazzara
Browse files

Merge branch 'papers/lazzara.13.ijdar' into unstable/scribo

Conflicts:
	milena/tests/unit_test/unit-tests.mk
	scribo/sandbox/ChangeLog
	scribo/scribo/binarization/otsu_threshold.hh
	scribo/scribo/debug/logger.hh
	scribo/scribo/text/paragraphs_closing.hh
	scribo/scribo/toolchain/text_in_doc_preprocess.hh
	scribo/src/binarization/Makefile.am
	scribo/src/binarization/otsu.cc
	scribo/tests/binarization/Makefile.am
	scribo/tests/unit_test/unit-tests.mk
parents 45129d3f 9d6aa0ae
2013-01-03 Guillaume Lazzara <z@lrde.epita.fr>
* mln/labeling/colorize.hh: Do not recompute previously computed
colors.
2012-11-13 Guillaume Lazzara <z@lrde.epita.fr>
* mln/histo/equalize.hh: Fix.
2012-11-13 Guillaume Lazzara <z@lrde.epita.fr>
* mln/histo/equalize.hh: Revamp.
2012-08-23 Guillaume Lazzara <z@lrde.epita.fr>
* tests/unit_test/unit-tests.mk: Regen.
2012-05-28 Guillaume Lazzara <z@lrde.epita.fr>
* mln/fun/x2x/rotation.hh: Remove alpha and axis attributes.
2012-05-28 Guillaume Lazzara <z@lrde.epita.fr>
* mln/registration/icp.hh: Cleanup some debug.
2012-05-28 Guillaume Lazzara <z@lrde.epita.fr>
* mln/geom/rotate.hh: Add support for n-D images.
2012-05-28 Guillaume Lazzara <z@lrde.epita.fr>
* mln/algebra/mat.hh: Add implementations for 4x4 matrices.
2012-05-25 Guillaume Lazzara <z@lrde.epita.fr>
New routines to get bottom left and top right sites.
* mln/geom/bottom_left.hh,
* mln/geom/top_right.hh: New.
* mln/geom/all.hh: Add includes.
2012-05-25 Guillaume Lazzara <z@lrde.epita.fr>
Improve conversion between algebra::h_mat and algebra::quat.
* mln/algebra/h_mat.hh,
* mln/algebra/quat.hh: New from_to_ overloads.
* mln/fun/x2x/rotation.hh: Make use of new make::h_mat overload.
* mln/make/h_mat.hh: New overload using quaternion as argument.
* mln/value/builtin/integers.hh: Add epsilon.
* tests/algebra/h_mat.cc,
* tests/make/h_mat.cc: Improve tests.
2012-05-10 Guillaume Lazzara <z@lrde.epita.fr>
Rely on Argument-Dependent Lookup (ADL) in from_to_ overloads.
* mln/accu/count_labels.hh,
* mln/convert/from_to.hxx,
* mln/convert/to.hh,
* mln/core/alias/point1d.hh,
* mln/core/alias/point2d.hh,
* mln/core/alias/point3d.hh,
* mln/core/dpoint.hh,
* mln/core/internal/neighborhood_base.hh,
* mln/core/point.hh,
* mln/core/site_set/p_centered.hh,
* mln/core/site_set/p_vaccess.hh,
* mln/fun/v2v/hsl_to_rgb.hh,
* mln/fun/v2v/rgb_to_hsl.hh,
* mln/io/magick/save.hh,
* mln/io/plot/save.hh,
* mln/labeling/blobs_and_compute.hh,
* mln/labeling/value_and_compute.hh,
* mln/make/w_window2d.hh,
* mln/win/multiple.hh,
* mln/win/multiple_size.hh,
* tests/accu/site_set/rectangularity.cc,
* tests/core/other/graph_elt_neighborhood.cc,
* tests/core/other/graph_elt_window.cc,
* tests/core/other/point_set_compatibility.cc,
* tests/draw/graph.cc: Update forward declarations and includes.
* mln/algebra/vec.hh,
* mln/convert/from_to.hh,
* mln/convert/impl/from_double_to_value.hh,
* mln/convert/impl/from_float_to_value.hh,
* mln/convert/impl/from_image_to_site_set.hh,
* mln/convert/impl/from_int_to_value.hh,
* mln/convert/impl/from_unsigned_to_value.hh,
* mln/convert/impl/from_value_to_value.hh,
* mln/core/alias/neighb2d.hh,
* mln/core/alias/neighb3d.hh,
* mln/core/alias/window1d.hh,
* mln/core/alias/window2d.hh,
* mln/core/alias/window3d.hh,
* mln/core/concept/accumulator.hh,
* mln/core/concept/gdpoint.hh,
* mln/core/concept/gpoint.hh,
* mln/core/concept/image.hh,
* mln/core/concept/proxy.hh,
* mln/core/concept/site_set.hh,
* mln/core/concept/window.hh,
* mln/core/image/graph_window_if_piter.hh,
* mln/core/image/image1d.hh,
* mln/core/mixed_neighb.hh,
* mln/core/neighb.hh,
* mln/core/site_set/operators.hh,
* mln/core/w_window.hh,
* mln/fun/i2v/array.hh,
* mln/util/object_id.hh,
* mln/value/hsl.hh,
* mln/value/int_u.hh,
* mln/value/label.hh,
* mln/value/qt/rgb32.hh,
* mln/value/rgb.hh,
* mln/histo/array.hh,
* mln/util/array.hh: Move from_to_ overloads in the same namespace
as their first argument.
2012-05-22 Guillaume Lazzara <z@lrde.epita.fr>
* demos/graph/region_adjacency_graph.cc: Add program arguments.
2012-08-23 Guillaume Lazzara <z@lrde.epita.fr>
* mln/core/internal/image_base.hh: Improve documentation.
2012-08-23 Guillaume Lazzara <z@lrde.epita.fr>
* mln/data/compute_in_window.hh: Fix warnings.
2013-03-01 Guillaume Lazzara <z@lrde.epita.fr>
 
* mln/io/pdf/load.hh: Check if the PDF can be rendered.
// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
// Copyright (C) 2009, 2012 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of Olena.
//
......@@ -67,6 +68,9 @@
#include <mln/math/diff_abs.hh>
#include <mln/debug/draw_graph.hh>
#include <mln/debug/filename.hh>
#include <mln/data/transform.hh>
#include <mln/fun/v2v/rgb_to_int_u.hh>
namespace mln
{
......@@ -149,27 +153,42 @@ namespace mln
}
int main()
int main(int argc, char *argv[])
{
using namespace mln;
using value::int_u8;
using value::rgb8;
using value::label_16;
image2d<int_u8> input_pgm;
io::pgm::load(input_pgm, "house.pgm");
if (argc != 3 && argc != 4)
{
std::cout << "Usage: " << argv[0] << " <input.*> <output_prefix>"
<< " [closing_area_value (default:25)]" << std::endl;
return 1;
}
/// Load input image.
image2d<rgb8> input_ppm;
io::ppm::load(input_ppm, "house.ppm");
io::ppm::load(input_ppm, argv[1]);
/// Convert input image to graylevel image.
image2d<value::int_u8>
input_pgm = data::transform(input_ppm, fun::v2v::rgb_to_int_u<8>());
/// Set output filename prefix.
debug::internal::filename_prefix = argv[2];
unsigned area_value = 25;
if (argc == 4)
area_value = atoi(argv[3]);
/// Gradient of the gray level image.
image2d<int_u8> grad = morpho::gradient(input_pgm, win_c4p());
io::pgm::save(grad, "tmp_grad_c4p.pgm");
io::pgm::save(grad, debug::filename("grad_c4p.pgm"));
/// Closing of the gradient.
image2d<int_u8> clo = morpho::closing::area(grad, c4(), 25);
io::pgm::save(clo, "tmp_clo_a100.pgm");
image2d<int_u8> clo = morpho::closing::area(grad, c4(), area_value);
io::pgm::save(clo, debug::filename("clo_a100.pgm"));
/// Watershed on the closing image.
label_16 nbasins;
......@@ -178,12 +197,12 @@ int main()
/// Output: A watershed image where each basin value is set to the basin
/// mean value in the original ppm image.
io::ppm::save(labeling::mean_values(input_ppm, wshed, nbasins),
"tmp_wshed_mean_colors.ppm");
debug::filename("wshed_mean_colors.ppm"));
/// Set watershed line value to yellow.
data::fill((input_ppm | (pw::value(wshed) == 0u)).rw(), literal::yellow);
io::ppm::save(input_ppm, "tmp_wshed_color.ppm");
io::ppm::save(input_ppm, debug::filename("wshed_color.ppm"));
/// Build region adjacency graph.
......@@ -210,5 +229,5 @@ int main()
mln_VAR(ima_e, make::edge_image(ima_v, dist()));
io::ppm::save(make_debug_graph_image(input_ppm, ima_v, ima_e, literal::white),
"tmp_wst_rag_graph_image_white.ppm");
debug::filename("wst_rag_graph_image_white.ppm"));
}
// Copyright (C) 2007, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
// Copyright (C) 2007, 2008, 2009, 2012 EPITA Research and Development
// Laboratory (LRDE)
//
// This file is part of Olena.
//
......@@ -31,10 +32,21 @@
* \brief Definition of a matrix with homogeneous coordinates.
*
* \todo Add traits.
*
* FIXME: there is a big issue with this class. exact() does not
* return the correct type since the exact type is NOT correctly
* propagated to Object. mat and h_mat should inherit from a base
* class and the operator traits should be updated so that
* interoperability between mat and h_mat is preserved which is not
* obvious.
*
*/
# include <mln/algebra/mat.hh>
# include <mln/algebra/quat.hh>
# include <mln/math/pi.hh>
# include <mln/util/couple.hh>
namespace mln
{
......@@ -57,9 +69,15 @@ namespace mln
h_mat();
/// Constructor with the underlying matrix.
h_mat(const mat<d+1, d+1, T>& x);
};
/// \internal Conversion: h_mat -> quat
template <typename C>
void from_to_(const algebra::h_mat<3,C>& from, algebra::quat& to);
# ifndef MLN_INCLUDE_ONLY
template <unsigned d, typename T>
......@@ -76,6 +94,80 @@ namespace mln
{
}
// Conversions
template <typename C>
void from_to_(const algebra::h_mat<3,C>& from, algebra::quat& to)
{
C tr = from(0, 0) + from(1, 1) + from(2, 2) + 1;
if (tr > 0.005f) // Actually, greater than 0
{
C s = 0.5 / sqrt(tr),
w = 0.25 / s,
x = (from(2, 1) - from(1, 2)) * s,
y = (from(0, 2) - from(2, 0)) * s,
z = (from(1, 0) - from(0, 1)) * s;
to = algebra::quat(w, x, y, z);
return;
}
// If the trace of the matrix is less than or equal to zero
// then identify which major diagonal element has the greatest
// value.
C max = 0;
unsigned c = 0;
for (unsigned d = 0; d <= 3; ++d)
if (from(d, d) > max)
{
max = from(d, d);
c = d;
}
// Depending on this value, calculate the following:
C s, w, x, y, z;
switch(c)
{
case 0:
s = sqrt(1.0 + from(0, 0) - from(1, 1) - from(2, 2)) * 2;
x = 0.5 / s;
y = (from(0, 1) + from(1, 0)) / s;
z = (from(0, 2) + from(2, 0)) / s;
w = (from(1, 2) + from(2, 1)) / s;
break;
case 1:
s = sqrt(1.0 + from(1, 1) - from(0, 0) - from(2, 2)) * 2;
x = (from(0, 1) + from(1, 0)) / s;
y = 0.5 / s;
z = (from(1, 2) + from(2, 1)) / s;
w = (from(0, 2) + from(2, 0)) / s;
break;
case 2:
s = sqrt(1.0 + from(2, 2) - from(0, 0) - from(1, 1)) * 2;
x = (from(0, 2) + from(2, 0)) / s;
y = (from(1, 2) + from(2, 1)) / s;
z = 0.5 / s;
w = (from(0, 1) + from(1, 0) ) / s;
break;
// Error case
default:
x = 0;
y = 0;
z = 0;
w = 0;
}
to = algebra::quat(w, x, y, z);
return;
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::algebra
......
<
// Copyright (C) 2006, 2008, 2009 EPITA Research and Development Laboratory (LRDE)
// Copyright (C) 2006, 2008, 2009, 2012 EPITA Research and Development
// Laboratory (LRDE)
//
// This file is part of Olena.
//
......@@ -123,7 +124,7 @@ namespace mln
mat<m,n,T> t() const;
/// Return the inverse of the matrix.
/// Only compile on square matrix.
/// Only compile on square matrix.
mat<n,m,T> _1() const;
private:
......@@ -134,18 +135,6 @@ namespace mln
};
template <typename T>
mat<2,2,T>
make(const T& t00, const T& t01,
const T& t10, const T& t11);
template <typename T>
mat<3,3,T>
make(const T& t00, const T& t01, const T& t02,
const T& t10, const T& t11, const T& t12,
const T& t20, const T& t21, const T& t22);
} // end of namespace algebra
......@@ -225,7 +214,7 @@ namespace mln
{
typedef algebra::mat<m, m, mln_trait_op_times(T, U)> ret;
};
// mat * s
template < unsigned n, unsigned m, typename T,
......@@ -245,7 +234,7 @@ namespace mln
// {
// typedef algebra::mat<n, m, mln_trait_binary(Name, T, S)> ret;
// };
// mat / s
template < unsigned n, unsigned m, typename T,
......@@ -340,6 +329,7 @@ namespace mln
// Trace.
/// Compute the trace of a matrix \p m
template<unsigned n, typename T>
mln_sum(T)
tr(const mat<n,n,T>& m);
......@@ -347,13 +337,10 @@ namespace mln
// Determinant.
template<typename T>
mln_sum_product(T,T)
det(const mat<2,2,T>& m);
template<typename T>
/// Compute the determinant of a matrix \p m
template<unsigned n, typename T>
mln_sum_product(T,T)
det(const mat<3,3,T>& m);
det(const mat<n,n,T>& m);
......@@ -548,6 +535,37 @@ namespace mln
namespace internal
{
// "Make" routines.
template <typename T>
inline
mat<2,2,T>
make(const T& t00, const T& t01,
const T& t10, const T& t11)
{
mat<2,2,T> tmp;
tmp(0, 0) = t00; tmp(0, 1) = t01;
tmp(1, 0) = t10; tmp(1, 1) = t11;
return tmp;
}
template <typename T>
inline
mat<3,3,T>
make(const T& t00, const T& t01, const T& t02,
const T& t10, const T& t11, const T& t12,
const T& t20, const T& t21, const T& t22)
{
mat<3,3,T> tmp;
tmp(0, 0) = t00; tmp(0, 1) = t01; tmp(0, 2) = t02;
tmp(1, 0) = t10; tmp(1, 1) = t11; tmp(1, 2) = t12;
tmp(2, 0) = t20; tmp(2, 1) = t21; tmp(2, 2) = t22;
return tmp;
}
// Inverse routines.
template <typename T>
inline
mat<2,2,float>
......@@ -568,35 +586,119 @@ namespace mln
mln_precondition(d != 0);
return make<float>( det(make(m(1,1), m(1,2),
m(2,1), m(2,2))),
det(make(m(0,2), m(0,1),
m(2,2), m(2,1))),
det(make(m(0,1), m(0,2),
m(1,1), m(1,2))),
det(make(m(1,2), m(1,0),
m(2,2), m(2,0))),
det(make(m(0,0), m(0,2),
m(2,0), m(2,2))),
det(make(m(0,2), m(0,0),
m(1,2), m(1,0))),
det(make(m(1,0), m(1,1),
m(2,0), m(2,1))),
det(make(m(0,1), m(0,0),
m(2,1), m(2,0))),
det(make(m(0,0), m(0,1),
m(1,0), m(1,1)))
) / d;
}
} // end of namespace algebra::inverse
template <typename T>
inline
mat<4,4,float>
inverse(const mat<4,4,T>& m)
{
mat<4,4,T> mo;
// Based on MESA implementation of the GLU library.
mo(0,0) = m(1,1) * m(2,2) * m(3,3) - m(1,1) * m(2,3) * m(3,2) -
m(2,1) * m(1,2) * m(3,3) + m(2,1) * m(1,3) * m(3,2) +
m(3,1) * m(1,2) * m(2,3) - m(3,1) * m(1,3) * m(2,2);
mo(1,0) = -m(1,0) * m(2,2) * m(3,3) + m(1,0) * m(2,3) * m(3,2) +
m(2,0) * m(1,2) * m(3,3) - m(2,0) * m(1,3) * m(3,2) -
m(3,0) * m(1,2) * m(2,3) + m(3,0) * m(1,3) * m(2,2);
mo(2,0) = m(1,0) * m(2,1) * m(3,3) - m(1,0) * m(2,3) * m(3,1) -
m(2,0) * m(1,1) * m(3,3) + m(2,0) * m(1,3) * m(3,1) +
m(3,0) * m(1,1) * m(2,3) - m(3,0) * m(1,3) * m(2,1);
mo(3,0) = -m(1,0) * m(2,1) * m(3,2) + m(1,0) * m(2,2) * m(3,1) +
m(2,0) * m(1,1) * m(3,2) - m(2,0) * m(1,2) * m(3,1) -
m(3,0) * m(1,1) * m(2,2) + m(3,0) * m(1,2) * m(2,1);
mo(0,1) = -m(0,1) * m(2,2) * m(3,3) + m(0,1) * m(2,3) * m(3,2) +
m(2,1) * m(0,2) * m(3,3) - m(2,1) * m(0,3) * m(3,2) -
m(3,1) * m(0,2) * m(2,3) + m(3,1) * m(0,3) * m(2,2);
mo(1,1) = m(0,0) * m(2,2) * m(3,3) - m(0,0) * m(2,3) * m(3,2) -
m(2,0) * m(0,2) * m(3,3) + m(2,0) * m(0,3) * m(3,2) +
m(3,0) * m(0,2) * m(2,3) - m(3,0) * m(0,3) * m(2,2);
mo(2,1) = -m(0,0) * m(2,1) * m(3,3) + m(0,0) * m(2,3) * m(3,1) +
m(2,0) * m(0,1) * m(3,3) - m(2,0) * m(0,3) * m(3,1) -
m(3,0) * m(0,1) * m(2,3) + m(3,0) * m(0,3) * m(2,1);
mo(3,1) = m(0,0) * m(2,1) * m(3,2) - m(0,0) * m(2,2) * m(3,1) -
m(2,0) * m(0,1) * m(3,2) + m(2,0) * m(0,2) * m(3,1) +
m(3,0) * m(0,1) * m(2,2) - m(3,0) * m(0,2) * m(2,1);
mo(0,2) = m(0,1) * m(1,2) * m(3,3) - m(0,1) * m(1,3) * m(3,2) -
m(1,1) * m(0,2) * m(3,3) + m(1,1) * m(0,3) * m(3,2) +
m(3,1) * m(0,2) * m(1,3) - m(3,1) * m(0,3) * m(1,2);
mo(1,2) = -m(0,0) * m(1,2) * m(3,3) + m(0,0) * m(1,3) * m(3,2) +
m(1,0) * m(0,2) * m(3,3) - m(1,0) * m(0,3) * m(3,2) -
m(3,0) * m(0,2) * m(1,3) + m(3,0) * m(0,3) * m(1,2);
mo(2,2) = m(0,0) * m(1,1) * m(3,3) - m(0,0) * m(1,3) * m(3,1) -
m(1,0) * m(0,1) * m(3,3) + m(1,0) * m(0,3) * m(3,1) +
m(3,0) * m(0,1) * m(1,3) - m(3,0) * m(0,3) * m(1,1);
mo(3,2) = -m(0,0) * m(1,1) * m(3,2) + m(0,0) * m(1,2) * m(3,1) +
m(1,0) * m(0,1) * m(3,2) - m(1,0) * m(0,2) * m(3,1) -
m(3,0) * m(0,1) * m(1,2) + m(3,0) * m(0,2) * m(1,1);
mo(0,3) = -m(0,1) * m(1,2) * m(2,3) + m(0,1) * m(1,3) * m(2,2) +
m(1,1) * m(0,2) * m(2,3) - m(1,1) * m(0,3) * m(2,2) -
m(2,1) * m(0,2) * m(1,3) + m(2,1) * m(0,3) * m(1,2);
mo(1,3) = m(0,0) * m(1,2) * m(2,3) - m(0,0) * m(1,3) * m(2,2) -
m(1,0) * m(0,2) * m(2,3) + m(1,0) * m(0,3) * m(2,2) +
m(2,0) * m(0,2) * m(1,3) - m(2,0) * m(0,3) * m(1,2);
mo(2,3) = -m(0,0) * m(1,1) * m(2,3) + m(0,0) * m(1,3) * m(2,1) +
m(1,0) * m(0,1) * m(2,3) - m(1,0) * m(0,3) * m(2,1) -
m(2,0) * m(0,1) * m(1,3) + m(2,0) * m(0,3) * m(1,1);
mo(3,3) = m(0,0) * m(1,1) * m(2,2) - m(0,0) * m(1,2) * m(2,1) -
m(1,0) * m(0,1) * m(2,2) + m(1,0) * m(0,2) * m(2,1) +
m(2,0) * m(0,1) * m(1,2) - m(2,0) * m(0,2) * m(1,1);
double det = m(0,0) * mo(0,0) + m(0,1) * mo(1,0) + m(0,2) * mo(2,0) + m(0,3) * mo(0,3);
mln_precondition(det != 0);
det = 1.0 / det;
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
mo(i,j) *= det;
return mo;
}
} // end of namespace algebra::internal
template <unsigned n, unsigned m, typename T>
inline
......@@ -608,35 +710,6 @@ namespace mln
}