/* -*- mona-c++ -*-
* Copyright (c) Leipzig, Madrid 2004 - 2008
* Max-Planck-Institute for Human Cognitive and Brain Science
* Max-Planck-Institute for Evolutionary Anthropology
* BIT, ETSI Telecomunicacion, UPM
*
* This program 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
// $Id: imagestats.cc 938 2006-07-11 11:57:01Z write1 $
/*! \brief mona-imagestats -- retrieves some basic statistic from the image
\par Program description
This routine scans through an integer image and counts the number of different values/labels
(in different connected regions).
\par Usage
<code>mona-imagestats --usage</code> (or <code> mona-imagestats --help</code>)
\param --in-file file holding a list of pre-segmented labels
\param --out-file labels and no of the particular label
\param --verbose some verbose output
\par Example
-# Performs a label count and writes to stdout
\code
user> mona-crispSegmentation -i cls.v | mona-imagestats -o -
\endcode
Note, the image format must be integer.
\par Known bugs
\todo
\sa crispSegmentation.cc
\file imagestats.cc
\author M. Tittgemeyer (tittge@cbs.mpg.de), 2004
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <fstream>
#include <cstdlib>
#include <string>
#include <algorithm>
#include <map>
#include <algorithm>
// MONA
#include <mona.hh>
#include <boost/type_traits.hpp>
using namespace std;
using namespace mona;
static const char *revision = "$Revision: 938 $";
/* Initialize error handling */
#define error_report(level, text) cverb << level << (text) << endl
namespace options {
string in_filename;
string out_filename = "-";
}
namespace {
popt::COptions opts;
void get_options( int argc, const char *argv[] )
{
opts.push_back(popt::option( options::in_filename, "in-file", 'i',
"image be labeled", "" ));
opts.push_back(popt::option( options::out_filename, "out-file", 'o',
"no of labels, label number", "-" ));
vector<string> non_options;
popt::parse_options(argc, argv, opts, non_options);
// what to do with unrecognized options
if ( non_options.size() > 0 )
throw invalid_argument("unknown options");
// required options (anything that has no default value)
if ( options::in_filename.empty() )
throw mona_runtime_error("'--in-file' ('i') option required\n");
}
} // anonymous namespace
/*! \brief Functor to label class files
The class is derived from the image filterbase, that solely defines a result type.
Whenever using in an image filter, the result_type is specified by
<code>typename Filter::result_type</code> that needs to be resolved here.
The template specifications grants the correct type; routine would only work with
integer type images.
*/
template <class ImageType, bool b>
struct __count_dispatch {
static map<int,int> count(const ImageType& image)
{
throw mona_runtime_error("Image type can not be processed");
return map<int,int>();
}
};
template <class ImageType>
struct __count_dispatch<ImageType, true> {
static map<int,int> count(const ImageType& image)
{
map<int,int> MapOfIntLabels;
typename ImageType::const_iterator iImage = image.begin();
for( ; iImage != image.end(); ++iImage )
MapOfIntLabels[*iImage]++;
return MapOfIntLabels;
return map<int,int>();
}
};
class CCountComponents: public TUnaryImageFilter<map<int,int> > {
private:
public:
//! \name Operator
//@{
template <class ImageType>
CCountComponents::result_type operator () (const ImageType& image) const
{
const bool is_integral = ::boost::is_integral<typename ImageType::value_type>::value;
return __count_dispatch<ImageType, is_integral>::count(image);
}
//@}
}; // CCountComponets
int main( int argc, const char *argv[] )
{
using namespace std;
using namespace mona;
try {
get_options(argc, argv);
#ifdef DEBUG
error_report.set_level( vstream::ml_debug );
#endif
C3DImageIOPluginHandler imageio;
// read data
auto_ptr<C3DImageList> inImage_list( imageio.load( options::in_filename ) );
if (!inImage_list.get() || !inImage_list->size() ) {
string not_found = ("No supported data found in ") + options::in_filename;
throw mona_runtime_error(not_found);
}
CCountComponents countComponents;
// facilitate counting
map<int,int> MapOfLabels = image_filter( countComponents, (*inImage_list)[0] );
// get voxel volume
float voxelVolume = 1.f;
C3DFVector vox = (*inImage_list)[0].get_3dvector_attribute("voxel", C3DFVector(0,0,0));
voxelVolume = vox.x * vox.y * vox.z;
map<int,int>::const_iterator iMap = MapOfLabels.begin();
// Write label count
if ( options::out_filename == "-" ){
cout << "# Label\t NoLabels\t Volume[ml]" << endl;
for( ; iMap != MapOfLabels.end(); ++iMap )
cout << iMap->first << "\t " << setw(8) << iMap->second << "\t " << iMap->second*voxelVolume*1e-3 << endl;
}else {
ofstream fout( options::out_filename.c_str() );
for( ; iMap != MapOfLabels.end(); ++iMap )
fout << iMap->first << "\t" << iMap->second << "\t " << iMap->second*voxelVolume*1e-3 << endl;
};
return EXIT_SUCCESS;
}
catch (const mona_runtime_error& e){
cerr << argv[0] << " error: " << e.what() << endl;
}
catch (const mona_fatal_error& e){
cerr << argv[0] << " fatal: " << e.what() << endl;
}
catch (const mona_exception& e){
cerr << argv[0] << " error: " << e.what() << endl;
}
catch (const invalid_argument &e){
cerr << argv[0] << " error: " << e.what() << endl;
}
catch (const exception& e){
cerr << argv[0] << " error: " << e.what() << endl;
}
catch (...){
cerr << argv[0] << " unknown exception" << endl;
}
return EXIT_FAILURE;
}
/*
$Log$
Revision 1.6 2005/06/29 13:32:02 wollny
move to libmona-version 0.7
Revision 1.2 2005/06/02 13:33:23 gerddie
adapt code to new plugin handling
Revision 1.1.1.1 2005/03/17 13:48:32 gerddie
initial checkin
Revision 1.5 2005/01/25 14:12:09 wollny
support for typed attributes
Revision 1.4 2005/01/19 11:10:07 wollny
adapted to new verbose handling of libmona
Revision 1.3 2005/01/18 12:28:21 tittge
adjusted documetation
Revision 1.2 2004/12/14 12:20:15 tittge
facilitate voxel attribute reading from input file
Revision 1.1 2004/12/08 14:11:32 tittge
rename countComponents in imagestats
Revision 1.1 2004/12/01 16:29:29 tittge
add program to count labed components
Revision 1.6 2004/11/15 14:27:45 tittge
passing of attributes enhanced
Revision 1.5 2004/11/01 16:24:54 wollny
move from old error-report to cverb
Revision 1.4 2004/10/22 15:03:04 tittge
remove some memory problems (by consitently using auto_ptr's)
Revision 1.3 2004/10/20 14:32:43 tittge
consitency check in documentation
Revision 1.2 2004/10/15 14:31:42 tittge
some error handling
Revision 1.1 2004/10/15 14:24:45 tittge
added a crisp (maximum likelyhood) segmentation
*/