/* -*- 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: costFkt.hh 887 2006-03-01 12:22:14Z write1 $
/*! \brief Base class for different cost functions
This contains basic cost functions to image registrtion.
\todo move test- funtions to ../test
\file costFkt.hh
\author Gert Wollny <wollny@cbs.mpg.de>
*/
#ifndef __MONA_COSTFKT_HH
#define __MONA_COSTFKT_HH 1
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
//#pragma interface
#include <vector>
#include <libmona/monaUtils.hh>
#include <libmona/3DImage.hh>
namespace mona {
class CCostFunction {
public:
/** Construct the cost function object
*/
CCostFunction();
/// ensure a virtual destructor
virtual ~CCostFunction();
/** \returns current value of cost function
\remark this is a pure virtual function
*/
double get_cost() const;
private:
virtual double evaluate_cost() const = 0;
mutable TCachedValue<double> value;
};
/** An class to offer a runtime polymorphism to the cost function evaluation */
class TCostEvaluator {
public:
/** makes sure the destructor is virtual */
virtual ~TCostEvaluator();
/** updates toe cost based on given intensity values (pure virtual)
\param src_val intensity value of source image
\param ref_val intensity value of reference image
*/
virtual void accumulate(double src_val, double ref_val) = 0;
/** \returns the accumulated value of the cost function */
virtual double get_value() const = 0;
virtual void clear() = 0;
};
/** a class for the Sum of Squared Differences (SSD) cost function */
class CSSDCostEvaluator: public TCostEvaluator {
public:
/// constructor initializes the cost with zero
CSSDCostEvaluator();
/** updates the cost based on given intensity values
\param src_val intensity value of source image
\param ref_val intensity value of reference image
*/
virtual void accumulate(double src_val, double ref_val);
/** \returns the accumulated value of the cost function */
virtual double get_value() const;
virtual void clear();
#ifndef NDEBUG
static bool test();
#endif
private:
double _M_cost;
};
/** Class of a correlation coefficient (CC) based cost function evaluator */
class CCCCostEvaluator: public TCostEvaluator {
public:
/** Initializes the evaluator
*/
CCCCostEvaluator();
/** updates the cost based on given intensity values
\param src_val intensity value of source image
\param ref_val intensity value of reference image
*/
virtual void accumulate(double src_val, double ref_val);
/** \returns the accumulated value of the cost function */
virtual double get_value() const;
virtual void clear();
#ifndef NDEBUG
static bool test();
#endif
private:
double _M_sumS;
double _M_sumR;
double _M_sumS2;
double _M_sumR2;
double _M_sumDP;
int _M_n;
};
class CNMICostEvaluator: public TCostEvaluator {
public:
/** Initializes the evaluator
*/
CNMICostEvaluator(double maxi, int hsize);
/** updates the cost based on given intensity values
\param src_val intensity value of source image
\param ref_val intensity value of reference image
*/
virtual void accumulate(double src_val, double ref_val);
/** \returns the accumulated value of the cost function */
virtual double get_value() const;
virtual void clear();
#ifndef NDEBUG
static bool test();
#endif
private:
CNMICostEvaluator(const CNMICostEvaluator& org);
unsigned int _M_n;
unsigned int _M_hsize;
double _M_factor;
typedef std::vector<unsigned long> CHistogram;
CHistogram _M_shisto;
CHistogram _M_rhisto;
CHistogram _M_xhisto;
};
/** Base class for 3D image registration cost functions */
template <class Transformation, class Image>
class CImageRegCostFunction: public CCostFunction {
public:
/** constructor
\param src the source image
\param ref the refercnec image
\param t the initial transformation
\retval cev provides the value of the cost function
\param mask provides a mask of the relevant image data
*/
CImageRegCostFunction(const Image& src, const Image& ref,
const Transformation& t, TCostEvaluator& cev,
const C3DUBImage *mask = NULL);
/** set a new transformation
\param t the new transformation
*/
void set_transformation(const Transformation& t);
private:
virtual double evaluate_cost() const;
class TTransformationWrap {
friend class CImageRegCostFunction;
const Transformation& _M_t;
TTransformationWrap(const Transformation& t):
_M_t(t)
{
}
typedef typename Transformation::const_iterator const_iterator;
const_iterator begin()const {
return _M_t.begin();
}
};
const Image& _M_src;
const Image& _M_ref;
TCostEvaluator& _M_cev;
auto_ptr<TTransformationWrap> _M_trans;
const C3DUBImage *_M_mask;
};
// implementation of templates
template <class Transformation, class Image>
CImageRegCostFunction<Transformation,Image>::CImageRegCostFunction(const Image& src, const Image& ref,
const Transformation& t,
TCostEvaluator& cev,
const C3DUBImage *mask):
_M_src(src),
_M_ref(ref),
_M_cev(cev),
_M_trans(new TTransformationWrap(src,t)),
_M_mask(mask)
{
assert(_M_src.get_size() == _M_ref.get_size());
if (_M_mask) {
assert(_M_src.get_size() == this->_M_mask.get_size());
}
}
template <class Transformation, class Image>
double CImageRegCostFunction<Transformation,Image>::evaluate_cost() const
{
C3DBounds l;
_M_cev.clear();
typename Image::const_iterator i_ref = _M_ref.begin();
typename Transformation::const_iterator i_trans = _M_trans.begin();
if (_M_mask) {
C3DUBImage::const_iterator i_mask = this->_M_mask.begin();
for(l.z = 0; l.z < this->_M_mask.get_size().z; ++l.z)
for(l.y = 0; l.y < this->_M_mask.get_size().y; ++l.y)
for(l.x = 0; l.x < this->_M_mask.get_size().x; ++l.x, ++i_ref, ++i_mask, ++_M_trans)
if (*i_mask)
_M_cev.accumulate((*_M_src)(*i_trans),*i_ref);
} else {
for(l.z = 0; l.z < _M_ref.get_size().z; ++l.z)
for(l.y = 0; l.y < _M_ref.get_size().y; ++l.y)
for(l.x = 0; l.x < _M_ref.get_size().x; ++l.x, ++i_ref,++_M_trans)
_M_cev.accumulate((*_M_src)(*i_trans),*i_ref);
}
return _M_cev.get_value();
}
template <class Transformation, class Image>
void CImageRegCostFunction<Transformation,Image>::set_transformation(const Transformation& t)
{
_M_trans.reset(new TTransformationWrap(t));
value.invalidate();
}
} // namespace mona
#endif
/* CVS LOG
$Log$
Revision 1.7 2005/06/29 13:22:23 wollny
switch to version 0.7
Revision 1.1.1.1 2005/03/17 13:44:20 gerddie
initial import
Revision 1.6 2004/07/13 09:16:16 wollny
g++ 3.4 compile
Revision 1.5 2004/06/03 09:57:32 wollny
Changed (hopefully) all instancable class names to Cxxxxx
Revision 1.4 2004/03/16 18:56:37 tittge
making release 0.3.1 (starting to divide algorithms from data classifiers)
Revision 1.3 2004/03/05 10:30:38 tittge
more plugin functionality
Revision 1.2 2004/02/20 08:57:44 tittge
add version tracking, improve iterator performance
Revision 1.1 2004/02/13 08:01:13 tittge
set up some test
*/