* mln/opt/all.hh,
* mln/opt/essential.hh: new.
---
milena/ChangeLog | 21 +++++++++++++++++++++
milena/mln/opt/all.hh | 39 +++++++++++++++++++++++++++++++++++++++
milena/mln/opt/essential.hh | 37 +++++++++++++++++++++++++++++++++++++
3 files changed, 97 insertions(+), 0 deletions(-)
create mode 100644 milena/mln/opt/all.hh
create mode 100644 milena/mln/opt/essential.hh
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 5727ea3..9c8ace6 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,24 @@
+2009-02-25 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Add all.hh and essential.hh in mln/opt.
+
+ * mln/opt/all.hh,
+ * mln/opt/essential.hh: new.
+
+2009-02-24 Guillaume Lazzara <z(a)lrde.epita.fr>
+
+ Fix step 4 in tutorial.
+
+ * doc/tutorial/figures/tuto4_genericity_and_algorithms-5.ppm,
+ * doc/tutorial/figures/tuto4_genericity_and_algorithms-6.ppm,
+ * doc/tutorial/figures/tuto4_genericity_and_algorithms-9.ppm: update
+ reference file.
+
+ * doc/tutorial/samples/tuto4_genericity_and_algorithms.cc: fix
+ threshold function.
+
+ * doc/tutorial/tutorial.tex: include the proper image in step 4.
+
2009-02-24 Guillaume Lazzara <z(a)lrde.epita.fr>
Various small fixes.
diff --git a/milena/mln/opt/all.hh b/milena/mln/opt/all.hh
new file mode 100644
index 0000000..ac80cd4
--- /dev/null
+++ b/milena/mln/opt/all.hh
@@ -0,0 +1,39 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_OPT_ALL_HH
+# define MLN_OPT_ALL_HH
+
+/// \file mln/opt/all.hh
+///
+/// File that includes the most useful optional routines.
+
+# include <mln/opt/at.hh>
+# include <mln/opt/element.hh>
+# include <mln/opt/value.hh>
+
+#endif // ! MLN_OPT_ALL_HH
diff --git a/milena/mln/opt/essential.hh b/milena/mln/opt/essential.hh
new file mode 100644
index 0000000..f6d144a
--- /dev/null
+++ b/milena/mln/opt/essential.hh
@@ -0,0 +1,37 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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_OPT_ESSENTIAL_HH
+# define MLN_OPT_ESSENTIAL_HH
+
+/// \file mln/opt/essential.hh
+///
+/// File that includes the most useful optional routines.
+
+# include <mln/opt/all.hh>
+
+#endif // ! MLN_OPT_ESSENTIAL_HH
--
1.5.6.5
URL: https://svn.lrde.epita.fr/svn/oln/trunk/milena
ChangeLog:
2009-02-23 Fabien Freling <fabien.freling(a)lrde.epita.fr>
Add DICOM support.
* mln/io/dicom/load.hh: DICOM support through GDCM library.
---
load.hh | 388 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 388 insertions(+)
Index: trunk/milena/mln/io/dicom/load.hh
===================================================================
--- trunk/milena/mln/io/dicom/load.hh (revision 0)
+++ trunk/milena/mln/io/dicom/load.hh (revision 3418)
@@ -0,0 +1,388 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+
+/*
+ *
+ * Copyright (C) 1994-2005, OFFIS
+ *
+ * This software and supporting documentation were developed by
+ *
+ * Kuratorium OFFIS e.V.
+ * Healthcare Information and Communication Systems
+ * Escherweg 2
+ * D-26121 Oldenburg, Germany
+ *
+ * THIS SOFTWARE IS MADE AVAILABLE, AS IS, AND OFFIS MAKES NO WARRANTY
+ * REGARDING THE SOFTWARE, ITS PERFORMANCE, ITS MERCHANTABILITY OR
+ * FITNESS FOR ANY PARTICULAR USE, FREEDOM FROM ANY COMPUTER DISEASES OR
+ * ITS CONFORMITY TO ANY SPECIFICATION. THE ENTIRE RISK AS TO QUALITY AND
+ * PERFORMANCE OF THE SOFTWARE IS WITH THE USER.
+ *
+ * Module: dcmdata
+ *
+ * Author: Gerd Ehlers
+ *
+ * Purpose: List the contents of a dicom file
+ *
+ * Last Update: $Author: meichel $
+ * Update Date: $Date: 2005/12/08 15:40:46 $
+ * CVS/RCS Revision: $Revision: 1.55 $
+ * Status: $State: Exp $
+ *
+ * CVS/RCS Log at end of file
+ *
+ */
+
+#ifndef MLN_IO_DICOM_LOAD_HH
+# define MLN_IO_DICOM_LOAD_HH
+
+/*!
+ * \file mln/io/dicom/load.hh
+ *
+ * \brief Define a function which loads an image of kind dicom with
+ * given path.
+ *
+ */
+
+# include <mln/io/pnm/load.hh>
+
+# include <dcmtk/config/osconfig.h> /* make sure OS specific configuration is included first */
+# include <dcmtk/ofstd/ofstream.h>
+# include <dcmtk/dcmdata/dctk.h>
+# include <dcmtk/dcmdata/dcdebug.h>
+# include <dcmtk/dcmdata/cmdlnarg.h>
+# include <dcmtk/ofstd/ofconapp.h>
+# include <dcmtk/dcmdata/dcuid.h> /* for dcmtk version name */
+# include <dcmtk/dcmdata/dcistrmz.h> /* for dcmZlibExpectRFC1950Encoding */
+
+# define INCLUDE_CSTDLIB
+# define INCLUDE_CSTRING
+# include <dcmtk/ofstd/ofstdinc.h>
+
+# ifdef WITH_ZLIB
+# include <zlib.h> /* for zlibVersion() */
+# endif
+
+# define SHORTCOL 3
+# define LONGCOL 20
+# define PATH_SEPARATOR '/'
+
+
+
+namespace mln
+{
+
+ namespace io
+ {
+
+ namespace dicom
+ {
+
+ /*! Load a dicom image in a Milena image.
+ *
+ * \param[out] ima A reference to the image which will receive
+ * data.
+ * \param[in] filename The source.
+ */
+ template <typename I>
+ void load(Image<I>& ima,
+ const std::string& filename);
+
+ /*! Load a dicom image in a Milena image. To use this routine, you
+ * should specialize the template whith the value type of the
+ * image loaded. (ex : load<value::int_u8>("...") )
+ *
+ * \param[in] filename The image source.
+ *
+ * \return An image2d which contains loaded data.
+ */
+ template <typename V>
+ image2d<V> load(const std::string& filename);
+
+ /*! Load a dicom image in a Milena image. To use this routine, you
+ * should specialize the template whith the value type of the
+ * image loaded. (ex : load<value::int_u8>("...") )
+ *
+ * \param[in] filename The image source.
+ *
+ * \return An image2d which contains loaded data.
+ */
+ template <typename V>
+ image3d<V> load(const std::string& filename);
+
+# ifndef MLN_INCLUDE_ONLY
+
+ template <typename V>
+ inline
+ image2d<V> load(const std::string& filename)
+ {
+ trace::entering("mln::io::dicom::load");
+ image2d<V> ima;// = io::pnm::load<V>(DICOM, filename);
+ trace::exiting("mln::io::dicom::load");
+ return ima;
+ }
+
+ template <typename V>
+ inline
+ image3d<V> load(const std::string& filename)
+ {
+ trace::entering("mln::io::dicom::load");
+ image2d<V> ima;// = io::pnm::load<V>(DICOM, filename);
+ trace::exiting("mln::io::dicom::load");
+ return ima;
+ }
+
+
+
+
+
+
+ static OFBool printAllInstances = OFTrue;
+ static OFBool prependSequenceHierarchy = OFFalse;
+ static int printTagCount = 0;
+ static const int MAX_PRINT_TAG_NAMES = 1024;
+ static const char* printTagNames[MAX_PRINT_TAG_NAMES];
+ static const DcmTagKey* printTagKeys[MAX_PRINT_TAG_NAMES];
+ static OFCmdUnsignedInt maxReadLength = 4096; // default is 4 KB
+
+ static OFBool addPrintTagName(const char* tagName)
+ {
+ if (printTagCount >= MAX_PRINT_TAG_NAMES) {
+ std::cerr << "error: too many print Tag options (max: " << MAX_PRINT_TAG_NAMES << ")" << endl;
+ return OFFalse;
+ }
+
+ unsigned int group = 0xffff;
+ unsigned int elem = 0xffff;
+ if (sscanf(tagName, "%x,%x", &group, &elem) != 2)
+ {
+ /* it is a name */
+ const DcmDataDictionary& globalDataDict = dcmDataDict.rdlock();
+ const DcmDictEntry *dicent = globalDataDict.findEntry(tagName);
+ if (dicent == NULL)
+ {
+ std::cerr << "error: unrecognised tag name: '" << tagName << "'" << endl;
+ dcmDataDict.unlock();
+ return OFFalse;
+ }
+ else
+ {
+ /* note for later */
+ printTagKeys[printTagCount] = new DcmTagKey(dicent->getKey());
+ }
+ dcmDataDict.unlock();
+ }
+ else
+ {
+ /* tag name has format xxxx,xxxx */
+ /* do not lookup in dictionary, tag could be private */
+ printTagKeys[printTagCount] = NULL;
+ }
+
+ printTagNames[printTagCount] = strcpy(OFstatic_cast(char*, malloc(strlen(tagName)+1)), tagName);
+ printTagCount++;
+ return OFTrue;
+ }
+
+
+ template <typename I>
+ static void printResult(Image<I>& ima, DcmStack& stack, size_t printFlags)
+ {
+ unsigned long n = stack.card();
+ if (n == 0)
+ return;
+
+ if (prependSequenceHierarchy) {
+ /* print the path leading up to the top stack elem */
+ for (unsigned long i = n - 1; i >= 1; i--) {
+ DcmObject *dobj = stack.elem(i);
+ /* do not print if a DCM_Item as this is not
+ * very helpful to distinguish instances.
+ */
+ if (dobj != NULL && dobj->getTag().getXTag() != DCM_Item) {
+ char buf[512];
+ sprintf(buf, "(%x,%x).",
+ OFstatic_cast(unsigned, dobj->getGTag()),
+ OFstatic_cast(unsigned, dobj->getETag()));
+ std::cout << buf;
+ }
+ }
+ }
+
+ /* print the tag and its value */
+ DcmObject *dobj = stack.top();
+ dobj->print(std::cout, printFlags);
+ }
+
+ template <typename I>
+ static int dumpFile(Image<I>& ima,
+ const char *ifname,
+ const E_FileReadMode readMode,
+ const E_TransferSyntax xfer,
+ const size_t printFlags,
+ const OFBool loadIntoMemory,
+ const OFBool stopOnErrors,
+ const OFBool writePixelData,
+ const char *pixelDirectory)
+ {
+ int result = 0;
+
+ DcmFileFormat dfile;
+ DcmObject *dset = &dfile;
+
+ if (readMode == ERM_dataset)
+ dset = dfile.getDataset();
+
+ // Load file
+
+ OFCondition cond = dfile.loadFile(ifname, xfer, EGL_noChange, maxReadLength, readMode);
+
+ // Read error
+
+ if (!cond.good())
+ {
+ std::cerr << "error: " << dfile.error().text()
+ << ": reading file: "<< ifname << endl;
+ result = 1;
+ if (stopOnErrors)
+ return result;
+ }
+
+ if (loadIntoMemory)
+ dfile.loadAllDataIntoMemory();
+
+ if (printTagCount == 0)
+ {
+ if (writePixelData)
+ {
+ OFString str = ifname;
+ OFString rname = pixelDirectory;
+ if ((rname.length() > 0) && (rname[rname.length() - 1] != PATH_SEPARATOR))
+ rname += PATH_SEPARATOR;
+ size_t pos = str.find_last_of(PATH_SEPARATOR);
+ if (pos == OFString_npos)
+ rname += str;
+ else
+ rname += str.substr(pos + 1);
+ size_t counter = 0;
+ dset->print(std::cout, printFlags, 0 /*level*/, rname.c_str(), &counter);
+ }
+ else
+ dset->print(std::cout, printFlags);
+ }
+ else
+ {
+ /* only print specified tags */
+ for (int i = 0; i < printTagCount; i++)
+ {
+ unsigned int group = 0xffff;
+ unsigned int elem = 0xffff;
+ DcmTagKey searchKey;
+ const char* tagName = printTagNames[i];
+ if (printTagKeys[i])
+ searchKey = *printTagKeys[i];
+ else
+ {
+ if (sscanf(tagName, "%x,%x", &group, &elem) == 2)
+ searchKey.set(group, elem);
+ else
+ {
+ std::cerr << "Internal ERROR in File " << __FILE__ << ", Line "
+ << __LINE__ << std::endl
+ << "-- Named tag inconsistency" << std::endl;
+ abort();
+ }
+ }
+
+ DcmStack stack;
+ if (dset->search(searchKey, stack, ESM_fromHere, OFTrue) == EC_Normal)
+ {
+ printResult(ima, stack, printFlags);
+ if (printAllInstances)
+ {
+ while (dset->search(searchKey, stack, ESM_afterStackTop, OFTrue) == EC_Normal)
+ printResult(ima, stack, printFlags);
+ }
+ }
+ }
+ }
+
+ return result;
+ }
+
+
+ template <typename I>
+ inline
+ void load(Image<I>& ima,
+ const std::string& filename)
+ {
+ trace::entering("mln::io::dicom::load");
+
+ std::ifstream file(filename.c_str());
+ if (! file)
+ {
+ std::cerr << "error: cannot open file '" << filename << "'!";
+ abort();
+ }
+
+ int opt_debugMode = 0;
+ OFBool loadIntoMemory = OFTrue;
+ size_t printFlags = DCMTypes::PF_shortenLongTagValues /*| DCMTypes::PF_showTreeStructure*/;
+ OFBool printFilename = OFFalse;
+ OFBool writePixelData = OFFalse;
+ E_FileReadMode readMode = ERM_autoDetect;
+ E_TransferSyntax xfer = EXS_Unknown;
+ OFBool stopOnErrors = OFTrue;
+ const char *current = NULL;
+ const char *pixelDirectory = NULL;
+
+
+ /* make sure data dictionary is loaded */
+ if (!dcmDataDict.isDictionaryLoaded())
+ {
+ std::cerr << "Warning: no data dictionary loaded, "
+ << "check environment variable: "
+ << DCM_DICT_ENVIRONMENT_VARIABLE;
+ }
+
+ int errorCount = 0;
+ dumpFile(ima, current, readMode, xfer, printFlags, loadIntoMemory, stopOnErrors,
+ writePixelData, pixelDirectory);
+
+ trace::exiting("mln::io::dicom::load");
+ }
+
+# endif // ! MLN_INCLUDE_ONLY
+
+ } // end of namespace mln::io::dicom
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+
+#endif // ! MLN_IO_DICOM_LOAD_HH
* mln/labeling/mean_values.hh: add a more generic version.
* tests/labeling/Makefile.am,
* tests/labeling/mean_values.cc: add missing test.
---
milena/ChangeLog | 9 ++++
milena/mln/labeling/mean_values.hh | 52 ++++++++++++++++++-------
milena/tests/labeling/Makefile.am | 2 +
milena/tests/labeling/mean_values.cc | 70 ++++++++++++++++++++++++++++++++++
4 files changed, 119 insertions(+), 14 deletions(-)
create mode 100644 milena/tests/labeling/mean_values.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 53827ae..62d0de4 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,14 @@
2009-02-23 Guillaume Lazzara <z(a)lrde.epita.fr>
+ Add a missing test for labeling::mean_values.
+
+ * mln/labeling/mean_values.hh: add a more generic version.
+
+ * tests/labeling/Makefile.am,
+ * tests/labeling/mean_values.cc: add missing test.
+
+2009-02-23 Guillaume Lazzara <z(a)lrde.epita.fr>
+
Various small fixes.
* doc/tutorial/samples/win-create-1.cc: fix ref output.
diff --git a/milena/mln/labeling/mean_values.hh b/milena/mln/labeling/mean_values.hh
index 7014c59..0565abb 100644
--- a/milena/mln/labeling/mean_values.hh
+++ b/milena/mln/labeling/mean_values.hh
@@ -28,6 +28,15 @@
#ifndef MLN_LABELING_MEAN_VALUES_HH
# define MLN_LABELING_MEAN_VALUES_HH
+/// \file mln/labeling/mean_values.hh
+///
+/// Construct from a labeled image a new image, the labels values are
+/// replaced by the components mean values.
+///
+/// \todo handle mean value for label 0 correctly.
+/// \todo merge rgb and generic version.
+
+
# include <mln/core/concept/image.hh>
# include <mln/core/alias/vec3d.hh>
@@ -39,11 +48,6 @@
# include <mln/literal/colors.hh>
-/// \file mln/labeling/mean_values.hh
-///
-/// Construct from a labeled image a new image, the labels values are
-/// replaced by the components mean values.
-
namespace mln
{
@@ -92,15 +96,35 @@ namespace mln
template <typename I, typename L>
mln_concrete(I)
- mean_values(const Image<I>& input,
- const Image<L>& lbl, mln_value(L) nlabels)
+ mean_values(const Image<I>& input_,
+ const Image<L>& lbl_, mln_value(L) nlabels)
{
- internal::mean_values_tests(input, lbl, nlabels);
+ trace::entering("mln::labeling::impl::generic::mean_values");
+
+ internal::mean_values_tests(input_, lbl_, nlabels);
+
+ const I& input = exact(input_);
+ const L& lbl = exact(lbl_);
+ typedef mln_value(L) LV;
+ typedef mln_value(I) IV;
+
+ util::array<float> m_3f
+ = labeling::compute(accu::mean<IV>(),
+ input, // input color image
+ lbl, // watershed labeling
+ nlabels);
+ m_3f[0] = 0.f;
+
+ util::array<IV> m;
+ convert::from_to(m_3f, m);
+ m[0] = 150u; //FIXME: handle label 0 correctly.
+
+ mln_concrete(I) output = level::transform(lbl,
+ convert::to< fun::i2v::array<IV> >(m));
+
- trace::warning("labeling::impl::generic::mean_values() is not \
- implemented!");
- //FIXME: to write!
- abort();
+ trace::exiting("mln::labeling::impl::generic::mean_values");
+ return output;
}
}
@@ -110,7 +134,7 @@ namespace mln
mean_values_rgb(const Image<I>& input_,
const Image<L>& lbl_, mln_value(L) nlabels)
{
- trace::entering("mln::labeling::mean_values_rgb");
+ trace::entering("mln::labeling::impl::mean_values_rgb");
internal::mean_values_tests(input_, lbl_, nlabels);
@@ -131,7 +155,7 @@ namespace mln
convert::to< fun::i2v::array<mln_value(I)> >(m));
- trace::exiting("mln::labeling::mean_values_rgb");
+ trace::exiting("mln::labeling::impl::mean_values_rgb");
return output;
}
diff --git a/milena/tests/labeling/Makefile.am b/milena/tests/labeling/Makefile.am
index 083244a..6b3231f 100644
--- a/milena/tests/labeling/Makefile.am
+++ b/milena/tests/labeling/Makefile.am
@@ -10,6 +10,7 @@ check_PROGRAMS = \
flat_zones \
foreground \
level \
+ mean_values \
n_max \
regional_maxima \
regional_minima \
@@ -22,6 +23,7 @@ fill_holes_SOURCES = fill_holes.cc
flat_zones_SOURCES = flat_zones.cc
foreground_SOURCES = foreground.cc
level_SOURCES = level.cc
+mean_values_SOURCES = mean_values.cc
n_max_SOURCES = n_max.cc
regional_maxima_SOURCES = regional_maxima.cc
regional_minima_SOURCES = regional_minima.cc
diff --git a/milena/tests/labeling/mean_values.cc b/milena/tests/labeling/mean_values.cc
new file mode 100644
index 0000000..c46193a
--- /dev/null
+++ b/milena/tests/labeling/mean_values.cc
@@ -0,0 +1,70 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+
+/// \file tests/labeling/blobs.cc
+///
+/// Test on mln::labeling::mean_values.
+
+#include <mln/core/image/image2d.hh>
+
+#include <mln/level/compare.hh>
+
+#include <mln/labeling/mean_values.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/value/label_8.hh>
+
+#include "tests/data.hh"
+
+int main()
+{
+ using namespace mln;
+ using value::int_u8;
+ using value::label_8;
+
+ int_u8 input_[16] = { 1, 2, 0, 1,
+ 3, 0, 2, 3,
+ 0, 0, 2, 3,
+ 1, 1, 0, 1 };
+ image2d<int_u8> input = make::image2d(input_);
+
+ label_8 lbl_[16] = { 1, 1, 0, 2,
+ 1, 0, 2, 2,
+ 0, 0, 2, 2,
+ 3, 3, 0, 2 };
+ image2d<label_8> lbl = make::image2d(lbl_);
+
+ int_u8 means_[16] = { 2, 2, 150, 2,
+ 2, 150, 2, 2,
+ 150, 150, 2, 2,
+ 1, 1, 150, 2 };
+ image2d<int_u8> means = make::image2d(means_);
+
+ image2d<int_u8> res = labeling::mean_values(input, lbl, 3);
+
+ mln_assertion(res == means);
+}
--
1.5.6.5