[med-svn] [mia] 01/04: Imported Upstream version 2.2.6

Gert Wollny gert-guest at moszumanska.debian.org
Sun Oct 25 16:34:52 UTC 2015


This is an automated email from the git hooks/post-receive script.

gert-guest pushed a commit to branch master
in repository mia.

commit 1f3ff3fea499d11615b4d3af3c2ee9eeead71a55
Author: Gert Wollny <gw.fossdev at gmail.com>
Date:   Sun Oct 25 16:45:41 2015 +0100

    Imported Upstream version 2.2.6
---
 CMakeLists.txt                       |   8 +-
 ChangeLog                            |  26 ++---
 README                               |   9 +-
 README.md                            |  37 +++++++
 doc/reference.dox.cmake              |   2 +-
 mia/3d/fifof/label.cc                |  40 ++++----
 mia/3d/fifof/label.hh                |  18 ++--
 mia/3d/fifof/test_label.cc           |   8 +-
 mia/3d/test_imagedraw.cc             |   8 +-
 mia/core/labelmap.hh                 |   2 +-
 mia/core/parameter.hh                |   3 +-
 mia/core/xmlinterface.hh             |  31 +++++-
 mia3d.pc.cmake                       |   2 +-
 scripts/mia-segment-class-from-stack | 179 ++++++++++++++++++++++++++++++++++
 scripts/remove-small-blobs.sh        |  22 +++--
 src/2dstack-cmeans-presegment.cc     | 181 ++++++++++++-----------------------
 16 files changed, 396 insertions(+), 180 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3cb98eb..bdd42ff 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -52,9 +52,9 @@ SET(VENDOR "Gert Wollny")
 SET(PACKAGE_NAME "mia")
 SET(MAJOR_VERSION 2)
 SET(MINOR_VERSION 2)
-SET(MICRO_VERSION 5)
-SET(INTERFACE_AGE 1)
-SET(BINARY_AGE    1)
+SET(MICRO_VERSION 6)
+SET(INTERFACE_AGE 2)
+SET(BINARY_AGE    2)
 
 #
 #SET(CMAKE_BUILD_WITH_INSTALL_RPATH 1)
@@ -382,8 +382,6 @@ pkg_check_modules(XMLPP libxml++-2.6 REQUIRED)
 IF (XMLPP_FOUND)
   INCLUDE_DIRECTORIES(${XMLPP_INCLUDE_DIRS})
   LINK_DIRECTORIES(${XMLPP_LIBRARY_DIRS})
-  SET(PKG_CONFIG_DEPS "${PKG_CONFIG_DEPS} libxml++-2.6")
-  SET(HAVE_LIBXMLPP 1)
 ENDIF (XMLPP_FOUND)
 
 #
diff --git a/ChangeLog b/ChangeLog
index f53e0fe..30b33a4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,18 +1,22 @@
-2.2.5 
-   
-   Bug Fixes: 
-   
-    * Fix SSE2 alignment bugs on 32 bit x86 
-    * Correct test to use BOOST_CHECK_CLOSE for floating point numbers 
-    * Fix a series of Coverity reported bugs 
-      - Change the CXMLElement to track ist children 
-      - fix past-end access in histograms 
-      - check for empty histogram in new CMeans implementation 
+2.2.6
+
+    * Correct pkg-config dependencies
+	* Change label type in fifof to unsigned int
+
+2.2.5
+
+   Bug Fixes:
+    * Fix SSE2 alignment bugs on 32 bit x86
+    * Correct test to use BOOST_CHECK_CLOSE for floating point numbers
+    * Fix a series of Coverity reported bugs
+      - Change the CXMLElement to track ist children
+      - fix past-end access in histograms
+      - check for empty histogram in new CMeans implementation
     * Correct explicite instanciation of 3diterator, clang++ needed this
 
     Other fixes
 
-    * Remove outdate documentation files 
+    * Remove outdate documentation files
     * Correct licenses
 
 2.2.4
diff --git a/README b/README
index b890700..525f253 100644
--- a/README
+++ b/README
@@ -7,9 +7,9 @@ For details, help, etc see http://mia.sourceforge.net
 
 If you use this software for scientific research, please cite it as 
 
-  Wollny G, Kellman P, Ledesma-Carbayo M-J, Skinner MM, Hublin J-J, and Hierl Th, 
-  "MIA - A Free and Open Source Software for Gray Scale Medical Image Analysis", 
-  Source Code for Biology and Medicine, 2013, 8:20
+  Wollny G, Kellman P, Ledesma-Carbayo M-J, Skinner MM, Hublin J-J, and Hierl
+  Th,   "MIA - A Free and Open Source Software for Gray Scale Medical 
+  Image Analysis", Source Code for Biology and Medicine, 2013, 8:20
 
 
 SUPPORT: 
@@ -26,6 +26,7 @@ Please use the bug tracker at sourceforge to report new bugs:
 
 KNOWN BUGS: 
 
-* Image orientation and pixel size information is not honoured in the image registration code. 
+* Image orientation and pixel size information is not honoured in the
+  image registration code. 
 * the implementation of Mutual information needs testing 
 
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..5e1f7b6
--- /dev/null
+++ b/README.md
@@ -0,0 +1,37 @@
+This repository is a mirror of the master branch of
+
+    git://git.code.sf.net/p/mia/mia2
+
+SYNOPSIS: 
+
+MIA is a collection of libraries and command line tools for the processing 
+of gray scale images. 
+
+For details, help, etc, see http://mia.sourceforge.net
+
+If you use this software for scientific research, please cite it as 
+
+    Wollny G, Kellman P, Ledesma-Carbayo M-J, Skinner MM, Hublin J-J, and Hierl
+    Th, "MIA - A Free and Open Source Software for Gray Scale Medical 
+    Image Analysis", Source Code for Biology and Medicine, 2013, 8:20
+
+SUPPORT: 
+
+For support with running MIA or developing new software using MIA please go to 
+
+     https://sourceforge.net/p/mia/discussion/
+
+REPORTING BUGS:
+ 
+For the moment the preferred option to report bugs is the bug tracker at sourceforge to report new bugs: 
+
+    https://sourceforge.net/p/mia/tickets/
+
+Nevertheless, Github issue tracker is also enabled for those who don't have or don't want a sourceforge account. 
+
+FURTHER READING:
+
+For further information, tutorials how to install and use the software please go to 
+
+    http://sourceforge.net/p/mia/wiki/Home/
+
diff --git a/doc/reference.dox.cmake b/doc/reference.dox.cmake
index e7188f7..a6ebad3 100644
--- a/doc/reference.dox.cmake
+++ b/doc/reference.dox.cmake
@@ -143,7 +143,7 @@ INCLUDE_GRAPH          = YES
 INCLUDED_BY_GRAPH      = YES
 CALL_GRAPH             = NO
 GRAPHICAL_HIERARCHY    = YES
-DOT_IMAGE_FORMAT       = png
+DOT_IMAGE_FORMAT       = svg
 DOT_PATH               = 
 DOTFILE_DIRS           = 
 MAX_DOT_GRAPH_DEPTH    = 0
diff --git a/mia/3d/fifof/label.cc b/mia/3d/fifof/label.cc
index 622c255..244b83d 100644
--- a/mia/3d/fifof/label.cc
+++ b/mia/3d/fifof/label.cc
@@ -35,7 +35,8 @@ using namespace std;
 
 C2DLabelStackFilter::C2DLabelStackFilter(const string& mapfile, P2DShape n):
 	C2DImageFifoFilter(1, 1, 0), 
-	m_neigbourhood(n), 
+	m_neigbourhood(n),
+	m_start_label(1), 
 	m_last_label(1), 
 	m_map_file(mapfile), 
 	m_first_pass(true)
@@ -51,11 +52,17 @@ void C2DLabelStackFilter::do_initialize(::boost::call_traits<mia::P2DImage>::par
 {
 	m_first_pass = true; 
 	m_joints.clear(); 
-	m_out_buffer = C2DUSImage(x->get_size()); 
-	m_last_label = 1; 
+	m_out_buffer = C2DUIImage(x->get_size()); 
+	m_last_label = m_start_label; 
 }
 
-void C2DLabelStackFilter::grow( int x, int y, C2DBitImage& input, unsigned short l)
+void C2DLabelStackFilter::set_start_label(unsigned int start_label)
+{
+	m_start_label = start_label; 
+}
+	
+
+void C2DLabelStackFilter::grow( int x, int y, C2DBitImage& input, unsigned int l)
 {
 	vector<C2DBounds> seed; 
 	seed.push_back(C2DBounds(x,y)); 
@@ -71,7 +78,7 @@ void C2DLabelStackFilter::grow( int x, int y, C2DBitImage& input, unsigned short
 			    py >= input.get_size().y) 
 				continue; 
 			
-			unsigned short lold = m_out_buffer(px, py); 
+			unsigned int lold = m_out_buffer(px, py); 
 			if (lold) {
 				if (l != lold) {
 					m_joints.add_pair(l, lold); 
@@ -86,6 +93,7 @@ void C2DLabelStackFilter::grow( int x, int y, C2DBitImage& input, unsigned short
 	}
 }
 
+
 void C2DLabelStackFilter::label_new_regions(C2DBitImage& input)
 {
 	auto ii = input.begin();
@@ -96,12 +104,12 @@ void C2DLabelStackFilter::label_new_regions(C2DBitImage& input)
 			if (*ii) {
 				cvdebug() << "("<< x << ", " << y <<"," << slice <<  "):" 
 					  << m_last_label << "\n"; 
-				if (m_last_label < numeric_limits<unsigned short>::max()) 
+				if (m_last_label < numeric_limits<unsigned int>::max()) 
 					*usi = m_last_label++;
 				else 
 					throw create_exception<invalid_argument>("C2DLabelStackFilter: number of connected components is about to "
 								       "exeed the  supported limit of ",
-								       numeric_limits<unsigned short>::max(), 
+								       numeric_limits<unsigned int>::max(), 
 								       ", sorry can't continue\n");
 				*ii = false; 
 				grow(x,y,input,*usi); 
@@ -125,7 +133,7 @@ void C2DLabelStackFilter::label(C2DBitImage& input)
 
 void C2DLabelStackFilter::new_label(C2DBitImage& input)
 {
-	m_out_buffer = C2DUSImage(input.get_size(), input); 
+	m_out_buffer = C2DUIImage(input.get_size(), input); 
 	label_new_regions(input); 
 }
 
@@ -176,21 +184,21 @@ void CLabelRemapper::clear()
 
 P2DImage C2DLabelStackFilter::do_filter()
 {
-	return P2DImage(new C2DUSImage(m_out_buffer)); 
+	return P2DImage(new C2DUIImage(m_out_buffer)); 
 }
 
-void CLabelRemapper::add_pair(unsigned short a, unsigned short b)
+void CLabelRemapper::add_pair(unsigned int a, unsigned int b)
 {
 	if (a > b) 
-		m_raw_map.insert(T2DVector<unsigned short>(a,b));
+		m_raw_map.insert(T2DVector<unsigned int>(a,b));
 	else 
-		m_raw_map.insert(T2DVector<unsigned short>(b,a)); 
+		m_raw_map.insert(T2DVector<unsigned int>(b,a)); 
 }
 
 struct greater_than {
-	typedef T2DVector<unsigned short> value_type; 
-	bool operator() (const T2DVector<unsigned short>& lhs, 
-			 const T2DVector<unsigned short>& rhs) {
+	typedef T2DVector<unsigned int> value_type; 
+	bool operator() (const T2DVector<unsigned int>& lhs, 
+			 const T2DVector<unsigned int>& rhs) {
 		return lhs.x > rhs.x || ((lhs.x  == rhs.x)  && lhs.y > rhs.y); 
 	}
 };
@@ -198,7 +206,7 @@ struct greater_than {
 CLabelMap CLabelRemapper::get_map() const
 {
 	CLabelMap result; 
-	priority_queue<T2DVector<unsigned short>, vector<T2DVector<unsigned short>>, greater_than> sorted; 
+	priority_queue<T2DVector<unsigned int>, vector<T2DVector<unsigned int>>, greater_than> sorted; 
 	cvdebug()<< "got " << m_raw_map.size() << " joints\n"; 
 
 	for (auto i = m_raw_map.begin();  i != m_raw_map.end();  ++i)
diff --git a/mia/3d/fifof/label.hh b/mia/3d/fifof/label.hh
index 8b38aa9..9a52bcd 100644
--- a/mia/3d/fifof/label.hh
+++ b/mia/3d/fifof/label.hh
@@ -40,12 +40,12 @@ class CLabelRemapper {
 public: 
 	void clear(); 
 	
-	void add_pair(unsigned short a, unsigned short b); 
+	void add_pair(unsigned int  a, unsigned int  b); 
 	
 	mia::CLabelMap get_map() const; 
 private: 
-	std::set<mia::T2DVector<unsigned short>, 
-		 mia::less_then<mia::T2DVector<unsigned short>>> m_raw_map;
+	std::set<mia::T2DVector<unsigned int >, 
+		 mia::less_then<mia::T2DVector<unsigned int >>> m_raw_map;
 }; 
 
 class C2DLabelStackFilter: public mia::C2DImageFifoFilter {
@@ -56,6 +56,9 @@ public:
 	C2DLabelStackFilter(const std::string& mapfile, mia::P2DShape n); 
 	~C2DLabelStackFilter(); 
 
+	// only for testing 
+	void set_start_label(unsigned int); 
+	
 	// this is public for testing 
 	const mia::CLabelMap& get_joints() const; 
 private: 
@@ -69,16 +72,17 @@ private:
 	void new_label(mia::C2DBitImage& input); 
 	void re_label(mia::C2DBitImage& input);
 	void label_new_regions(mia::C2DBitImage& input); 
-	void grow( int x, int y, mia::C2DBitImage& input, unsigned short l); 
+	void grow( int x, int y, mia::C2DBitImage& input, unsigned int l); 
 
-	mia::P2DShape m_neigbourhood; 
-	mutable int   m_last_label;
+	mia::P2DShape m_neigbourhood;
+	unsigned int   m_start_label;
+	mutable unsigned int   m_last_label;
 	CLabelRemapper m_joints; 
 	std::string   m_map_file;
 	bool m_first_pass; 
 
 	mia::C2DBounds m_slice_size; 
-	mia::C2DUSImage m_out_buffer;
+	mia::C2DUIImage m_out_buffer;
 	
 	mia::CLabelMap m_target; 
 	
diff --git a/mia/3d/fifof/test_label.cc b/mia/3d/fifof/test_label.cc
index d1374ff..beb28e9 100644
--- a/mia/3d/fifof/test_label.cc
+++ b/mia/3d/fifof/test_label.cc
@@ -69,7 +69,7 @@ BOOST_FIXTURE_TEST_CASE( test_fifof_label , fifof_Fixture )
 
 	};
 
-	unsigned short test_data[n_slices * 4 * 4] = {
+	unsigned int test_data[n_slices * 4 * 4] = {
 		  0, 0, 0, 0,  
 		  1, 0, 0, 0,   
 		  0, 0, 0, 0,
@@ -148,20 +148,20 @@ BOOST_AUTO_TEST_CASE( test_labelremap )
 
 BOOST_AUTO_TEST_CASE( test_overflow ) 
 {
-	const C2DBounds size(300,300);
+	const C2DBounds size(40,40);
 	C2DBitImage *img(new C2DBitImage(size)); 
 	fill(img->begin(), img->end(), 1); 
 	P2DImage pimg(img); 
 	
 	P2DShape shape(new C1n2DShape()); 
 	
-	C2DLabelStackFilter filter("", shape ); 
+	C2DLabelStackFilter filter("", shape );
+	filter.set_start_label(numeric_limits<unsigned int>::max() - 10); 
 
 	typedef TFifoFilterSink<P2DImage> C2DImageFifoFilterSink;
 
 	C2DImageFifoFilterSink::Pointer sink(new C2DImageFifoFilterSink());
 	filter.append_filter(sink);
-	
 	BOOST_CHECK_THROW(filter.push(pimg), invalid_argument); 
 
 }
diff --git a/mia/3d/test_imagedraw.cc b/mia/3d/test_imagedraw.cc
index c73c5de..e5d963a 100644
--- a/mia/3d/test_imagedraw.cc
+++ b/mia/3d/test_imagedraw.cc
@@ -147,7 +147,7 @@ BOOST_FIXTURE_TEST_CASE( test_simple_draw_line_z_pivot, SimpleBitImageDrawFixtur
 
 BOOST_FIXTURE_TEST_CASE( test_simple_draw_line_pivot_x, SimpleBitImageDrawFixture ) 
 {
-        output.draw_line(C3DFVector(0,4,5), C3DFVector(10,10,12)); 
+        output.draw_line(C3DFVector(0.1,4.2,5.3), C3DFVector(10.1,10.2,12.3)); 
         auto& img = output.get_image(); 
                 
         auto i = img.begin_range(C3DBounds::_0, img.get_size()); 
@@ -159,7 +159,7 @@ BOOST_FIXTURE_TEST_CASE( test_simple_draw_line_pivot_x, SimpleBitImageDrawFixtur
 
 	C3DFVector dir(0.5, 0.3, 0.35f);
 	
-	C3DFVector p(0,4,5);
+	C3DFVector p(0.1,4.2,5.3);
 	for (int k = 0; k < 22; ++k, p += dir) {
 		C3DBounds ip(static_cast<unsigned>(floor(p.x + 0.5)), 
 			     static_cast<unsigned>(floor(p.y + 0.5)), 
@@ -180,7 +180,7 @@ BOOST_FIXTURE_TEST_CASE( test_simple_draw_line_pivot_x, SimpleBitImageDrawFixtur
 
 BOOST_FIXTURE_TEST_CASE( test_simple_draw_line_pivot_y, SimpleBitImageDrawFixture ) 
 {
-        output.draw_line(C3DFVector(4,0,5), C3DFVector(10,10,9)); 
+        output.draw_line(C3DFVector(4,0.1,5.2), C3DFVector(10,10.1,9.2)); 
         auto& img = output.get_image(); 
                 
         auto i = img.begin_range(C3DBounds::_0, img.get_size()); 
@@ -192,7 +192,7 @@ BOOST_FIXTURE_TEST_CASE( test_simple_draw_line_pivot_y, SimpleBitImageDrawFixtur
 
 	C3DFVector dir(0.3, .5, 0.2f);
 	
-	C3DFVector p(4,0,5);
+	C3DFVector p(4,0.1,5.2);
 	for (int k = 0; k < 22; ++k, p += dir) {
 		C3DBounds ip(static_cast<unsigned>(floor(p.x + 0.5)), 
 			     static_cast<unsigned>(floor(p.y + 0.5)), 
diff --git a/mia/core/labelmap.hh b/mia/core/labelmap.hh
index 28fa62d..f66873f 100644
--- a/mia/core/labelmap.hh
+++ b/mia/core/labelmap.hh
@@ -33,7 +33,7 @@ NS_MIA_BEGIN
    \ingroup misc
    \brief A simple class to add loadind and storeing to a map of labels. 
 */
-class EXPORT_CORE CLabelMap: public std::map<unsigned short,  unsigned short> {
+class EXPORT_CORE CLabelMap: public std::map<unsigned int,  unsigned int> {
 public: 
 	CLabelMap() = default; 
 
diff --git a/mia/core/parameter.hh b/mia/core/parameter.hh
index 2b81961..4a71bf5 100644
--- a/mia/core/parameter.hh
+++ b/mia/core/parameter.hh
@@ -4,7 +4,8 @@
  * Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
  *
  * MIA is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
+ * it under the terms of the GNU General Pub
+lic License as published by
  * the Free Software Foundation; either version 3 of the License, or
  * (at your option) any later version.
  *
diff --git a/mia/core/xmlinterface.hh b/mia/core/xmlinterface.hh
index a3d9633..17a4ba1 100644
--- a/mia/core/xmlinterface.hh
+++ b/mia/core/xmlinterface.hh
@@ -23,6 +23,8 @@
 #define mia_core_xmlinterface_hh
 
 #include <mia/core/defines.hh>
+#include <memory> 
+
 
 NS_MIA_BEGIN
 
@@ -48,11 +50,29 @@ public:
 	CXMLElement(const CXMLElement& orig) = delete;
 	CXMLElement& operator = (const CXMLElement& orig) = delete;
 
+	/**
+	   \brief add a new child element 
 
+	   This method adds a new child element to this node
+	   \param name name tag of the new child element 
+	   \returns the newly created node 
 
-	
+	 */
 	CXMLElement::Pointer add_child(const char *name);
+
+	/**
+	   \brief Set an attribute of the node 
+
+	   This method sets an attribute of a node 
+	   \param name attribute name 
+	   \param value (string) value of the attribute 
+	 */
 	void set_attribute(const char *name, const std::string& value);
+
+	/**
+	   Set the child text of the node 
+	   \param value text value to be set 
+	 */
 	void set_child_text(const std::string& value);
 private:
 	friend class CXMLDocument; 
@@ -60,6 +80,15 @@ private:
 }; 
 
 
+/**
+   \brief facate for an XML document 
+
+   This class implements a facade for a XML document.  
+   
+   
+
+*/
+
 class EXPORT_CORE CXMLDocument {
 public: 
 	CXMLDocument();
diff --git a/mia3d.pc.cmake b/mia3d.pc.cmake
index 22940e4..4f50174 100644
--- a/mia3d.pc.cmake
+++ b/mia3d.pc.cmake
@@ -12,6 +12,6 @@ Name: mia3d
 Description: A library for 3D grayscale image processing 
 Version: @PACKAGE_VERSION@
 Conflicts:
-Requires: mia2d- at VERSION@ eigen3
+Requires: mia2d- at VERSION@
 Libs: -lmia3d- at VERSION@ -L${prefix}/@LIBRARY_INSTALL_PATH@
 Cflags: -I${prefix}/@INCLUDE_INSTALL_PATH@ -I${prefix}/@LIB_INCLUDE_INSTALL_PATH@
diff --git a/scripts/mia-segment-class-from-stack b/scripts/mia-segment-class-from-stack
new file mode 100644
index 0000000..190ab34
--- /dev/null
+++ b/scripts/mia-segment-class-from-stack
@@ -0,0 +1,179 @@
+#!/bin/bash 
+#
+#
+# This file is part of MIA - a toolbox for medical image analysis 
+# Copyright (c) Leipzig, Madrid 1999-2015 Gert Wollny
+#
+# MIA 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; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 program; if not, see <http://www.gnu.org/licenses/>.
+#
+
+
+out_image_type="png"
+blob_thresh=100
+class=2
+nclasses=3 
+prob_thresh=0.96 
+hist_thresh=1
+verbosity=message
+
+print_help() {
+    echo "This script runs the segmentation of one class from a series of gray "
+    echo "scale images. Parameters are"
+    echo " " 
+    echo "Usage: mia-segment-class-from-stack [options]"
+    echo " "
+    echo "File IO:"
+    echo "  --input       Input images (give like e.g. input0000.png), Input images"
+    echo "                are expected to be consecutively numbered" 
+    echo "  --output      Output image base name"  
+    echo "  --output-type Output file type, (default=$out_image_type)"
+    echo " "
+    echo "Parameters:"
+    echo "  --blop-thresh threshold for minimum size of blobs to be accepted (default=$blob_thresh)"
+    echo "  --prob-thresh class probability to accept as class member (default=$prob_thresh)"
+    echo "  --hist-thresh Percentage of pixels to merge into the extreme bins (default=$hist_thresh)"
+    echo "  --class class Id to segment"
+    echo "  --n-classes   number of classes to use in the fuzzy c-means classification (default=$nclasses)"
+    echo " "
+    echo "Info:"
+    echo "  --verbose -V  verbosity of the output (info|message|warning|error|fatal)"
+    echo " "
+    exit 0 
+}
+
+#
+# read the command line 
+#
+while [ -n "$1" ] ; do 
+
+    case "$1" in 
+	--blop-thresh) 
+	blop_thresh="$2"
+	shift
+	;;
+
+	--class)
+	class="$2"
+	shift
+	;;
+
+        --n-classes)
+	nclasses="$2"
+	shift
+	;;
+
+	--prob-thresh)
+	prob_thresh="$2"
+	shift
+	;;
+
+        --hist-thresh) 
+        hist_thresh="$2"
+        shift
+        ;;
+
+        --input) 
+        in_images="$2"
+        shift
+        ;;
+
+        --output) 
+        out_images="$2"
+        shift
+        ;;
+
+        --output-type) 
+            out_image_type="$2"
+            shift
+            ;;
+        
+        --verbose,-V)
+            verbosity="$2"
+            shift
+            ;;
+        
+	--help)
+            print_help
+	    exit 
+	    ;;
+
+	*)
+        echo "unknown option '$1' given, run with option --help to see supported options"
+	exit 
+	;;
+
+    esac
+    shift 
+done
+
+datestr=$(date +%y-%m-%d-%H-%m)
+temp_dir=$(mktemp -d stackprocess-${datestr}.XXX)
+
+echo mia-2dstack-cmeans-presegment -i $in_images -o "$temp_dir/class" \
+                              -T $hist_thresh \
+                              -S $prob_thresh \
+                              -C "kmeans:nc=$nclasses" \
+                              -L $class -V $verbosity 
+
+
+mia-2dstack-cmeans-presegment -i $in_images -o "$temp_dir/class" \
+                              -T $hist_thresh \
+                              -S $prob_thresh \
+                              -C "kmeans:nc=$nclasses" \
+                              -L $class -V $verbosity 
+
+number_pattern=$(mia-filenumberpattern -i "$in_images")
+
+# label the images 
+mia-2dstackfilter -i "$temp_dir/class${number_pattern}.png" -t v -o "$temp_dir/labeled"\
+                  "label:map=$temp_dir/labelmap.txt" -V $verbosity 
+
+#relabel joined labels 
+mia-2dimagefilterstack -i "$temp_dir/labeled${number_pattern}.v" -o $temp_dir/relabeled -t v \
+                        "labelmap:map=$temp_dir/labelmap.txt" -V $verbosity 
+
+# evaluate the histogram
+mia-multihist -i "$temp_dir/relabeled${number_pattern}.v" -o "$temp_dir/labelcount.txt" --max 1000000 --bins 1000000 -V $verbosity 
+
+
+# this can be done with awk
+echo "MiaLabelmap" > "$temp_dir/labelbinarizationmap.txt"
+awk -v thresh=$blob_thresh <"$temp_dir/labelcount.txt" \
+    '{if ($2 > thresh){ print $1 " 1"}else{ print $1 " 0"} }' \
+    >> "$temp_dir/labelbinarizationmap.txt" 
+
+mia-2dimagefilterstack -i "$temp_dir/relabeled${number_pattern}.v" -o "$temp_dir/inverse" -t v \
+                       "labelmap:map=$temp_dir/labelbinarizationmap.txt" \
+                       binarize:min=1 invert -V $verbosity 
+
+mia-2dstackfilter -i "$temp_dir/inverse${number_pattern}.v" -t v \
+                  -o "$temp_dir/ilabeled" "label:map=$temp_dir/ilabelmap.txt" -V $verbosity 
+
+mia-2dimagefilterstack -i "$temp_dir/ilabeled${number_pattern}.v" -o $temp_dir/irelabeled -t v \
+                       "labelmap:map=$temp_dir/ilabelmap.txt" -V $verbosity 
+
+mia-multihist -i "$temp_dir/irelabeled${number_pattern}.v" -o "$temp_dir/ilabelcount.txt" \
+              -V $verbosity --max 1000000 --bins 1000000
+
+echo "MiaLabelmap" > "$temp_dir/ilabelbinarizationmap.txt"
+awk -v thresh=$thresh <"$temp_dir/ilabelcount.txt" \
+    '{if ($2 > thresh){ print $1 " 1"}else{ print $1 " 0"} }'\
+    >> "$temp_dir/ilabelbinarizationmap.txt" 
+
+mia-2dimagefilterstack -i "$temp_dir/irelabeled${number_pattern}.v" -o "$out_images" -t png \
+                       "labelmap:map=$temp_dir/ilabelbinarizationmap.txt" binarize:min=1 invert -V $verbosity 
+
+#rm -rf $temp_dir
+
+
diff --git a/scripts/remove-small-blobs.sh b/scripts/remove-small-blobs.sh
index 0d625fb..67f19dd 100644
--- a/scripts/remove-small-blobs.sh
+++ b/scripts/remove-small-blobs.sh
@@ -33,14 +33,14 @@ thresh=$3
 mkdir -p $temp_dir
 
 
-number_pattern=$(mia-filenumber-pattern "$1")
+number_pattern=$(mia-filenumberpattern -i "$1")
 
 # label the images 
 mia-2dstackfilter -i "$in_images" -t v -o "$temp_dir/labeled" "label:map=$temp_dir/labelmap.txt" 
 
 #relabel joined labels 
 mia-2dimagefilterstack -i "$temp_dir/labeled${number_pattern}.v" -o $temp_dir/relabeled -t v \
-                        "relabel:map=$temp_dir/labelmap.txt"
+                        "labelmap:map=$temp_dir/labelmap.txt"
 
 # evaluate the histogram
 mia-multihist -i "$temp_dir/relabeled${number_pattern}.v" -o "$temp_dir/labelcount.txt"
@@ -50,11 +50,21 @@ mia-multihist -i "$temp_dir/relabeled${number_pattern}.v" -o "$temp_dir/labelcou
 echo "MiaLabelmap" > "$temp_dir/labelbinarizationmap.txt"
 awk -v thresh=$thresh <"$temp_dir/labelcount.txt" >> "$temp_dir/labelbinarizationmap.txt" '{if ($2 > thresh){ print $1 " 1"}else{ print $1 " 0"} }'
 
-mia-create-labelbinarization -i "$temp_dir/labelcount.txt" -o "$temp_dir/labelbinarizationmap.txt" \
-                             --thresh ${min_blobsize}
+mia-2dimagefilterstack -i "$temp_dir/relabeled${number_pattern}.v" -o "$temp_dir/inverse" -t v \
+                       "labelmap:map=$temp_dir/labelbinarizationmap.txt" binarize:min=1 invert 
 
-mia-2dimagefilterstack -i "$temp_dir/relabeled${number_pattern}.v" -o "$out_images" \
-                       "relabel:map=$temp_dir/labelbinarizationmap.txt" binarize:min=1
+mia-2dstackfilter -i "$temp_dir/inverse${number_pattern}.v" -t v -o "$temp_dir/ilabeled" "label:map=$temp_dir/ilabelmap.txt"
+
+mia-2dimagefilterstack -i "$temp_dir/ilabeled${number_pattern}.v" -o $temp_dir/irelabeled -t v \
+                       "labelmap:map=$temp_dir/ilabelmap.txt"
+
+mia-multihist -i "$temp_dir/irelabeled${number_pattern}.v" -o "$temp_dir/ilabelcount.txt"
+
+echo "MiaLabelmap" > "$temp_dir/ilabelbinarizationmap.txt"
+awk -v thresh=$thresh <"$temp_dir/ilabelcount.txt" >> "$temp_dir/ilabelbinarizationmap.txt" '{if ($2 > thresh){ print $1 " 1"}else{ print $1 " 0"} }'
+
+mia-2dimagefilterstack -i "$temp_dir/irelabeled${number_pattern}.v" -o "$out_images" -t png \
+                       "labelmap:map=$temp_dir/ilabelbinarizationmap.txt" binarize:min=1 invert 
 
 rm -rf $temp_dir
 
diff --git a/src/2dstack-cmeans-presegment.cc b/src/2dstack-cmeans-presegment.cc
index 3dd5122..4878ca4 100644
--- a/src/2dstack-cmeans-presegment.cc
+++ b/src/2dstack-cmeans-presegment.cc
@@ -37,16 +37,16 @@ const SProgramDescription g_description = {
 	
 	
 	{pdi_description, "This program first evaluates a sparse histogram of an input image "
-         "series, then runs a c-means classification over the histogram, and then estimates a "
-         "per image seeds for later segmentation based on class probabilities. "
+         "series, then runs a c-means classification over the histogram, and then estimates the "
+         "mask for one (given) class based on class probabilities. "
          "This program accepts only images of eight or 16 bit integer pixels."
         }, 
 	
 	{pdi_example_descr,"Run the program over images imageXXXX.png with the sparse histogram, "
          "threshold the lower 30% bins (if available), run cmeans with two classes on the non-zero "
-         "pixels and then create the seeds mask as seedXXXX.png."}, 
+         "pixels and then create the mask for class 1 as foregroundXXXX.png."}, 
 	
-	{pdi_example_code, "-i image.png -o seed -t png --histogram-tresh=30 --classes 2"}
+	{pdi_example_code, "-i imageXXXX.png -o foreground -t png --histogram-tresh=30 --classes 2 --label 1"}
 }; 
 
 class CFullHistogram : public TFilter<size_t> {
@@ -172,116 +172,85 @@ vector<pair<int, unsigned long>> CFullHistogram::get_compressed_histogram()const
 
 typedef map<double, CMeans::DVector> Probmap; 
 
-class FGetFlowImages: public TFilter<pair<C2DFImage, C2DFImage>> {
+class FGetClassSeedMask: public TFilter<P2DImage> {
 public: 
-	FGetFlowImages(const Probmap& map,
-		       int low_end, int low_label, int high_end, int high_label,  
-		       const vector<int>& sink_labels,
-		       const vector<int>& source_labels, float thresh_prob, float flow_scale);
+	FGetClassSeedMask(const Probmap& map,
+			  int low_end, int low_label, int high_end, int high_label,
+			  const int label, float prob_thresh);
 
 	template <typename T> 
-	pair<C2DFImage, C2DFImage> operator() (const T2DImage<T>& image) const;   
+	P2DImage operator() (const T2DImage<T>& image) const;   
 private:
-	template <typename T>
-	void add_flows(C2DFImage& flow, int label, const T2DImage<T>& image) const;
-
 	const Probmap& m_map;
 
 	int m_low_end;
 	int m_low_label;
 	int m_high_end;
-	int m_high_label;  
-	
-	vector<int> m_sink_labels;
-	vector<int> m_source_labels; 
-	
-	float m_thresh_prob; 
-	float m_flow_scale; 
+	int m_high_label;
+	int m_label;
+	float m_prob_thresh; 
 }; 
 
 
-FGetFlowImages::FGetFlowImages(const Probmap& map,
-			       int low_end, int low_label, int high_end, int high_label,
-			       const vector<int>& sink_labels,
-			       const vector<int>& source_labels, float thresh_prob, float flow_scale):
+FGetClassSeedMask::FGetClassSeedMask(const Probmap& map,
+				     int low_end, int low_label, int high_end, int high_label,
+				     const int label, float prob_thresh):
 	m_map(map),
 	m_low_end(low_end),
 	m_low_label(low_label),
 	m_high_end(high_end),
 	m_high_label(high_label),  
-	m_sink_labels(sink_labels),
-	m_source_labels(source_labels),
-	m_thresh_prob(thresh_prob), 
-	m_flow_scale(flow_scale)
+	m_label(label),
+	m_prob_thresh(prob_thresh)
 {
 }
 
-template <typename T>
-void FGetFlowImages::add_flows(C2DFImage& flow, int label, const T2DImage<T>& image) const
-{
-	auto iflow = flow.begin();
-	auto ii = image.begin();
-	auto ie = image.end();
-
-	// here two signed-unsigned comparisong warnings are issued that should be silenced. 
-	while (ii != ie) {
-		if (*ii <= m_low_end)  {
-			if (m_low_label == label)
-				*iflow = 1.0f;
-		} else if (*ii >= m_high_end){
-			if (m_high_label == label)
-				*iflow = 1.0f;
-		} else {
-			auto l = m_map.find(*ii);
-			if (l != m_map.end()) {
-				if (l->second[label] >= m_thresh_prob && l->second[label] > *iflow)
-					*iflow = l->second[label];			       
-			} else {
-				// this should not happen and 
-				cvwarn() << "Unmapped value " << *ii << "\n";
-			}
-		}
-		//  should be a parameter
-		*iflow *= m_flow_scale; 
-		
-		++iflow;
-		++ii; 
-	}
-	
-}
-						    
+					    
 template <typename T> 
-pair<C2DFImage, C2DFImage> FGetFlowImages::operator() (const T2DImage<T>& image) const
+P2DImage FGetClassSeedMask::operator() (const T2DImage<T>& image) const
 {
+	C2DBitImage *result = new C2DBitImage(image.get_size(), image);
+	P2DImage presult(result);
 	
-	C2DFImage sink_flow(image.get_size());
-	C2DFImage source_flow(image.get_size());
-
-
-	for (auto sink_label: m_sink_labels) {
-		add_flows(sink_flow, sink_label, image); 
-	}
+	auto run_pixel = [this](T pixel) -> bool {
+
+		const T low_end = static_cast<T>(m_low_end);
+		const T high_end = static_cast<T>(m_high_end); 
+		// 
+		// check boundaries of probability map whether they 
+		// correspond to the label
+		// outside the range probability of that label is always 1.0 
+		if (pixel <= low_end)
+			return (m_label == m_low_label);
+		if (pixel >= high_end)
+			return (m_label == m_high_label);
+
+		auto l = m_map.find(pixel);
+		if (l != m_map.end()) {
+			return (l->second[m_label] >= m_prob_thresh);                          
+		} else {
+			// this should not happen
+			cvwarn() << "Unmapped value " << pixel << "\n";
+			return false; 
+		}
 
-	for (auto source_label: m_source_labels) {
-		add_flows(source_flow, source_label, image); 
-	}
-	
-	return make_pair(sink_flow, source_flow); 
+	}; 
 	
+	transform(image.begin(), image.end(), result->begin(), run_pixel); 
+	return presult; 
 }
 
 int do_main( int argc, char *argv[] )
 {
-        string out_labels;
+        string out_mask;
 	string out_probmap;
 	string in_filename;
-	string flow_fileprefix; 
         string out_type("png");
 
-	float seed_threshold = 0.9; 
+	float seed_threshold = 0.95; 
         float histogram_thresh = 5;
-	float flow_prob_thresh = 0.5; 
-	float flow_scale = 100.0f; 
+
+	int label = -1; 
 	
 	CMeans::PInitializer class_center_initializer;
 
@@ -297,12 +266,10 @@ int do_main( int argc, char *argv[] )
 			      CCmdOptionFlags::output));
         options.add(make_opt( out_type, "type", 't', "output file name type"));
 
-	options.add(make_opt( out_labels, "out-labels", 'o', "output file name base", 
+	options.add(make_opt( out_mask, "out-mask", 'o', "output file name base", 
 			      CCmdOptionFlags::required_output));
 
-	options.add(make_opt( flow_fileprefix, "out-flow", 'f',
-			      "prefix for flow initialization images", CCmdOptionFlags::output)); 
-	
+
         options.set_group("Parameters");
         options.add(make_opt( histogram_thresh, EParameterBounds::bf_closed_interval, {0,50}, "histogram-thresh", 'T',
                               "Percent of the extrem parts of the histogram to be collapsed into the respective last histogram bin."));
@@ -312,13 +279,9 @@ int do_main( int argc, char *argv[] )
 	options.add(make_opt( seed_threshold, EParameterBounds::bf_open_interval, {0.0f,1.0f}, "seed-threshold", 'S',
                               "Probability threshold value to consider a pixel as seed pixel."));
 
-	options.add(make_opt( flow_prob_thresh, EParameterBounds::bf_min_closed | EParameterBounds::bf_max_open,
-			      {0.0f, 1.0f}, "flow-prob-thresh", 'F', "Class probability threshold to cut the flow "
-			      "to zero for the source/sink flow connectivity creation")); 
-	options.add(make_opt( flow_scale, EParameterBounds::bf_min_open, {0.0f}, "flow-scale", 'W',
-                              "Scaling factor to adjust the flow evaluated from the initial c-means segmentation."));
+	options.add(make_opt( label, EParameterBounds::bf_closed_interval, {0,10}, "label", 'L',
+                              "Class label to create the mask from", CCmdOptionFlags::required));
 
-	
         
 	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
 		return EXIT_SUCCESS; 
@@ -393,12 +356,15 @@ int do_main( int argc, char *argv[] )
 	if (class_centers.size() > 65535) {
 		throw create_exception<runtime_error>("This code only allows 65535 classes, initializer created ",  class_centers.size()); 
 	}
+
+	if (class_centers.size() <= static_cast<unsigned>(label)) {
+		throw create_exception<runtime_error>("Try to segment class ", label, " but only ",
+						      class_centers.size(), "classes available"); 
+	}
+
 	
-	// created the labeled images
-	FGetFlowImages  get_flow_images(pmap, ii->first, 0, ie->first, class_centers.size(),
-					{static_cast<int>(class_centers.size()-1)}, {1}, flow_prob_thresh, flow_scale);
-	
-	P2DFilter maxflow = produce_2dimage_filter("maxflow:sink-flow=sink.@,source-flow=source.@"); 
+	FGetClassSeedMask seeder(pmap, ii->first, 0, ie->first, class_centers.size() - 1,
+				 label, seed_threshold);
 	
         for (size_t i = start_filenum; i < end_filenum; ++i) {
                 string src_name = create_filename(src_basename.c_str(), i);
@@ -407,32 +373,11 @@ int do_main( int argc, char *argv[] )
                 if (in_image_list.get() && in_image_list->size()) {
                         for (auto k = in_image_list->begin(); k != in_image_list->end(); ++k) {
 				// create label image
-
-				auto flow_images = mia::filter (get_flow_images, **k);
-				if (!flow_fileprefix.empty()) {
-					stringstream ssinkfn; 
-					ssinkfn << flow_fileprefix << "-sink"
-						<< setw(format_width) << setfill('0') << i
-						<< ".v";
-					save_image(ssinkfn.str(), flow_images.first);
-
-					stringstream sssourcefn; 
-					sssourcefn << flow_fileprefix << "-source"
-						   << setw(format_width) << setfill('0') << i
-						   << ".v";
-					save_image(sssourcefn.str(), flow_images.second);
-					
-				}
-				
-				save_image("sink.@", flow_images.first);
-				save_image("source.@", flow_images.second);
-				
-				auto label = maxflow->filter(**k);
-				*k = label; 
+				*k = mia::filter (seeder, **k);
 			}
                 }
 		stringstream ss;
-		ss << out_labels << setw(format_width) << setfill('0') << i << "." << out_type;
+		ss << out_mask << setw(format_width) << setfill('0') << i << "." << out_type;
 		
 		imageio.save(ss.str(), *in_image_list);
         }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/mia.git



More information about the debian-med-commit mailing list