[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