Commit 4d14a475 authored by Guillaume Lazzara's avatar Guillaume Lazzara
Browse files

Merge branch 'exp/scribo-z' into exp/next

Conflicts:
	milena/ChangeLog
	milena/mln/core/point.hh
	milena/tests/io/magick/save.cc
	scribo/Makefile.am
	scribo/core/def/lbl_type.hh
	scribo/core/object_image.hh
	scribo/demo/Makefile.am
	scribo/src/binarization/sauvola_ms.cc
	scribo/src/debug/Makefile.am
	scribo/table/internal/connect_lines.hh
	scribo/test.cc
	scribo/tests/toolchain/Makefile.am
	scribo/text/clean.hh
parents fd16f7ee 7b211184
......@@ -2,6 +2,22 @@
* m4/autotroll.m4: Fix invalid configuration when Qt is missing.
2010-06-25 Guillaume Lazzara <z@lrde.epita.fr>
* configure.ac: Set HAVE_QT correctly.
2010-06-15 Guillaume Lazzara <z@lrde.epita.fr>
* configure.ac: Configure scribo/demo.
2010-06-03 Guillaume Lazzara <z@lrde.epita.fr>
* configure.ac: Configure several directories in scribo/.
2010-07-01 Guillaume Lazzara <z@lrde.epita.fr>
* m4/autotroll.m4: Fix invalid configuration when Qt is missing.
2010-06-03 Guillaume Lazzara <z@lrde.epita.fr>
* configure.ac: Check for Qt library using AutoTroll.
......
......@@ -215,9 +215,9 @@ OLN_WITH_LIB([TESSERACT], [tesseract/baseapi.h], [tesseract_full],
[tesseract], [TESSERACT])
# Qt.
AT_WITH_QT([], [], [],
AC_DEFINE([HAVE_QT], 1, [Define to 1 if we can use Qt]),
AC_DEFINE([HAVE_QT], 0))
AT_WITH_QT([+xml], [], [],
AC_DEFINE([HAVE_QT], 0, [Define to 1 if we can use Qt]),
AC_DEFINE([HAVE_QT], 1))
AM_CONDITIONAL([HAVE_QT], [test x$QT_PATH != x])
......@@ -288,12 +288,17 @@ AM_CONDITIONAL([ENABLE_SCRIBO], [test "x$enable_scribo" = xyes])
AC_CONFIG_FILES([
scribo/Makefile
scribo/demo/review/Makefile
scribo/demo/Makefile
scribo/demo/review/Makefile
scribo/demo/viewer/Makefile
scribo/src/Makefile
scribo/src/binarization/Makefile
scribo/src/contest/Makefile
scribo/src/contest/hdibco-2010/Makefile
scribo/src/debug/Makefile
scribo/src/filter/Makefile
scribo/src/misc/Makefile
scribo/src/postprocessing/Makefile
scribo/src/preprocessing/Makefile
scribo/src/primitive/Makefile
scribo/src/primitive/extract/Makefile
......@@ -313,6 +318,8 @@ AC_CONFIG_FILES([
scribo/tests/preprocessing/Makefile
scribo/tests/table/Makefile
scribo/tests/text/Makefile
scribo/tests/toolchain/Makefile
scribo/tests/toolchain/nepomuk/Makefile
scribo/tests/unit_test/Makefile
])
......
2010-06-21 Yann Jacquelet <jacquelet@lrde.epita.fr>
Fix the way to convert unsigned to float.
* mln/convert/from_to.hxx: New conversion utilities.
* mln/convert/impl/from_unsigned_to_value.hh: New conversion utilities.
2009-12-02 Yann Jacquelet <jacquelet@lrde.epita.fr>
Fix the outside template use case for the convolve macros.
* mln/linear/ch_convolve.hh (mln_ch_convolve_, mln_ch_convolve_grad_):
Define new macros to work outside templates.
2010-06-28 Guillaume Lazzara <z@lrde.epita.fr>
Revamp and fix a bug in io::magick::*.
* mln/io/magick/load.hh: Revamp.
* mln/io/magick/save.hh: Fix a bug while saving. RGB values must
be between 0 and 1.
* tests/io/magick/save.cc: Remove useless output.
2010-06-25 Guillaume Lazzara <z@lrde.epita.fr>
Add new tests.
* tests/convert/Makefile.am,
* tests/subsampling/Makefile.am: Add targets for these new tests.
* tests/convert/to_qimage.cc,
* tests/convert/to_qimage_nocopy.cc,
* tests/subsampling/antialiased.cc: New.
2010-06-25 Guillaume Lazzara <z@lrde.epita.fr>
Fix conversion routines towards qimage.
* mln/convert/to_qimage.hh: Fix invalid conversions.
* mln/convert/to_qimage_nocopy.hh: Avoid a warning.
2010-06-25 Guillaume Lazzara <z@lrde.epita.fr>
* mln/accu/count_value.hh: Add properties.
2010-06-18 Guillaume Lazzara <z@lrde.epita.fr>
Fix a bug in conversions from vec to point.
* milena/mln/core/concept/gpoint.hh: Fix comment.
* milena/mln/core/image/image1d.hh: Share a dpoint value.
* milena/mln/core/point.hh: Handle point1d.
2010-06-15 Guillaume Lazzara <z@lrde.epita.fr>
Introduce labeling::value_and_compute.
* mln/canvas/labeling/video.hh: Call more functor members.
* mln/labeling/value.hh: Provide new members to the functor.
* mln/labeling/value_and_compute.hh: New functor computing
attributes while labeling.
2010-05-18 Guillaume Lazzara <z@lrde.epita.fr>
* mln/io/magick/load.hh: set minimum resolution for PDF files to
300DPI.
2010-07-01 Guillaume Lazzara <z@lrde.epita.fr>
 
Fix a few tests.
// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory
// (LRDE)
//
// This file is part of Olena.
//
......@@ -37,6 +38,29 @@
namespace mln
{
// Forward declaration.
namespace accu {
template <typename V> struct count_value;
}
// Traits.
namespace trait
{
template <typename V>
struct accumulator_< accu::count_value<V> >
{
typedef accumulator::has_untake::yes has_untake;
typedef accumulator::has_set_value::yes has_set_value;
typedef accumulator::has_stop::no has_stop;
typedef accumulator::when_pix::use_v when_pix;
};
} // end of namespace mln::trait
namespace accu
{
......
......@@ -162,14 +162,20 @@ namespace mln
return output;
}
output.element(p) = ++nlabels;
f.set_new_label_(p, nlabels);
}
}
else
output.element(p) = output.element(parent.element(p));
{
L lbl = output.element(parent.element(p));
output.element(p) = lbl;
f.set_label_(p, lbl);
}
}
status = true;
}
f.finalize();
trace::exiting("canvas::impl::video_fastest");
return output;
}
......
......@@ -302,6 +302,10 @@ namespace mln
void
from_to_(const Value<F>& from, Value<T>& to);
// unsigned -> float
void
from_to_(const unsigned& from, float& to);
// double-> Value
template <typename V>
void
......
......@@ -118,6 +118,16 @@ namespace mln
internal::from_unsigned_to_value_dispatch(from, to);
}
// Facades.
// unsigned-> float
void
from_to_(const unsigned& from, float& to)
{
to = from;
}
} // end of namespace mln::convert::over_load
......
......@@ -55,6 +55,17 @@ namespace mln
namespace convert
{
/// \brief Convert a Milena image to a Qimage.
///
//
template <typename I>
inline
QImage
to_qimage(const Image<I>& ima);
# ifndef MLN_INCLUDE_ONLY
// Implementation
namespace impl
......@@ -68,26 +79,30 @@ namespace mln
const I& ima = exact(ima_);
mln_precondition(ima.is_valid());
const int
const unsigned
nrows = geom::nrows(ima),
ncols = geom::ncols(ima);
# if QT_VERSION >= 0x040000 && QT_VERSION < 0x040400
QImage qima(ncols, nrows, QImage::Format_RGB32);
uchar * ptr_qima = qima.scanLine(0);
uchar * ptr_qima = qima.bits();
unsigned offset = ima.delta_index(dpoint2d(+1, - ncols));
unsigned padding = 0;
# if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
++ptr_qima;
# endif // ! Q_BYTE_ORDER
# else
QImage qima(ncols, nrows, QImage::Format_RGB888);
uchar * ptr_qima = qima.scanLine(0);
uchar * ptr_qima = qima.bits();
unsigned padding = ncols % 4;
# endif // ! QT_VERSION
const mln_value(I)* ptr_ima = &ima(ima.domain().pmin());
unsigned row_offset = ima.delta_index(dpoint2d(+1, - ncols));
unsigned offset = ima.delta_index(dpoint2d(+1, - ncols));
// Data is stored as ABGR so we skip the first value which is ignored.
for (unsigned row = 0; row < nrows; ++row, ptr_ima += row_offset)
for (unsigned row = 0; row < nrows; ++row, ptr_ima += offset)
{
for (unsigned col = 0; col < ncols; ++col)
{
const mln_value(I)& v = *ptr_ima++;
......@@ -99,6 +114,8 @@ namespace mln
ptr_qima += 3;
# endif // ! QT_VERSION
}
ptr_qima += padding;
}
return qima;
}
......@@ -121,9 +138,10 @@ namespace mln
QImage qima(ncols, nrows, QImage::Format_RGB32);
uchar * ptr_qima = qima.scanLine(0);
const mln_value(I)* ptr_ima = &ima(ima.domain().pmin());
unsigned row_offset = ima.delta_index(dpoint2d(+1, - ncols));
unsigned offset = ima.delta_index(dpoint2d(+1, - ncols));
for (unsigned row = 0; row < nrows; ++row, ptr_ima += row_offset)
for (unsigned row = 0; row < nrows; ++row, ptr_ima += offset)
{
for (unsigned col = 0; col < ncols; ++col)
{
const mln::value::rgb8& v = *ptr_ima++;
......@@ -141,6 +159,7 @@ namespace mln
*ptr_qima = v.blue();
# endif // ! Q_BYTE_ORDER
}
}
return qima;
}
......@@ -158,13 +177,21 @@ namespace mln
ncols = geom::ncols(ima);
typedef mln_site(I) P;
typedef mln_dpsite(P) DP;
// Required by a one-shot data copy:
mln::border::resize(ima, 0);
unsigned
offset = ima.delta_index(DP(+1, 0)),
line_offset = 0;
QImage qima(ncols, nrows, QImage::Format_RGB888);
std::memcpy(qima.scanLine(0),
ima.buffer(),
ima.nelements() * 3);
for (int i = 0 ; i < qima.height(); ++i, line_offset += offset)
std::memcpy(qima.scanLine(i),
ima.buffer() + line_offset,
ima.ncols() * 3);
return qima;
}
......@@ -187,9 +214,7 @@ namespace mln
mln::border::resize(ima, 0);
QImage qima(ncols, nrows, QImage::Format_RGB32);
std::memcpy(qima.scanLine(0),
ima.buffer(),
ima.nelements() * 4);
std::memcpy(qima.bits(), ima.buffer(), ima.nelements() * 4);
return qima;
}
......@@ -263,6 +288,8 @@ namespace mln
}
# endif // ! MLN_INCLUDE_ONLY
} // end of namespace mln::convert
} // end of namespace mln
......
......@@ -136,7 +136,7 @@ namespace mln
template <typename I, typename V>
inline
QImage to_qimage_nocopy_dispatch(const Image<I>& ima, V&)
QImage to_qimage_nocopy_dispatch(const Image<I>&, V&)
{
// Not supported yet!
mlc_abort(I)::check();
......
......@@ -182,7 +182,7 @@ namespace mln
* topology and with the same type of coordinates; otherwise this
* test does not compile.
*
* \post The result, \p dp, is such as \p lhs == \p rhs + \p dp.
* \post The result, \p dp, is such as \p lhs == \p rhs + \p dp.
*
* \return A delta point (temporary object).
*
......
......@@ -304,8 +304,10 @@ namespace mln
void
data< image1d<T> >::update_vb_()
{
vb_.pmin() = b_.pmin() - dpoint1d(all_to(bdr_));
vb_.pmax() = b_.pmax() + dpoint1d(all_to(bdr_));
dpoint1d dp(all_to(bdr_));
vb_.pmin() = b_.pmin() - dp;
vb_.pmax() = b_.pmax() + dp;
}
template <typename T>
......
......@@ -428,7 +428,6 @@ namespace mln
}
template <typename G, typename C>
inline
point<G,C>::point(C ind)
......
......@@ -116,14 +116,26 @@ namespace mln
I& ima = exact(ima_);
//std::ifstream file(filename.c_str());
//if (! file)
//{
// std::cerr << "error: cannot open file '" << filename << "'!";
// abort();
//}
Magick::Image im_file(filename);
Magick::Image im_file;
im_file.ping(filename);
// if (im_file)
// {
// std::cerr << "error: cannot open file '" << filename << "'!";
// abort();
// }
// Force a minimum resolution of 300DPI for PDF document.
if (im_file.magick() == "PDF"
&& (im_file.xResolution() < 300
|| im_file.yResolution() < 300))
{
im_file.density(Magick::Geometry(300, 300));
}
im_file.read(filename);
im_file.modifyImage();
im_file.type(Magick::TrueColorType);
int columns = im_file.columns();
......@@ -134,7 +146,8 @@ namespace mln
std::cout << "format: " <<im_file.format() << std::endl;
std::cout << "magick: " <<im_file.magick() << std::endl;*/
const Magick::PixelPacket *pixel_cache = im_file.getConstPixels(0, 0, columns, rows);
const Magick::PixelPacket *
pixel_cache = im_file.getConstPixels(0, 0, columns, rows);
algebra::vec<mln_site_(I)::dim, unsigned int> vmin;
algebra::vec<mln_site_(I)::dim, unsigned int> vmax;
......@@ -149,10 +162,15 @@ namespace mln
mln_piter(I) p(ima.domain());
for_all(p)
{
const Magick::PixelPacket *pixel = pixel_cache + (int) p.to_site().to_vec()[0] * columns
+ (int) p.to_site().to_vec()[1];
const Magick::PixelPacket *
pixel = pixel_cache
+ (int) p.to_site().to_vec()[0] * columns
+ (int) p.to_site().to_vec()[1];
// FIXME: Quantum = 16bits but rgb is 8bits
value::rgb8 pix(pixel->red % 256, pixel->green % 256, pixel->blue % 256);
value::rgb8 pix(pixel->red % 256,
pixel->green % 256,
pixel->blue % 256);
mln_value(I) res;
if (!do_it(pix, res, filename))
abort();
......
......@@ -78,26 +78,29 @@ namespace mln
return Magick::ColorMono(value);
}
// Gray values must be between 0 and 1.
inline
Magick::Color get_color(const value::int_u8& value)
{
return Magick::ColorGray(256 - value);
return Magick::ColorGray(value / 255.0f);
}
// Color values must be between 0 and 1.
inline
Magick::Color get_color(const value::rgb8& value)
{
return Magick::ColorRGB(256 - value.red(),
256 - value.green(),
256 - value.blue());
return Magick::ColorRGB(value.red() / 255.0f,
value.green() / 255.0f,
value.blue() / 255.0f);
}
// Color values must be between 0 and 1.
inline
Magick::Color get_color(const value::qt::rgb32& value)
{
return Magick::ColorRGB(256 - value.red(),
256 - value.green(),
256 - value.blue());
return Magick::ColorRGB(value.red() / 255.0f,
value.green() / 255.0f,
value.blue() / 255.0f);
}
template <typename I>
......@@ -119,20 +122,20 @@ namespace mln
}
Magick::Image im_file;
im_file.size(Magick::Geometry(ima.nrows(), ima.ncols()));
im_file.size(Magick::Geometry(ima.ncols(), ima.nrows()));
Magick::PixelPacket* pixel_cache = im_file.getPixels(0, 0, ima.nrows(), ima.ncols());
Magick::PixelPacket* pixel;
im_file.modifyImage();
Magick::PixelPacket *
pp = im_file.getPixels(0,0, ima.ncols(), ima.nrows());
mln_site(I) pmin = ima.domain().pmin();
mln_piter(I) p(ima.domain());
for_all(p)
{
pixel = pixel_cache + (int) (p.to_site().to_vec()[0] - pmin.to_vec()[0]) * ima.ncols()
+ (int) (p.to_site().to_vec()[1] - pmin.to_vec()[1]);
*pixel = get_color(ima(p));
}
*pp++ = get_color(ima(p));
im_file.syncPixels();
im_file.write(filename);
trace::exiting("mln::io::magick::save");
......
// Copyright (C) 2007, 2008, 2009 EPITA Research and Development
// Copyright (C) 2007, 2008, 2009, 2010 EPITA Research and Development
// Laboratory (LRDE)
//
// This file is part of Olena.
......@@ -73,7 +73,7 @@ namespace mln
L& nlabels)
{
mln_precondition(exact(input).is_valid());
// mln_precondition(exact(nbh).is_valid());
mln_precondition(exact(nbh).is_valid());
(void) input;
(void) val;
......@@ -90,7 +90,7 @@ namespace mln
// Generic functor.
template <typename I>
template <typename I, typename L>
struct value_functor
{
typedef mln_psite(I) P;
......@@ -108,9 +108,12 @@ namespace mln
bool handles(const P& p) const { return input(p) == val; }
bool equiv(const P& n, const P&) const { return input(n) == val; }
bool labels(const P&) const { return true; }
void do_no_union(const P&, const P&) {}
void do_no_union(const P&, const P&) {}
void init_attr(const P&) {}
void merge_attr(const P&, const P&) {}
void set_new_label(const P& p, const L& l){}
void set_label(const P& p, const L& l) {}
void finalize() {}
// Fastest implementation
......@@ -121,6 +124,9 @@ namespace mln
void do_no_union_(unsigned, unsigned) {}
void init_attr_(unsigned) {}
void merge_attr_(unsigned, unsigned) {}
void set_new_label_(unsigned, const L&) {}
void set_label_(unsigned, const L&) {}
void finalize_() {}
// end of Requirements.
......@@ -148,7 +154,7 @@ namespace mln
internal::value_tests(input, val, nbh, nlabels);
mln_ch_value(I, L) output;
impl::value_functor<I> f(input, val);
impl::value_functor<I,L> f(input, val);
output = canvas::labeling::video(input, nbh, nlabels, f);
trace::exiting("labeling::value");
......
// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE)
//
// This file is part of Olena.
//
// Olena is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation, version 2 of the License.
//
// Olena is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Olena. If not, see <http://www.gnu.org/licenses/>.
//
// As a special exception, you may use this file as part of a free
// software project without restriction. Specifically, if other files
// instantiate templates or use macros or inline functions from this
// file, or you compile this file and link it with other files to produce
// an executable, this file does not by itself cause the resulting
// executable to be covered by the GNU General Public License. This
// exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
#ifndef MLN_LABELING_VALUE_AND_COMPUTE_HH
# define MLN_LABELING_VALUE_AND_COMPUTE_HH
/// \file
///
/// Connected component labeling of image sites at a given value.