accessor.hxx   accessor.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 61 skipping to change at line 61
Data accessors are used to allow for flexible access to the data Data accessors are used to allow for flexible access to the data
an iterator points to. When we access the data directly, we an iterator points to. When we access the data directly, we
are bound to what <TT>operator*()</TT> returns, if this method exists a t are bound to what <TT>operator*()</TT> returns, if this method exists a t
all. Encapsulating access in an accessor enables a better all. Encapsulating access in an accessor enables a better
decoupling of data structures and algorithms. decoupling of data structures and algorithms.
<a href="documents/DataAccessors.ps">This paper</a> contains <a href="documents/DataAccessors.ps">This paper</a> contains
a detailed description of the concept. Here is a brief list of the basi c a detailed description of the concept. Here is a brief list of the basi c
accessor requirements: accessor requirements:
<p> <p>
<table border=2 cellspacing=0 cellpadding=2 width="100%"> <table border=2 cellspacing=0 cellpadding=2 width="100%">
<tr><td> <tr><th>
\htmlonly
<th>
\endhtmlonly
Operation Operation
\htmlonly
</th><th> </th><th>
\endhtmlonly
Result Result
\htmlonly
</th><th> </th><th>
\endhtmlonly
Semantics Semantics
\htmlonly
</th> </th>
\endhtmlonly </tr>
</td></tr>
<tr> <tr>
<td><tt>accessor(iter)</tt></td><td>convertible to <br><tt>Iterator::va lue_type const &</tt></td> <td><tt>accessor(iter)</tt></td><td>convertible to <br><tt>Iterator::va lue_type const &</tt></td>
<td>read data at the current position of the iterator</td> <td>read data at the current position of the iterator</td>
</tr> </tr>
<tr> <tr>
<td><tt>accessor(iter, index)</tt></td><td>convertible to <br><tt>Acces sor::value_type const &</tt></td> <td><tt>accessor(iter, index)</tt></td><td>convertible to <br><tt>Acces sor::value_type const &</tt></td>
<td>read data at offset <tt>index</tt> relative to iterator's current p osition <td>read data at offset <tt>index</tt> relative to iterator's current p osition
(random-access iterator only)</td> (random-access iterator only)</td>
</tr> </tr>
<tr> <tr>
<td><tt>accessor.set(value, iter)</tt></td><td><tt>void</tt></td> <td><tt>accessor.set(value, iter)</tt></td><td><tt>void</tt></td>
<td>write data <tt>value</tt> at the current position of the iterator ( mutable iterator only)</td> <td>write data <tt>value</tt> at the current position of the iterator ( mutable iterator only)</td>
</tr> </tr>
<tr> <tr>
<td><tt>accessor.set(value, iter, index)</tt></td><td><tt>void</tt></td > <td><tt>accessor.set(value, iter, index)</tt></td><td><tt>void</tt></td >
<td>write data <tt>value</tt> at offset <tt>index</tt> relative to iter ator's current position <td>write data <tt>value</tt> at offset <tt>index</tt> relative to iter ator's current position
(mutable random-access iterator only)</td> (mutable random-access iterator only)</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>Accessor::value_type</tt></td> <tt>Accessor::value_type</tt></td>
<td>type of the data field the accessor refers to</td> <td>type of the data field the accessor refers to</td>
</tr> </tr>
<tr> <tr><td colspan=3>
<td>
\htmlonly
<td colspan=3>
\endhtmlonly
<tt>iter</tt> is an iterator<br> <tt>iter</tt> is an iterator<br>
<tt>index</tt> has the iterator's index type (<tt>Iterator::differe nce_type</tt>)<br> <tt>index</tt> has the iterator's index type (<tt>Iterator::differe nce_type</tt>)<br>
<tt>value</tt> is convertible to <tt>Accessor::value_type const &</ tt> <tt>value</tt> is convertible to <tt>Accessor::value_type const &</ tt>
</td> </td>
</tr> </tr>
</table> </table>
</p> </p>
The template <tt>AccessorTraits<T&gt;</tt> can be used to find the d efault accessor The template <tt>AccessorTraits<T></tt> can be used to find the default accessor
associated with the type <tt>T</tt>, e.g. associated with the type <tt>T</tt>, e.g.
\code \code
typedef typename AccessorTraits<typename Image::value_type>::default_ac cessor Accessor; typedef typename AccessorTraits<typename Image::value_type>::default_ac cessor Accessor;
typedef typename AccessorTraits<typename Image::value_type>::default_co nst_accessor ConstAccessor; typedef typename AccessorTraits<typename Image::value_type>::default_co nst_accessor ConstAccessor;
\endcode \endcode
*/ */
//@{ //@{
/********************************************************/ /********************************************************/
skipping to change at line 147 skipping to change at line 130
read and write functions. It passes its arguments <em>by reference</em> . read and write functions. It passes its arguments <em>by reference</em> .
If you want to return items by value, you If you want to return items by value, you
must use StandardValueAccessor instead of StandardAccessor. must use StandardValueAccessor instead of StandardAccessor.
Both accessors have different optimization properties -- Both accessors have different optimization properties --
StandardAccessor is usually faster for compound pixel types, StandardAccessor is usually faster for compound pixel types,
while StandardValueAccessor is faster for the built-in types. while StandardValueAccessor is faster for the built-in types.
When a floating point number is assigned by means of an accessor When a floating point number is assigned by means of an accessor
with integral value_type, the value is rounded and clipped as approriat e. with integral value_type, the value is rounded and clipped as approriat e.
<b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hx x</a>"<br> <b>\#include</b> \<<a href="accessor_8hxx-source.html">vigra/accessor.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class VALUETYPE> template <class VALUETYPE>
class StandardAccessor class StandardAccessor
{ {
public: public:
/** the value_type /** the value_type
*/ */
typedef VALUETYPE value_type; typedef VALUETYPE value_type;
skipping to change at line 212 skipping to change at line 195
read and write functions. It passes its arguments <em>by value</em>. read and write functions. It passes its arguments <em>by value</em>.
If the iterator returns its items by reference (such as \ref vigra::Ima geIterator), If the iterator returns its items by reference (such as \ref vigra::Ima geIterator),
you can also use StandardAccessor. you can also use StandardAccessor.
These accessors have different optimization properties -- These accessors have different optimization properties --
StandardAccessor is usually faster for compound pixel types, StandardAccessor is usually faster for compound pixel types,
while StandardValueAccessor is faster for the built-in types. while StandardValueAccessor is faster for the built-in types.
When a floating point number is assigned by means of an accessor When a floating point number is assigned by means of an accessor
with integral value_type, the value is rounded and clipped as approriat e. with integral value_type, the value is rounded and clipped as approriat e.
<b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hx x</a>"<br> <b>\#include</b> \<<a href="accessor_8hxx-source.html">vigra/accessor.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class VALUETYPE> template <class VALUETYPE>
class StandardValueAccessor class StandardValueAccessor
{ {
public: public:
/** the value_type /** the value_type
*/ */
typedef VALUETYPE value_type; typedef VALUETYPE value_type;
skipping to change at line 283 skipping to change at line 266
StandardConstAccessor is a trivial accessor that simply encapsulates StandardConstAccessor is a trivial accessor that simply encapsulates
the iterator's operator*() and operator[]() in its the iterator's operator*() and operator[]() in its
read functions. It passes its arguments <em>by reference</em>. read functions. It passes its arguments <em>by reference</em>.
If the iterator returns its items by value (such as \ref vigra::Coordin ateIterator), you If the iterator returns its items by value (such as \ref vigra::Coordin ateIterator), you
must use StandardConstValueAccessor instead of StandardConstAccessor. must use StandardConstValueAccessor instead of StandardConstAccessor.
Both accessors also have different optimization properties -- Both accessors also have different optimization properties --
StandardConstAccessor is usually faster for compound pixel types, StandardConstAccessor is usually faster for compound pixel types,
while StandardConstValueAccessor is faster for the built-in types. while StandardConstValueAccessor is faster for the built-in types.
<b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hx x</a>"<br> <b>\#include</b> \<<a href="accessor_8hxx-source.html">vigra/accessor.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class VALUETYPE> template <class VALUETYPE>
class StandardConstAccessor class StandardConstAccessor
{ {
public: public:
typedef VALUETYPE value_type; typedef VALUETYPE value_type;
/** read the current data item /** read the current data item
*/ */
skipping to change at line 321 skipping to change at line 304
read functions. It passes its arguments <em>by value</em>. read functions. It passes its arguments <em>by value</em>.
If the iterator returns its items by reference (such as \ref vigra::Con stImageIterator), If the iterator returns its items by reference (such as \ref vigra::Con stImageIterator),
you can also use StandardConstAccessor. you can also use StandardConstAccessor.
These accessors have different optimization properties -- These accessors have different optimization properties --
StandardConstAccessor is usually faster for compound pixel types, StandardConstAccessor is usually faster for compound pixel types,
while StandardConstValueAccessor is faster for the built-in types. while StandardConstValueAccessor is faster for the built-in types.
When an iterator passes a floating point number to an accessor When an iterator passes a floating point number to an accessor
with integral value_type, the value is rounded and clipped as approriat e. with integral value_type, the value is rounded and clipped as approriat e.
<b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hx x</a>"<br> <b>\#include</b> \<<a href="accessor_8hxx-source.html">vigra/accessor.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class VALUETYPE> template <class VALUETYPE>
class StandardConstValueAccessor class StandardConstValueAccessor
{ {
public: public:
typedef VALUETYPE value_type; typedef VALUETYPE value_type;
/** Read the current data item. The type <TT>ITERATOR::reference</T T> /** Read the current data item. The type <TT>ITERATOR::reference</T T>
is automatically converted to <TT>VALUETYPE</TT>. is automatically converted to <TT>VALUETYPE</TT>.
skipping to change at line 378 skipping to change at line 361
\code \code
vigra::BRGBImage image(w,h); vigra::BRGBImage image(w,h);
// init red channel with 255 // init red channel with 255
initImage(destImageRange(image, initImage(destImageRange(image,
VectorComponentAccessor<vigra::BRGBImage::valu e_type>(0)), VectorComponentAccessor<vigra::BRGBImage::valu e_type>(0)),
255); 255);
\endcode \endcode
<b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hx x</a>"<br> <b>\#include</b> \<<a href="accessor_8hxx-source.html">vigra/accessor.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class VECTORTYPE> template <class VECTORTYPE>
class VectorComponentAccessor class VectorComponentAccessor
{ {
int index_; int index_;
public: public:
/** the value_type /** the value_type
*/ */
skipping to change at line 462 skipping to change at line 445
\code \code
vigra::BRGBImage image(w,h); vigra::BRGBImage image(w,h);
// init red channel with 255 // init red channel with 255
initImage(destImageRange(image, initImage(destImageRange(image,
VectorComponentValueAccessor<vigra::BRGBImage: :value_type>(0)), VectorComponentValueAccessor<vigra::BRGBImage: :value_type>(0)),
255); 255);
\endcode \endcode
<b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hx x</a>"<br> <b>\#include</b> \<<a href="accessor_8hxx-source.html">vigra/accessor.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class VECTORTYPE> template <class VECTORTYPE>
class VectorComponentValueAccessor class VectorComponentValueAccessor
{ {
int index_; int index_;
public: public:
/** the value_type /** the value_type
*/ */
skipping to change at line 552 skipping to change at line 535
\code \code
vigra::BRGBImage image(w,h); vigra::BRGBImage image(w,h);
// init red channel with 255 // init red channel with 255
initImage(destImageRange(image, initImage(destImageRange(image,
VectorElementAccessor<vigra::BRGBImage::Access or>(0)), VectorElementAccessor<vigra::BRGBImage::Access or>(0)),
255); 255);
\endcode \endcode
<b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hx x</a>"<br> <b>\#include</b> \<<a href="accessor_8hxx-source.html">vigra/accessor.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class ACCESSOR> template <class ACCESSOR>
class VectorElementAccessor class VectorElementAccessor
{ {
int index_; int index_;
ACCESSOR a_; ACCESSOR a_;
public: public:
/** the value_type /** the value_type
skipping to change at line 629 skipping to change at line 612
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Accessor for items that are STL compatible sequences. /** \brief Accessor for items that are STL compatible sequences.
It encapsulates access to the sequences' begin() and end() It encapsulates access to the sequences' begin() and end()
functions. functions.
<b>Usage:</b> <b>Usage:</b>
<b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hx x</a>"<br> <b>\#include</b> \<<a href="accessor_8hxx-source.html">vigra/accessor.h xx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
typedef std::list<std::list<int> > ListOfLists; typedef std::list<std::list<int> > ListOfLists;
ListOfLists ll; ListOfLists ll;
... ...
typedef vigra::SequenceAccessor<ListOfLists::value_type> ListOfListsAcc essor; typedef vigra::SequenceAccessor<ListOfLists::value_type> ListOfListsAcc essor;
ListOfListsAccessor a; ListOfListsAccessor a;
skipping to change at line 728 skipping to change at line 711
/* VectorAccessor */ /* VectorAccessor */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Accessor for items that are STL compatible vectors. /** \brief Accessor for items that are STL compatible vectors.
It encapsulates access to a vector's access functionality. It encapsulates access to a vector's access functionality.
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hx x</a>"<br> <b>\#include</b> \<<a href="accessor_8hxx-source.html">vigra/accessor.h xx</a>\><br>
Namespace: vigra Namespace: vigra
The accessor has two modes of operation: The accessor has two modes of operation:
<ol> <ol>
<li> Access the vector's iterator via the <TT>begin()</TT> and <TT>end( )</TT> <li> Access the vector's iterator via the <TT>begin()</TT> and <TT>end( )</TT>
functions: functions:
\code \code
typedef std::list<std::vector<int> > ListOfVectors; typedef std::list<std::vector<int> > ListOfVectors;
skipping to change at line 861 skipping to change at line 844
need more information to calcuate this cost, for example gray value need more information to calcuate this cost, for example gray value
and local gradient magnitude. These values can be stored in two images, and local gradient magnitude. These values can be stored in two images,
which appear as only one when we pass a <TT>MultiImageAccessor2</TT> to which appear as only one when we pass a <TT>MultiImageAccessor2</TT> to
the lagorithms. Of course, the cost functor must accept a <TT>pair</TT> the lagorithms. Of course, the cost functor must accept a <TT>pair</TT>
of values for this to work. Instead of an actual image iterator, we of values for this to work. Instead of an actual image iterator, we
pass a <a href="CoordinateIterator.html">CoordinateIterator</a> which pass a <a href="CoordinateIterator.html">CoordinateIterator</a> which
selects the right pixels form both images. selects the right pixels form both images.
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hx x</a>"<br> <b>\#include</b> \<<a href="accessor_8hxx-source.html">vigra/accessor.h xx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
using namespace vigra; using namespace vigra;
FImage gray_values(w,h), gradient_magnitude(w,h); FImage gray_values(w,h), gradient_magnitude(w,h);
IImage seeds(w,h), labels(w,h); IImage seeds(w,h), labels(w,h);
seededRegionGrowing( seededRegionGrowing(
srcIterRange(CoordinateIterator(), CoordinateIterator(w,h), srcIterRange(CoordinateIterator(), CoordinateIterator(w,h),
 End of changes. 22 change blocks. 
35 lines changed or deleted 18 lines changed or added


 affinegeometry.hxx   affinegeometry.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2005-2006 by Ullrich Koethe */ /* Copyright 2005-2006 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 42 skipping to change at line 42
/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
/* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
/* OTHER DEALINGS IN THE SOFTWARE. */ /* OTHER DEALINGS IN THE SOFTWARE. */
/* */ /* */
/************************************************************************/ /************************************************************************/
#ifndef VIGRA_AFFINEGEOMETRY_HXX #ifndef VIGRA_AFFINEGEOMETRY_HXX
#define VIGRA_AFFINEGEOMETRY_HXX #define VIGRA_AFFINEGEOMETRY_HXX
#include "mathutil.hxx" #include "mathutil.hxx"
#include "matrix.hxx"
#include "tinyvector.hxx"
#include "splineimageview.hxx" #include "splineimageview.hxx"
#include <cmath> #include <cmath>
namespace vigra { namespace vigra {
/** \addtogroup GeometricTransformations Geometric Transformations /** \addtogroup GeometricTransformations Geometric Transformations
*/ */
//@{ //@{
/********************************************************/ /********************************************************/
/* */ /* */
/* create affine matrices */
/* */
/********************************************************/
/** \brief Create homogeneous matrix representing a 2D translation.
For use with \ref affineWarpImage().
*/
inline
linalg::TemporaryMatrix<double> translationMatrix2D(TinyVector<double, 2> c
onst & shift)
{
linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
ret(0,2) = shift[0];
ret(1,2) = shift[1];
return ret;
}
/** \brief Create homogeneous matrix representing a 2D uniform scaling abou
t the coordinate origin.
For use with \ref affineWarpImage().
*/
inline
linalg::TemporaryMatrix<double> scalingMatrix2D(double scalingFactor)
{
linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
ret(0,0) = scalingFactor;
ret(1,1) = scalingFactor;
return ret;
}
/** \brief Create homogeneous matrix representing a 2D non-uniform scaling
about the coordinate origin.
For use with \ref affineWarpImage().
*/
inline
linalg::TemporaryMatrix<double> scalingMatrix2D(double sx, double sy)
{
linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
ret(0,0) = sx;
ret(1,1) = sy;
return ret;
}
/** \brief Create homogeneous matrix representing a 2D shearing.
For use with \ref affineWarpImage().
*/
inline
linalg::TemporaryMatrix<double> shearMatrix2D(double s01, double s10)
{
linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
ret(0,1) = s01;
ret(1,0) = s10;
return ret;
}
/** \brief Create homogeneous matrix representing a 2D rotation about the c
oordinate origin.
For use with \ref affineWarpImage(). Angle must be in radians.
*/
inline
linalg::TemporaryMatrix<double> rotationMatrix2DRadians(double angle)
{
linalg::TemporaryMatrix<double> ret(identityMatrix<double>(3));
double s = std::sin(angle);
double c = std::cos(angle);
ret(0,0) = c;
ret(1,1) = c;
ret(0,1) = -s;
ret(1,0) = s;
return ret;
}
/** \brief Create homogeneous matrix representing a 2D rotation about the c
oordinate origin.
For use with \ref affineWarpImage(). Angle must be in degrees.
*/
inline
linalg::TemporaryMatrix<double> rotationMatrix2DDegrees(double angle)
{
return rotationMatrix2DRadians(angle*M_PI/180.0);
}
/** \brief Create homogeneous matrix representing a 2D rotation about the g
iven point.
For use with \ref affineWarpImage(). Angle must be in radians.
*/
inline
linalg::TemporaryMatrix<double> rotationMatrix2DRadians(double angle, TinyV
ector<double, 2> const & center)
{
return translationMatrix2D(center) * rotationMatrix2DRadians(angle) * t
ranslationMatrix2D(-center);
}
/** \brief Create homogeneous matrix representing a 2D rotation about the g
iven point.
For use with \ref affineWarpImage(). Angle must be in degrees.
*/
inline
linalg::TemporaryMatrix<double> rotationMatrix2DDegrees(double angle, TinyV
ector<double, 2> const & center)
{
return rotationMatrix2DRadians(angle*M_PI/180.0, center);
}
/********************************************************/
/* */
/* rotateImage */ /* rotateImage */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Rotate image by an arbitrary angle. /** \brief Rotate image by an arbitrary angle.
The algorithm performs a rotation about the given center point (the ima ge center by default) The algorithm performs a rotation about the given center point (the ima ge center by default)
using the given SplineImageView for interpolation. The destination imae must have the same size using the given SplineImageView for interpolation. The destination imag e must have the same size
as the source SplineImageView. The rotation is counter-clockwise, and t he angle must be given in degrees. as the source SplineImageView. The rotation is counter-clockwise, and t he angle must be given in degrees.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
// rotate about given center point // rotate about given center point
template <int ORDER, class T, template <int ORDER, class T,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
skipping to change at line 85 skipping to change at line 192
// rotate about image center // rotate about image center
template <int ORDER, class T, template <int ORDER, class T,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
rotateImage(SplineImageView<ORDER, T> const & src, rotateImage(SplineImageView<ORDER, T> const & src,
DestIterator id, DestAccessor dest, DestIterator id, DestAccessor dest,
double angleInDegree) double angleInDegree)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
// rotate about given center point // rotate about given center point
template <int ORDER, class T, template <int ORDER, class T,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
rotateImage(SplineImageView<ORDER, T> const & src, rotateImage(SplineImageView<ORDER, T> const & src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
double angleInDegree, TinyVector<double, 2> const & cen ter); double angleInDegree, TinyVector<double, 2> const & cen ter);
skipping to change at line 108 skipping to change at line 215
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
rotateImage(SplineImageView<ORDER, T> const & src, rotateImage(SplineImageView<ORDER, T> const & src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
double angleInDegree); double angleInDegree);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="affinegeometry_8hxx-source.html">vigra/a ffinegeometry.hxx</a>"<br> <b>\#include</b> \<<a href="affinegeometry_8hxx-source.html">vigra/ affinegeometry.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
Image src(width, height); Image src(width, height);
vigra::SplineImageView<3, Image::value_type> spline(srcImageRange(src)) ; vigra::SplineImageView<3, Image::value_type> spline(srcImageRange(src)) ;
Image dest(width, height); Image dest(width, height);
vigra::rotateImage(spline, destImage(dest), 38.5); vigra::rotateImage(spline, destImage(dest), 38.5);
skipping to change at line 134 skipping to change at line 241
\code \code
DestImageIterator dest_upperleft; DestImageIterator dest_upperleft;
double x = ..., y = ...; double x = ..., y = ...;
if (spline.isInside(x,y)) if (spline.isInside(x,y))
dest_accessor.set(spline(x, y), dest_upperleft); dest_accessor.set(spline(x, y), dest_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void rotateImage)
template <int ORDER, class T, template <int ORDER, class T,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void rotateImage(SplineImageView<ORDER, T> const & src, void rotateImage(SplineImageView<ORDER, T> const & src,
DestIterator id, DestAccessor dest, DestIterator id, DestAccessor dest,
double angleInDegree, TinyVector<double, 2> const & center ) double angleInDegree, TinyVector<double, 2> const & center )
{ {
int w = src.width(); int w = src.width();
int h = src.height(); int h = src.height();
double angle = angleInDegree*M_PI/180.0; double angle = angleInDegree*M_PI/180.0;
skipping to change at line 192 skipping to change at line 301
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void inline void
rotateImage(SplineImageView<ORDER, T> const & src, rotateImage(SplineImageView<ORDER, T> const & src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double angleInDegree) double angleInDegree)
{ {
TinyVector<double, 2> center((src.width()-1.0) / 2.0, (src.height()-1.0 ) / 2.0); TinyVector<double, 2> center((src.width()-1.0) / 2.0, (src.height()-1.0 ) / 2.0);
rotateImage(src, dest.first, dest.second, angleInDegree, center); rotateImage(src, dest.first, dest.second, angleInDegree, center);
} }
/********************************************************/
/* */
/* affineWarpImage */
/* */
/********************************************************/
/** \brief Warp an image according to an affine transformation.
<b> Declarations:</b>
pass arguments explicitly:
\code
namespace vigra {
template <int ORDER, class T,
class DestIterator, class DestAccessor,
class C>
void affineWarpImage(SplineImageView<ORDER, T> const & src,
DestIterator dul, DestIterator dlr, DestAccesso
r dest,
MultiArrayView<2, double, C> const & affineMatr
ix);
}
\endcode
use argument objects in conjunction with \ref ArgumentObjectFactories :
\code
namespace vigra {
template <int ORDER, class T,
class DestIterator, class DestAccessor,
class C>
void affineWarpImage(SplineImageView<ORDER, T> const & src,
triple<DestIterator, DestIterator, DestAccessor
> dest,
MultiArrayView<2, double, C> const & affineMatr
ix);
}
\endcode
The algorithm applies the given \a affineMatrix to the <i>destination c
oordinates</i> and copies
the image value from the resulting source coordinates, using the given
SplineImageView \a src for interpolation.
If the resulting coordinate is outside the source image, nothing will b
e writen at that destination point.
\code
for all dest pixels:
currentSrcCoordinate = affineMatrix * currentDestCoordinate;
if src.isInside(currentSrcCoordinate):
dest[currentDestCoordinate] = src[currentSrcCoordinate]; //
copy an interpolated value
\endcode
The matrix represent a 2-dimensional affine transform by means of homog
eneous coordinates,
i.e. it must be a 3x3 matrix whose last row is (0,0,1).
<b> Usage:</b>
<b>\#include</b> \<<a href="affinegeometry_8hxx-source.html">vigra/
affinegeometry.hxx</a>\><br>
Namespace: vigra
\code
Image src(width, height);
vigra::SplineImageView<3, Image::value_type> spline(srcImageRange(src))
;
Image dest1(width, height);
// equivalent (up to round-off errors) with
// rotateImage(spline, destImage(dest1), 45.0);
TinyVector<double, 2> center((width-1.0)/2.0, (height-1.0)/2.0);
affineWarpImage(spline, destImageRange(dest1), rotationMatrix2DDegrees(
45.0, center));
Image dest2(2*width-1, 2*height-1);
// equivalent (up to round-off errors) with
// resizeImageSplineInterpolation(srcImageRange(img), destImageRang
e(dest2));
// note that scaleFactor = 0.5, because we must pass the transformation
from destination to source
affineWarpImage(spline, destImageRange(dest2), scalingMatrix2D(0.5));
\endcode
<b> Required Interface:</b>
\code
DestImageIterator dest_upperleft;
double x = ..., y = ...;
if (spline.isInside(x,y))
dest_accessor.set(spline(x, y), dest_upperleft);
\endcode
<b>See also:</b> Functions to specify affine transformation: \ref trans
lationMatrix2D(), \ref scalingMatrix2D(),
\ref shearMatrix2D(), \ref rotationMatrix2DRadians(), \
ref rotationMatrix2DDegrees()
*/
doxygen_overloaded_function(template <...> void affineWarpImage)
template <int ORDER, class T,
class DestIterator, class DestAccessor,
class C>
void affineWarpImage(SplineImageView<ORDER, T> const & src,
DestIterator dul, DestIterator dlr, DestAccessor dest,
MultiArrayView<2, double, C> const & affineMatrix)
{
vigra_precondition(rowCount(affineMatrix) == 3 && columnCount(affineMat
rix) == 3 &&
affineMatrix(2,0) == 0.0 && affineMatrix(2,1) == 0.0
&& affineMatrix(2,2) == 1.0,
"affineWarpImage(): matrix doesn't represent an affine transformati
on with homogeneous 2D coordinates.");
double w = dlr.x - dul.x;
double h = dlr.y - dul.y;
for(double y = 0.0; y < h; ++y, ++dul.y)
{
typename DestIterator::row_iterator rd = dul.rowIterator();
for(double x=0.0; x < w; ++x, ++rd)
{
double sx = x*affineMatrix(0,0) + y*affineMatrix(0,1) + affineM
atrix(0,2);
double sy = x*affineMatrix(1,0) + y*affineMatrix(1,1) + affineM
atrix(1,2);
if(src.isInside(sx, sy))
dest.set(src(sx, sy), rd);
}
}
}
template <int ORDER, class T,
class DestIterator, class DestAccessor,
class C>
inline
void affineWarpImage(SplineImageView<ORDER, T> const & src,
triple<DestIterator, DestIterator, DestAccessor> dest,
MultiArrayView<2, double, C> const & affineMatrix)
{
affineWarpImage(src, dest.first, dest.second, dest.third, affineMatrix)
;
}
//@} //@}
} // namespace vigra } // namespace vigra
#endif /* VIGRA_AFFINEGEOMETRY_HXX */ #endif /* VIGRA_AFFINEGEOMETRY_HXX */
 End of changes. 9 change blocks. 
6 lines changed or deleted 276 lines changed or added


 array_vector.hxx   array_vector.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2002-2004 by Ullrich Koethe */ /* Copyright 2002-2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 44 skipping to change at line 44
/* OTHER DEALINGS IN THE SOFTWARE. */ /* OTHER DEALINGS IN THE SOFTWARE. */
/* */ /* */
/************************************************************************/ /************************************************************************/
#ifndef VIGRA_ARRAY_VECTOR_HXX #ifndef VIGRA_ARRAY_VECTOR_HXX
#define VIGRA_ARRAY_VECTOR_HXX #define VIGRA_ARRAY_VECTOR_HXX
#include "memory.hxx" #include "memory.hxx"
#include <memory> #include <memory>
#include <algorithm> #include <algorithm>
#include <iosfwd>
namespace vigra namespace vigra
{ {
/** Replacement for <tt>std::vector</tt>. template <class T, class Alloc = std::allocator<T> >
class ArrayVector;
This template implements the same functionality as <tt>std::vector</tt>
.
However, it gives two usful guarantees, that <tt>std::vector</tt> fails
to provide:
<ul>
<li>The memory is always allocated as one contigous piece</li>
<li>The iterator is always a <TT>T *</TT> </li>
</ul>
This means that memory managed by <tt>ArrayVector</tt> can be passed /** Provide STL conforming interface for C-arrays.
to algorithms that expect raw memory. This is especially important
when lagacy or C code has to be called, but it is also useful for certa
in
optimizations.
Refer to the documentation of <tt>std::vector</tt> for a detailed This template implements much of the functionality of <tt>std::vector</
description of <tt>ArrayVector</tt> functionality. tt>
on top of a C-array. <tt>ArrayVectorView</tt> does not manage the memor
y
it refers to (i.e. it does not allocate or deallocate any memory).
Thus, if the underlying memory changes, all dependent <tt>ArrayVectorVi
ew</tt>
objects are invalidated. This is especially important when <tt>ArrayVec
torView</tt>
is used as a base class for <tt>ArrayVector</tt>, where several functio
ns
(e.g. resize(), insert()) can allocate new memory and thus invalidate t
he
dependent views. The rules what operations invalidate view objects are
the
same as the rules concerning standard iterators.
<b>\#include</b> "<a href="array_vector_8hxx-source.html">vigra/array_v ector.hxx</a>"<br> <b>\#include</b> \<<a href="array__vector_8hxx-source.html">vigra/array _vector.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class T, class Alloc = std::allocator<T> > template <class T>
class ArrayVector class ArrayVectorView
{ {
typedef ArrayVector<T, Alloc> this_type; typedef ArrayVectorView<T> this_type;
enum { minimumCapacity = 2 };
public: public:
/** default constructor
*/
typedef T value_type; typedef T value_type;
typedef value_type & reference; typedef value_type & reference;
typedef value_type const & const_reference; typedef value_type const & const_reference;
typedef value_type * pointer; typedef value_type * pointer;
typedef value_type const * const_pointer; typedef value_type const * const_pointer;
typedef value_type * iterator; typedef value_type * iterator;
typedef value_type const * const_iterator; typedef value_type const * const_iterator;
typedef unsigned int size_type; typedef unsigned int size_type;
typedef int difference_type; typedef int difference_type;
typedef Alloc allocator_type;
typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
public: public:
ArrayVector(); /** default constructor.
View contains NULL pointer.
*/
ArrayVectorView()
: size_(0),
data_(0)
{}
explicit ArrayVector(Alloc const & alloc); /** Construct for given array \a data of length \a size.
<tt>data, data+size</tt> must form a valid range.
*/
ArrayVectorView( size_type size, pointer const & data)
: size_(size),
data_(data)
{}
explicit ArrayVector( size_type size, Alloc const & alloc = Alloc()); /** Copy constructor.
*/
ArrayVectorView( this_type const & rhs )
: size_(rhs.size_),
data_(rhs.data_)
{}
ArrayVector( size_type size, value_type const & initial, Alloc const & alloc = Alloc()); /** Copy assignment. There are 3 cases:
ArrayVector( this_type const & rhs ); <ul>
<li> When this <tt>ArrayVectorView</tt> does not point to valid
data
(e.g. after default construction), it becomes a copy of \a
rhs.
<li> When the shapes of the two arrays match, the array content
s
(not the pointers) are copied.
<li> Otherwise, a <tt>PreconditionViolation</tt> exception is t
hrown.
</ul>
*/
ArrayVectorView & operator=( ArrayVectorView const & rhs );
template <class InputIterator> /** Copy assignment.
ArrayVector(InputIterator i, InputIterator end); When the shapes of the two arrays match, the array contents
(not the pointers) are copied. Otherwise, a <tt>PreconditionVio
lation</tt>
exception is thrown.
*/
template <class U>
this_type & operator=( ArrayVectorView<U> const & rhs )
{
copyImpl(rhs);
return *this;
}
template <class InputIterator> /** Overwrite all array elements with the value \a initial.
ArrayVector(InputIterator i, InputIterator end, Alloc const & alloc); */
template <class U>
void init(U const & initial)
{
std::fill(begin(), end(), initial);
}
this_type & operator=( this_type const & rhs ); /** Copy array elements.
When the shapes of the two arrays match, the array contents
(not the pointers) are copied. Otherwise, a <tt>PreconditionVio
lation</tt>
exception is thrown.
*/
void copy( this_type const & rhs )
{
if(data_ != rhs.data_)
copyImpl(rhs);
}
~ArrayVector(); /** Copy array elements.
When the shapes of the two arrays match, the array contents
(not the pointers) are copied. Otherwise, a <tt>PreconditionVio
lation</tt>
exception is thrown.
*/
template <class U>
void copy( ArrayVectorView<U> const & rhs )
{
copyImpl(rhs);
}
/** Swap array elements.
When the shapes of the two arrays match, the array contents
(not the pointers) are swapped. Otherwise, a <tt>PreconditionVi
olation</tt>
exception is thrown.
*/
void swapData(this_type rhs)
{
if(data_ != rhs.data_)
swapDataImpl(rhs);
}
/** Swap array elements.
When the shapes of the two arrays match, the array contents
(not the pointers) are swapped. Otherwise, a <tt>PreconditionVi
olation</tt>
exception is thrown.
*/
template <class U>
void swapData(ArrayVectorView<U> rhs)
{
swapDataImpl(rhs);
}
/** Construct <tt>ArrayVectorView</tt> refering to a subarray.
\a begin and \a end must be a valid sub-range of the current ar
ray.
Otherwise, a <tt>PreconditionViolation</tt>
exception is thrown.
*/
this_type subarray (size_type begin, size_type end) const
{
vigra_precondition(begin >= 0 && begin <= end && end <= size_,
"ArrayVectorView::subarray(): Limits out of range.");
return this_type(end-begin, data_ + begin);
}
/** Get contained const pointer to the data.
*/
inline const_pointer data() const inline const_pointer data() const
{ {
return data_; return data_;
} }
/** Get contained pointer to the data.
*/
inline pointer data() inline pointer data()
{ {
return data_; return data_;
} }
/** Get const iterator refering to the first array element.
*/
inline const_iterator begin() const inline const_iterator begin() const
{ {
return data(); return data();
} }
/** Get iterator refering to the first array element.
*/
inline iterator begin() inline iterator begin()
{ {
return data(); return data();
} }
/** Get const iterator pointing beyond the last array element.
*/
inline const_iterator end() const inline const_iterator end() const
{ {
return data() + size(); return data() + size();
} }
/** Get iterator pointing beyond the last array element.
*/
inline iterator end() inline iterator end()
{ {
return data() + size(); return data() + size();
} }
/** Get reverse iterator referring to the last array element.
*/
inline reverse_iterator rbegin() inline reverse_iterator rbegin()
{ {
return (reverse_iterator(end())); return (reverse_iterator(end()));
} }
/** Get const reverse iterator referring to the last array element.
*/
inline const_reverse_iterator rbegin() const inline const_reverse_iterator rbegin() const
{ {
return (const_reverse_iterator(end())); return (const_reverse_iterator(end()));
} }
/** Get reverse iterator pointing before the first array element.
*/
inline reverse_iterator rend() inline reverse_iterator rend()
{ {
return (reverse_iterator(begin())); return (reverse_iterator(begin()));
} }
/** Get const reverse iterator pointing before the first array elem
ent.
*/
inline const_reverse_iterator rend() const inline const_reverse_iterator rend() const
{ {
return (const_reverse_iterator(begin())); return (const_reverse_iterator(begin()));
} }
/** Access first array element.
*/
reference front() reference front()
{ {
return *data_; return *data_;
} }
/** Read first array element.
*/
const_reference front() const const_reference front() const
{ {
return *data_; return *data_;
} }
/** Access last array element.
*/
reference back() reference back()
{ {
return data_[size_-1]; return data_[size_-1];
} }
/** Read last array element.
*/
const_reference back() const const_reference back() const
{ {
return data_[size_-1]; return data_[size_-1];
} }
reference operator[]( size_type i ) /** Access array element \a i.
*/
reference operator[]( difference_type i )
{ {
return data()[i]; return data()[i];
} }
const_reference operator[]( size_type i ) const /** Read array element \a i.
*/
const_reference operator[]( difference_type i ) const
{ {
return data()[i]; return data()[i];
} }
/** Equivalent to <tt>size() == 0</tt>.
*/
bool empty() const
{
return size_ == 0;
}
/** Number of elements in the array.
*/
size_type size() const
{
return size_;
}
/** Check for element-wise equality of two array.
Also returns <tt>false</tt> if the two arrays have different si
zes.
*/
template <class U>
bool operator==(ArrayVectorView<U> const & rhs) const;
/** check whether two arrays are not elementwise equal.
Also returns <tt>true</tt> if the two arrays have different siz
es.
*/
template <class U>
bool operator!=(ArrayVectorView<U> const & rhs) const
{
return !operator==(rhs);
}
/** check whether the given point is in the array range.
*/
bool isInside (difference_type const & p) const
{
return p >= 0 && p < size_;
}
protected:
template <class U>
void copyImpl(const ArrayVectorView <U>& rhs);
void copyImpl(const ArrayVectorView & rhs);
template <class U>
void swapDataImpl(const ArrayVectorView <U>& rhs);
size_type size_;
pointer data_;
};
template <class T>
ArrayVectorView<T> & ArrayVectorView<T>::operator=( ArrayVectorView<T> cons
t & rhs )
{
if(data_ == 0)
{
size_ = rhs.size_;
data_ = rhs.data_;
}
else if(data_ != rhs.data_)
copyImpl(rhs);
return *this;
}
template <class T>
template <class U>
bool ArrayVectorView<T>::operator==(ArrayVectorView<U> const & rhs) const
{
if(size() != rhs.size())
return false;
for(unsigned int k=0; k<size(); ++k)
if(data_[k] != rhs[k])
return false;
return true;
}
template <class T>
void
ArrayVectorView <T>::copyImpl(const ArrayVectorView & rhs)
{
vigra_precondition (size() == rhs.size(),
"ArrayVectorView::copy(): shape mismatch.");
// use copy() or copy_backward() according to possible overlap of this
and rhs
if(data_ <= rhs.data())
{
std::copy(rhs.begin(), rhs.end(), begin());
}
else
{
std::copy_backward(rhs.begin(), rhs.end(), end());
}
}
template <class T>
template <class U>
void
ArrayVectorView <T>::copyImpl(const ArrayVectorView <U>& rhs)
{
vigra_precondition (size() == rhs.size(),
"ArrayVectorView::copy(): shape mismatch.");
std::copy(rhs.begin(), rhs.end(), begin());
}
template <class T>
template <class U>
void
ArrayVectorView <T>::swapDataImpl(const ArrayVectorView <U>& rhs)
{
vigra_precondition (size () == rhs.size() (),
"ArrayVectorView::swapData(): size mismatch.");
// check for overlap
if(data_ + size_ <= rhs.data_ || rhs.data_ + size_ <= data_)
{
for(unsigned int k=0; k<size_; ++k)
std::swap(data_[k], rhs.data_[k]);
}
else
{
ArrayVector<T> t(*this);
copyImpl(rhs);
rhs.copyImpl(*this);
}
}
/** Replacement for <tt>std::vector</tt>.
This template implements the same functionality as <tt>std::vector</tt>
.
However, it gives two useful guarantees, that <tt>std::vector</tt> fail
s
to provide:
<ul>
<li>The memory is always allocated as one contiguous piece.</li>
<li>The iterator is always a <TT>T *</TT> </li>
</ul>
This means that memory managed by <tt>ArrayVector</tt> can be passed
to algorithms that expect raw memory. This is especially important
when lagacy or C code has to be called, but it is also useful for certa
in
optimizations.
Moreover, <tt>ArrayVector</tt> is derived from <tt>ArrayVectorView</tt>
so that one
can create views of the array (in particular, subarrays). This implies
another
important difference to <tt>std::vector</tt>: the indexing operator
(<tt>ArrayVector::operator[]</tt>) takes <tt>signed</tt> indices. In th
is way,
an <tt>ArrayVectorView</tt> can be used with negative indices:
\code
ArrayVector<int> data(100);
ArrayVectorView<int> view = data.subarray(50, 100);
view[-50] = 1; // valid access
\endcode
Refer to the documentation of <tt>std::vector</tt> for a detailed
description of <tt>ArrayVector</tt> functionality.
<b>\#include</b> \<<a href="array__vector_8hxx-source.html">vigra/array
_vector.hxx</a>\><br>
Namespace: vigra
*/
template <class T, class Alloc /* = std::allocator<T> */ >
class ArrayVector
: public ArrayVectorView<T>
{
typedef ArrayVector<T, Alloc> this_type;
enum { minimumCapacity = 2 };
public:
typedef ArrayVectorView<T> view_type;
typedef typename view_type::value_type value_type;
typedef typename view_type::reference reference;
typedef typename view_type::const_reference const_reference;
typedef typename view_type::pointer pointer;
typedef typename view_type::const_pointer const_pointer;
typedef typename view_type::iterator iterator;
typedef typename view_type::const_iterator const_iterator;
typedef typename view_type::size_type size_type;
typedef typename view_type::difference_type difference_type;
typedef typename view_type::reverse_iterator reverse_iterator;
typedef typename view_type::const_reverse_iterator const_reverse_iterat
or;
typedef Alloc allocator_type;
public:
ArrayVector()
: view_type(),
capacity_(minimumCapacity),
alloc_(Alloc())
{
this->data_ = reserve_raw(capacity_);
}
explicit ArrayVector(Alloc const & alloc)
: view_type(),
capacity_(minimumCapacity),
alloc_(alloc)
{
this->data_ = reserve_raw(capacity_);
}
explicit ArrayVector( size_type size, Alloc const & alloc = Alloc())
: view_type(size, 0),
capacity_(size),
alloc_(alloc)
{
this->data_ = reserve_raw(capacity_);
if(this->size_ > 0)
std::uninitialized_fill(this->data_, this->data_+this->size_, va
lue_type());
}
ArrayVector( size_type size, value_type const & initial, Alloc const &
alloc = Alloc())
: view_type(size, 0),
capacity_(size),
alloc_(alloc)
{
this->data_ = reserve_raw(capacity_);
if(this->size_ > 0)
std::uninitialized_fill(this->data_, this->data_+this->size_, i
nitial);
}
ArrayVector( this_type const & rhs )
: view_type(rhs.size(), 0),
capacity_(rhs.capacity_),
alloc_(rhs.alloc_)
{
this->data_ = reserve_raw(capacity_);
if(this->size_ > 0)
std::uninitialized_copy(rhs.data_, rhs.data_+rhs.size_, this->d
ata_);
}
template <class U>
explicit ArrayVector( ArrayVectorView<U> const & rhs, Alloc const & all
oc = Alloc() );
template <class InputIterator>
ArrayVector(InputIterator i, InputIterator end);
template <class InputIterator>
ArrayVector(InputIterator i, InputIterator end, Alloc const & alloc);
this_type & operator=( this_type const & rhs )
{
if(this == &rhs)
return *this;
if(this->size_ == rhs.size_)
this->copyImpl(rhs);
else
{
ArrayVector t(rhs);
this->swap(t);
}
return *this;
}
template <class U>
this_type & operator=( ArrayVectorView<U> const & rhs);
~ArrayVector()
{
deallocate(this->data_, this->size_);
}
void pop_back(); void pop_back();
void push_back( value_type const & t ); void push_back( value_type const & t );
iterator insert(iterator p, value_type const & v); iterator insert(iterator p, value_type const & v);
iterator insert(iterator p, size_type n, value_type const & v); iterator insert(iterator p, size_type n, value_type const & v);
template <class InputIterator> template <class InputIterator>
iterator insert(iterator p, InputIterator i, InputIterator iend); iterator insert(iterator p, InputIterator i, InputIterator iend);
skipping to change at line 219 skipping to change at line 598
void reserve(); void reserve();
void resize( size_type new_size, value_type const & initial ); void resize( size_type new_size, value_type const & initial );
void resize( size_type new_size ) void resize( size_type new_size )
{ {
resize(new_size, value_type()); resize(new_size, value_type());
} }
bool empty() const
{
return size_ == 0;
}
size_type size() const
{
return size_;
}
size_type capacity() const size_type capacity() const
{ {
return capacity_; return capacity_;
} }
void swap(this_type & rhs); void swap(this_type & rhs);
private: private:
void deallocate(pointer data, size_type size); void deallocate(pointer data, size_type size);
pointer reserve_raw(size_type capacity); pointer reserve_raw(size_type capacity);
size_type capacity_;
Alloc alloc_; Alloc alloc_;
size_type size_, capacity_;
pointer data_;
}; };
template <class T, class Alloc> template <class T, class Alloc>
ArrayVector<T, Alloc>::ArrayVector() template <class U>
: alloc_(Alloc()), ArrayVector<T, Alloc>::ArrayVector( ArrayVectorView<U> const & rhs, Alloc c
size_(0), onst & alloc )
capacity_(minimumCapacity), : view_type(rhs.size(), 0),
data_(reserve_raw(minimumCapacity)) capacity_(rhs.size()),
{} alloc_(alloc)
template <class T, class Alloc>
ArrayVector<T, Alloc>::ArrayVector(Alloc const & alloc)
: alloc_(alloc),
size_(0),
capacity_(minimumCapacity),
data_(reserve_raw(minimumCapacity))
{}
template <class T, class Alloc>
ArrayVector<T, Alloc>::ArrayVector( size_type size, Alloc const & alloc)
: alloc_(alloc),
size_(size),
capacity_(size),
data_(reserve_raw(size))
{
if(size_ > 0)
std::uninitialized_fill(data_, data_+size_, value_type());
}
template <class T, class Alloc>
ArrayVector<T, Alloc>::ArrayVector( size_type size,
value_type const & initial, Alloc const & alloc)
: alloc_(alloc),
size_(size),
capacity_(size),
data_(reserve_raw(size))
{
if(size_ > 0)
std::uninitialized_fill(data_, data_+size_, initial);
}
template <class T, class Alloc>
ArrayVector<T, Alloc>::ArrayVector( this_type const & rhs )
: alloc_(rhs.alloc_),
size_(rhs.size_),
capacity_(rhs.capacity_),
data_(reserve_raw(rhs.capacity_))
{ {
if(size_ > 0) this->data_ = reserve_raw(capacity_);
std::uninitialized_copy(rhs.data_, rhs.data_+size_, data_); if(this->size_ > 0)
std::uninitialized_copy(rhs.data(), rhs.data()+rhs.size(), this->da
ta_);
} }
template <class T, class Alloc> template <class T, class Alloc>
template <class InputIterator> template <class InputIterator>
ArrayVector<T, Alloc>::ArrayVector(InputIterator i, InputIterator end) ArrayVector<T, Alloc>::ArrayVector(InputIterator i, InputIterator end)
: alloc_(), : view_type(std::distance(i, end), 0),
size_(std::distance(i, end)), capacity_(view_type::size_),
capacity_(size_), alloc_()
data_(reserve_raw(size_))
{ {
std::uninitialized_copy(i, end, data_); this->data_ = reserve_raw(capacity_);
std::uninitialized_copy(i, end, this->data_);
} }
template <class T, class Alloc> template <class T, class Alloc>
template <class InputIterator> template <class InputIterator>
ArrayVector<T, Alloc>::ArrayVector(InputIterator i, InputIterator end, Allo c const & alloc) ArrayVector<T, Alloc>::ArrayVector(InputIterator i, InputIterator end, Allo c const & alloc)
: alloc_(alloc), : view_type(std::distance(i, end), 0),
size_(std::distance(i, end)), capacity_(view_type::size_),
capacity_(size_), alloc_(alloc)
data_(reserve_raw(size_))
{ {
std::uninitialized_copy(i, end, data_); this->data_ = reserve_raw(capacity_);
std::uninitialized_copy(i, end, this->data_);
} }
template <class T, class Alloc> template <class T, class Alloc>
ArrayVector<T, Alloc> & ArrayVector<T, Alloc>::operator=( this_type const & template <class U>
rhs ) ArrayVector<T, Alloc> & ArrayVector<T, Alloc>::operator=( ArrayVectorView<U
> const & rhs )
{ {
if(this == &rhs) if(this->size_ == rhs.size())
return *this; this->copyImpl(rhs);
ArrayVector new_vector(rhs); else
swap(new_vector); {
ArrayVector t(rhs);
this->swap(t);
}
return *this; return *this;
} }
template <class T, class Alloc> template <class T, class Alloc>
ArrayVector<T, Alloc>::~ArrayVector() inline void ArrayVector<T, Alloc>::pop_back()
{
deallocate(data_, size_);
}
template <class T, class Alloc>
void ArrayVector<T, Alloc>::pop_back()
{ {
--size_; --this->size_;
alloc_.destroy(data_ + size_); alloc_.destroy(this->data_ + this->size_);
} }
template <class T, class Alloc> template <class T, class Alloc>
void ArrayVector<T, Alloc>::push_back( value_type const & t ) inline void ArrayVector<T, Alloc>::push_back( value_type const & t )
{ {
reserve(); reserve();
alloc_.construct(data_ + size_, t); alloc_.construct(this->data_ + this->size_, t);
++size_; ++this->size_;
} }
template <class T, class Alloc> template <class T, class Alloc>
void ArrayVector<T, Alloc>::clear() inline void ArrayVector<T, Alloc>::clear()
{ {
detail::destroy_n(data_, size_); detail::destroy_n(this->data_, (int)this->size_);
size_ = 0; this->size_ = 0;
} }
template <class T, class Alloc> template <class T, class Alloc>
typename ArrayVector<T, Alloc>::iterator typename ArrayVector<T, Alloc>::iterator
ArrayVector<T, Alloc>::insert(iterator p, value_type const & v) ArrayVector<T, Alloc>::insert(iterator p, value_type const & v)
{ {
difference_type pos = p - begin(); difference_type pos = p - this->begin();
if(p == end()) if(p == this->end())
{ {
push_back(v); push_back(v);
p = begin() + pos; p = this->begin() + pos;
} }
else else
{ {
push_back(back()); push_back(this->back());
p = begin() + pos; p = this->begin() + pos;
std::copy_backward(p, end() - 2, end() - 1); std::copy_backward(p, this->end() - 2, this->end() - 1);
*p = v; *p = v;
} }
return p; return p;
} }
template <class T, class Alloc> template <class T, class Alloc>
typename ArrayVector<T, Alloc>::iterator typename ArrayVector<T, Alloc>::iterator
ArrayVector<T, Alloc>::insert(iterator p, size_type n, value_type const & v ) ArrayVector<T, Alloc>::insert(iterator p, size_type n, value_type const & v )
{ {
difference_type pos = p - begin(); difference_type pos = p - this->begin();
size_type new_size = size() + n; size_type new_size = this->size() + n;
if(new_size >= capacity_) if(new_size >= capacity_)
{ {
pointer new_data = reserve_raw(new_size); pointer new_data = reserve_raw(new_size);
std::uninitialized_copy(begin(), p, new_data); std::uninitialized_copy(this->begin(), p, new_data);
std::uninitialized_fill(new_data + pos, new_data + pos + n, v); std::uninitialized_fill(new_data + pos, new_data + pos + n, v);
std::uninitialized_copy(p, end(), new_data + pos + n); std::uninitialized_copy(p, this->end(), new_data + pos + n);
deallocate(data_, size_); deallocate(this->data_, this->size_);
capacity_ = new_size; capacity_ = new_size;
data_ = new_data; this->data_ = new_data;
} }
else if(pos + n >= size_) else if(pos + n >= this->size_)
{ {
size_type diff = pos + n - size_; size_type diff = pos + n - this->size_;
std::uninitialized_copy(p, end(), end() + diff); std::uninitialized_copy(p, this->end(), this->end() + diff);
std::uninitialized_fill(end(), end() + diff, v); std::uninitialized_fill(this->end(), this->end() + diff, v);
std::fill(p, end(), v); std::fill(p, this->end(), v);
} }
else else
{ {
size_type diff = size_ - (pos + n); size_type diff = this->size_ - (pos + n);
std::uninitialized_copy(end() - n, end(), end()); std::uninitialized_copy(this->end() - n, this->end(), this->end());
std::copy_backward(p, p + diff, end()); std::copy_backward(p, p + diff, this->end());
std::fill(p, p + n, v); std::fill(p, p + n, v);
} }
size_ = new_size; this->size_ = new_size;
return begin() + pos; return this->begin() + pos;
} }
template <class T, class Alloc> template <class T, class Alloc>
template <class InputIterator> template <class InputIterator>
typename ArrayVector<T, Alloc>::iterator typename ArrayVector<T, Alloc>::iterator
ArrayVector<T, Alloc>::insert(iterator p, InputIterator i, InputIterator ie nd) ArrayVector<T, Alloc>::insert(iterator p, InputIterator i, InputIterator ie nd)
{ {
size_type n = iend - i; size_type n = iend - i;
size_type pos = p - begin(); size_type pos = p - this->begin();
size_type new_size = size() + n; size_type new_size = this->size() + n;
if(new_size >= capacity_) if(new_size >= capacity_)
{ {
pointer new_data = reserve_raw(new_size); pointer new_data = reserve_raw(new_size);
std::uninitialized_copy(begin(), p, new_data); std::uninitialized_copy(this->begin(), p, new_data);
std::uninitialized_copy(i, iend, new_data + pos); std::uninitialized_copy(i, iend, new_data + pos);
std::uninitialized_copy(p, end(), new_data + pos + n); std::uninitialized_copy(p, this->end(), new_data + pos + n);
deallocate(data_, size_); deallocate(this->data_, this->size_);
capacity_ = new_size; capacity_ = new_size;
data_ = new_data; this->data_ = new_data;
} }
else if(pos + n >= size_) else if(pos + n >= this->size_)
{ {
size_type diff = pos + n - size_; size_type diff = pos + n - this->size_;
std::uninitialized_copy(p, end(), end() + diff); std::uninitialized_copy(p, this->end(), this->end() + diff);
std::uninitialized_copy(iend - diff, iend, end()); std::uninitialized_copy(iend - diff, iend, this->end());
std::copy(i, iend - diff, p); std::copy(i, iend - diff, p);
} }
else else
{ {
size_type diff = size_ - (pos + n); size_type diff = this->size_ - (pos + n);
std::uninitialized_copy(end() - n, end(), end()); std::uninitialized_copy(this->end() - n, this->end(), this->end());
std::copy_backward(p, p + diff, end()); std::copy_backward(p, p + diff, this->end());
std::copy(i, iend, p); std::copy(i, iend, p);
} }
size_ = new_size; this->size_ = new_size;
return begin() + pos; return this->begin() + pos;
} }
template <class T, class Alloc> template <class T, class Alloc>
typename ArrayVector<T, Alloc>::iterator typename ArrayVector<T, Alloc>::iterator
ArrayVector<T, Alloc>::erase(iterator p) ArrayVector<T, Alloc>::erase(iterator p)
{ {
std::copy(p+1, end(), p); std::copy(p+1, this->end(), p);
pop_back(); pop_back();
return p; return p;
} }
template <class T, class Alloc> template <class T, class Alloc>
typename ArrayVector<T, Alloc>::iterator typename ArrayVector<T, Alloc>::iterator
ArrayVector<T, Alloc>::erase(iterator p, iterator q) ArrayVector<T, Alloc>::erase(iterator p, iterator q)
{ {
std::copy(q, end(), p); std::copy(q, this->end(), p);
size_type eraseCount = q - p; difference_type eraseCount = q - p;
detail::destroy_n(end() - eraseCount, eraseCount); detail::destroy_n(this->end() - eraseCount, eraseCount);
size_ -= eraseCount; this->size_ -= eraseCount;
return p; return p;
} }
template <class T, class Alloc> template <class T, class Alloc>
void ArrayVector<T, Alloc>::reserve( size_type new_capacity ) inline void
ArrayVector<T, Alloc>::reserve( size_type new_capacity )
{ {
if(new_capacity <= capacity_) if(new_capacity <= capacity_)
return; return;
pointer new_data = reserve_raw(new_capacity); pointer new_data = reserve_raw(new_capacity);
if(size_ > 0) if(this->size_ > 0)
std::uninitialized_copy(data_, data_+size_, new_data); std::uninitialized_copy(this->data_, this->data_+this->size_, new_d
deallocate(data_, size_); ata);
data_ = new_data; deallocate(this->data_, this->size_);
this->data_ = new_data;
capacity_ = new_capacity; capacity_ = new_capacity;
} }
template <class T, class Alloc> template <class T, class Alloc>
void ArrayVector<T, Alloc>::reserve() inline void
ArrayVector<T, Alloc>::reserve()
{ {
if(capacity_ == 0) if(capacity_ == 0)
reserve(minimumCapacity); reserve(minimumCapacity);
else if(size_ == capacity_) else if(this->size_ == capacity_)
reserve(2*capacity_); reserve(2*capacity_);
} }
template <class T, class Alloc> template <class T, class Alloc>
void ArrayVector<T, Alloc>::resize( size_type new_size, value_type const & inline void
initial) ArrayVector<T, Alloc>::resize( size_type new_size, value_type const & initi
al)
{ {
if(new_size < size_) if(new_size < this->size_)
erase(begin() + new_size, end()); erase(this->begin() + new_size, this->end());
else if(size_ < new_size) else if(this->size_ < new_size)
{ {
insert(end(), new_size - size(), initial); insert(this->end(), new_size - this->size(), initial);
} }
} }
template <class T, class Alloc> template <class T, class Alloc>
void ArrayVector<T, Alloc>::swap(this_type & rhs) inline void
ArrayVector<T, Alloc>::swap(this_type & rhs)
{ {
std::swap(size_, rhs.size_); std::swap(this->size_, rhs.size_);
std::swap(capacity_, rhs.capacity_); std::swap(capacity_, rhs.capacity_);
std::swap(data_, rhs.data_); std::swap(this->data_, rhs.data_);
} }
template <class T, class Alloc> template <class T, class Alloc>
void ArrayVector<T, Alloc>::deallocate(pointer data, size_type size) inline void
ArrayVector<T, Alloc>::deallocate(pointer data, size_type size)
{ {
if(data) if(data)
{ {
detail::destroy_n(data, size); detail::destroy_n(data, (int)size);
alloc_.deallocate(data, size); alloc_.deallocate(data, size);
} }
} }
template <class T, class Alloc> template <class T, class Alloc>
typename ArrayVector<T, Alloc>::pointer inline typename ArrayVector<T, Alloc>::pointer
ArrayVector<T, Alloc>::reserve_raw(size_type capacity) ArrayVector<T, Alloc>::reserve_raw(size_type capacity)
{ {
pointer data = 0; pointer data = 0;
if(capacity) if(capacity)
{ {
data = alloc_.allocate(capacity); data = alloc_.allocate(capacity);
} }
return data; return data;
} }
} // namespace vigra } // namespace vigra
namespace std {
template <class T>
ostream & operator<<(ostream & s, vigra::ArrayVectorView<T> const & a)
{
for(unsigned int k=0; k<a.size()-1; ++k)
s << a[k] << ", ";
if(a.size())
s << a.back();
return s;
}
} // namespace std
#endif /* VIGRA_ARRAY_VECTOR_HXX */ #endif /* VIGRA_ARRAY_VECTOR_HXX */
 End of changes. 89 change blocks. 
190 lines changed or deleted 573 lines changed or added


 basicgeometry.hxx   basicgeometry.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 76 skipping to change at line 76
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
rotateImage(SrcIterator is, SrcIterator end, SrcAccessor as, rotateImage(SrcIterator is, SrcIterator end, SrcAccessor as,
DestIterator id, DestAccessor ad, int rotation); DestIterator id, DestAccessor ad, int rotation);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
inline void inline void
rotateImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, rotateImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<DestImageIterator, DestAccessor> dest, int rotatio n); pair<DestImageIterator, DestAccessor> dest, int rotatio n);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="basicgeometry_8hxx-source.html">vigra/ba sicgeometry.hxx</a>"<br> <b>\#include</b> \<<a href="basicgeometry_8hxx-source.html">vigra/b asicgeometry.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
Image dest(src.height(), src.width()); // note that width and height ar e exchanged Image dest(src.height(), src.width()); // note that width and height ar e exchanged
vigra::rotateImage(srcImageRange(src), destImage(dest), 90); vigra::rotateImage(srcImageRange(src), destImage(dest), 90);
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
skipping to change at line 119 skipping to change at line 119
\endcode \endcode
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
src_lowerright.x - src_upperleft.x > 1 src_lowerright.x - src_upperleft.x > 1
src_lowerright.y - src_upperleft.y > 1 src_lowerright.y - src_upperleft.y > 1
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void rotateImage)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void rotateImage(SrcIterator is, SrcIterator end, SrcAccessor as, void rotateImage(SrcIterator is, SrcIterator end, SrcAccessor as,
DestIterator id, DestAccessor ad, int rotation) DestIterator id, DestAccessor ad, int rotation)
{ {
int x, y; int x, y;
int ws = end.x - is.x; int ws = end.x - is.x;
int hs = end.y - is.y; int hs = end.y - is.y;
vigra_precondition(rotation % 90 == 0, vigra_precondition(rotation % 90 == 0,
skipping to change at line 227 skipping to change at line 229
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as, reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as,
DestIterator id, DestAccessor ad, Reflect axis); DestIterator id, DestAccessor ad, Reflect axis);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
inline void inline void
reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor > src, reflectImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor > src,
pair<DestImageIterator, DestAccessor> dest, Reflect ax is); pair<DestImageIterator, DestAccessor> dest, Reflect ax is);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="basicgeometry_8hxx-source.html">vigra/ba sicgeometry.hxx</a>"<br> <b>\#include</b> \<<a href="basicgeometry_8hxx-source.html">vigra/b asicgeometry.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
Image dest(src.width(), src.height()); Image dest(src.width(), src.height());
vigra::reflectImage(srcImageRange(src), destImage(dest), vigra::horizon tal | vigra::vertical); vigra::reflectImage(srcImageRange(src), destImage(dest), vigra::horizon tal | vigra::vertical);
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
skipping to change at line 270 skipping to change at line 272
\endcode \endcode
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
src_lowerright.x - src_upperleft.x > 1 src_lowerright.x - src_upperleft.x > 1
src_lowerright.y - src_upperleft.y > 1 src_lowerright.y - src_upperleft.y > 1
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void reflectImage)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as, void reflectImage(SrcIterator is, SrcIterator end, SrcAccessor as,
DestIterator id, DestAccessor ad, Reflect reflect) DestIterator id, DestAccessor ad, Reflect reflect)
{ {
int ws = end.x - is.x; int ws = end.x - is.x;
int hs = end.y - is.y; int hs = end.y - is.y;
int x, y; int x, y;
skipping to change at line 368 skipping to change at line 372
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as, transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as,
DestIterator id, DestAccessor ad, Transpose axis); DestIterator id, DestAccessor ad, Transpose axis);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
inline void inline void
transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccess or> src, transposeImage(triple<SrcImageIterator, SrcImageIterator, SrcAccess or> src,
pair<DestImageIterator, DestAccessor> dest, Transpos e axis); pair<DestImageIterator, DestAccessor> dest, Transpos e axis);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="basicgeometry_8hxx-source.html">vigra/ba sicgeometry.hxx</a>"<br> <b>\#include</b> \<<a href="basicgeometry_8hxx-source.html">vigra/b asicgeometry.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
Image dest(src.width(), src.height()); Image dest(src.width(), src.height());
vigra::transposeImage(srcImageRange(src), destImage(dest), vigra::major | vigra::minor); vigra::transposeImage(srcImageRange(src), destImage(dest), vigra::major | vigra::minor);
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
skipping to change at line 411 skipping to change at line 415
\endcode \endcode
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
src_lowerright.x - src_upperleft.x > 1 src_lowerright.x - src_upperleft.x > 1
src_lowerright.y - src_upperleft.y > 1 src_lowerright.y - src_upperleft.y > 1
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void transposeImage)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as, void transposeImage(SrcIterator is, SrcIterator end, SrcAccessor as,
DestIterator id, DestAccessor ad, Transpose transpose) DestIterator id, DestAccessor ad, Transpose transpose)
{ {
int ws = end.x - is.x; int ws = end.x - is.x;
int hs = end.y - is.y; int hs = end.y - is.y;
int x, y; int x, y;
skipping to change at line 574 skipping to change at line 580
/* resampleImage */ /* resampleImage */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Resample image by a given factor. /** \brief Resample image by a given factor.
This algorithm is very fast and does not require any arithmetic on the pixel types. This algorithm is very fast and does not require any arithmetic on the pixel types.
The input image must have a size of at The input image must have a size of at
least 2x2. Destiniation pixels are directly copied from the appropriate least 2x2. Destiniation pixels are directly copied from the appropriate
source pixels. The size of the result image is the product of <tt>facto r</tt> source pixels. The size of the result image is the product of <tt>facto r</tt>
and the original size, where we round up if <tt>factor < 1.0</tt> an d down otherwise. and the original size, where we round up if <tt>factor < 1.0</tt> and d own otherwise.
This size calculation is the main difference to the convention used in the similar This size calculation is the main difference to the convention used in the similar
function \ref resizeImageNoInterpolation(): function \ref resizeImageNoInterpolation():
there, the result size is calculated as <tt>n*(old_width-1)+1</tt> and there, the result size is calculated as <tt>n*(old_width-1)+1</tt> and
<tt>n*(old_height-1)+1</tt>. This is because \ref resizeImageNoInterpol ation() <tt>n*(old_height-1)+1</tt>. This is because \ref resizeImageNoInterpol ation()
does not replicate the last pixel in every row/column in order to make it compatible does not replicate the last pixel in every row/column in order to make it compatible
with the other functions of the <tt>resizeImage...</tt> family. with the other functions of the <tt>resizeImage...</tt> family.
It should also be noted that resampleImage() is implemented so that an enlargement followed It should also be noted that resampleImage() is implemented so that an enlargement followed
by the corresponding shrinking reproduces the original image. The funct ion uses accessors. by the corresponding shrinking reproduces the original image. The funct ion uses accessors.
skipping to change at line 598 skipping to change at line 604
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa, resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
DestIterator id, DestAccessor ad, double factor); DestIterator id, DestAccessor ad, double factor);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
inline void inline void
resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccesso r> src, resampleImage(triple<SrcImageIterator, SrcImageIterator, SrcAccesso r> src,
pair<DestImageIterator, DestAccessor> dest, double fa ctor); pair<DestImageIterator, DestAccessor> dest, double fa ctor);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="basicgeometry_8hxx-source.html">vigra/ba sicgeometry.hxx</a>"<br> <b>\#include</b> \<<a href="basicgeometry_8hxx-source.html">vigra/b asicgeometry.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
double factor = 2.0; double factor = 2.0;
Image dest((int)(factor*src.width()), (int)(factor*src.height())); Image dest((int)(factor*src.width()), (int)(factor*src.height()));
vigra::resampleImage(srcImageRange(src), destImage(dest), factor); vigra::resampleImage(srcImageRange(src), destImage(dest), factor);
\endcode \endcode
skipping to change at line 642 skipping to change at line 648
\endcode \endcode
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
src_lowerright.x - src_upperleft.x > 1 src_lowerright.x - src_upperleft.x > 1
src_lowerright.y - src_upperleft.y > 1 src_lowerright.y - src_upperleft.y > 1
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void resampleImage)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa, resampleImage(SrcIterator is, SrcIterator iend, SrcAccessor sa,
DestIterator id, DestAccessor ad, double factor) DestIterator id, DestAccessor ad, double factor)
{ {
int width_old = iend.x - is.x; int width_old = iend.x - is.x;
int height_old = iend.y - is.y; int height_old = iend.y - is.y;
//Bei Verkleinerung muss das dest-Bild ceiling(src*factor), da z.B. //Bei Verkleinerung muss das dest-Bild ceiling(src*factor), da z.B.
 End of changes. 15 change blocks. 
12 lines changed or deleted 20 lines changed or added


 basicimage.hxx   basicimage.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 112 skipping to change at line 112
/********************************************************/ /********************************************************/
/* */ /* */
/* BasicImageIterator */ /* BasicImageIterator */
/* */ /* */
/********************************************************/ /********************************************************/
/** Implementation of the standard image iterator for \ref vigra::BasicImag e. /** Implementation of the standard image iterator for \ref vigra::BasicImag e.
See \ref vigra::ImageIterator for documentation. See \ref vigra::ImageIterator for documentation.
<b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimag e.hxx</a>" <b>\#include</b> \<<a href="basicimage_8hxx-source.html">vigra/basicima ge.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class IMAGEITERATOR, class PIXELTYPE, template <class IMAGEITERATOR, class PIXELTYPE,
class REFERENCE, class POINTER, class LINESTARTITERATOR> class REFERENCE, class POINTER, class LINESTARTITERATOR>
class BasicImageIteratorBase class BasicImageIteratorBase
{ {
public: public:
typedef BasicImageIteratorBase<IMAGEITERATOR, typedef BasicImageIteratorBase<IMAGEITERATOR,
PIXELTYPE, REFERENCE, POINTER, LINESTARTITERATOR> self_type; PIXELTYPE, REFERENCE, POINTER, LINESTARTITERATOR> self_type;
skipping to change at line 248 skipping to change at line 248
/********************************************************/ /********************************************************/
/* */ /* */
/* BasicImageIterator */ /* BasicImageIterator */
/* */ /* */
/********************************************************/ /********************************************************/
/** Implementation of the standard image iterator for \ref vigra::BasicImag e. /** Implementation of the standard image iterator for \ref vigra::BasicImag e.
See \ref vigra::ImageIterator for documentation. See \ref vigra::ImageIterator for documentation.
<b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimag e.hxx</a>" <b>\#include</b> \<<a href="basicimage_8hxx-source.html">vigra/basicima ge.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class PIXELTYPE, class ITERATOR> template <class PIXELTYPE, class ITERATOR>
class BasicImageIterator class BasicImageIterator
: public BasicImageIteratorBase<BasicImageIterator<PIXELTYPE, ITERATOR>, : public BasicImageIteratorBase<BasicImageIterator<PIXELTYPE, ITERATOR>,
PIXELTYPE, PIXELTYPE &, PIXELTYPE *, ITERATOR> PIXELTYPE, PIXELTYPE &, PIXELTYPE *, ITERATOR>
{ {
public: public:
typedef BasicImageIteratorBase<BasicImageIterator, PIXELTYPE, typedef BasicImageIteratorBase<BasicImageIterator, PIXELTYPE,
skipping to change at line 279 skipping to change at line 279
/********************************************************/ /********************************************************/
/* */ /* */
/* ConstBasicImageIterator */ /* ConstBasicImageIterator */
/* */ /* */
/********************************************************/ /********************************************************/
/** Implementation of the standard const image iterator for \ref vigra::Bas icImage. /** Implementation of the standard const image iterator for \ref vigra::Bas icImage.
See \ref vigra::ConstImageIterator for documentation. See \ref vigra::ConstImageIterator for documentation.
<b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimag e.hxx</a>" <b>\#include</b> \<<a href="basicimage_8hxx-source.html">vigra/basicima ge.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class PIXELTYPE, class ITERATOR> template <class PIXELTYPE, class ITERATOR>
class ConstBasicImageIterator class ConstBasicImageIterator
: public BasicImageIteratorBase<ConstBasicImageIterator<PIXELTYPE, ITERATOR >, : public BasicImageIteratorBase<ConstBasicImageIterator<PIXELTYPE, ITERATOR >,
PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERAT OR> PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, ITERAT OR>
{ {
public: public:
typedef BasicImageIteratorBase<ConstBasicImageIterator, typedef BasicImageIteratorBase<ConstBasicImageIterator,
skipping to change at line 456 skipping to change at line 456
/* */ /* */
/* BasicImage */ /* BasicImage */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Fundamental class template for images. /** \brief Fundamental class template for images.
A customized memory allocator can be specified as a templated argument A customized memory allocator can be specified as a templated argument
and passed in the constructor. and passed in the constructor.
<b>\#include</b> "<a href="basicimage_8hxx-source.html">vigra/basicimag e.hxx</a>" <b>\#include</b> \<<a href="basicimage_8hxx-source.html">vigra/basicima ge.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class PIXELTYPE, class Alloc = std::allocator<PIXELTYPE> > template <class PIXELTYPE, class Alloc = std::allocator<PIXELTYPE> >
class BasicImage class BasicImage
{ {
public: public:
/** the BasicImage's pixel type /** the BasicImage's pixel type
*/ */
skipping to change at line 1078 skipping to change at line 1078
"width and height must be >= 0.\n"); "width and height must be >= 0.\n");
if (width_ != width || height_ != height) // change size? if (width_ != width || height_ != height) // change size?
{ {
value_type * newdata = 0; value_type * newdata = 0;
value_type ** newlines = 0; value_type ** newlines = 0;
if(width*height > 0) if(width*height > 0)
{ {
if (width*height != width_*height_) // different sizes, must re allocate if (width*height != width_*height_) // different sizes, must re allocate
{ {
newdata = allocator_.allocate(width*height); newdata = allocator_.allocate(typename Alloc::size_type(wid th*height));
std::uninitialized_fill_n(newdata, width*height, d); std::uninitialized_fill_n(newdata, width*height, d);
newlines = initLineStartArray(newdata, width, height); newlines = initLineStartArray(newdata, width, height);
deallocate(); deallocate();
} }
else // need only to reshape else // need only to reshape
{ {
newdata = data_; newdata = data_;
std::fill_n(newdata, width*height, d); std::fill_n(newdata, width*height, d);
newlines = initLineStartArray(newdata, width, height); newlines = initLineStartArray(newdata, width, height);
pallocator_.deallocate(lines_, height_); pallocator_.deallocate(lines_, typename Alloc::size_type(he ight_));
} }
} }
else else
{ {
deallocate(); deallocate();
} }
data_ = newdata; data_ = newdata;
lines_ = newlines; lines_ = newlines;
width_ = width; width_ = width;
skipping to change at line 1120 skipping to change at line 1120
{ {
int newsize = width*height; int newsize = width*height;
if (width_ != width || height_ != height) // change size? if (width_ != width || height_ != height) // change size?
{ {
value_type * newdata = 0; value_type * newdata = 0;
value_type ** newlines = 0; value_type ** newlines = 0;
if(newsize > 0) if(newsize > 0)
{ {
if (newsize != width_*height_) // different sizes, must realloc ate if (newsize != width_*height_) // different sizes, must realloc ate
{ {
newdata = allocator_.allocate(newsize); newdata = allocator_.allocate(typename Alloc::size_type(new size));
std::uninitialized_copy(data, data + newsize, newdata); std::uninitialized_copy(data, data + newsize, newdata);
newlines = initLineStartArray(newdata, width, height); newlines = initLineStartArray(newdata, width, height);
deallocate(); deallocate();
} }
else // need only to reshape else // need only to reshape
{ {
newdata = data_; newdata = data_;
std::copy(data, data + newsize, newdata); std::copy(data, data + newsize, newdata);
newlines = initLineStartArray(newdata, width, height); newlines = initLineStartArray(newdata, width, height);
pallocator_.deallocate(lines_, height_); pallocator_.deallocate(lines_, typename Alloc::size_type(he ight_));
} }
} }
else else
{ {
deallocate(); deallocate();
} }
data_ = newdata; data_ = newdata;
lines_ = newlines; lines_ = newlines;
width_ = width; width_ = width;
skipping to change at line 1173 skipping to change at line 1173
void void
BasicImage<PIXELTYPE, Alloc>::deallocate() BasicImage<PIXELTYPE, Alloc>::deallocate()
{ {
if(data_) if(data_)
{ {
ScanOrderIterator i = begin(); ScanOrderIterator i = begin();
ScanOrderIterator iend = end(); ScanOrderIterator iend = end();
for(; i != iend; ++i) (*i).~PIXELTYPE(); for(; i != iend; ++i) (*i).~PIXELTYPE();
allocator_.deallocate(data_, width()*height()); allocator_.deallocate(data_, typename Alloc::size_type(width()*heig
pallocator_.deallocate(lines_, height_); ht()));
pallocator_.deallocate(lines_, typename Alloc::size_type(height_));
} }
} }
template <class PIXELTYPE, class Alloc> template <class PIXELTYPE, class Alloc>
PIXELTYPE ** PIXELTYPE **
BasicImage<PIXELTYPE, Alloc>::initLineStartArray(value_type * data, int wid th, int height) BasicImage<PIXELTYPE, Alloc>::initLineStartArray(value_type * data, int wid th, int height)
{ {
value_type ** lines = pallocator_.allocate(height); value_type ** lines = pallocator_.allocate(typename Alloc::size_type(he ight));
for(int y=0; y<height; ++y) for(int y=0; y<height; ++y)
lines[y] = data + y*width; lines[y] = data + y*width;
return lines; return lines;
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* argument object factories */ /* argument object factories */
/* */ /* */
/********************************************************/ /********************************************************/
 End of changes. 12 change blocks. 
14 lines changed or deleted 15 lines changed or added


 basicimageview.hxx   basicimageview.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 62 skipping to change at line 62
/** \brief BasicImage using foreign memory. /** \brief BasicImage using foreign memory.
This class provides the same interface as \ref vigra::BasicImage This class provides the same interface as \ref vigra::BasicImage
(with the exception of <tt>resize()</tt>) but the image's (with the exception of <tt>resize()</tt>) but the image's
memory is provided from the outside instead of allocated internally. memory is provided from the outside instead of allocated internally.
A <tt>BasicImageView</tt> can also be created from a A <tt>BasicImageView</tt> can also be created from a
\ref vigra::MultiArrayView with the appropriate shape -- see \ref vigra::MultiArrayView with the appropriate shape -- see
\ref MultiArrayToImage. \ref MultiArrayToImage.
<b>\#include</b> "<a href="basicimageview_8hxx-source.html">vigra/basic imageview.hxx</a>" <b>\#include</b> \<<a href="basicimageview_8hxx-source.html">vigra/basi cimageview.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class PIXELTYPE> template <class PIXELTYPE>
class BasicImageView class BasicImageView
{ {
public: public:
/** the BasicImageView's pixel type /** the BasicImageView's pixel type
*/ */
 End of changes. 3 change blocks. 
4 lines changed or deleted 4 lines changed or added


 bordertreatment.hxx   bordertreatment.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 50 skipping to change at line 50
namespace vigra { namespace vigra {
/*! \page BorderTreatmentMode BorderTreatmentMode /*! \page BorderTreatmentMode BorderTreatmentMode
Choose between different border treatment modes. In the convolution Choose between different border treatment modes. In the convolution
algorithms, these modes apply to algorithms, these modes apply to
all image pixels where the kernel does not completely fit inside all image pixels where the kernel does not completely fit inside
the image. the image.
<b>\#include</b> "<a href="bordertreatment_8hxx-source.html">vigra/bord ertreatment.hxx</a>"<br> <b>\#include</b> \<<a href="bordertreatment_8hxx-source.html">vigra/bor dertreatment.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
enum BorderTreatmentMode enum BorderTreatmentMode
{ {
// do not operate on a pixel where the kernel does // do not operate on a pixel where the kernel does
// not fit in the image // not fit in the image
BORDER_TREATMENT_AVOID, BORDER_TREATMENT_AVOID,
// clip kernel at image border (this is only useful if the // clip kernel at image border (this is only useful if the
 End of changes. 3 change blocks. 
4 lines changed or deleted 4 lines changed or added


 boundarytensor.hxx   boundarytensor.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2004 by Ullrich Koethe */ /* Copyright 1998-2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 373 skipping to change at line 373
/** \brief Calculate Riesz transforms of the Laplacian of Gaussian. /** \brief Calculate Riesz transforms of the Laplacian of Gaussian.
The Riesz transforms of the Laplacian of Gaussian have the following tr ansfer The Riesz transforms of the Laplacian of Gaussian have the following tr ansfer
functions (defined in a polar coordinate representation of the frequenc y domain): functions (defined in a polar coordinate representation of the frequenc y domain):
\f[ \f[
F_{\sigma}(r, \phi)=(i \cos \phi)^n (i \sin \phi)^m r^2 e^{-r^2 \si gma^2 / 2} F_{\sigma}(r, \phi)=(i \cos \phi)^n (i \sin \phi)^m r^2 e^{-r^2 \si gma^2 / 2}
\f] \f]
where <i>n</i> = <tt>xorder</tt> and <i>m</i> = <tt>yorder</tt> determi ne th e where <i>n</i> = <tt>xorder</tt> and <i>m</i> = <tt>yorder</tt> determi ne th e
order of the transform, and <tt>sigma > 0</tt> is the scale of the L aplacian order of the transform, and <tt>sigma > 0</tt> is the scale of the Lapl acian
of Gaussian. This function computes a good spatial domain approximation of of Gaussian. This function computes a good spatial domain approximation of
these transforms for <tt>xorder + yorder <= 2</tt>. The filter respo nses may be used these transforms for <tt>xorder + yorder <= 2</tt>. The filter response s may be used
to calculate the monogenic signal or the boundary tensor. to calculate the monogenic signal or the boundary tensor.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void rieszTransformOfLOG(SrcIterator supperleft, SrcIterator slower right, SrcAccessor src, void rieszTransformOfLOG(SrcIterator supperleft, SrcIterator slower right, SrcAccessor src,
DestIterator dupperleft, DestAccessor dest , DestIterator dupperleft, DestAccessor dest ,
double scale, unsigned int xorder, unsigne d int yorder); double scale, unsigned int xorder, unsigne d int yorder);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void rieszTransformOfLOG(triple<SrcIterator, SrcIterator, SrcAccess or> src, void rieszTransformOfLOG(triple<SrcIterator, SrcIterator, SrcAccess or> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale, unsigned int xorder, unsigne d int yorder); double scale, unsigned int xorder, unsigne d int yorder);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="boundarytensor_8hxx-source.html">vigra/bound arytensor.hxx</a>" <b>\#include</b> \<<a href="boundarytensor_8hxx-source.html">vigra/boun darytensor.hxx</a>\>
\code \code
FImage impulse(17,17), res(17, 17); FImage impulse(17,17), res(17, 17);
impulse(8,8) = 1.0; impulse(8,8) = 1.0;
// calculate the impulse response of the first order Riesz transform in x-direction // calculate the impulse response of the first order Riesz transform in x-direction
rieszTransformOfLOG(srcImageRange(impulse), destImage(res), 2.0, 1, 0); rieszTransformOfLOG(srcImageRange(impulse), destImage(res), 2.0, 1, 0);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void rieszTransformOfLOG)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void rieszTransformOfLOG(SrcIterator supperleft, SrcIterator slowerright, S rcAccessor src, void rieszTransformOfLOG(SrcIterator supperleft, SrcIterator slowerright, S rcAccessor src,
DestIterator dupperleft, DestAccessor dest, DestIterator dupperleft, DestAccessor dest,
double scale, unsigned int xorder, unsigned int yo rder) double scale, unsigned int xorder, unsigned int yo rder)
{ {
unsigned int order = xorder + yorder; unsigned int order = xorder + yorder;
vigra_precondition(order <= 2, vigra_precondition(order <= 2,
"rieszTransformOfLOG(): can only compute Riesz transforms up to order 2."); "rieszTransformOfLOG(): can only compute Riesz transforms up to order 2.");
skipping to change at line 538 skipping to change at line 540
//@{ //@{
/********************************************************/ /********************************************************/
/* */ /* */
/* boundaryTensor */ /* boundaryTensor */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Calculate the boundary tensor for a scalar valued image. /** \brief Calculate the boundary tensor for a scalar valued image.
These functions calculates a spatial domain approximation of These functions calculate a spatial domain approximation of
the boundary tensor as described in the boundary tensor as described in
U. K&ouml;the: <a href="http://kogs-www.informatik.uni-hamburg.de/~koet he/papers/abstracts/polarfilters.html"> U. K&ouml;the: <a href="http://kogs-www.informatik.uni-hamburg.de/~koet he/papers/abstracts/polarfilters.html">
<i>"Integrated Edge and Junction Detection with the Boundary Tensor"</i ></a>, <i>"Integrated Edge and Junction Detection with the Boundary Tensor"</i ></a>,
in: ICCV 03, Proc. of 9th Intl. Conf. on Computer Vision, Nice 2003, v ol. 1, in: ICCV 03, Proc. of 9th Intl. Conf. on Computer Vision, Nice 2003, v ol. 1,
pp. 424-431, Los Alamitos: IEEE Computer Society, 2003 pp. 424-431, Los Alamitos: IEEE Computer Society, 2003
with the Laplacian of Gaussian as the underlying bandpass filter (see with the Laplacian of Gaussian as the underlying bandpass filter (see
\ref rieszTransformOfLOG()). The output image must have 3 bands which w ill hold the \ref rieszTransformOfLOG()). The output image must have 3 bands which w ill hold the
tensor components in the order t11, t12 (== t21), t22. The function tensor components in the order t11, t12 (== t21), t22. The function
\ref boundaryTensor1() with the same interface implements a variant of the \ref boundaryTensor1() with the same interface implements a variant of the
boundary tensor where the 0th-order Riesz transform has been dropped, s o that the boundary tensor where the 0th-order Riesz transform has been dropped, s o that the
tensor is no longer sensitive to blobs. tensor is no longer sensitive to blobs.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void boundaryTensor(SrcIterator supperleft, SrcIterator slowerright , SrcAccessor src, void boundaryTensor(SrcIterator supperleft, SrcIterator slowerright , SrcAccessor src,
DestIterator dupperleft, DestAccessor dest, DestIterator dupperleft, DestAccessor dest,
double scale); double scale);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void boundaryTensor(triple<SrcIterator, SrcIterator, SrcAccessor> s rc, void boundaryTensor(triple<SrcIterator, SrcIterator, SrcAccessor> s rc,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale); double scale);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="boundarytensor_8hxx-source.html">vigra/bound arytensor.hxx</a>" <b>\#include</b> \<<a href="boundarytensor_8hxx-source.html">vigra/boun darytensor.hxx</a>\>
\code \code
FImage img(w,h); FImage img(w,h);
FVector3Image bt(w,h); FVector3Image bt(w,h);
... ...
boundaryTensor(srcImageRange(img), destImage(bt), 2.0); boundaryTensor(srcImageRange(img), destImage(bt), 2.0);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void boundaryTensor)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void boundaryTensor(SrcIterator supperleft, SrcIterator slowerright, SrcAcc essor src, void boundaryTensor(SrcIterator supperleft, SrcIterator slowerright, SrcAcc essor src,
DestIterator dupperleft, DestAccessor dest, DestIterator dupperleft, DestAccessor dest,
double scale) double scale)
{ {
vigra_precondition(dest.size(dupperleft) == 3, vigra_precondition(dest.size(dupperleft) == 3,
"boundaryTensor(): image for even output must have 3 bands."); "boundaryTensor(): image for even output must have 3 bands.");
vigra_precondition(scale > 0.0, vigra_precondition(scale > 0.0,
"boundaryTensor(): scale must be positive."); "boundaryTensor(): scale must be positive.");
skipping to change at line 617 skipping to change at line 621
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline inline
void boundaryTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src, void boundaryTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale) double scale)
{ {
boundaryTensor(src.first, src.second, src.third, boundaryTensor(src.first, src.second, src.third,
dest.first, dest.second, scale); dest.first, dest.second, scale);
} }
/** \brief Boundary tensor variant.
This function implements a variant of the boundary tensor where the
0th-order Riesz transform has been dropped, so that the tensor is no
longer sensitive to blobs. See \ref boundaryTensor() for more detailed
documentation.
<b> Declarations:</b>
<b>\#include</b> \<<a href="boundarytensor_8hxx-source.html">vigra/boun
darytensor.hxx</a>\>
pass arguments explicitly:
\code
namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void boundaryTensor1(SrcIterator supperleft, SrcIterator slowerrigh
t, SrcAccessor src,
DestIterator dupperleft, DestAccessor dest,
double scale);
}
\endcode
use argument objects in conjunction with \ref ArgumentObjectFactories :
\code
namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void boundaryTensor1(triple<SrcIterator, SrcIterator, SrcAccessor>
src,
pair<DestIterator, DestAccessor> dest,
double scale);
}
\endcode
*/
doxygen_overloaded_function(template <...> void boundaryTensor1)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void boundaryTensor1(SrcIterator supperleft, SrcIterator slowerright, SrcAc cessor src, void boundaryTensor1(SrcIterator supperleft, SrcIterator slowerright, SrcAc cessor src,
DestIterator dupperleft, DestAccessor dest, DestIterator dupperleft, DestAccessor dest,
double scale) double scale)
{ {
vigra_precondition(dest.size(dupperleft) == 3, vigra_precondition(dest.size(dupperleft) == 3,
"boundaryTensor1(): image for even output must have 3 bands."); "boundaryTensor1(): image for even output must have 3 bands.");
vigra_precondition(scale > 0.0, vigra_precondition(scale > 0.0,
"boundaryTensor1(): scale must be positive."); "boundaryTensor1(): scale must be positive.");
 End of changes. 14 change blocks. 
12 lines changed or deleted 54 lines changed or added


 codec.hxx   codec.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2001-2002 by Gunnar Kedenburg */ /* Copyright 2001-2002 by Gunnar Kedenburg */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 199 skipping to change at line 199
virtual std::string getFileType() const = 0; virtual std::string getFileType() const = 0;
virtual unsigned int getOffset() const = 0; virtual unsigned int getOffset() const = 0;
virtual void setWidth( unsigned int ) = 0; virtual void setWidth( unsigned int ) = 0;
virtual void setHeight( unsigned int ) = 0; virtual void setHeight( unsigned int ) = 0;
virtual void setNumBands( unsigned int ) = 0; virtual void setNumBands( unsigned int ) = 0;
virtual void setCompressionType( const std::string &, int = -1 ) = 0; virtual void setCompressionType( const std::string &, int = -1 ) = 0;
virtual void setPixelType( const std::string & ) = 0; virtual void setPixelType( const std::string & ) = 0;
virtual void finalizeSettings() = 0; virtual void finalizeSettings() = 0;
virtual void setPosition( const vigra::Diff2D & pos ) virtual void setPosition( const vigra::Diff2D & /*pos*/ )
{ {
} }
virtual void setXResolution( float xres ) virtual void setXResolution( float /*xres*/ )
{ {
} }
virtual void setYResolution( float yres ) virtual void setYResolution( float /*yres*/ )
{ {
} }
typedef ArrayVector<unsigned char> ICCProfile; typedef ArrayVector<unsigned char> ICCProfile;
virtual void setICCProfile(const ICCProfile & /* data */) virtual void setICCProfile(const ICCProfile & /* data */)
{ {
} }
virtual void * currentScanlineOfBand( unsigned int ) = 0; virtual void * currentScanlineOfBand( unsigned int ) = 0;
skipping to change at line 244 skipping to change at line 244
// - (if provided) the FileType // - (if provided) the FileType
// - (in case of decoders) the file's magic string // - (in case of decoders) the file's magic string
// - the filename extension // - the filename extension
VIGRA_EXPORT std::auto_ptr<Decoder> VIGRA_EXPORT std::auto_ptr<Decoder>
getDecoder( const std::string &, const std::string & = "undefined" ); getDecoder( const std::string &, const std::string & = "undefined" );
VIGRA_EXPORT std::auto_ptr<Encoder> VIGRA_EXPORT std::auto_ptr<Encoder>
getEncoder( const std::string &, const std::string & = "undefined" ); getEncoder( const std::string &, const std::string & = "undefined" );
VIGRA_EXPORT std::string
getEncoderType( const std::string &, const std::string & = "undefined"
);
// functions to query the capabilities of certain codecs // functions to query the capabilities of certain codecs
VIGRA_EXPORT std::vector<std::string> queryCodecPixelTypes( const std:: string & ); VIGRA_EXPORT std::vector<std::string> queryCodecPixelTypes( const std:: string & );
VIGRA_EXPORT bool negotiatePixelType( std::string const & codecname, VIGRA_EXPORT bool negotiatePixelType( std::string const & codecname,
std::string const & srcPixeltype, std::string & destPixelt ype); std::string const & srcPixeltype, std::string & destPixelt ype);
VIGRA_EXPORT bool isPixelTypeSupported( const std::string &, const std: :string & ); VIGRA_EXPORT bool isPixelTypeSupported( const std::string &, const std: :string & );
VIGRA_EXPORT bool isBandNumberSupported( const std::string &, int bands ); VIGRA_EXPORT bool isBandNumberSupported( const std::string &, int bands );
 End of changes. 6 change blocks. 
6 lines changed or deleted 10 lines changed or added


 colorconversions.hxx   colorconversions.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 46 skipping to change at line 46
/************************************************************************/ /************************************************************************/
#ifndef VIGRA_COLORCONVERSIONS_HXX #ifndef VIGRA_COLORCONVERSIONS_HXX
#define VIGRA_COLORCONVERSIONS_HXX #define VIGRA_COLORCONVERSIONS_HXX
#include <cmath> #include <cmath>
#include "mathutil.hxx" #include "mathutil.hxx"
#include "rgbvalue.hxx" #include "rgbvalue.hxx"
#include "functortraits.hxx" #include "functortraits.hxx"
/** \page ColorConversions Color Space Conversions namespace vigra {
Convert between RGB, R'G'B', XYZ, L*a*b*, L*u*v*, Y'PbPr, Y'CbCr, Y'IQ, namespace detail
and Y'UV color spaces. {
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col inline double gammaCorrection(double value, double gamma)
orconversions.hxx</a>"<br> {
return (value < 0.0) ?
-VIGRA_CSTD::pow(-value, gamma) :
VIGRA_CSTD::pow(value, gamma);
}
inline double gammaCorrection(double value, double gamma, double norm)
{
return (value < 0.0) ?
-norm*VIGRA_CSTD::pow(-value/norm, gamma) :
norm*VIGRA_CSTD::pow(value/norm, gamma);
}
inline double sRGBCorrection(double value, double norm)
{
value /= norm;
return (value <= 0.00304)
? norm*12.92*value
: norm*(1.055*VIGRA_CSTD::pow(value, 0.41666666666666667) -
0.055);
}
inline double inverse_sRGBCorrection(double value, double norm)
{
value /= norm;
return (value <= 0.03928)
? norm*value / 12.92
: norm*VIGRA_CSTD::pow((value + 0.055)/1.055, 2.4);
}
} // namespace detail
/** \defgroup ColorConversions Color Space Conversions
Convert between RGB, sRGB, R'G'B', XYZ, L*a*b*, L*u*v*, Y'PbPr, Y'CbCr,
Y'IQ, and Y'UV color spaces.
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co
lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
<UL> <UL>
<LI> <b>RGB/R'G'B'</b><br> <LI> <b>RGB/sRGB/R'G'B'</b><br>
<em>linear and non-linear (gamma corrected) additive color</em> <em>linear and non-linear (gamma corrected) additive color</em>
<p> <p>
<DL> <UL style="list-style-image:url(documents/bullet.gif)">
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref vigra::RGB2sRGBFunctor
vigra::RGB2RGBPrimeFunctor <LI> \ref vigra::sRGB2RGBFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref vigra::RGB2RGBPrimeFunctor
vigra::RGBPrime2RGBFunctor <LI> \ref vigra::RGBPrime2RGBFunctor
</DL><p> </UL><p>
<LI> <b>XYZ</b><br> <LI> <b>XYZ</b><br>
<em>device independent color representation <em>device independent color representation
(according to Publication CIE No 15.2 "Colorimetry" (according to Publication CIE No 15.2 "Colorimetry"
and ITU-R Recommendation BT.709)</em> and ITU-R Recommendation BT.709)</em>
<p> <p>
<DL> <UL style="list-style-image:url(documents/bullet.gif)">
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref vigra::RGB2XYZFunctor
vigra::RGB2XYZFunctor <LI> \ref vigra::RGBPrime2XYZFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref vigra::XYZ2RGBFunctor
vigra::RGBPrime2XYZFunctor <LI> \ref vigra::XYZ2RGBPrimeFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> </UL><p>
vigra::XYZ2RGBFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
vigra::XYZ2RGBPrimeFunctor
</DL><p>
<LI> <b>L*a*b* </b><br> <LI> <b>L*a*b* </b><br>
<em>perceptually uniform color representation <em>perceptually uniform color representation
(according to Publication CIE No 15.2 "Colorimetry" and (according to Publication CIE No 15.2 "Colorimetry" and
ITU-R Recommendation BT.709)</em> ITU-R Recommendation BT.709)</em>
<p> <p>
<DL> <UL style="list-style-image:url(documents/bullet.gif)">
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref vigra::RGB2LabFunctor
vigra::RGB2LabFunctor <LI> \ref vigra::RGBPrime2LabFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref vigra::XYZ2LabFunctor
vigra::RGBPrime2LabFunctor <LI> \ref vigra::Lab2RGBFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref vigra::Lab2RGBPrimeFunctor
vigra::XYZ2LabFunctor <LI> \ref vigra::Lab2XYZFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref polar2Lab()
vigra::Lab2RGBFunctor <LI> \ref lab2Polar()
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> </UL><p>
vigra::Lab2RGBPrimeFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
vigra::Lab2XYZFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref polar2Lab "vigra::polar2Lab"()
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref lab2Polar "vigra::lab2Polar"()
</DL><p>
<LI> <b>L*u*v* </b><br> <LI> <b>L*u*v* </b><br>
<em>perceptually uniform color representation <em>perceptually uniform color representation
(according to Publication CIE No 15.2 "Colorimetry" and (according to Publication CIE No 15.2 "Colorimetry" and
ITU-R Recommendation BT.709)</em> ITU-R Recommendation BT.709)</em>
<p> <p>
<DL> <UL style="list-style-image:url(documents/bullet.gif)">
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref vigra::RGB2LuvFunctor
vigra::RGB2LuvFunctor <LI> \ref vigra::RGBPrime2LuvFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref vigra::XYZ2LuvFunctor
vigra::RGBPrime2LuvFunctor <LI> \ref vigra::Luv2RGBFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref vigra::Luv2RGBPrimeFunctor
vigra::XYZ2LuvFunctor <LI> \ref vigra::Luv2XYZFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref polar2Luv()
vigra::Luv2RGBFunctor <LI> \ref luv2Polar()
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> </UL><p>
vigra::Luv2RGBPrimeFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
vigra::Luv2XYZFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref polar2Luv "vigra::polar2Luv"()
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref luv2Polar "vigra::luv2Polar"()
</DL><p>
<LI> <b>Y'PbPr and Y'CbCr </b><br> <LI> <b>Y'PbPr and Y'CbCr </b><br>
<em>color difference coding <em>color difference coding
(according to ITU-R Recommendation BT. 601)</em> (according to ITU-R Recommendation BT. 601)</em>
<p> <p>
<DL> <UL style="list-style-image:url(documents/bullet.gif)">
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref vigra::RGBPrime2YPrimePbPrFunctor
vigra::RGBPrime2YPrimePbPrFunctor <LI> \ref vigra::YPrimePbPr2RGBPrimeFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref polar2YPrimePbPr()
vigra::YPrimePbPr2RGBPrimeFunctor <LI> \ref yPrimePbPr2Polar()
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref vigra::RGBPrime2YPrimeCbCrFunctor
\ref polar2YPrimePbPr "vigra::polar2YPrimePbPr"() <LI> \ref vigra::YPrimeCbCr2RGBPrimeFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref polar2YPrimeCbCr()
\ref yPrimePbPr2Polar "vigra::yPrimePbPr2Polar"() <LI> \ref yPrimeCbCr2Polar()
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> </UL><p>
vigra::RGBPrime2YPrimeCbCrFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
vigra::YPrimeCbCr2RGBPrimeFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref polar2YPrimeCbCr "vigra::polar2YPrimeCbCr"()
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref yPrimeCbCr2Polar "vigra::yPrimeCbCr2Polar"()
</DL><p>
<LI> <b>Y'UV and Y'IQ </b><br> <LI> <b>Y'UV and Y'IQ </b><br>
<em>analog video coding according to NTSC and PAL standards</em> <em>analog video coding according to NTSC and PAL standards</em>
<p> <p>
<DL> <UL style="list-style-image:url(documents/bullet.gif)">
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref vigra::RGBPrime2YPrimeUVFunctor
vigra::RGBPrime2YPrimeUVFunctor <LI> \ref vigra::YPrimeUV2RGBPrimeFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref polar2YPrimeUV()
vigra::YPrimeUV2RGBPrimeFunctor <LI> \ref yPrimeUV2Polar()
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref vigra::RGBPrime2YPrimeIQFunctor
\ref polar2YPrimeUV "vigra::polar2YPrimeUV"() <LI> \ref vigra::YPrimeIQ2RGBPrimeFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref polar2YPrimeIQ()
\ref yPrimeUV2Polar "vigra::yPrimeUV2Polar"() <LI> \ref yPrimeIQ2Polar()
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> </UL><p>
vigra::RGBPrime2YPrimeIQFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
vigra::YPrimeIQ2RGBPrimeFunctor
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref polar2YPrimeIQ "vigra::polar2YPrimeIQ"()
<DT> <IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref yPrimeIQ2Polar "vigra::yPrimeIQ2Polar"()
</DL><p>
</UL> </UL>
\anchor _details \anchor _details
This module provides conversion from RGB/R'G'B' into more perceptually uniform This module provides conversion from RGB/R'G'B' into more perceptually uniform
color spaces. In image analysis, colors are usually converted into anot her color space color spaces. In image analysis, colors are usually converted into anot her color space
in order to get good estimates of perceived color differences by just c alculating in order to get good estimates of perceived color differences by just c alculating
Euclidean distances between the transformed colors. The L*a*b* and L*u* v* were Euclidean distances between the transformed colors. The L*a*b* and L*u* v* were
designed with exactly this application in mind and thus give the best r esults. But these designed with exactly this application in mind and thus give the best r esults. But these
conversions are also the most computationally demanding. The Y'PbPr col or difference conversions are also the most computationally demanding. The Y'PbPr col or difference
space (designed for the coding of digital video) is computationally muc h cheaper, and space (designed for coding digital video) is computationally much cheap er, and
almost as good. Y'CbCr represents esentially the same transformation, b ut the color values almost as good. Y'CbCr represents esentially the same transformation, b ut the color values
are scaled so that they can be stored with 8 bits per channel with mini mal loss of are scaled so that they can be stored with 8 bits per channel with mini mal loss of
information. The other transformations are of lesser interest here: XYZ is a device independent information. The other transformations are of lesser interest here: XYZ is a device independent
(but not perceptually uniform) color representation, and Y'IQ and Y'UV are the color (but not perceptually uniform) color representation, and Y'IQ and Y'UV are the color
spaces used by the PAL and NTSC analog video standards. Detailed inform ation about spaces used by the PAL and NTSC analog video standards. Detailed inform ation about
these color spaces and their transformations can be found in these color spaces and their transformations can be found in
<a href="http://www.poynton.com/ColorFAQ.html">Charles Poynton's Color FAQ</a> <a href="http://www.poynton.com/ColorFAQ.html">Charles Poynton's Color FAQ</a>
When you want to perform a color conversion, you must first know in whi ch When you want to perform a color conversion, you must first know in whi ch
color space the data are given. Although this sounds trivial, it is color space the data are given. Although this sounds trivial, it is
quite often done wrong in practice, because the distinction quite often done wrong, because the distinction between RGB and sRGB (s
between RGB and R'G'B' is frequently overlooked: nowadays, most images till images) or R'G'B'
are stored in (digital video) is frequently overlooked: nowadays, most still images a
R'G'B' space, and treating them as RGB leads to wrong results. RGB and re stored in
R'G'B' are sRGB space, and treating them as RGB leads to wrong results (although t
related by a so called <em>gamma correction</em>: he color primaries
are named the same). RGB and R'G'B' are related by a so called <em>gamm
a correction</em>:
\f[ \f[
R' = R_{max} \left(\frac{R}{R_{max}} \right)^{0.45} \qquad C' = C_{max} \left(\frac{C_{RGB}}{C_{max}} \right)^{0.45} \qquad
G' = G_{max} \left(\frac{G}{G_{max}} \right)^{0.45} \qquad
B' = B_{max} \left(\frac{B}{B_{max}} \right)^{0.45}
\f] \f]
(where usually \f$ R_{max} = G_{max} = B_{max} = 255 \f$). In practice, where C represents one of the color channels R, G, and B, and \f$ C_{ma
you can x} \f$ usually equals 255.
distinguish the two kinds of red, green, and blue by displaying the ima The sRGB color space realizes a slight enhancement of this definition:
ges: if they look
too dark, they are probably RGB, if they are OK, they are likely R'G'B' \f[
. (However, C_{sRGB} = \left\{\begin{array}{ll}
this may also be misleading: Some graphics cards and display programs s 12.92\,C_{RGB} & \textrm{ if }\frac{C_{RGB}}{C_{max}} \le 0.00304 \
ilently apply a \
gamma correction to every image, so that RGB appears correct and R'G'B' C_{max}\left( 1.055 \left(\frac{C_{RGB}}{C_{max}}\right)^{1/2.4}-0.
is too bright.) 055\right) & \textrm{ otherwise}
\end{array} \right.
\f]
sRGB has now become a widely accepted international standard (IEC 61966
-2.1) which is used by most
consumer products (digital cameras, printers, and screens). In practice
, you can
distinguish between linear and gamma-corrected red, green, and blue by
displaying the images: if they look
too dark, they are probably RGB, if they are OK, they are likely sRGB.
(However, there are still a few older
graphics cards and display programs which silently apply an additional
gamma correction to every image,
so that RGB appears correct and sRGB is too bright.) Whether or not the
data are represented
in the sRGB color space can also be seen in the color space tag of an i
mage's EXIF data, if available.
The distinction between RGB and R'G'B' is important because some conver sions start at The distinction between RGB and R'G'B' is important because some conver sions start at
RGB (XYZ, L*a*b*, L*u*v*), while others start at R'G'B' (Y'PbPr, Y'CbCr , Y'IQ, and Y'UV). RGB (XYZ, L*a*b*, L*u*v*), while others start at R'G'B' (Y'PbPr, Y'CbCr , Y'IQ, and Y'UV).
The names of VIGRA's color conversion functors always make clear to whi ch color space The names of VIGRA's color conversion functors always make clear to whi ch color space
they must be applied. they must be applied.
In addition VIGRA provides a <em>polar coordinate interface</em> In addition VIGRA provides a <em>\ref PolarColors "polar coordinate int erface"</em>
to several color spaces (L*a*b*, L*u*v*, Y'PbPr, Y'CbCr, Y'IQ, and Y'UV ). This to several color spaces (L*a*b*, L*u*v*, Y'PbPr, Y'CbCr, Y'IQ, and Y'UV ). This
interface makes use of the fact that these color spaces are conceptuall y similar: interface makes use of the fact that these color spaces are conceptuall y similar:
they represent colors by a "brightness" coordinate (L* or Y') and a pai r of they represent colors by a "brightness" coordinate (L* or Y') and a pai r of
"chromaticity" coordinates that span a plane of colors with equal brigh tness. "chromaticity" coordinates that span a plane of colors with equal brigh tness.
The polar representation transforms chroma coordinates into a color "an gle" The polar representation transforms chroma coordinates into a color "an gle"
(similar to hue in the HSV system) and a "saturation". The polar coordi nates are (similar to hue in the HSV system) and a "saturation". The polar coordi nates are
normalized so that a color angle of 0 degrees is always associated with red normalized so that a color angle of 0 degrees is always associated with red
(green is at about 120 degrees, blue at about 240 degrees - exact value s differ (green is at about 120 degrees, blue at about 240 degrees - exact value s differ
between color spaces). A saturation of 1 is the highest saturation that any RGB color between color spaces). A saturation of 1 is the highest saturation that any RGB color
in the unit cube can have after transformation into the respective colo r space, in the unit cube can have after transformation into the respective colo r space,
and saturation 0 corresponds to gray. Polar coordinates provide a more intuitive and saturation 0 corresponds to gray. Polar coordinates provide a more intuitive
interface to color specification by users and make different color spac es somewhat interface to color specification by users and make different color spac es somewhat
comparable. comparable.
*/ */
namespace vigra { //@{
namespace detail
{
inline double gammaCorrection(double value, double gamma)
{
return (value < 0.0) ?
-VIGRA_CSTD::pow(-value, gamma) :
VIGRA_CSTD::pow(value, gamma);
}
inline double gammaCorrection(double value, double gamma, double norm)
{
return (value < 0.0) ?
-norm*VIGRA_CSTD::pow(-value/norm, gamma) :
norm*VIGRA_CSTD::pow(value/norm, gamma);
}
} // namespace detail
/** \brief Convert linear (raw) RGB into non-linear (gamma corrected) R'G'B '. /** \brief Convert linear (raw) RGB into non-linear (gamma corrected) R'G'B '.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the transformation The functor realizes the transformation
\f[ \f[
R' = R_{max} \left(\frac{R}{R_{max}} \right)^{0.45} \qquad R' = R_{max} \left(\frac{R}{R_{max}} \right)^{0.45} \qquad
G' = G_{max} \left(\frac{G}{G_{max}} \right)^{0.45} \qquad G' = G_{max} \left(\frac{G}{G_{max}} \right)^{0.45} \qquad
B' = B_{max} \left(\frac{B}{B_{max}} \right)^{0.45} B' = B_{max} \left(\frac{B}{B_{max}} \right)^{0.45}
\f] \f]
By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
in the constructor. If both source and target colors components are sto red in the constructor. If both source and target colors components are sto red
as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation. as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class From, class To = From> template <class From, class To = From>
class RGB2RGBPrimeFunctor class RGB2RGBPrimeFunctor
{ {
public: public:
/** the functor's argument type /** the functor's argument type
*/ */
typedef TinyVector<From, 3> argument_type; typedef TinyVector<From, 3> argument_type;
skipping to change at line 355 skipping to change at line 348
}; };
template <class From, class To> template <class From, class To>
class FunctorTraits<RGB2RGBPrimeFunctor<From, To> > class FunctorTraits<RGB2RGBPrimeFunctor<From, To> >
: public FunctorTraitsBase<RGB2RGBPrimeFunctor<From, To> > : public FunctorTraitsBase<RGB2RGBPrimeFunctor<From, To> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert linear (raw) RGB into standardized sRGB.
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co
lorconversions.hxx</a>\><br>
Namespace: vigra
The sRGB color space is a slight improvement over the R'G'B' space. It
is now a widely accepted
international standard (IEC 61966-2.1) which is used by most consumer p
roducts
(digital cameras, printers, and screens). The functor realizes the tran
sformation
\f[
C_{sRGB} = \left\{ \begin{array}{ll}
12.92\,C_{RGB} & \textrm{ if }\frac{C_{RGB}}{C_{max}} \le 0.00304 \
\
C_{max}\left( 1.055 \left(\frac{C_{RGB}}{C_{max}}\right)^{1/2.4}-0.
055\right) & \textrm{ otherwise}
\end{array} \right.
\f]
where C is any of the primaries R, G, and B. By default, \f$ C_{max} =
255 \f$ (this default can be
overridden in the constructor). If both source and target color compone
nts are stored
as <tt>unsigned char</tt>, a look-up-table will be used to speed up the
transformation.
<b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/
template <class From, class To = From>
class RGB2sRGBFunctor
{
public:
/** the functor's argument type
*/
typedef TinyVector<From, 3> argument_type;
/** the functor's result type
*/
typedef RGBValue<To> result_type;
/** \deprecated use argument_type and result_type
*/
typedef RGBValue<To> value_type;
/** the result component's promote type
*/
typedef typename NumericTraits<To>::RealPromote component_type;
/** Default constructor.
The maximum value for each RGB component defaults to 255
*/
RGB2sRGBFunctor()
: max_(255.0)
{}
/** constructor
\arg max - the maximum value for each RGB component
*/
RGB2sRGBFunctor(component_type max)
: max_(max)
{}
/** apply the transformation
*/
template <class V>
result_type operator()(V const & rgb) const
{
return RGBValue<To>(
NumericTraits<To>::fromRealPromote(detail::sRGBCorrection(rgb[0
], max_)),
NumericTraits<To>::fromRealPromote(detail::sRGBCorrection(rgb[1
], max_)),
NumericTraits<To>::fromRealPromote(detail::sRGBCorrection(rgb[2
], max_)));
}
private:
component_type max_;
};
template <>
class RGB2sRGBFunctor<unsigned char, unsigned char>
{
unsigned char lut_[256];
public:
typedef RGBValue<unsigned char> value_type;
RGB2sRGBFunctor()
{
for(int i=0; i<256; ++i)
{
lut_[i] = NumericTraits<unsigned char>::fromRealPromote(detail:
:sRGBCorrection(i, 255.0));
}
}
RGB2sRGBFunctor(double max)
{
for(int i=0; i<256; ++i)
{
lut_[i] = NumericTraits<unsigned char>::fromRealPromote(detail:
:sRGBCorrection(i, max));
}
}
template <class V>
RGBValue<unsigned char> operator()(V const & rgb) const
{
return RGBValue<unsigned char>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb
[2]]);
}
};
template <class From, class To>
class FunctorTraits<RGB2sRGBFunctor<From, To> >
: public FunctorTraitsBase<RGB2sRGBFunctor<From, To> >
{
public:
typedef VigraTrueType isUnaryFunctor;
};
/** \brief Convert non-linear (gamma corrected) R'G'B' into non-linear (raw ) RGB. /** \brief Convert non-linear (gamma corrected) R'G'B' into non-linear (raw ) RGB.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the transformation The functor realizes the transformation
\f[ \f[
R = R_{max} \left(\frac{R'}{R_{max}} \right)^{1/0.45} \qquad R = R_{max} \left(\frac{R'}{R_{max}} \right)^{1/0.45} \qquad
G = G_{max} \left(\frac{G'}{G_{max}} \right)^{1/0.45} \qquad G = G_{max} \left(\frac{G'}{G_{max}} \right)^{1/0.45} \qquad
B = B_{max} \left(\frac{B'}{B_{max}} \right)^{1/0.45} B = B_{max} \left(\frac{B'}{B_{max}} \right)^{1/0.45}
\f] \f]
By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
in the constructor. If both source and target colors components are sto red in the constructor. If both source and target color components are stor ed
as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation. as <tt>unsigned char</tt>, a look-up-table will be used to speed up the transformation.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class From, class To = From> template <class From, class To = From>
class RGBPrime2RGBFunctor class RGBPrime2RGBFunctor
{ {
public: public:
/** the functor's argument type /** the functor's argument type
*/ */
typedef TinyVector<From, 3> argument_type; typedef TinyVector<From, 3> argument_type;
skipping to change at line 466 skipping to change at line 573
}; };
template <class From, class To> template <class From, class To>
class FunctorTraits<RGBPrime2RGBFunctor<From, To> > class FunctorTraits<RGBPrime2RGBFunctor<From, To> >
: public FunctorTraitsBase<RGBPrime2RGBFunctor<From, To> > : public FunctorTraitsBase<RGBPrime2RGBFunctor<From, To> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert standardized sRGB into non-linear (raw) RGB.
<b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co
lorconversions.hxx</a>\><br>
Namespace: vigra
The sRGB color space is a slight improvement over the R'G'B' space. Is
is now a widely accepted
international standard (IEC 61966-2.1) which is used by most consumer p
roducts
(digital cameras, printers, and screens). The functor realizes the tran
sformation
\f[
C_{RGB} = \left\{\begin{array}{ll}
C_{sRGB} / 12.92 & \textrm{if }\frac{C_{sRGB}}{C_{max}} \le 0.03928
\\
C_{max}\left( \frac{C_{sRGB}/C_{max}+0.055}{1.055}\right)^{2.4} & \
textrm{otherwise}
\end{array}\right.
\f]
where C is one of the color channels R, G, or B, and \f$ C_{max}\f$ equ
als 255 by default (This default
can be overridden in the constructor). If both source and target color
components are stored
as <tt>unsigned char</tt>, a look-up-table will be used to speed up the
transformation.
<b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/
template <class From, class To = From>
class sRGB2RGBFunctor
{
public:
/** the functor's argument type
*/
typedef TinyVector<From, 3> argument_type;
/** the functor's result type
*/
typedef RGBValue<To> result_type;
/** \deprecated use argument_type and result_type
*/
typedef RGBValue<To> value_type;
/** the result component's promote type
*/
typedef typename NumericTraits<To>::RealPromote component_type;
/** Default constructor.
The maximum value for each RGB component defaults to 255.
*/
sRGB2RGBFunctor()
: max_(255.0)
{}
/** constructor
\arg max - the maximum value for each RGB component
*/
sRGB2RGBFunctor(component_type max)
: max_(max)
{}
/** apply the transformation
*/
result_type operator()(argument_type const & rgb) const
{
return RGBValue<To>(
NumericTraits<To>::fromRealPromote(detail::inverse_sRGBCorrecti
on(rgb[0], max_)),
NumericTraits<To>::fromRealPromote(detail::inverse_sRGBCorrecti
on(rgb[1], max_)),
NumericTraits<To>::fromRealPromote(detail::inverse_sRGBCorrecti
on(rgb[2], max_)));
}
private:
component_type max_;
};
template <>
class sRGB2RGBFunctor<unsigned char, unsigned char>
{
unsigned char lut_[256];
public:
typedef RGBValue<unsigned char> value_type;
sRGB2RGBFunctor()
{
for(int i=0; i<256; ++i)
{
lut_[i] = NumericTraits<unsigned char>::fromRealPromote(detail:
:inverse_sRGBCorrection(i, 255.0));
}
}
sRGB2RGBFunctor(double max)
{
for(int i=0; i<256; ++i)
{
lut_[i] = NumericTraits<unsigned char>::fromRealPromote(detail:
:inverse_sRGBCorrection(i, max));
}
}
template <class V>
RGBValue<unsigned char> operator()(V const & rgb) const
{
return RGBValue<unsigned char>(lut_[rgb[0]], lut_[rgb[1]], lut_[rgb
[2]]);
}
};
template <class From, class To>
class FunctorTraits<sRGB2RGBFunctor<From, To> >
: public FunctorTraitsBase<sRGB2RGBFunctor<From, To> >
{
public:
typedef VigraTrueType isUnaryFunctor;
};
/** \brief Convert linear (raw) RGB into standardized tri-stimulus XYZ. /** \brief Convert linear (raw) RGB into standardized tri-stimulus XYZ.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
According to ITU-R Recommendation BT.709, the functor realizes the tran sformation According to ITU-R Recommendation BT.709, the functor realizes the tran sformation
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
X & = & 0.412453\enspace R / R_{max} + 0.357580\enspace G / G_{max} + 0.180423\enspace B / B_{max}\\ X & = & 0.412453\enspace R / R_{max} + 0.357580\enspace G / G_{max} + 0.180423\enspace B / B_{max}\\
Y & = & 0.212671\enspace R / R_{max} + 0.715160\enspace G / G_{max} + 0.072169\enspace B / B_{max} \\ Y & = & 0.212671\enspace R / R_{max} + 0.715160\enspace G / G_{max} + 0.072169\enspace B / B_{max} \\
Z & = & 0.019334\enspace R / R_{max} + 0.119193\enspace G / G_{max} + 0.950227\enspace B / B_{max} Z & = & 0.019334\enspace R / R_{max} + 0.119193\enspace G / G_{max} + 0.950227\enspace B / B_{max}
\end{array} \end{array}
\f] \f]
By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
in the constructor. X, Y, and Z are always positive and reach their max imum for white. in the constructor. X, Y, and Z are always positive and reach their max imum for white.
The white point is obtained by transforming RGB(255, 255, 255). It corr esponds to the The white point is obtained by transforming RGB(255, 255, 255). It corr esponds to the
D65 illuminant. Y represents the <em>luminance</em> ("brightness") of t he color. D65 illuminant. Y represents the <em>luminance</em> ("brightness") of t he color.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class RGB2XYZFunctor class RGB2XYZFunctor
{ {
public: public:
/** the result's component type /** the result's component type
*/ */
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
skipping to change at line 553 skipping to change at line 773
template <class T> template <class T>
class FunctorTraits<RGB2XYZFunctor<T> > class FunctorTraits<RGB2XYZFunctor<T> >
: public FunctorTraitsBase<RGB2XYZFunctor<T> > : public FunctorTraitsBase<RGB2XYZFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert non-linear (gamma corrected) R'G'B' into standardized tr i-stimulus XYZ. /** \brief Convert non-linear (gamma corrected) R'G'B' into standardized tr i-stimulus XYZ.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the transformation The functor realizes the transformation
\f[ \f[
R'G'B' \Rightarrow RGB \Rightarrow XYZ R'G'B' \Rightarrow RGB \Rightarrow XYZ
\f] \f]
See vigra::RGBPrime2RGBFunctor and vigra::RGB2XYZFunctor for a descript ion of the two See vigra::RGBPrime2RGBFunctor and vigra::RGB2XYZFunctor for a descript ion of the two
steps. steps.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class RGBPrime2XYZFunctor class RGBPrime2XYZFunctor
{ {
public: public:
/** the result's component type /** the result's component type
*/ */
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
skipping to change at line 632 skipping to change at line 852
template <class T> template <class T>
class FunctorTraits<RGBPrime2XYZFunctor<T> > class FunctorTraits<RGBPrime2XYZFunctor<T> >
: public FunctorTraitsBase<RGBPrime2XYZFunctor<T> > : public FunctorTraitsBase<RGBPrime2XYZFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert standardized tri-stimulus XYZ into linear (raw) RGB. /** \brief Convert standardized tri-stimulus XYZ into linear (raw) RGB.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
According to ITU-R Recommendation BT.709, the functor realizes the tran sformation According to ITU-R Recommendation BT.709, the functor realizes the tran sformation
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
R & = & R_{max} (3.2404813432\enspace X - 1.5371515163\enspace Y - 0.4985363262\enspace Z) \\ R & = & R_{max} (3.2404813432\enspace X - 1.5371515163\enspace Y - 0.4985363262\enspace Z) \\
G & = & G_{max} (-0.9692549500\enspace X + 1.8759900015\enspace Y + 0.0415559266\enspace Z) \\ G & = & G_{max} (-0.9692549500\enspace X + 1.8759900015\enspace Y + 0.0415559266\enspace Z) \\
B & = & B_{max} (0.0556466391\enspace X - 0.2040413384\enspace Y + 1.0573110696\enspace Z) B & = & B_{max} (0.0556466391\enspace X - 0.2040413384\enspace Y + 1.0573110696\enspace Z)
\end{array} \end{array}
\f] \f]
By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden By default, \f$ R_{max} = G_{max} = B_{max} = 255 \f$. This default can be overridden
in the constructor. This is the inverse transform of vigra::RGB2XYZFunc tor. in the constructor. This is the inverse transform of vigra::RGB2XYZFunc tor.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class XYZ2RGBFunctor class XYZ2RGBFunctor
{ {
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
component_type max_; component_type max_;
public: public:
/** the functor's argument type. (Actually, the argument type /** the functor's argument type. (Actually, the argument type
skipping to change at line 712 skipping to change at line 932
template <class T> template <class T>
class FunctorTraits<XYZ2RGBFunctor<T> > class FunctorTraits<XYZ2RGBFunctor<T> >
: public FunctorTraitsBase<XYZ2RGBFunctor<T> > : public FunctorTraitsBase<XYZ2RGBFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert standardized tri-stimulus XYZ into non-linear (gamma cor rected) R'G'B'. /** \brief Convert standardized tri-stimulus XYZ into non-linear (gamma cor rected) R'G'B'.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the transformation The functor realizes the transformation
\f[ \f[
XYZ \Rightarrow RGB \Rightarrow R'G'B' XYZ \Rightarrow RGB \Rightarrow R'G'B'
\f] \f]
See vigra::XYZ2RGBFunctor and vigra::RGB2RGBPrimeFunctor for a descript ion of the two See vigra::XYZ2RGBFunctor and vigra::RGB2RGBPrimeFunctor for a descript ion of the two
steps. steps.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class XYZ2RGBPrimeFunctor class XYZ2RGBPrimeFunctor
{ {
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
component_type max_, gamma_; component_type max_, gamma_;
public: public:
skipping to change at line 790 skipping to change at line 1010
template <class T> template <class T>
class FunctorTraits<XYZ2RGBPrimeFunctor<T> > class FunctorTraits<XYZ2RGBPrimeFunctor<T> >
: public FunctorTraitsBase<XYZ2RGBPrimeFunctor<T> > : public FunctorTraitsBase<XYZ2RGBPrimeFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CI E L*u*v*. /** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CI E L*u*v*.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the transformation The functor realizes the transformation
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \ mbox{if} \quad 0.008856 < \frac{Y}{Y_n}\\ L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \ mbox{if} \quad 0.008856 < \frac{Y}{Y_n}\\
& & \\ & & \\
L^{*} & = & 903.3\enspace \frac{Y}{Y_n} \quad \mbox{otherwise} \\ L^{*} & = & 903.3\enspace \frac{Y}{Y_n} \quad \mbox{otherwise} \\
& & \\ & & \\
skipping to change at line 817 skipping to change at line 1037
\f] \f]
where \f$(X_n, Y_n, Z_n)\f$ is the reference white point, and where \f$(X_n, Y_n, Z_n)\f$ is the reference white point, and
\f$u_n' = 0.197839, v_n'=0.468342\f$ are the quantities \f$u', v'\f$ ca lculated for this \f$u_n' = 0.197839, v_n'=0.468342\f$ are the quantities \f$u', v'\f$ ca lculated for this
point. \f$L^{*}\f$ represents the point. \f$L^{*}\f$ represents the
<em>lighness</em> ("brightness") of the color, and \f$u^{*}, v^{*}\f$ c ode the <em>lighness</em> ("brightness") of the color, and \f$u^{*}, v^{*}\f$ c ode the
chromaticity. chromaticity.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class XYZ2LuvFunctor class XYZ2LuvFunctor
{ {
public: public:
/** the result's component type /** the result's component type
*/ */
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
skipping to change at line 883 skipping to change at line 1103
template <class T> template <class T>
class FunctorTraits<XYZ2LuvFunctor<T> > class FunctorTraits<XYZ2LuvFunctor<T> >
: public FunctorTraitsBase<XYZ2LuvFunctor<T> > : public FunctorTraitsBase<XYZ2LuvFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert perceptual uniform CIE L*u*v* into standardized tri-stim ulus XYZ. /** \brief Convert perceptual uniform CIE L*u*v* into standardized tri-stim ulus XYZ.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the inverse of the transformation described in vig ra::XYZ2LuvFunctor The functor realizes the inverse of the transformation described in vig ra::XYZ2LuvFunctor
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class Luv2XYZFunctor class Luv2XYZFunctor
{ {
public: public:
/** the result's component type /** the result's component type
*/ */
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
skipping to change at line 957 skipping to change at line 1177
template <class T> template <class T>
class FunctorTraits<Luv2XYZFunctor<T> > class FunctorTraits<Luv2XYZFunctor<T> >
: public FunctorTraitsBase<Luv2XYZFunctor<T> > : public FunctorTraitsBase<Luv2XYZFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CI E L*a*b*. /** \brief Convert standardized tri-stimulus XYZ into perceptual uniform CI E L*a*b*.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the transformation The functor realizes the transformation
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \ mbox{if} \quad 0.008856 < \frac{Y}{Y_n}\\ L^{*} & = & 116 \left( \frac{Y}{Y_n} \right)^\frac{1}{3}-16 \quad \ mbox{if} \quad 0.008856 < \frac{Y}{Y_n}\\
& & \\ & & \\
L^{*} & = & 903.3\enspace \frac{Y}{Y_n} \quad \mbox{otherwise} \\ L^{*} & = & 903.3\enspace \frac{Y}{Y_n} \quad \mbox{otherwise} \\
& & \\ & & \\
skipping to change at line 980 skipping to change at line 1200
b^{*} & = & 200 \left[ \left( \frac{Y}{Y_n} \right)^\frac{1}{3} - \ left( \frac{Z}{Z_n} \right)^\frac{1}{3} \right] \\ b^{*} & = & 200 \left[ \left( \frac{Y}{Y_n} \right)^\frac{1}{3} - \ left( \frac{Z}{Z_n} \right)^\frac{1}{3} \right] \\
\end{array} \end{array}
\f] \f]
where \f$(X_n, Y_n, Z_n)\f$ is the reference white point. \f$L^{*}\f$ r epresents the where \f$(X_n, Y_n, Z_n)\f$ is the reference white point. \f$L^{*}\f$ r epresents the
<em>lighness</em> ("brightness") of the color, and \f$a^{*}, b^{*}\f$ c ode the <em>lighness</em> ("brightness") of the color, and \f$a^{*}, b^{*}\f$ c ode the
chromaticity. chromaticity.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class XYZ2LabFunctor class XYZ2LabFunctor
{ {
public: public:
/** the result's component type /** the result's component type
*/ */
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
skipping to change at line 1039 skipping to change at line 1259
template <class T> template <class T>
class FunctorTraits<XYZ2LabFunctor<T> > class FunctorTraits<XYZ2LabFunctor<T> >
: public FunctorTraitsBase<XYZ2LabFunctor<T> > : public FunctorTraitsBase<XYZ2LabFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert perceptual uniform CIE L*a*b* into standardized tri-stim ulus XYZ. /** \brief Convert perceptual uniform CIE L*a*b* into standardized tri-stim ulus XYZ.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the inverse of the transformation described in vig ra::XYZ2LabFunctor The functor realizes the inverse of the transformation described in vig ra::XYZ2LabFunctor
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class Lab2XYZFunctor class Lab2XYZFunctor
{ {
public: public:
/** the result's component type /** the result's component type
*/ */
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
skipping to change at line 1107 skipping to change at line 1327
template <class T> template <class T>
class FunctorTraits<Lab2XYZFunctor<T> > class FunctorTraits<Lab2XYZFunctor<T> >
: public FunctorTraitsBase<Lab2XYZFunctor<T> > : public FunctorTraitsBase<Lab2XYZFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert linear (raw) RGB into perceptual uniform CIE L*u*v*. /** \brief Convert linear (raw) RGB into perceptual uniform CIE L*u*v*.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the transformation The functor realizes the transformation
\f[ \f[
RGB \Rightarrow XYZ \Rightarrow L^*u^*v^* RGB \Rightarrow XYZ \Rightarrow L^*u^*v^*
\f] \f]
See vigra::RGB2XYZFunctor and vigra::XYZ2LuvFunctor for a description o f the two See vigra::RGB2XYZFunctor and vigra::XYZ2LuvFunctor for a description o f the two
steps. The resulting color components will have the following bounds: steps. The resulting color components will have the following bounds:
skipping to change at line 1129 skipping to change at line 1349
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
0 \leq & L^* & \leq 100 \\ 0 \leq & L^* & \leq 100 \\
-83.077 \leq & u^* & \leq 175.015 \\ -83.077 \leq & u^* & \leq 175.015 \\
-134.101 \leq & v^* & \leq 107.393 -134.101 \leq & v^* & \leq 107.393
\end{array} \end{array}
\f] \f]
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class RGB2LuvFunctor class RGB2LuvFunctor
{ {
/* /*
L in [0, 100] L in [0, 100]
u in [-83.077, 175.015] u in [-83.077, 175.015]
v in [-134.101, 107.393] v in [-134.101, 107.393]
maximum saturation: 179.04 maximum saturation: 179.04
red = [53.2406, 175.015, 37.7522] red = [53.2406, 175.015, 37.7522]
skipping to change at line 1196 skipping to change at line 1416
template <class T> template <class T>
class FunctorTraits<RGB2LuvFunctor<T> > class FunctorTraits<RGB2LuvFunctor<T> >
: public FunctorTraitsBase<RGB2LuvFunctor<T> > : public FunctorTraitsBase<RGB2LuvFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert linear (raw) RGB into perceptual uniform CIE L*a*b*. /** \brief Convert linear (raw) RGB into perceptual uniform CIE L*a*b*.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the transformation The functor realizes the transformation
\f[ \f[
RGB \Rightarrow XYZ \Rightarrow L^*a^*b^* RGB \Rightarrow XYZ \Rightarrow L^*a^*b^*
\f] \f]
See vigra::RGB2XYZFunctor and vigra::XYZ2LabFunctor for a description o f the two See vigra::RGB2XYZFunctor and vigra::XYZ2LabFunctor for a description o f the two
steps. The resulting color components will have the following bounds: steps. The resulting color components will have the following bounds:
skipping to change at line 1218 skipping to change at line 1438
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
0 \leq & L^* & \leq 100 \\ 0 \leq & L^* & \leq 100 \\
-86.1813 \leq & u^* & \leq 98.2352 \\ -86.1813 \leq & u^* & \leq 98.2352 \\
-107.862 \leq & v^* & \leq 94.4758 -107.862 \leq & v^* & \leq 94.4758
\end{array} \end{array}
\f] \f]
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class RGB2LabFunctor class RGB2LabFunctor
{ {
/* /*
L in [0, 100] L in [0, 100]
a in [-86.1813, 98.2352] a in [-86.1813, 98.2352]
b in [-107.862, 94.4758] b in [-107.862, 94.4758]
maximum saturation: 133.809 maximum saturation: 133.809
red = [53.2406, 80.0942, 67.2015] red = [53.2406, 80.0942, 67.2015]
skipping to change at line 1285 skipping to change at line 1505
template <class T> template <class T>
class FunctorTraits<RGB2LabFunctor<T> > class FunctorTraits<RGB2LabFunctor<T> >
: public FunctorTraitsBase<RGB2LabFunctor<T> > : public FunctorTraitsBase<RGB2LabFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert perceptual uniform CIE L*u*v* into linear (raw) RGB. /** \brief Convert perceptual uniform CIE L*u*v* into linear (raw) RGB.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the inverse of the transformation described in vig ra::RGB2LuvFunctor The functor realizes the inverse of the transformation described in vig ra::RGB2LuvFunctor
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class Luv2RGBFunctor class Luv2RGBFunctor
{ {
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
XYZ2RGBFunctor<T> xyz2rgb; XYZ2RGBFunctor<T> xyz2rgb;
Luv2XYZFunctor<component_type> luv2xyz; Luv2XYZFunctor<component_type> luv2xyz;
public: public:
skipping to change at line 1344 skipping to change at line 1564
template <class T> template <class T>
class FunctorTraits<Luv2RGBFunctor<T> > class FunctorTraits<Luv2RGBFunctor<T> >
: public FunctorTraitsBase<Luv2RGBFunctor<T> > : public FunctorTraitsBase<Luv2RGBFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert perceptual uniform CIE L*a*b* into linear (raw) RGB. /** \brief Convert perceptual uniform CIE L*a*b* into linear (raw) RGB.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the inverse of the transformation described in vig ra::RGB2LabFunctor The functor realizes the inverse of the transformation described in vig ra::RGB2LabFunctor
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class Lab2RGBFunctor class Lab2RGBFunctor
{ {
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
XYZ2RGBFunctor<T> xyz2rgb; XYZ2RGBFunctor<T> xyz2rgb;
Lab2XYZFunctor<component_type> lab2xyz; Lab2XYZFunctor<component_type> lab2xyz;
public: public:
skipping to change at line 1410 skipping to change at line 1630
template <class T> template <class T>
class FunctorTraits<Lab2RGBFunctor<T> > class FunctorTraits<Lab2RGBFunctor<T> >
: public FunctorTraitsBase<Lab2RGBFunctor<T> > : public FunctorTraitsBase<Lab2RGBFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual unif orm CIE L*u*v*. /** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual unif orm CIE L*u*v*.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the transformation The functor realizes the transformation
\f[ \f[
R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*u^*v^* R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*u^*v^*
\f] \f]
See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2Lu vFunctor for a description of the three See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2Lu vFunctor for a description of the three
steps. The resulting color components will have the following bounds: steps. The resulting color components will have the following bounds:
skipping to change at line 1432 skipping to change at line 1652
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
0 \leq & L^* & \leq 100 \\ 0 \leq & L^* & \leq 100 \\
-83.077 \leq & u^* & \leq 175.015 \\ -83.077 \leq & u^* & \leq 175.015 \\
-134.101 \leq & v^* & \leq 107.393 -134.101 \leq & v^* & \leq 107.393
\end{array} \end{array}
\f] \f]
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class RGBPrime2LuvFunctor class RGBPrime2LuvFunctor
{ {
public: public:
/** the result's component type /** the result's component type
*/ */
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
skipping to change at line 1492 skipping to change at line 1712
template <class T> template <class T>
class FunctorTraits<RGBPrime2LuvFunctor<T> > class FunctorTraits<RGBPrime2LuvFunctor<T> >
: public FunctorTraitsBase<RGBPrime2LuvFunctor<T> > : public FunctorTraitsBase<RGBPrime2LuvFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual unif orm CIE L*a*b*. /** \brief Convert non-linear (gamma corrected) R'G'B' into perceptual unif orm CIE L*a*b*.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the transformation The functor realizes the transformation
\f[ \f[
R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*a^*b^* R'G'B' \Rightarrow RGB \Rightarrow XYZ \Rightarrow L^*a^*b^*
\f] \f]
See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2La bFunctor for a description of the three See vigra::RGBPrime2RGBFunctor, vigra::RGB2XYZFunctor and vigra::XYZ2La bFunctor for a description of the three
steps. The resulting color components will have the following bounds: steps. The resulting color components will have the following bounds:
skipping to change at line 1514 skipping to change at line 1734
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
0 \leq & L^* & \leq 100 \\ 0 \leq & L^* & \leq 100 \\
-86.1813 \leq & u^* & \leq 98.2352 \\ -86.1813 \leq & u^* & \leq 98.2352 \\
-107.862 \leq & v^* & \leq 94.4758 -107.862 \leq & v^* & \leq 94.4758
\end{array} \end{array}
\f] \f]
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class RGBPrime2LabFunctor class RGBPrime2LabFunctor
{ {
public: public:
/** the result's component type /** the result's component type
*/ */
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
skipping to change at line 1574 skipping to change at line 1794
template <class T> template <class T>
class FunctorTraits<RGBPrime2LabFunctor<T> > class FunctorTraits<RGBPrime2LabFunctor<T> >
: public FunctorTraitsBase<RGBPrime2LabFunctor<T> > : public FunctorTraitsBase<RGBPrime2LabFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert perceptual uniform CIE L*u*v* into non-linear (gamma cor rected) R'G'B'. /** \brief Convert perceptual uniform CIE L*u*v* into non-linear (gamma cor rected) R'G'B'.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the inverse of the transformation described in vig ra::RGBPrime2LuvFunctor The functor realizes the inverse of the transformation described in vig ra::RGBPrime2LuvFunctor
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class Luv2RGBPrimeFunctor class Luv2RGBPrimeFunctor
{ {
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
XYZ2RGBPrimeFunctor<T> xyz2rgb; XYZ2RGBPrimeFunctor<T> xyz2rgb;
Luv2XYZFunctor<component_type> luv2xyz; Luv2XYZFunctor<component_type> luv2xyz;
public: public:
skipping to change at line 1640 skipping to change at line 1860
template <class T> template <class T>
class FunctorTraits<Luv2RGBPrimeFunctor<T> > class FunctorTraits<Luv2RGBPrimeFunctor<T> >
: public FunctorTraitsBase<Luv2RGBPrimeFunctor<T> > : public FunctorTraitsBase<Luv2RGBPrimeFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert perceptual uniform CIE L*a*b* into non-linear (gamma cor rected) R'G'B'. /** \brief Convert perceptual uniform CIE L*a*b* into non-linear (gamma cor rected) R'G'B'.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the inverse of the transformation described in vig ra::RGBPrime2LabFunctor The functor realizes the inverse of the transformation described in vig ra::RGBPrime2LabFunctor
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class Lab2RGBPrimeFunctor class Lab2RGBPrimeFunctor
{ {
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
XYZ2RGBPrimeFunctor<T> xyz2rgb; XYZ2RGBPrimeFunctor<T> xyz2rgb;
Lab2XYZFunctor<component_type> lab2xyz; Lab2XYZFunctor<component_type> lab2xyz;
public: public:
skipping to change at line 1706 skipping to change at line 1926
template <class T> template <class T>
class FunctorTraits<Lab2RGBPrimeFunctor<T> > class FunctorTraits<Lab2RGBPrimeFunctor<T> >
: public FunctorTraitsBase<Lab2RGBPrimeFunctor<T> > : public FunctorTraitsBase<Lab2RGBPrimeFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert non-linear (gamma corrected) R'G'B' into Y'PbPr color di fference components. /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'PbPr color di fference components.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
According to ITU-R Recommendation BT.601, the functor realizes the tran sformation According to ITU-R Recommendation BT.601, the functor realizes the tran sformation
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0. 114\enspace B / B_{max}\\ Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0. 114\enspace B / B_{max}\\
Pb & = & -0.1687358916\enspace R / R_{max} + 0.3312641084\enspace G / G_{max} + 0.5\enspace B / B_{max} \\ Pb & = & -0.1687358916\enspace R / R_{max} + 0.3312641084\enspace G / G_{max} + 0.5\enspace B / B_{max} \\
Pr & = & 0.5\enspace R / R_{max} + 0.4186875892\enspace G / G_{max} + 0.0813124108\enspace B / B_{max} Pr & = & 0.5\enspace R / R_{max} + 0.4186875892\enspace G / G_{max} + 0.0813124108\enspace B / B_{max}
\end{array} \end{array}
skipping to change at line 1734 skipping to change at line 1954
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
0 \leq & Y' & \leq 1 \\ 0 \leq & Y' & \leq 1 \\
-0.5 \leq & Pb & \leq 0.5 \\ -0.5 \leq & Pb & \leq 0.5 \\
-0.5 \leq & Pr & \leq 0.5 -0.5 \leq & Pr & \leq 0.5
\end{array} \end{array}
\f] \f]
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class RGBPrime2YPrimePbPrFunctor class RGBPrime2YPrimePbPrFunctor
{ {
/* /*
Y in [0, 1] Y in [0, 1]
Pb in [-0.5, 0.5] Pb in [-0.5, 0.5]
Pr in [-0.5, 0.5] Pr in [-0.5, 0.5]
maximum saturation: 0.533887 maximum saturation: 0.533887
red = [0.299, -0.168736, 0.5] red = [0.299, -0.168736, 0.5]
skipping to change at line 1808 skipping to change at line 2028
template <class T> template <class T>
class FunctorTraits<RGBPrime2YPrimePbPrFunctor<T> > class FunctorTraits<RGBPrime2YPrimePbPrFunctor<T> >
: public FunctorTraitsBase<RGBPrime2YPrimePbPrFunctor<T> > : public FunctorTraitsBase<RGBPrime2YPrimePbPrFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert Y'PbPr color difference components into non-linear (gamm a corrected) R'G'B'. /** \brief Convert Y'PbPr color difference components into non-linear (gamm a corrected) R'G'B'.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the inverse of the transformation described in vig ra::RGBPrime2YPrimePbPrFunctor The functor realizes the inverse of the transformation described in vig ra::RGBPrime2YPrimePbPrFunctor
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class YPrimePbPr2RGBPrimeFunctor class YPrimePbPr2RGBPrimeFunctor
{ {
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
component_type max_; component_type max_;
public: public:
skipping to change at line 1878 skipping to change at line 2098
template <class T> template <class T>
class FunctorTraits<YPrimePbPr2RGBPrimeFunctor<T> > class FunctorTraits<YPrimePbPr2RGBPrimeFunctor<T> >
: public FunctorTraitsBase<YPrimePbPr2RGBPrimeFunctor<T> > : public FunctorTraitsBase<YPrimePbPr2RGBPrimeFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert non-linear (gamma corrected) R'G'B' into Y'IQ components . /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'IQ components .
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
According to the PAL analog videa standard, the functor realizes the tr ansformation According to the PAL analog videa standard, the functor realizes the tr ansformation
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0. 114\enspace B / B_{max}\\ Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0. 114\enspace B / B_{max}\\
I & = & 0.596\enspace R / R_{max} - 0.274\enspace G / G_{max} - 0.3 22\enspace B / B_{max} \\ I & = & 0.596\enspace R / R_{max} - 0.274\enspace G / G_{max} - 0.3 22\enspace B / B_{max} \\
Q & = & 0.212\enspace R / R_{max} - 0.523\enspace G / G_{max} + 0.3 11\enspace B / B_{max} Q & = & 0.212\enspace R / R_{max} - 0.523\enspace G / G_{max} + 0.3 11\enspace B / B_{max}
\end{array} \end{array}
skipping to change at line 1905 skipping to change at line 2125
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
0 \leq & Y' & \leq 1 \\ 0 \leq & Y' & \leq 1 \\
-0.596 \leq & I & \leq 0.596 \\ -0.596 \leq & I & \leq 0.596 \\
-0.523 \leq & Q & \leq 0.523 -0.523 \leq & Q & \leq 0.523
\end{array} \end{array}
\f] \f]
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class RGBPrime2YPrimeIQFunctor class RGBPrime2YPrimeIQFunctor
{ {
/* /*
Y in [0, 1] Y in [0, 1]
I in [-0.596, 0.596] I in [-0.596, 0.596]
Q in [-0.523, 0.523] Q in [-0.523, 0.523]
maximum saturation: 0.632582 maximum saturation: 0.632582
red = [0.299, 0.596, 0.212] red = [0.299, 0.596, 0.212]
skipping to change at line 1979 skipping to change at line 2199
template <class T> template <class T>
class FunctorTraits<RGBPrime2YPrimeIQFunctor<T> > class FunctorTraits<RGBPrime2YPrimeIQFunctor<T> >
: public FunctorTraitsBase<RGBPrime2YPrimeIQFunctor<T> > : public FunctorTraitsBase<RGBPrime2YPrimeIQFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert Y'IQ color components into non-linear (gamma corrected) R'G'B'. /** \brief Convert Y'IQ color components into non-linear (gamma corrected) R'G'B'.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the inverse of the transformation described in vig ra::RGBPrime2YPrimeIQFunctor The functor realizes the inverse of the transformation described in vig ra::RGBPrime2YPrimeIQFunctor
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class YPrimeIQ2RGBPrimeFunctor class YPrimeIQ2RGBPrimeFunctor
{ {
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
component_type max_; component_type max_;
public: public:
skipping to change at line 2049 skipping to change at line 2269
template <class T> template <class T>
class FunctorTraits<YPrimeIQ2RGBPrimeFunctor<T> > class FunctorTraits<YPrimeIQ2RGBPrimeFunctor<T> >
: public FunctorTraitsBase<YPrimeIQ2RGBPrimeFunctor<T> > : public FunctorTraitsBase<YPrimeIQ2RGBPrimeFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert non-linear (gamma corrected) R'G'B' into Y'UV components . /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'UV components .
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
According to the NTSC analog videa standard, the functor realizes the t ransformation According to the NTSC analog videa standard, the functor realizes the t ransformation
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0. 114\enspace B / B_{max}\\ Y' & = & 0.299\enspace R / R_{max} + 0.587\enspace G / G_{max} + 0. 114\enspace B / B_{max}\\
U & = & -0.147\enspace R / R_{max} - 0.289\enspace G / G_{max} + 0. 436\enspace B / B_{max} \\ U & = & -0.147\enspace R / R_{max} - 0.289\enspace G / G_{max} + 0. 436\enspace B / B_{max} \\
V & = & 0.615\enspace R / R_{max} - 0.515\enspace G / G_{max} - 0.1 00\enspace B / B_{max} V & = & 0.615\enspace R / R_{max} - 0.515\enspace G / G_{max} - 0.1 00\enspace B / B_{max}
\end{array} \end{array}
skipping to change at line 2076 skipping to change at line 2296
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
0 \leq & Y' & \leq 1 \\ 0 \leq & Y' & \leq 1 \\
-0.436 \leq & U & \leq 0.436 \\ -0.436 \leq & U & \leq 0.436 \\
-0.615 \leq & V & \leq 0.615 -0.615 \leq & V & \leq 0.615
\end{array} \end{array}
\f] \f]
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class RGBPrime2YPrimeUVFunctor class RGBPrime2YPrimeUVFunctor
{ {
/* /*
Y in [0, 1] Y in [0, 1]
U in [-0.436, 0.436] U in [-0.436, 0.436]
V in [-0.615, 0.615] V in [-0.615, 0.615]
maximum saturation: 0.632324 maximum saturation: 0.632324
red = [0.299, -0.147, 0.615] red = [0.299, -0.147, 0.615]
skipping to change at line 2150 skipping to change at line 2370
template <class T> template <class T>
class FunctorTraits<RGBPrime2YPrimeUVFunctor<T> > class FunctorTraits<RGBPrime2YPrimeUVFunctor<T> >
: public FunctorTraitsBase<RGBPrime2YPrimeUVFunctor<T> > : public FunctorTraitsBase<RGBPrime2YPrimeUVFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert Y'UV color components into non-linear (gamma corrected) R'G'B'. /** \brief Convert Y'UV color components into non-linear (gamma corrected) R'G'B'.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the inverse of the transformation described in vig ra::RGBPrime2YPrimeUVFunctor The functor realizes the inverse of the transformation described in vig ra::RGBPrime2YPrimeUVFunctor
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class YPrimeUV2RGBPrimeFunctor class YPrimeUV2RGBPrimeFunctor
{ {
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
component_type max_; component_type max_;
public: public:
skipping to change at line 2220 skipping to change at line 2440
template <class T> template <class T>
class FunctorTraits<YPrimeUV2RGBPrimeFunctor<T> > class FunctorTraits<YPrimeUV2RGBPrimeFunctor<T> >
: public FunctorTraitsBase<YPrimeUV2RGBPrimeFunctor<T> > : public FunctorTraitsBase<YPrimeUV2RGBPrimeFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert non-linear (gamma corrected) R'G'B' into Y'CbCr color di fference components. /** \brief Convert non-linear (gamma corrected) R'G'B' into Y'CbCr color di fference components.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
This functor basically applies the same transformation as vigra::RGBPri me2YPrimePbPrFunctor This functor basically applies the same transformation as vigra::RGBPri me2YPrimePbPrFunctor
but the color components are scaled so that they can be coded as 8 bit intergers with but the color components are scaled so that they can be coded as 8 bit intergers with
minimal loss of information: minimal loss of information:
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
16\leq & Y' & \leq 235 \\ 16\leq & Y' & \leq 235 \\
16 \leq & Cb & \leq 240 \\ 16 \leq & Cb & \leq 240 \\
16 \leq & Cr & \leq 240 16 \leq & Cr & \leq 240
\end{array} \end{array}
\f] \f]
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class RGBPrime2YPrimeCbCrFunctor class RGBPrime2YPrimeCbCrFunctor
{ {
/* /*
Y in [16, 235] Y in [16, 235]
Cb in [16, 240] Cb in [16, 240]
Cr in [16, 240] Cr in [16, 240]
maximum saturation: 119.591 maximum saturation: 119.591
red = [81.481, 90.203, 240] red = [81.481, 90.203, 240]
skipping to change at line 2311 skipping to change at line 2531
template <class T> template <class T>
class FunctorTraits<RGBPrime2YPrimeCbCrFunctor<T> > class FunctorTraits<RGBPrime2YPrimeCbCrFunctor<T> >
: public FunctorTraitsBase<RGBPrime2YPrimeCbCrFunctor<T> > : public FunctorTraitsBase<RGBPrime2YPrimeCbCrFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
/** \brief Convert Y'CbCr color difference components into non-linear (gamm a corrected) R'G'B'. /** \brief Convert Y'CbCr color difference components into non-linear (gamm a corrected) R'G'B'.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
The functor realizes the inverse of the transformation described in vig ra::RGBPrime2YPrimeCbCrFunctor The functor realizes the inverse of the transformation described in vig ra::RGBPrime2YPrimeCbCrFunctor
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
*/ */
template <class T> template <class T>
class YPrimeCbCr2RGBPrimeFunctor class YPrimeCbCr2RGBPrimeFunctor
{ {
typedef typename NumericTraits<T>::RealPromote component_type; typedef typename NumericTraits<T>::RealPromote component_type;
component_type max_; component_type max_;
public: public:
skipping to change at line 2383 skipping to change at line 2603
}; };
template <class T> template <class T>
class FunctorTraits<YPrimeCbCr2RGBPrimeFunctor<T> > class FunctorTraits<YPrimeCbCr2RGBPrimeFunctor<T> >
: public FunctorTraitsBase<YPrimeCbCr2RGBPrimeFunctor<T> > : public FunctorTraitsBase<YPrimeCbCr2RGBPrimeFunctor<T> >
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
//@}
/* /*
Polar coordinates of standard colors: Polar coordinates of standard colors:
===================================== =====================================
Lab: black = [320.002, 0, 0] Lab: black = [320.002, 0, 0]
Luv: black = [347.827, 0, 0] Luv: black = [347.827, 0, 0]
YPbPr: black = [341.352, 0, 0] YPbPr: black = [341.352, 0, 0]
YCbCr: black = [341.352, 0, 0] YCbCr: black = [341.352, 0, 0]
YIQ: black = [19.5807, 0, 0] YIQ: black = [19.5807, 0, 0]
YUV: black = [346.557, 0, 0] YUV: black = [346.557, 0, 0]
skipping to change at line 2438 skipping to change at line 2660
YUV: cyan = [180, 0.701, 1] YUV: cyan = [180, 0.701, 1]
Lab: white = [320.002, 1, 0] Lab: white = [320.002, 1, 0]
Luv: white = [14.3606, 1, 3.26357e-06] Luv: white = [14.3606, 1, 3.26357e-06]
YPbPr: white = [341.352, 1, 0] YPbPr: white = [341.352, 1, 0]
YCbCr: white = [341.352, 1, 0] YCbCr: white = [341.352, 1, 0]
YIQ: white = [154.581, 1, 1.24102e-16] YIQ: white = [154.581, 1, 1.24102e-16]
YUV: white = [229.992, 1, 9.81512e-17] YUV: white = [229.992, 1, 9.81512e-17]
*/ */
/** \addtogroup PolarColors Polar Color Coordinates /** \ingroup ColorConversions
\defgroup PolarColors Polar Color Coordinates
Transform colors from/to a polar representation (hue, brighness, satura tion). Transform colors from/to a polar representation (hue, brighness, satura tion).
In many situations, this is more inituitive than direct initialization in a In many situations, this is more inituitive than direct initialization in a
particular color space. The polar coordinates are particular color space. The polar coordinates are
normalized so that a color angle of 0 degrees is always associated with red normalized so that a color angle of 0 degrees is always associated with red
(green is at about 120 degrees, blue at about 240 degrees - exact value s differ (green is at about 120 degrees, blue at about 240 degrees - exact value s differ
between color spaces). A saturation of 1 is the highest saturation that any RGB color between color spaces). A saturation of 1 is the highest saturation that any RGB color
gets after transformation into the respective color space, and saturati on 0 corresponds to gets after transformation into the respective color space, and saturati on 0 corresponds to
gray. Thus, different color spaces become somewhat comparable. gray. Thus, different color spaces become somewhat comparable.
*/ */
//@{ //@{
/** \brief Init L*a*b* color triple from polar representation. /** \brief Init L*a*b* color triple from polar representation.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
<b> Declarations:</b> <b> Declarations:</b>
\code \code
TinyVector<float, 3> TinyVector<float, 3>
polar2Lab(double color, double brightness, double saturation); polar2Lab(double color, double brightness, double saturation);
TinyVector<float, 3> TinyVector<float, 3>
polar2Lab(TinyVector<float, 3> const & polar); polar2Lab(TinyVector<float, 3> const & polar);
skipping to change at line 2513 skipping to change at line 2736
/** \brief Create polar representation form L*a*b* /** \brief Create polar representation form L*a*b*
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
TinyVector<float, 3> lab2Polar(TinyVector<float, 3> const & lab); TinyVector<float, 3> lab2Polar(TinyVector<float, 3> const & lab);
} }
\endcode \endcode
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
This realizes the inverse of the transformation described in This realizes the inverse of the transformation described in
\link PolarColors#polar2Lab polar2Lab\endlink(). \ref polar2Lab().
*/ */
template <class V> template <class V>
TinyVector<float, 3> TinyVector<float, 3>
lab2Polar(V const & lab) lab2Polar(V const & lab)
{ {
TinyVector<float, 3> result; TinyVector<float, 3> result;
result[1] = lab[0]/100.0; result[1] = lab[0]/100.0;
double angle = (lab[1] == 0.0 && lab[2] == 0.0) double angle = (lab[1] == 0.0 && lab[2] == 0.0)
? 0.0 ? 0.0
: VIGRA_CSTD::atan2(lab[2], lab[1])/M_PI*180.0-39.9977; : VIGRA_CSTD::atan2(lab[2], lab[1])/M_PI*180.0-39.9977;
result[0] = angle < 0.0 ? result[0] = angle < 0.0 ?
angle + 360.0 : angle + 360.0 :
angle; angle;
result[2] = VIGRA_CSTD::sqrt(lab[1]*lab[1] + lab[2]*lab[2])/133.809; result[2] = VIGRA_CSTD::sqrt(lab[1]*lab[1] + lab[2]*lab[2])/133.809;
return result; return result;
} }
/** \brief Init L*u*v* color triple from polar representation. /** \brief Init L*u*v* color triple from polar representation.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
<b> Declarations:</b> <b> Declarations:</b>
\code \code
TinyVector<float, 3> TinyVector<float, 3>
polar2Luv(double color, double brightness, double saturation); polar2Luv(double color, double brightness, double saturation);
TinyVector<float, 3> TinyVector<float, 3>
polar2Luv(TinyVector<float, 3> const & polar); polar2Luv(TinyVector<float, 3> const & polar);
skipping to change at line 2598 skipping to change at line 2821
/** \brief Create polar representation form L*u*v* /** \brief Create polar representation form L*u*v*
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
TinyVector<float, 3> luv2Polar(TinyVector<float, 3> const & luv); TinyVector<float, 3> luv2Polar(TinyVector<float, 3> const & luv);
} }
\endcode \endcode
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
This realizes the inverse of the transformation described in This realizes the inverse of the transformation described in
\link PolarColors#polar2Luv polar2Luv\endlink(). \ref polar2Luv().
*/ */
template <class V> template <class V>
TinyVector<float, 3> TinyVector<float, 3>
luv2Polar(V const & luv) luv2Polar(V const & luv)
{ {
TinyVector<float, 3> result; TinyVector<float, 3> result;
result[1] = luv[0]/100.0; result[1] = luv[0]/100.0;
double angle = (luv[1] == 0.0 && luv[2] == 0.0) double angle = (luv[1] == 0.0 && luv[2] == 0.0)
? 0.0 ? 0.0
: VIGRA_CSTD::atan2(luv[2], luv[1])/M_PI*180.0-12.1727; : VIGRA_CSTD::atan2(luv[2], luv[1])/M_PI*180.0-12.1727;
result[0] = angle < 0.0 ? result[0] = angle < 0.0 ?
angle + 360.0 : angle + 360.0 :
angle; angle;
result[2] = VIGRA_CSTD::sqrt(luv[1]*luv[1] + luv[2]*luv[2])/179.04; result[2] = VIGRA_CSTD::sqrt(luv[1]*luv[1] + luv[2]*luv[2])/179.04;
return result; return result;
} }
/** \brief Init Y'PbPr color triple from polar representation. /** \brief Init Y'PbPr color triple from polar representation.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
<b> Declarations:</b> <b> Declarations:</b>
\code \code
TinyVector<float, 3> TinyVector<float, 3>
polar2YPrimePbPr(double color, double brightness, double saturation); polar2YPrimePbPr(double color, double brightness, double saturation);
TinyVector<float, 3> TinyVector<float, 3>
polar2YPrimePbPr(TinyVector<float, 3> const & polar); polar2YPrimePbPr(TinyVector<float, 3> const & polar);
skipping to change at line 2683 skipping to change at line 2906
/** \brief Create polar representation form Y'PbPr /** \brief Create polar representation form Y'PbPr
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
TinyVector<float, 3> yPrimePbPr2Polar(TinyVector<float, 3> const & ypbpr); TinyVector<float, 3> yPrimePbPr2Polar(TinyVector<float, 3> const & ypbpr);
} }
\endcode \endcode
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
This realizes the inverse of the transformation described in This realizes the inverse of the transformation described in
\link PolarColors#polar2YPrimePbPr polar2YPrimePbPr\endlink(). \ref polar2YPrimePbPr().
*/ */
template <class V> template <class V>
TinyVector<float, 3> TinyVector<float, 3>
yPrimePbPr2Polar(V const & ypbpr) yPrimePbPr2Polar(V const & ypbpr)
{ {
TinyVector<float, 3> result; TinyVector<float, 3> result;
result[1] = ypbpr[0]; result[1] = ypbpr[0];
double angle = (ypbpr[1] == 0.0 && ypbpr[2] == 0.0) double angle = (ypbpr[1] == 0.0 && ypbpr[2] == 0.0)
? 0.0 ? 0.0
: VIGRA_CSTD::atan2(-ypbpr[1], ypbpr[2])/M_PI*180.0-18.6481; : VIGRA_CSTD::atan2(-ypbpr[1], ypbpr[2])/M_PI*180.0-18.6481;
result[0] = angle < 0.0 ? result[0] = angle < 0.0 ?
angle + 360.0 : angle + 360.0 :
angle; angle;
result[2] = VIGRA_CSTD::sqrt(ypbpr[1]*ypbpr[1] + ypbpr[2]*ypbpr[2])/0.5 33887; result[2] = VIGRA_CSTD::sqrt(ypbpr[1]*ypbpr[1] + ypbpr[2]*ypbpr[2])/0.5 33887;
return result; return result;
} }
/** \brief Init Y'CbCr color triple from polar representation. /** \brief Init Y'CbCr color triple from polar representation.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
<b> Declarations:</b> <b> Declarations:</b>
\code \code
TinyVector<float, 3> TinyVector<float, 3>
polar2YPrimeCbCr(double color, double brightness, double saturation); polar2YPrimeCbCr(double color, double brightness, double saturation);
TinyVector<float, 3> TinyVector<float, 3>
polar2YPrimeCbCr(TinyVector<float, 3> const & polar); polar2YPrimeCbCr(TinyVector<float, 3> const & polar);
skipping to change at line 2768 skipping to change at line 2991
/** \brief Create polar representation form Y'CbCr /** \brief Create polar representation form Y'CbCr
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
TinyVector<float, 3> yPrimeCbCr2Polar(TinyVector<float, 3> const & ycbcr); TinyVector<float, 3> yPrimeCbCr2Polar(TinyVector<float, 3> const & ycbcr);
} }
\endcode \endcode
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
This realizes the inverse of the transformation described in This realizes the inverse of the transformation described in
\link PolarColors#polar2YPrimeCbCr polar2YPrimeCbCr\endlink(). \ref polar2YPrimeCbCr().
*/ */
template <class V> template <class V>
TinyVector<float, 3> TinyVector<float, 3>
yPrimeCbCr2Polar(V const & ycbcr) yPrimeCbCr2Polar(V const & ycbcr)
{ {
TinyVector<float, 3> result; TinyVector<float, 3> result;
result[1] = (ycbcr[0]-16.0)/219.0; result[1] = (ycbcr[0]-16.0)/219.0;
double cb = ycbcr[1]-128.0; double cb = ycbcr[1]-128.0;
double cr = ycbcr[2]-128.0; double cr = ycbcr[2]-128.0;
double angle = (cb == 0.0 && cr == 0.0) double angle = (cb == 0.0 && cr == 0.0)
skipping to change at line 2794 skipping to change at line 3017
: VIGRA_CSTD::atan2(-cb, cr)/M_PI*180.0-18.6482; : VIGRA_CSTD::atan2(-cb, cr)/M_PI*180.0-18.6482;
result[0] = angle < 0.0 ? result[0] = angle < 0.0 ?
angle + 360.0 : angle + 360.0 :
angle; angle;
result[2] = VIGRA_CSTD::sqrt(cb*cb + cr*cr)/119.591; result[2] = VIGRA_CSTD::sqrt(cb*cb + cr*cr)/119.591;
return result; return result;
} }
/** \brief Init Y'IQ color triple from polar representation. /** \brief Init Y'IQ color triple from polar representation.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
<b> Declarations:</b> <b> Declarations:</b>
\code \code
TinyVector<float, 3> TinyVector<float, 3>
polar2YPrimeIQ(double color, double brightness, double saturation); polar2YPrimeIQ(double color, double brightness, double saturation);
TinyVector<float, 3> TinyVector<float, 3>
polar2YPrimeIQ(TinyVector<float, 3> const & polar); polar2YPrimeIQ(TinyVector<float, 3> const & polar);
skipping to change at line 2855 skipping to change at line 3078
/** \brief Create polar representation form Y'IQ /** \brief Create polar representation form Y'IQ
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
TinyVector<float, 3> yPrimeIQ2Polar(TinyVector<float, 3> const & yi q); TinyVector<float, 3> yPrimeIQ2Polar(TinyVector<float, 3> const & yi q);
} }
\endcode \endcode
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
This realizes the inverse of the transformation described in This realizes the inverse of the transformation described in
\link PolarColors#polar2YPrimeIQ polar2YPrimeIQ\endlink(). \ref polar2YPrimeIQ().
*/ */
template <class V> template <class V>
TinyVector<float, 3> TinyVector<float, 3>
yPrimeIQ2Polar(V const & yiq) yPrimeIQ2Polar(V const & yiq)
{ {
TinyVector<float, 3> result; TinyVector<float, 3> result;
result[1] = yiq[0]; result[1] = yiq[0];
double angle = (yiq[1] == 0.0 && yiq[2] == 0.0) double angle = (yiq[1] == 0.0 && yiq[2] == 0.0)
? 0.0 ? 0.0
: VIGRA_CSTD::atan2(-yiq[2], yiq[1])/M_PI*180.0+19.5807; : VIGRA_CSTD::atan2(-yiq[2], yiq[1])/M_PI*180.0+19.5807;
result[0] = angle < 0.0 ? result[0] = angle < 0.0 ?
angle + 360.0 : angle + 360.0 :
angle; angle;
result[2] = VIGRA_CSTD::sqrt(yiq[1]*yiq[1] + yiq[2]*yiq[2])/0.632582; result[2] = VIGRA_CSTD::sqrt(yiq[1]*yiq[1] + yiq[2]*yiq[2])/0.632582;
return result; return result;
} }
/** \brief Init Y'UV color triple from polar representation. /** \brief Init Y'UV color triple from polar representation.
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
<b> Declarations:</b> <b> Declarations:</b>
\code \code
TinyVector<float, 3> TinyVector<float, 3>
polar2YPrimeUV(double color, double brightness, double saturation); polar2YPrimeUV(double color, double brightness, double saturation);
TinyVector<float, 3> TinyVector<float, 3>
polar2YPrimeUV(TinyVector<float, 3> const & polar); polar2YPrimeUV(TinyVector<float, 3> const & polar);
skipping to change at line 2940 skipping to change at line 3163
/** \brief Create polar representation form Y'UV /** \brief Create polar representation form Y'UV
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
TinyVector<float, 3> yPrimeUV2Polar(TinyVector<float, 3> const & yu v); TinyVector<float, 3> yPrimeUV2Polar(TinyVector<float, 3> const & yu v);
} }
\endcode \endcode
<b>\#include</b> "<a href="colorconversions_8hxx-source.html">vigra/col orconversions.hxx</a>"<br> <b>\#include</b> \<<a href="colorconversions_8hxx-source.html">vigra/co lorconversions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
This realizes the inverse of the transformation described in This realizes the inverse of the transformation described in
\link PolarColors#polar2YPrimeUV polar2YPrimeUV\endlink(). \ref polar2YPrimeUV().
*/ */
template <class V> template <class V>
TinyVector<float, 3> TinyVector<float, 3>
yPrimeUV2Polar(V const & yuv) yPrimeUV2Polar(V const & yuv)
{ {
TinyVector<float, 3> result; TinyVector<float, 3> result;
result[1] = yuv[0]; result[1] = yuv[0];
double angle = (yuv[1] == 0.0 && yuv[2] == 0.0) double angle = (yuv[1] == 0.0 && yuv[2] == 0.0)
? 0.0 ? 0.0
: VIGRA_CSTD::atan2(-yuv[1], yuv[2])/M_PI*180.0-13.4569; : VIGRA_CSTD::atan2(-yuv[1], yuv[2])/M_PI*180.0-13.4569;
 End of changes. 93 change blocks. 
210 lines changed or deleted 471 lines changed or added


 combineimages.hxx   combineimages.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 142 skipping to change at line 142
class Functor> class Functor>
void void
combineTwoImages(SrcImageIterator1 src1_upperleft, combineTwoImages(SrcImageIterator1 src1_upperleft,
SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1, SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1,
SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2, SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2,
DestImageIterator dest_upperleft, DestAccessor da, DestImageIterator dest_upperleft, DestAccessor da,
Functor const & f) Functor const & f)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator1, class SrcAccessor1, template <class SrcImageIterator1, class SrcAccessor1,
class SrcImageIterator2, class SrcAccessor2, class SrcImageIterator2, class SrcAccessor2,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class Functor> class Functor>
void void
combineTwoImages(triple<SrcImageIterator1, SrcImageIterator1, SrcAc cessor1> src1, combineTwoImages(triple<SrcImageIterator1, SrcImageIterator1, SrcAc cessor1> src1,
pair<SrcImageIterator2, SrcAccessor2> src2, pair<SrcImageIterator2, SrcAccessor2> src2,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
Functor const & f) Functor const & f)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="combineimages_8hxx-source.html">vigra/co mbineimages.hxx</a>"<br> <b>\#include</b> \<<a href="combineimages_8hxx-source.html">vigra/c ombineimages.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
#include <functional> // for plus #include <functional> // for plus
vigra::combineTwoImages( vigra::combineTwoImages(
srcIterRange(src1.upperLeft(), src1.lowerRight()), srcIterRange(src1.upperLeft(), src1.lowerRight()),
srcIter(src2.upperLeft()), srcIter(src2.upperLeft()),
destIter(dest.upperLeft()), destIter(dest.upperLeft()),
std::plus<SrcValueType>()); std::plus<SrcValueType>());
skipping to change at line 200 skipping to change at line 200
Functor functor; Functor functor;
dest_accessor.set( dest_accessor.set(
functor(src1_accessor(sx1), src2_accessor(sx2)), functor(src1_accessor(sx1), src2_accessor(sx2)),
dx); dx);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void combineTwoImages)
template <class SrcImageIterator1, class SrcAccessor1, template <class SrcImageIterator1, class SrcAccessor1,
class SrcImageIterator2, class SrcAccessor2, class SrcImageIterator2, class SrcAccessor2,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class Functor> class Functor>
void void
combineTwoImages(SrcImageIterator1 src1_upperleft, combineTwoImages(SrcImageIterator1 src1_upperleft,
SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1, SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1,
SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2, SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2,
DestImageIterator dest_upperleft, DestAccessor da, DestImageIterator dest_upperleft, DestAccessor da,
Functor const & f) Functor const & f)
skipping to change at line 277 skipping to change at line 279
void void
combineTwoImagesIf(SrcImageIterator1 src1_upperleft, combineTwoImagesIf(SrcImageIterator1 src1_upperleft,
SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1, SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1,
SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2, SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2,
MaskImageIterator mask_upperleft, MaskAccessor ma, MaskImageIterator mask_upperleft, MaskAccessor ma,
DestImageIterator dest_upperleft, DestAccessor da, DestImageIterator dest_upperleft, DestAccessor da,
Functor const & f) Functor const & f)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator1, class SrcAccessor1, template <class SrcImageIterator1, class SrcAccessor1,
class SrcImageIterator2, class SrcAccessor2, class SrcImageIterator2, class SrcAccessor2,
class MaskImageIterator, class MaskAccessor, class MaskImageIterator, class MaskAccessor,
class DestImageIterator, clas DestAccessor, class DestImageIterator, clas DestAccessor,
class Functor> class Functor>
void void
combineTwoImagesIf(triple<SrcImageIterator1, SrcImageIterator1, Src Accessor1> src1, combineTwoImagesIf(triple<SrcImageIterator1, SrcImageIterator1, Src Accessor1> src1,
pair<SrcImageIterator2, SrcAccessor2> src2, pair<SrcImageIterator2, SrcAccessor2> src2,
pair<MaskImageIterator, MaskAccessor> mask, pair<MaskImageIterator, MaskAccessor> mask,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
Functor const & f) Functor const & f)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="combineimages_8hxx-source.html">vigra/co mbineimages.hxx</a>"<br> <b>\#include</b> \<<a href="combineimages_8hxx-source.html">vigra/c ombineimages.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
#include <functional> // for plus #include <functional> // for plus
vigra::combineTwoImagesIf( vigra::combineTwoImagesIf(
srcIterRange(src1.upperLeft(), src1.lowerRight()), srcIterRange(src1.upperLeft(), src1.lowerRight()),
srcIter(src2.upperLeft()), srcIter(src2.upperLeft()),
maskIter(mask.upperLeft()), maskIter(mask.upperLeft()),
destIter(dest.upperLeft()), destIter(dest.upperLeft()),
skipping to change at line 342 skipping to change at line 344
Functor functor; Functor functor;
if(mask_accessor(mx)) if(mask_accessor(mx))
dest_accessor.set( dest_accessor.set(
functor(src1_accessor(sx1), src2_accessor(sx2)), functor(src1_accessor(sx1), src2_accessor(sx2)),
dx); dx);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void combineTwoImagesIf)
template <class SrcImageIterator1, class SrcAccessor1, template <class SrcImageIterator1, class SrcAccessor1,
class SrcImageIterator2, class SrcAccessor2, class SrcImageIterator2, class SrcAccessor2,
class MaskImageIterator, class MaskAccessor, class MaskImageIterator, class MaskAccessor,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class Functor> class Functor>
void void
combineTwoImagesIf(SrcImageIterator1 src1_upperleft, combineTwoImagesIf(SrcImageIterator1 src1_upperleft,
SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1, SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1,
SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2, SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2,
MaskImageIterator mask_upperleft, MaskAccessor ma, MaskImageIterator mask_upperleft, MaskAccessor ma,
skipping to change at line 421 skipping to change at line 425
void void
combineThreeImages(SrcImageIterator1 src1_upperleft, combineThreeImages(SrcImageIterator1 src1_upperleft,
SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1, SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1,
SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2, SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2,
SrcImageIterator3 src2_upperleft, SrcAccessor3 sa3, SrcImageIterator3 src2_upperleft, SrcAccessor3 sa3,
DestImageIterator dest_upperleft, DestAccessor da, DestImageIterator dest_upperleft, DestAccessor da,
Functor const & f) Functor const & f)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator1, class SrcAccessor1, template <class SrcImageIterator1, class SrcAccessor1,
class SrcImageIterator2, class SrcAccessor2, class SrcImageIterator2, class SrcAccessor2,
class SrcImageIterator3, class SrcAccessor3, class SrcImageIterator3, class SrcAccessor3,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class Functor> class Functor>
void void
combineThreeImages(triple<SrcImageIterator1, SrcImageIterator1, Src Accessor1> src1, combineThreeImages(triple<SrcImageIterator1, SrcImageIterator1, Src Accessor1> src1,
pair<SrcImageIterator2, SrcAccessor2> src2, pair<SrcImageIterator2, SrcAccessor2> src2,
pair<SrcImageIterator3, SrcAccessor3> src3, pair<SrcImageIterator3, SrcAccessor3> src3,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
Functor const & f) Functor const & f)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="combineimages_8hxx-source.html">vigra/co mbineimages.hxx</a>"<br> <b>\#include</b> \<<a href="combineimages_8hxx-source.html">vigra/c ombineimages.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::combineThreeImages( vigra::combineThreeImages(
srcIterRange(src1.upperLeft(), src1.lowerRight()), srcIterRange(src1.upperLeft(), src1.lowerRight()),
srcIter(src2.upperLeft()), srcIter(src2.upperLeft()),
srcIter(src3.upperLeft()), srcIter(src3.upperLeft()),
destIter(dest.upperLeft()), destIter(dest.upperLeft()),
SomeThreeArgumentFunctor()); SomeThreeArgumentFunctor());
skipping to change at line 481 skipping to change at line 485
dest_accessor.set( dest_accessor.set(
functor(src1_accessor(sx1), functor(src1_accessor(sx1),
src2_accessor(sx2), src2_accessor(sx2),
src3_accessor(sx3)), src3_accessor(sx3)),
dx); dx);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void combineThreeImages)
template <class SrcImageIterator1, class SrcAccessor1, template <class SrcImageIterator1, class SrcAccessor1,
class SrcImageIterator2, class SrcAccessor2, class SrcImageIterator2, class SrcAccessor2,
class SrcImageIterator3, class SrcAccessor3, class SrcImageIterator3, class SrcAccessor3,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class Functor> class Functor>
void void
combineThreeImages(SrcImageIterator1 src1_upperleft, combineThreeImages(SrcImageIterator1 src1_upperleft,
SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1, SrcImageIterator1 src1_lowerright, SrcAccessor1 sa1,
SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2, SrcImageIterator2 src2_upperleft, SrcAccessor2 sa2,
SrcImageIterator3 src3_upperleft, SrcAccessor3 sa3, SrcImageIterator3 src3_upperleft, SrcAccessor3 sa3,
skipping to change at line 549 skipping to change at line 555
/********************************************************/ /********************************************************/
/** Calculate the magnitude from two arguments. /** Calculate the magnitude from two arguments.
Can be used in conjunction with \ref gradientBasedTransform(). Can be used in conjunction with \ref gradientBasedTransform().
If the gradient is represented by a vector-valued image instead of If the gradient is represented by a vector-valued image instead of
a pair of scalar images, use \ref vigra::VectorNormFunctor. a pair of scalar images, use \ref vigra::VectorNormFunctor.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isBinaryFunctor</tt> are true (<tt>VigraTrueType<tt> ) <tt>FunctorTraits::isBinaryFunctor</tt> are true (<tt>VigraTrueType</tt >)
*/ */
template <class ValueType> template <class ValueType>
class MagnitudeFunctor class MagnitudeFunctor
{ {
public: public:
/** the functor's first argument type /** the functor's first argument type
*/ */
typedef ValueType first_argument_type; typedef ValueType first_argument_type;
/** the functor's second argument type /** the functor's second argument type
skipping to change at line 599 skipping to change at line 605
/* */ /* */
/* RGBGradientMagnitudeFunctor */ /* RGBGradientMagnitudeFunctor */
/* */ /* */
/********************************************************/ /********************************************************/
/** Calculate the gradient magnitude from RGB arguments. /** Calculate the gradient magnitude from RGB arguments.
Can be used in conjunction with \ref gradientBasedTransform(). Can be used in conjunction with \ref gradientBasedTransform().
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isBinaryFunctor</tt> are true (<tt>VigraTrueType<tt> ) <tt>FunctorTraits::isBinaryFunctor</tt> are true (<tt>VigraTrueType</tt >)
*/ */
template <class ValueType> template <class ValueType>
class RGBGradientMagnitudeFunctor class RGBGradientMagnitudeFunctor
{ {
public: public:
/** the functor's first argument type /** the functor's first argument type
*/ */
typedef RGBValue<ValueType> first_argument_type; typedef RGBValue<ValueType> first_argument_type;
/** the functor's second argument type /** the functor's second argument type
 End of changes. 13 change blocks. 
11 lines changed or deleted 17 lines changed or added


 config.hxx   config.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 103 skipping to change at line 103
namespace std { namespace std {
#endif // CMATH_NOT_IN_STD #endif // CMATH_NOT_IN_STD
inline double abs(double v) { return fabs(v); } inline double abs(double v) { return fabs(v); }
inline float abs(float v) { return fabs(v); } inline float abs(float v) { return fabs(v); }
#ifndef CMATH_NOT_IN_STD #ifndef CMATH_NOT_IN_STD
} }
#endif // CMATH_NOT_IN_STD #endif // CMATH_NOT_IN_STD
#endif // _MSC_EXTENSIONS #endif // _MSC_EXTENSIONS
#endif // _MSC_VER < 1310 #endif // _MSC_VER < 1310
#if _MSC_VER < 1400
#define VIGRA_NO_WORKING_STRINGSTREAM
#endif
#define VIGRA_NEED_BIN_STREAMS #define VIGRA_NEED_BIN_STREAMS
#ifdef VIGRA_DLL #ifdef VIGRA_DLL
#define VIGRA_EXPORT __declspec(dllexport) #define VIGRA_EXPORT __declspec(dllexport)
#elif defined(VIGRA_STATIC_LIB) #elif defined(VIGRA_STATIC_LIB)
#define VIGRA_EXPORT #define VIGRA_EXPORT
#else #else
#define VIGRA_EXPORT __declspec(dllimport) #define VIGRA_EXPORT __declspec(dllimport)
#endif #endif
#endif // _MSC_VER #endif // _MSC_VER
skipping to change at line 124 skipping to change at line 128
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// // // //
// gcc // // gcc //
// // // //
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
#if defined(__GNUC__) #if defined(__GNUC__)
#if __GNUC__ < 2 || ((__GNUC__ == 2) && (__GNUC_MINOR__ <= 8)) #if __GNUC__ < 2 || ((__GNUC__ == 2) && (__GNUC_MINOR__ <= 8))
#error "Need at least g++ 2.95" #error "Need at least g++ 2.95"
#endif #endif
#if __GNUC__ < 3
#define VIGRA_NO_WORKING_STRINGSTREAM
#endif
#define HAS_HASH_CONTAINERS #define HAS_HASH_CONTAINERS
#endif // __GNUC__ #endif // __GNUC__
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// // // //
// MingW // // MingW //
// // // //
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
#if defined(__MINGW32__) #if defined(__MINGW32__)
skipping to change at line 209 skipping to change at line 216
#endif #endif
namespace vigra { namespace vigra {
#ifndef SPECIAL_STDEXCEPTION_DEFINITION_NEEDED #ifndef SPECIAL_STDEXCEPTION_DEFINITION_NEEDED
typedef std::exception StdException; typedef std::exception StdException;
#endif #endif
} // namespace vigra } // namespace vigra
#ifdef DOXYGEN
# define doxygen_overloaded_function(fun) fun(...);
#else
# define doxygen_overloaded_function(fun)
#endif
#endif // VIGRA_CONFIG_HXX #endif // VIGRA_CONFIG_HXX
 End of changes. 5 change blocks. 
3 lines changed or deleted 16 lines changed or added


 contourcirculator.hxx   contourcirculator.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 90 skipping to change at line 90
{ {
area += crack.diff().x * crack.pos().y - area += crack.diff().x * crack.pos().y -
crack.diff().y * crack.pos().x; crack.diff().y * crack.pos().x;
} }
while(++crack != crackend); while(++crack != crackend);
area /= 2; area /= 2;
std::cout << "Area of region " << *region_anchor << ": " << area << std ::endl; std::cout << "Area of region " << *region_anchor << ": " << area << std ::endl;
\endcode \endcode
<b>\#include</b> "<a href="contourcirculator_8hxx-source.html">vigra/co ntourcirculator.hxx</a>"<br> <b>\#include</b> \<<a href="contourcirculator_8hxx-source.html">vigra/c ontourcirculator.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class IMAGEITERATOR> template <class IMAGEITERATOR>
class CrackContourCirculator class CrackContourCirculator
{ {
typedef NeighborhoodCirculator<IMAGEITERATOR, EightNeighborCode> typedef NeighborhoodCirculator<IMAGEITERATOR, EightNeighborCode>
NEIGHBORHOODCIRCULATOR; NEIGHBORHOODCIRCULATOR;
typedef typename IMAGEITERATOR::value_type label_type; typedef typename IMAGEITERATOR::value_type label_type;
protected: protected:
 End of changes. 3 change blocks. 
4 lines changed or deleted 4 lines changed or added


 convolution.hxx   convolution.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 52 skipping to change at line 52
#include "stdconvolution.hxx" #include "stdconvolution.hxx"
#include "separableconvolution.hxx" #include "separableconvolution.hxx"
#include "recursiveconvolution.hxx" #include "recursiveconvolution.hxx"
#include "nonlineardiffusion.hxx" #include "nonlineardiffusion.hxx"
#include "combineimages.hxx" #include "combineimages.hxx"
/** \page Convolution Functions to Convolve Images and Signals /** \page Convolution Functions to Convolve Images and Signals
1D and 2D filters, including separable and recursive convolution, and n on-linear diffusion 1D and 2D filters, including separable and recursive convolution, and n on-linear diffusion
<b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolut ion.hxx</a>"<br> <b>\#include</b> \<<a href="convolution_8hxx-source.html">vigra/convolu tion.hxx</a>\><br>
Namespace: vigra Namespace: vigra
<DL> <UL style="list-style-image:url(documents/bullet.gif)">
<DT> <LI> \ref CommonConvolutionFilters
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <BR>&nbsp;&nbsp;&nbsp;<em>Short-hands for the most common 2D convo
\ref CommonConvolutionFilters lution filters</em>
<DD><em>Short-hands for the most common 2D convolution filters</em> <LI> \ref MultiArrayConvolutionFilters
<DT> <BR>&nbsp;&nbsp;&nbsp;<em>Convolution filters for arbitrary dimens
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> ional arrays (MultiArray etc.)</em>
\ref MultiArrayConvolutionFilters <LI> \ref ResamplingConvolutionFilters
<DD><em>Convolution filters for arbitrary dimensional arrays (Multi <BR>&nbsp;&nbsp;&nbsp;<em>Resampling convolution filters</em>
Array etc.)</em> <LI> \ref StandardConvolution
<DT> <BR>&nbsp;&nbsp;&nbsp;<em>2D non-separable convolution, with and w
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> ithout ROI mask </em>
\ref ResamplingConvolutionFilters <LI> \ref vigra::Kernel2D
<DD><em>Resampling convolution filters</em> <BR>&nbsp;&nbsp;&nbsp;<em>Generic 2-dimensional discrete convoluti
<DT> on kernel </em>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref SeparableConvolution
\ref StandardConvolution <BR>&nbsp;&nbsp;&nbsp;<em>1D convolution and separable filters in
<DD><em>2D non-separable convolution, with and without ROI mask </e 2 dimensions </em>
m> <LI> \ref vigra::Kernel1D
<DT> <BR>&nbsp;&nbsp;&nbsp;<em>Generic 1-dimensional discrete convoluti
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> on kernel </em>
\ref vigra::Kernel2D <LI> \ref RecursiveConvolution
<DD><em>Generic 2-dimensional discrete convolution kernel </em> <BR>&nbsp;&nbsp;&nbsp;<em>Recursive filters (1st and 2nd order)</e
<DT> m>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref NonLinearDiffusion
\ref SeparableConvolution <BR>&nbsp;&nbsp;&nbsp;<em>Edge-preserving smoothing </em>
<DD> <em>1D convolution and separable filters in 2 dimensions </em> <LI> \ref BorderTreatmentMode
<DT> <BR>&nbsp;&nbsp;&nbsp;<em>Choose between different border treatmen
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> t modes </em>
\ref vigra::Kernel1D <LI> \ref KernelArgumentObjectFactories
<DD> <em>Generic 1-dimensional discrete convolution kernel </em> <BR>&nbsp;&nbsp;&nbsp;<em>Factory functions to create argument obj
<DT> ects to simplify passing kernels</em>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> </UL>
\ref RecursiveConvolution
<DD> <em>Recursive filters (1st and 2nd order)</em>
<DT>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref NonLinearDiffusion
<DD> <em>Edge-preserving smoothing </em>
<DT>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref BorderTreatmentMode
<DD><em>Choose between different border treatment modes </em>
<DT>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref KernelArgumentObjectFactories
<DD> <em>Factory functions to create argument objects to simplify p
assing kernels</em>
</DL>
*/ */
/** \page KernelArgumentObjectFactories Kernel Argument Object Factories /** \page KernelArgumentObjectFactories Kernel Argument Object Factories
These factory functions allow to create argument objects for 1D These factory functions allow to create argument objects for 1D
and 2D convolution kernel analogously to and 2D convolution kernel analogously to
\ref ArgumentObjectFactories for images. \ref ArgumentObjectFactories for images.
\section Kernel1dFactory kernel1d() \section Kernel1dFactory kernel1d()
skipping to change at line 122 skipping to change at line 100
These factories can be used to create argument objects when we These factories can be used to create argument objects when we
are given instances or subclasses of \ref vigra::Kernel1D are given instances or subclasses of \ref vigra::Kernel1D
(analogous to the \ref ArgumentObjectFactories for images). (analogous to the \ref ArgumentObjectFactories for images).
These factory functions access <TT>kernel.center()</TT>, These factory functions access <TT>kernel.center()</TT>,
<TT>kernel.left()</TT>, <TT>kernel.right()</TT>, <TT>kernel.accesso r()</TT>, <TT>kernel.left()</TT>, <TT>kernel.right()</TT>, <TT>kernel.accesso r()</TT>,
and <TT>kernel.borderTreatment()</TT> to obtain the necessary and <TT>kernel.borderTreatment()</TT> to obtain the necessary
information. The following factory functions are provided: information. The following factory functions are provided:
<table> <table>
<tr><td> <tr><th bgcolor="#f0e0c0" colspan=2 align=left>
\htmlonly
<th bgcolor="#f0e0c0" colspan=2 align=left>
\endhtmlonly
<TT>\ref vigra::Kernel1D "vigra::Kernel1D<SomeType>" kernel;</T T> <TT>\ref vigra::Kernel1D "vigra::Kernel1D<SomeType>" kernel;</T T>
\htmlonly
</th> </th>
\endhtmlonly </tr>
</td></tr>
<tr><td> <tr><td>
<TT>kernel1d(kernel)</TT> <TT>kernel1d(kernel)</TT>
</td><td> </td><td>
create argument object from information provided by create argument object from information provided by
kernel kernel
</td></tr> </td></tr>
<tr><td> <tr><td>
<TT>kernel1d(kernel, vigra::BORDER_TREATMENT_CLIP)</TT> <TT>kernel1d(kernel, vigra::BORDER_TREATMENT_CLIP)</TT>
</td><td> </td><td>
skipping to change at line 172 skipping to change at line 145
These factories can be used to create argument objects when we These factories can be used to create argument objects when we
are given instances or subclasses of \ref vigra::Kernel2D are given instances or subclasses of \ref vigra::Kernel2D
(analogous to the \ref ArgumentObjectFactories for images). (analogous to the \ref ArgumentObjectFactories for images).
These factory functions access <TT>kernel.center()</TT>, These factory functions access <TT>kernel.center()</TT>,
<TT>kernel.upperLeft()</TT>, <TT>kernel.lowerRight()</TT>, <TT>kern el.accessor()</TT>, <TT>kernel.upperLeft()</TT>, <TT>kernel.lowerRight()</TT>, <TT>kern el.accessor()</TT>,
and <TT>kernel.borderTreatment()</TT> to obtain the necessary and <TT>kernel.borderTreatment()</TT> to obtain the necessary
information. The following factory functions are provided: information. The following factory functions are provided:
<table> <table>
<tr><td> <tr><th bgcolor="#f0e0c0" colspan=2 align=left>
\htmlonly
<th bgcolor="#f0e0c0" colspan=2 align=left>
\endhtmlonly
<TT>\ref vigra::Kernel2D "vigra::Kernel2D<SomeType>" kernel;</T T> <TT>\ref vigra::Kernel2D "vigra::Kernel2D<SomeType>" kernel;</T T>
\htmlonly
</th> </th>
\endhtmlonly </tr>
</td></tr>
<tr><td> <tr><td>
<TT>kernel2d(kernel)</TT> <TT>kernel2d(kernel)</TT>
</td><td> </td><td>
create argument object from information provided by create argument object from information provided by
kernel kernel
</td></tr> </td></tr>
<tr><td> <tr><td>
<TT>kernel2d(kernel, vigra::BORDER_TREATMENT_CLIP)</TT> <TT>kernel2d(kernel, vigra::BORDER_TREATMENT_CLIP)</TT>
</td><td> </td><td>
skipping to change at line 220 skipping to change at line 188
/********************************************************/ /********************************************************/
/* */ /* */
/* Common convolution filters */ /* Common convolution filters */
/* */ /* */
/********************************************************/ /********************************************************/
/** \addtogroup CommonConvolutionFilters Common Filters /** \addtogroup CommonConvolutionFilters Common Filters
These functions calculate common filters by appropriate sequences of ca lls These functions calculate common filters by appropriate sequences of ca lls
to \link SeparableConvolution#separableConvolveX separableConvolveX\end to \ref separableConvolveX() and \ref separableConvolveY().
link()
and \link SeparableConvolution#separableConvolveY separableConvolveY\en
dlink().
*/ */
//@{ //@{
/********************************************************/ /********************************************************/
/* */ /* */
/* convolveImage */ /* convolveImage */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Apply two separable filters successively, the first in x-directi on, /** \brief Apply two separable filters successively, the first in x-directi on,
the second in y-direction. the second in y-direction.
This function is a shorthand for the concatenation of a call to This function is a shorthand for the concatenation of a call to
\link SeparableConvolution#separableConvolveX separableConvolveX\endlin \ref separableConvolveX() and \ref separableConvolveY()
k()
and \link SeparableConvolution#separableConvolveY separableConvolveY\en
dlink()
with the given kernels. with the given kernels.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class T> class T>
void convolveImage(SrcIterator supperleft, void convolveImage(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor sa, SrcIterator slowerright, SrcAccessor sa,
DestIterator dupperleft, DestAccessor da, DestIterator dupperleft, DestAccessor da,
Kernel1D<T> const & kx, Kernel1D<T> const & ky); Kernel1D<T> const & kx, Kernel1D<T> const & ky);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class T> class T>
inline void inline void
convolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src, convolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
Kernel1D<T> const & kx, Kernel1D<T> const & ky); Kernel1D<T> const & kx, Kernel1D<T> const & ky);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolut ion.hxx</a>" <b>\#include</b> \<<a href="convolution_8hxx-source.html">vigra/convolu tion.hxx</a>\>
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
// implement sobel filter in x-direction // implement sobel filter in x-direction
Kernel1D<double> kx, ky; Kernel1D<double> kx, ky;
kx.initSymmetricGradient(); kx.initSymmetricGradient();
ky.initBinomial(1); ky.initBinomial(1);
skipping to change at line 324 skipping to change at line 290
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* simpleSharpening */ /* simpleSharpening */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Perform simple sharpening function. /** \brief Perform simple sharpening function.
This function use \link StandardConvolution#convolveImage convolveImage \endlink( ) with following filter: This function use \ref convolveImage() with following filter:
\code \code
-sharpening_factor/16.0, -sharpening_factor/8.0, -sharpening_fact or/16.0, -sharpening_factor/16.0, -sharpening_factor/8.0, -sharpening_fact or/16.0,
-sharpening_factor/8.0, 1.0+sharpening_factor*0.75, -sharpening_fact or/8.0, -sharpening_factor/8.0, 1.0+sharpening_factor*0.75, -sharpening_fact or/8.0,
-sharpening_factor/16.0, -sharpening_factor/8.0, -sharpening_fact or/16.0; -sharpening_factor/16.0, -sharpening_factor/8.0, -sharpening_fact or/16.0;
\endcode \endcode
and use <TT>BORDER_TREATMENT_REFLECT</TT> as border treatment mode. and use <TT>BORDER_TREATMENT_REFLECT</TT> as border treatment mode.
<b> Preconditions:</b> <b> Preconditions:</b>
skipping to change at line 355 skipping to change at line 321
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void simpleSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAcce ssor src_acc, void simpleSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAcce ssor src_acc,
DestIterator dest_ul, DestAccessor dest_acc, do uble sharpening_factor) DestIterator dest_ul, DestAccessor dest_acc, do uble sharpening_factor)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline inline
void simpleSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> s rc, void simpleSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> s rc,
pair<DestIterator, DestAccessor> dest, double sharpening_factor) pair<DestIterator, DestAccessor> dest, double sharpening_factor)
{ {
simpleSharpening(src.first, src.second, src.third, simpleSharpening(src.first, src.second, src.third,
dest.first, dest.second, sharpening_factor); dest.first, dest.second, sharpening_factor);
} }
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolut ion.hxx</a>" <b>\#include</b> \<<a href="convolution_8hxx-source.html">vigra/convolu tion.hxx</a>\>
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
// sharpening with sharpening_factor = 0.1 // sharpening with sharpening_factor = 0.1
vigra::simpleSharpening(srcImageRange(src), destImage(dest), 0.1); vigra::simpleSharpening(srcImageRange(src), destImage(dest), 0.1);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void simpleSharpening)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void simpleSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor s rc_acc, void simpleSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor s rc_acc,
DestIterator dest_ul, DestAccessor dest_acc, double sha rpening_factor) DestIterator dest_ul, DestAccessor dest_acc, double sha rpening_factor)
{ {
vigra_precondition(sharpening_factor >= 0.0, vigra_precondition(sharpening_factor >= 0.0,
"simpleSharpening(): amount of sharpening must be >= 0."); "simpleSharpening(): amount of sharpening must be >= 0.");
Kernel2D<double> kernel; Kernel2D<double> kernel;
skipping to change at line 423 skipping to change at line 391
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* gaussianSharpening */ /* gaussianSharpening */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Perform sharpening function with gaussian filter. /** \brief Perform sharpening function with gaussian filter.
This function use the This function use the \ref gaussianSmoothing()
\link vigra::gaussianSmoothing gaussianSmoothing \endlink()
at first and scale the source image at first and scale the source image
(\code src \endcode) with the \code scale \endcode (\code src \endcode) with the \code scale \endcode
factor in an temporary image (\code tmp \endcode). At second the new factor in an temporary image (\code tmp \endcode). At second the new
pixel in the destination image will be with following pixel in the destination image will be with following
formel calculate: formel calculate:
\code \code
dest = (1 + sharpening_factor)*src - sharpening_factor*tmp dest = (1 + sharpening_factor)*src - sharpening_factor*tmp
\endcode \endcode
<b> Preconditions:</b> <b> Preconditions:</b>
skipping to change at line 453 skipping to change at line 420
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void gaussianSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAc cessor src_acc, void gaussianSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAc cessor src_acc,
DestIterator dest_ul, DestAccessor dest_acc , double sharpening_factor, DestIterator dest_ul, DestAccessor dest_acc , double sharpening_factor,
double scale) double scale)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void gaussianSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> src, void gaussianSharpening(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, doubl e sharpening_factor, pair<DestIterator, DestAccessor> dest, doubl e sharpening_factor,
double scale) double scale)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolut ion.hxx</a>" <b>\#include</b> \<<a href="convolution_8hxx-source.html">vigra/convolu tion.hxx</a>\>
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
// sharpening with sharpening_factor = 3.0 // sharpening with sharpening_factor = 3.0
// smoothing with scale = 0.5 // smoothing with scale = 0.5
vigra::gaussianSmoothing(srcImageRange(src), destImage(dest), 3.0, 0.5) ; vigra::gaussianSmoothing(srcImageRange(src), destImage(dest), 3.0, 0.5) ;
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void gaussianSharpening)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void gaussianSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc, void gaussianSharpening(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
DestIterator dest_ul, DestAccessor dest_acc, double sharpening_factor, DestIterator dest_ul, DestAccessor dest_acc, double sharpening_factor,
double scale) double scale)
{ {
vigra_precondition(sharpening_factor >= 0.0, vigra_precondition(sharpening_factor >= 0.0,
"gaussianSharpening(): amount of sharpening must be >= 0"); "gaussianSharpening(): amount of sharpening must be >= 0");
vigra_precondition(scale >= 0.0, vigra_precondition(scale >= 0.0,
"gaussianSharpening(): scale parameter should be >= 0."); "gaussianSharpening(): scale parameter should be >= 0.");
skipping to change at line 534 skipping to change at line 503
/********************************************************/ /********************************************************/
/* */ /* */
/* gaussianSmoothing */ /* gaussianSmoothing */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Perform isotropic Gaussian convolution. /** \brief Perform isotropic Gaussian convolution.
This function is a shorthand for the concatenation of a call to This function is a shorthand for the concatenation of a call to
\link SeparableConvolution#separableConvolveX separableConvolveX\endlin \ref separableConvolveX() and \ref separableConvolveY() with a
k()
and \link SeparableConvolution#separableConvolveY separableConvolveY\en
dlink() with a
Gaussian kernel of the given scale. The function uses Gaussian kernel of the given scale. The function uses
<TT>BORDER_TREATMENT_REFLECT</TT>. <TT>BORDER_TREATMENT_REFLECT</TT>.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void gaussianSmoothing(SrcIterator supperleft, void gaussianSmoothing(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor sa, SrcIterator slowerright, SrcAccessor sa,
DestIterator dupperleft, DestAccessor da, DestIterator dupperleft, DestAccessor da,
double scale); double scale);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void inline void
gaussianSmoothing(triple<SrcIterator, SrcIterator, SrcAccessor> src , gaussianSmoothing(triple<SrcIterator, SrcIterator, SrcAccessor> src ,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale); double scale);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolut ion.hxx</a>" <b>\#include</b> \<<a href="convolution_8hxx-source.html">vigra/convolu tion.hxx</a>\>
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
// smooth with scale = 3.0 // smooth with scale = 3.0
vigra::gaussianSmoothing(srcImageRange(src), destImage(dest), 3.0); vigra::gaussianSmoothing(srcImageRange(src), destImage(dest), 3.0);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void gaussianSmoothing)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void gaussianSmoothing(SrcIterator supperleft, void gaussianSmoothing(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor sa, SrcIterator slowerright, SrcAccessor sa,
DestIterator dupperleft, DestAccessor da, DestIterator dupperleft, DestAccessor da,
double scale) double scale)
{ {
typedef typename typedef typename
NumericTraits<typename SrcAccessor::value_type>::RealPromote NumericTraits<typename SrcAccessor::value_type>::RealPromote
TmpType; TmpType;
skipping to change at line 622 skipping to change at line 592
/********************************************************/ /********************************************************/
/* */ /* */
/* gaussianGradient */ /* gaussianGradient */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Calculate the gradient vector by means of a 1st derivatives of /** \brief Calculate the gradient vector by means of a 1st derivatives of
Gaussian filter. Gaussian filter.
This function is a shorthand for the concatenation of a call to This function is a shorthand for the concatenation of a call to
\link SeparableConvolution#separableConvolveX separableConvolveX\endlin \ref separableConvolveX() and \ref separableConvolveY() with the
k()
and \link SeparableConvolution#separableConvolveY separableConvolveY\en
dlink() with the
appropriate kernels at the given scale. Note that this function can eit her produce appropriate kernels at the given scale. Note that this function can eit her produce
two separate result images for the x- and y-components of the gradient, or write two separate result images for the x- and y-components of the gradient, or write
into a vector valued image (with at least two components). into a vector valued image (with at least two components).
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
// write x and y component of the gradient into separate images // write x and y component of the gradient into separate images
skipping to change at line 653 skipping to change at line 622
// write x and y component of the gradient into a vector-valued ima ge // write x and y component of the gradient into a vector-valued ima ge
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void gaussianGradient(SrcIterator supperleft, void gaussianGradient(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor src, SrcIterator slowerright, SrcAccessor src,
DestIterator dupperleft, DestAccessor dest, DestIterator dupperleft, DestAccessor dest,
double scale); double scale);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
// write x and y component of the gradient into separate images // write x and y component of the gradient into separate images
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIteratorX, class DestAccessorX, class DestIteratorX, class DestAccessorX,
class DestIteratorY, class DestAccessorY> class DestIteratorY, class DestAccessorY>
void void
gaussianGradient(triple<SrcIterator, SrcIterator, SrcAccessor> src, gaussianGradient(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIteratorX, DestAccessorX> destx, pair<DestIteratorX, DestAccessorX> destx,
pair<DestIteratorY, DestAccessorY> desty, pair<DestIteratorY, DestAccessorY> desty,
skipping to change at line 678 skipping to change at line 647
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
gaussianGradient(triple<SrcIterator, SrcIterator, SrcAccessor> src, gaussianGradient(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale); double scale);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolut ion.hxx</a>" <b>\#include</b> \<<a href="convolution_8hxx-source.html">vigra/convolu tion.hxx</a>\>
\code \code
vigra::FImage src(w,h), gradx(w,h), grady(w,h); vigra::FImage src(w,h), gradx(w,h), grady(w,h);
... ...
// calculate gradient vector at scale = 3.0 // calculate gradient vector at scale = 3.0
vigra::gaussianGradient(srcImageRange(src), vigra::gaussianGradient(srcImageRange(src),
destImage(gradx), destImage(grady), 3.0); destImage(gradx), destImage(grady), 3.0);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void gaussianGradient)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIteratorX, class DestAccessorX, class DestIteratorX, class DestAccessorX,
class DestIteratorY, class DestAccessorY> class DestIteratorY, class DestAccessorY>
void gaussianGradient(SrcIterator supperleft, void gaussianGradient(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor sa, SrcIterator slowerright, SrcAccessor sa,
DestIteratorX dupperleftx, DestAccessorX dax, DestIteratorX dupperleftx, DestAccessorX dax,
DestIteratorY dupperlefty, DestAccessorY day, DestIteratorY dupperlefty, DestAccessorY day,
double scale) double scale)
{ {
typedef typename typedef typename
skipping to change at line 777 skipping to change at line 748
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void gaussianGradientMagnitude(SrcIterator sul, void gaussianGradientMagnitude(SrcIterator sul,
SrcIterator slr, SrcAccessor src, SrcIterator slr, SrcAccessor src,
DestIterator dupperleft, DestAccesso r dest, DestIterator dupperleft, DestAccesso r dest,
double scale); double scale);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
gaussianGradientMagnitude(triple<SrcIterator, SrcIterator, SrcAcces sor> src, gaussianGradientMagnitude(triple<SrcIterator, SrcIterator, SrcAcces sor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale); double scale);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolut ion.hxx</a>" <b>\#include</b> \<<a href="convolution_8hxx-source.html">vigra/convolu tion.hxx</a>\>
\code \code
vigra::FImage src(w,h), grad(w,h); vigra::FImage src(w,h), grad(w,h);
... ...
// calculate gradient magnitude at scale = 3.0 // calculate gradient magnitude at scale = 3.0
vigra::gaussianGradientMagnitude(srcImageRange(src), destImage(grad), 3 .0); vigra::gaussianGradientMagnitude(srcImageRange(src), destImage(grad), 3 .0);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void gaussianGradientMagnitude)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void gaussianGradientMagnitude(SrcIterator sul, void gaussianGradientMagnitude(SrcIterator sul,
SrcIterator slr, SrcAccessor src, SrcIterator slr, SrcAccessor src,
DestIterator dupperleft, DestAccessor dest, DestIterator dupperleft, DestAccessor dest,
double scale) double scale)
{ {
typedef typename NumericTraits<typename SrcAccessor::value_type>::RealP romote TmpType; typedef typename NumericTraits<typename SrcAccessor::value_type>::RealP romote TmpType;
BasicImage<TmpType> gradx(slr-sul), grady(slr-sul); BasicImage<TmpType> gradx(slr-sul), grady(slr-sul);
skipping to change at line 839 skipping to change at line 812
/********************************************************/ /********************************************************/
/* */ /* */
/* laplacianOfGaussian */ /* laplacianOfGaussian */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Filter image with the Laplacian of Gaussian operator /** \brief Filter image with the Laplacian of Gaussian operator
at the given scale. at the given scale.
This function calls \link SeparableConvolution#separableConvolveX separ This function calls \ref separableConvolveX() and \ref separableConvolv
ableConvolveX\endlink() and eY() with the appropriate 2nd derivative
\link SeparableConvolution#separableConvolveY separableConvolveY\endlin
k() with the appropriate 2nd derivative
of Gaussian kernels in x- and y-direction and then sums the results of Gaussian kernels in x- and y-direction and then sums the results
to get the Laplacian. to get the Laplacian.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void laplacianOfGaussian(SrcIterator supperleft, void laplacianOfGaussian(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor sa, SrcIterator slowerright, SrcAccessor sa,
DestIterator dupperleft, DestAccessor da, DestIterator dupperleft, DestAccessor da,
double scale); double scale);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void inline void
laplacianOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> s rc, laplacianOfGaussian(triple<SrcIterator, SrcIterator, SrcAccessor> s rc,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale); double scale);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolut ion.hxx</a>" <b>\#include</b> \<<a href="convolution_8hxx-source.html">vigra/convolu tion.hxx</a>\>
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
// calculate Laplacian of Gaussian at scale = 3.0 // calculate Laplacian of Gaussian at scale = 3.0
vigra::laplacianOfGaussian(srcImageRange(src), destImage(dest), 3.0); vigra::laplacianOfGaussian(srcImageRange(src), destImage(dest), 3.0);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void laplacianOfGaussian)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void laplacianOfGaussian(SrcIterator supperleft, void laplacianOfGaussian(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor sa, SrcIterator slowerright, SrcAccessor sa,
DestIterator dupperleft, DestAccessor da, DestIterator dupperleft, DestAccessor da,
double scale) double scale)
{ {
typedef typename typedef typename
NumericTraits<typename SrcAccessor::value_type>::RealPromote NumericTraits<typename SrcAccessor::value_type>::RealPromote
TmpType; TmpType;
skipping to change at line 947 skipping to change at line 921
\mbox{\rm Hessian}(I) = \left( \mbox{\rm Hessian}(I) = \left(
\begin{array}{cc} \begin{array}{cc}
G_{xx} \ast I & G_{xy} \ast I \\ G_{xx} \ast I & G_{xy} \ast I \\
G_{xy} \ast I & G_{yy} \ast I G_{xy} \ast I & G_{yy} \ast I
\end{array} \right) \end{array} \right)
\f] \f]
where \f$G_{xx}, G_{xy}, G_{yy}\f$ denote 2nd derivatives of Gaussians where \f$G_{xx}, G_{xy}, G_{yy}\f$ denote 2nd derivatives of Gaussians
at the given scale, and at the given scale, and
\f$\ast\f$ is the convolution symbol. This function calls \f$\ast\f$ is the convolution symbol. This function calls
\link SeparableConvolution#separableConvolveX separableConvolveX\endlin \ref separableConvolveX() and \ref separableConvolveY()
k() and
\link SeparableConvolution#separableConvolveY separableConvolveY\endlin
k()
with the appropriate 2nd derivative with the appropriate 2nd derivative
of Gaussian kernels and puts the results in of Gaussian kernels and puts the results in
the three destination images. The first destination image will the three destination images. The first destination image will
contain the second derivative in x-direction, the second one the mixed contain the second derivative in x-direction, the second one the mixed
derivative, and the third one holds the derivative in y-direction. derivative, and the third one holds the derivative in y-direction.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
skipping to change at line 973 skipping to change at line 946
class DestIteratorY, class DestAccessorY> class DestIteratorY, class DestAccessorY>
void hessianMatrixOfGaussian(SrcIterator supperleft, void hessianMatrixOfGaussian(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor sa, SrcIterator slowerright, SrcAccessor sa,
DestIteratorX dupperleftx, DestAccessorX da x, DestIteratorX dupperleftx, DestAccessorX da x,
DestIteratorXY dupperleftxy, DestAccessorXY daxy, DestIteratorXY dupperleftxy, DestAccessorXY daxy,
DestIteratorY dupperlefty, DestAccessorY da y, DestIteratorY dupperlefty, DestAccessorY da y,
double scale); double scale);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIteratorX, class DestAccessorX, class DestIteratorX, class DestAccessorX,
class DestIteratorXY, class DestAccessorXY, class DestIteratorXY, class DestAccessorXY,
class DestIteratorY, class DestAccessorY> class DestIteratorY, class DestAccessorY>
inline void inline void
hessianMatrixOfGaussian(triple<SrcIterator, SrcIterator, SrcAccesso r> src, hessianMatrixOfGaussian(triple<SrcIterator, SrcIterator, SrcAccesso r> src,
pair<DestIteratorX, DestAccessorX> destx, pair<DestIteratorX, DestAccessorX> destx,
pair<DestIteratorXY, DestAccessorXY> destxy, pair<DestIteratorXY, DestAccessorXY> destxy,
pair<DestIteratorY, DestAccessorY> desty, pair<DestIteratorY, DestAccessorY> desty,
double scale); double scale);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolut ion.hxx</a>" <b>\#include</b> \<<a href="convolution_8hxx-source.html">vigra/convolu tion.hxx</a>\>
\code \code
vigra::FImage src(w,h), hxx(w,h), hxy(w,h), hyy(w,h); vigra::FImage src(w,h), hxx(w,h), hxy(w,h), hyy(w,h);
... ...
// calculate Hessian of Gaussian at scale = 3.0 // calculate Hessian of Gaussian at scale = 3.0
vigra::hessianMatrixOfGaussian(srcImageRange(src), vigra::hessianMatrixOfGaussian(srcImageRange(src),
destImage(hxx), destImage(hxy), destImage(hyy), 3.0); destImage(hxx), destImage(hxy), destImage(hyy), 3.0);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void hessianMatrixOfGaussian)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIteratorX, class DestAccessorX, class DestIteratorX, class DestAccessorX,
class DestIteratorXY, class DestAccessorXY, class DestIteratorXY, class DestAccessorXY,
class DestIteratorY, class DestAccessorY> class DestIteratorY, class DestAccessorY>
void hessianMatrixOfGaussian(SrcIterator supperleft, void hessianMatrixOfGaussian(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor sa, SrcIterator slowerright, SrcAccessor sa,
DestIteratorX dupperleftx, DestAccessorX dax, DestIteratorX dupperleftx, DestAccessorX dax,
DestIteratorXY dupperleftxy, DestAccessorXY daxy, DestIteratorXY dupperleftxy, DestAccessorXY daxy,
DestIteratorY dupperlefty, DestAccessorY day, DestIteratorY dupperlefty, DestAccessorY day,
double scale) double scale)
skipping to change at line 1085 skipping to change at line 1060
\begin{array}{cc} \begin{array}{cc}
A & C \\ A & C \\
C & B C & B
\end{array} \right) \end{array} \right)
\f] \f]
where \f$G\f$ denotes Gaussian smoothing at the <i>outer scale</i>, where \f$G\f$ denotes Gaussian smoothing at the <i>outer scale</i>,
\f$I_x, I_y\f$ are the gradient components taken at the <i>inner scale< /i>, \f$I_x, I_y\f$ are the gradient components taken at the <i>inner scale< /i>,
\f$\ast\f$ is the convolution symbol, and \f$I_x I_x\f$ etc. are pixelw ise \f$\ast\f$ is the convolution symbol, and \f$I_x I_x\f$ etc. are pixelw ise
products of the 1st derivative images. This function calls products of the 1st derivative images. This function calls
\link SeparableConvolution#separableConvolveX separableConvolveX\endlin \ref separableConvolveX() and \ref separableConvolveY() with the
k()
and \link SeparableConvolution#separableConvolveY separableConvolveY\en
dlink() with the
appropriate Gaussian kernels and puts the results in appropriate Gaussian kernels and puts the results in
the three destination images. The first destination image will the three separate destination images (where the first one will
contain \f$G \ast (I_x I_x)\f$, the second one \f$G \ast (I_x I_y)\f$, and the contain \f$G \ast (I_x I_x)\f$, the second one \f$G \ast (I_x I_y)\f$, and the
third one holds \f$G \ast (I_y I_y)\f$. third one holds \f$G \ast (I_y I_y)\f$), or into a single 3-band image
(where the bands
hold the result in the same order as above). The latter form is also ap
plicable when
the source image is a multi-band image (e.g. RGB). In this case, tensor
s are
first computed for each band separately, and then summed up to get a si
ngle result tensor.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
// create three separate destination images
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIteratorX, class DestAccessorX, class DestIteratorX, class DestAccessorX,
class DestIteratorXY, class DestAccessorXY, class DestIteratorXY, class DestAccessorXY,
class DestIteratorY, class DestAccessorY> class DestIteratorY, class DestAccessorY>
void structureTensor(SrcIterator supperleft, void structureTensor(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor sa, SrcIterator slowerright, SrcAccessor sa,
DestIteratorX dupperleftx, DestAccessorX da x, DestIteratorX dupperleftx, DestAccessorX da x,
DestIteratorXY dupperleftxy, DestAccessorXY daxy, DestIteratorXY dupperleftxy, DestAccessorXY daxy,
DestIteratorY dupperlefty, DestAccessorY da y, DestIteratorY dupperlefty, DestAccessorY da y,
double inner_scale, double outer_scale); double inner_scale, double outer_scale);
// create a single 3-band destination image
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void structureTensor(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor sa,
DestIterator dupperleft, DestAccessor da,
double inner_scale, double outer_scale);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
// create three separate destination images
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIteratorX, class DestAccessorX, class DestIteratorX, class DestAccessorX,
class DestIteratorXY, class DestAccessorXY, class DestIteratorXY, class DestAccessorXY,
class DestIteratorY, class DestAccessorY> class DestIteratorY, class DestAccessorY>
inline void void
structureTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src, structureTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIteratorX, DestAccessorX> destx, pair<DestIteratorX, DestAccessorX> destx,
pair<DestIteratorXY, DestAccessorXY> destxy, pair<DestIteratorXY, DestAccessorXY> destxy,
pair<DestIteratorY, DestAccessorY> desty, pair<DestIteratorY, DestAccessorY> desty,
double nner_scale, double outer_scale); double nner_scale, double outer_scale);
// create a single 3-band destination image
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void
structureTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest,
double nner_scale, double outer_scale);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="convolution_8hxx-source.html">vigra/convolut ion.hxx</a>" <b>\#include</b> \<<a href="convolution_8hxx-source.html">vigra/convolu tion.hxx</a>\>
\code \code
vigra::FImage src(w,h), stxx(w,h), stxy(w,h), styy(w,h); vigra::FImage src(w,h), stxx(w,h), stxy(w,h), styy(w,h);
vigra::BasicImage<TinyVector<float, 3> > st(w,h);
... ...
// calculate Structure Tensor at inner scale = 1.0 and outer scale = 3. 0 // calculate Structure Tensor at inner scale = 1.0 and outer scale = 3. 0
vigra::structureTensor(srcImageRange(src), vigra::structureTensor(srcImageRange(src),
destImage(stxx), destImage(stxy), destImage(styy), 1.0, 3.0); destImage(stxx), destImage(stxy), destImage(styy), 1.0, 3.0);
// dto. with a single 3-band destination image
vigra::structureTensor(srcImageRange(src), destImage(st), 1.0, 3.0);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void structureTensor)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIteratorX, class DestAccessorX, class DestIteratorX, class DestAccessorX,
class DestIteratorXY, class DestAccessorXY, class DestIteratorXY, class DestAccessorXY,
class DestIteratorY, class DestAccessorY> class DestIteratorY, class DestAccessorY>
void structureTensor(SrcIterator supperleft, void structureTensor(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor sa, SrcIterator slowerright, SrcAccessor sa,
DestIteratorX dupperleftx, DestAccessorX dax, DestIteratorX dupperleftx, DestAccessorX dax,
DestIteratorXY dupperleftxy, DestAccessorXY daxy, DestIteratorXY dupperleftxy, DestAccessorXY daxy,
DestIteratorY dupperlefty, DestAccessorY day, DestIteratorY dupperlefty, DestAccessorY day,
double inner_scale, double outer_scale) double inner_scale, double outer_scale)
skipping to change at line 1193 skipping to change at line 1194
pair<DestIteratorY, DestAccessorY> desty, pair<DestIteratorY, DestAccessorY> desty,
double inner_scale, double outer_scale) double inner_scale, double outer_scale)
{ {
structureTensor(src.first, src.second, src.third, structureTensor(src.first, src.second, src.third,
destx.first, destx.second, destx.first, destx.second,
destxy.first, destxy.second, destxy.first, destxy.second,
desty.first, desty.second, desty.first, desty.second,
inner_scale, outer_scale); inner_scale, outer_scale);
} }
namespace detail {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void structureTensor(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor src,
DestIterator dupperleft, DestAccessor dest,
double inner_scale, double outer_scale,
VigraTrueType /* isScalar */)
{
typedef VectorElementAccessor<DestAccessor> DA;
structureTensor(supperleft, slowerright, src,
dupperleft, DA(0, dest),
dupperleft, DA(1, dest),
dupperleft, DA(2, dest),
inner_scale, outer_scale);
}
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void structureTensor(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor src,
DestIterator dupperleft, DestAccessor dest,
double inner_scale, double outer_scale,
VigraFalseType /* isScalar */)
{
int bands = src.size(supperleft);
typedef VectorElementAccessor<SrcAccessor> SA;
structureTensor(supperleft, slowerright, SA(0, src),
dupperleft, dest,
inner_scale, outer_scale,
VigraTrueType() /* isScalar */);
BasicImage<typename DestAccessor::value_type> st(slowerright - supperle
ft);
for(int k=1; k < bands; ++k)
{
structureTensor(supperleft, slowerright, SA(k, src),
st.upperLeft(), st.accessor(),
inner_scale, outer_scale,
VigraTrueType() /* isScalar */);
combineTwoImages(srcImageRange(st), srcIter(dupperleft, dest), dest
Iter(dupperleft, dest),
std::plus<typename DestAccessor::value_type>());
}
}
} // namespace detail
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void structureTensor(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor src,
DestIterator dupperleft, DestAccessor dest,
double inner_scale, double outer_scale)
{
typedef typename
NumericTraits<typename SrcAccessor::value_type>::isScalar isScalar;
detail::structureTensor(supperleft, slowerright, src,
dupperleft, dest, inner_scale, outer_scale, isS
calar());
}
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
inline void
structureTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest,
double inner_scale, double outer_scale)
{
structureTensor(src.first, src.second, src.third,
dest.first, dest.second,
inner_scale, outer_scale);
}
//@} //@}
} // namespace vigra } // namespace vigra
#endif // VIGRA_CONVOLUTION_HXX #endif // VIGRA_CONVOLUTION_HXX
 End of changes. 55 change blocks. 
119 lines changed or deleted 193 lines changed or added


 copyimage.hxx   copyimage.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 106 skipping to change at line 106
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void void
copyImage(SrcImageIterator src_upperleft, copyImage(SrcImageIterator src_upperleft,
SrcImageIterator src_lowerright, SrcAccessor sa, SrcImageIterator src_lowerright, SrcAccessor sa,
DestImageIterator dest_upperleft, DestAccessor da) DestImageIterator dest_upperleft, DestAccessor da)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void void
copyImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> s rc, copyImage(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> s rc,
pair<DestImageIterator, DestAccessor> dest) pair<DestImageIterator, DestAccessor> dest)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="copyimage_8hxx-source.html">vigra/copyim age.hxx</a>"<br> <b>\#include</b> \<<a href="copyimage_8hxx-source.html">vigra/copyi mage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::copyImage(srcImageRange(src), destImage(dest)); vigra::copyImage(srcImageRange(src), destImage(dest));
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
\code \code
skipping to change at line 143 skipping to change at line 143
DestImageIterator::row_iterator dx = dest_upperleft.rowIterator(); DestImageIterator::row_iterator dx = dest_upperleft.rowIterator();
SrcAccessor src_accessor; SrcAccessor src_accessor;
DestAccessor dest_accessor; DestAccessor dest_accessor;
dest_accessor.set(src_accessor(sx), dx); dest_accessor.set(src_accessor(sx), dx);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void copyImage)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void void
copyImage(SrcImageIterator src_upperleft, copyImage(SrcImageIterator src_upperleft,
SrcImageIterator src_lowerright, SrcAccessor sa, SrcImageIterator src_lowerright, SrcAccessor sa,
DestImageIterator dest_upperleft, DestAccessor da) DestImageIterator dest_upperleft, DestAccessor da)
{ {
int w = src_lowerright.x - src_upperleft.x; int w = src_lowerright.x - src_upperleft.x;
for(; src_upperleft.y<src_lowerright.y; ++src_upperleft.y, ++dest_upper left.y) for(; src_upperleft.y<src_lowerright.y; ++src_upperleft.y, ++dest_upper left.y)
skipping to change at line 200 skipping to change at line 202
class MaskImageIterator, class MaskAccessor, class MaskImageIterator, class MaskAccessor,
class DestImageIterator, clas DestAccessor> class DestImageIterator, clas DestAccessor>
void void
copyImageIf(SrcImageIterator src_upperleft, copyImageIf(SrcImageIterator src_upperleft,
SrcImageIterator src_lowerright, SrcAccessor sa, SrcImageIterator src_lowerright, SrcAccessor sa,
MaskImageIterator mask_upperleft, MaskAccessor ma, MaskImageIterator mask_upperleft, MaskAccessor ma,
DestImageIterator dest_upperleft, DestAccessor da) DestImageIterator dest_upperleft, DestAccessor da)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class MaskImageIterator, class MaskAccessor, class MaskImageIterator, class MaskAccessor,
class DestImageIterator, clas DestAccessor> class DestImageIterator, clas DestAccessor>
void void
copyImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, copyImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<MaskImageIterator, MaskAccessor> mask, pair<MaskImageIterator, MaskAccessor> mask,
pair<DestImageIterator, DestAccessor> dest) pair<DestImageIterator, DestAccessor> dest)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="copyimage_8hxx-source.html">vigra/copyim age.hxx</a>"<br> <b>\#include</b> \<<a href="copyimage_8hxx-source.html">vigra/copyi mage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::copyImageIf(srcImageRange(src), maskImage(mask), destImage(dest) ); vigra::copyImageIf(srcImageRange(src), maskImage(mask), destImage(dest) );
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
\code \code
skipping to change at line 244 skipping to change at line 246
DestAccessor dest_accessor; DestAccessor dest_accessor;
MaskAccessor mask_accessor; MaskAccessor mask_accessor;
Functor functor; Functor functor;
if(mask_accessor(mx)) if(mask_accessor(mx))
dest_accessor.set(src_accessor(sx), dx); dest_accessor.set(src_accessor(sx), dx);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void copyImageIf)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class MaskImageIterator, class MaskAccessor, class MaskImageIterator, class MaskAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void void
copyImageIf(SrcImageIterator src_upperleft, copyImageIf(SrcImageIterator src_upperleft,
SrcImageIterator src_lowerright, SrcAccessor sa, SrcImageIterator src_lowerright, SrcAccessor sa,
MaskImageIterator mask_upperleft, MaskAccessor ma, MaskImageIterator mask_upperleft, MaskAccessor ma,
DestImageIterator dest_upperleft, DestAccessor da) DestImageIterator dest_upperleft, DestAccessor da)
{ {
int w = src_lowerright.x - src_upperleft.x; int w = src_lowerright.x - src_upperleft.x;
 End of changes. 8 change blocks. 
7 lines changed or deleted 11 lines changed or added


 cornerdetection.hxx   cornerdetection.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2004 by Ullrich Koethe */ /* Copyright 1998-2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 157 skipping to change at line 157
/** \brief Find corners in an image (1). /** \brief Find corners in an image (1).
This algorithm implements the so called 'corner response function' This algorithm implements the so called 'corner response function'
to measure the 'cornerness' of each pixel in the image, according to to measure the 'cornerness' of each pixel in the image, according to
[C.G. Harris and M.J. Stevens: <em> "A Combined Corner and Edge Detecto r"</em>, [C.G. Harris and M.J. Stevens: <em> "A Combined Corner and Edge Detecto r"</em>,
Proc. of 4th Alvey Vision Conference, 1988]. Several studies have found this to be a Proc. of 4th Alvey Vision Conference, 1988]. Several studies have found this to be a
very robust corner detector, although it moves the corners somewhat int o one very robust corner detector, although it moves the corners somewhat int o one
region, depending on the scale. region, depending on the scale.
The algorithm first determines the structure tensor at each pixel by ca lling The algorithm first determines the structure tensor at each pixel by ca lling
\link CommonConvolutionFilters#structureTensor structureTensor\endlink( \ref structureTensor(). Then the entries of the structure tensor are co
). mbined as
Then the entries of the structure tensor are combined as
\f[ \f[
\mbox{\rm CornerResponse} = \mbox{\rm det(StructureTensor)} - 0.04 \mbox{\rm tr(StructureTensor)}^2 \mbox{\rm CornerResponse} = \mbox{\rm det(StructureTensor)} - 0.04 \mbox{\rm tr(StructureTensor)}^2
= A B - C^2 - 0.04 (A + B)^2 = A B - C^2 - 0.04 (A + B)^2
\f] \f]
The local maxima of the corner response denote the corners in the gray level The local maxima of the corner response denote the corners in the gray level
image. image.
The source value type must be a linaer algebra, i.e. addition, subtract ion, and The source value type must be a linaer algebra, i.e. addition, subtract ion, and
skipping to change at line 187 skipping to change at line 186
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
cornerResponseFunction(SrcIterator sul, SrcIterator slr, SrcAccesso r as, cornerResponseFunction(SrcIterator sul, SrcIterator slr, SrcAccesso r as,
DestIterator dul, DestAccessor ad, DestIterator dul, DestAccessor ad,
double scale) double scale)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline inline
void cornerResponseFunction( void cornerResponseFunction(
triple<SrcIterator, SrcIterator, SrcAccessor> src, triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale) double scale)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/ cornerdetection.hxx</a>"<br> <b>\#include</b> \<<a href="cornerdetection_8hxx-source.html">vigra /cornerdetection.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), corners(w,h); vigra::BImage src(w,h), corners(w,h);
vigra::FImage corner_response(w,h); vigra::FImage corner_response(w,h);
// empty corner image // empty corner image
corners.init(0.0); corners.init(0.0);
... ...
skipping to change at line 250 skipping to change at line 249
double d; double d;
u = u + u u = u + u
u = u - u u = u - u
u = u * u u = u * u
u = d * u u = d * u
dest_accessor.set(u, dest_upperleft); dest_accessor.set(u, dest_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void cornerResponseFunction)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
cornerResponseFunction(SrcIterator sul, SrcIterator slr, SrcAccessor as, cornerResponseFunction(SrcIterator sul, SrcIterator slr, SrcAccessor as,
DestIterator dul, DestAccessor ad, DestIterator dul, DestAccessor ad,
double scale) double scale)
{ {
vigra_precondition(scale > 0.0, vigra_precondition(scale > 0.0,
"cornerResponseFunction(): Scale must be > 0"); "cornerResponseFunction(): Scale must be > 0");
skipping to change at line 310 skipping to change at line 311
/********************************************************/ /********************************************************/
/** \brief Find corners in an image (2). /** \brief Find corners in an image (2).
This algorithm implements the so called 'Foerstner Corner Detector' This algorithm implements the so called 'Foerstner Corner Detector'
to measure the 'cornerness' of each pixel in the image, according to to measure the 'cornerness' of each pixel in the image, according to
[W. F&ouml;rstner: <em> "A feature based correspondence algorithms for image [W. F&ouml;rstner: <em> "A feature based correspondence algorithms for image
matching"</em>, Intl. Arch. Photogrammetry and Remote Sensing, vol. 24, pp 160-166, matching"</em>, Intl. Arch. Photogrammetry and Remote Sensing, vol. 24, pp 160-166,
1986]. It is also known as the "Plessey Detector" by Harris. However, i t should not 1986]. It is also known as the "Plessey Detector" by Harris. However, i t should not
be confused with the be confused with the
"\link CornerDetection#cornerResponseFunction Corner Repsonse Function\ endlink ", "\link cornerResponseFunction Corner Response Function\endlink ",
another detector invented by Harris. another detector invented by Harris.
The algorithm first determines the structure tensor at each pixel by ca lling The algorithm first determines the structure tensor at each pixel by ca lling
\link CommonConvolutionFilters#structureTensor structureTensor\endlink( \ref structureTensor(). Then the entries of the structure tensor are co
). mbined as
Then the entries of the structure tensor are combined as
\f[ \f[
\mbox{\rm FoerstnerCornerStrength} = \frac{\mbox{\rm det(StructureT ensor)}}{\mbox{\rm tr(StructureTensor)}} = \mbox{\rm FoerstnerCornerStrength} = \frac{\mbox{\rm det(StructureT ensor)}}{\mbox{\rm tr(StructureTensor)}} =
\frac{A B - C^2}{A + B} \frac{A B - C^2}{A + B}
\f] \f]
The local maxima of the corner strength denote the corners in the gray level The local maxima of the corner strength denote the corners in the gray level
image. Its performance is similar to the image. Its performance is similar to the \ref cornerResponseFunction().
\link CornerDetection#cornerResponseFunction cornerResponseFunction\end
link().
The source value type must be a division algebra, i.e. addition, subtra ction, The source value type must be a division algebra, i.e. addition, subtra ction,
multiplication, and division with itself, multiplication with doubles a nd multiplication, and division with itself, multiplication with doubles a nd
\ref NumericTraits "NumericTraits" must \ref NumericTraits "NumericTraits" must
be defined. be defined.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
foerstnerCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccess or as, foerstnerCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccess or as,
DestIterator dul, DestAccessor ad, DestIterator dul, DestAccessor ad,
double scale) double scale)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline inline
void foerstnerCornerDetector( void foerstnerCornerDetector(
triple<SrcIterator, SrcIterator, SrcAccessor> src, triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale) double scale)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/ cornerdetection.hxx</a>"<br> <b>\#include</b> \<<a href="cornerdetection_8hxx-source.html">vigra /cornerdetection.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), corners(w,h); vigra::BImage src(w,h), corners(w,h);
vigra::FImage foerstner_corner_strength(w,h); vigra::FImage foerstner_corner_strength(w,h);
// empty corner image // empty corner image
corners.init(0.0); corners.init(0.0);
... ...
skipping to change at line 400 skipping to change at line 399
u = u + u u = u + u
u = u - u u = u - u
u = u * u u = u * u
u = u / u u = u / u
u = d * u u = d * u
dest_accessor.set(u, dest_upperleft); dest_accessor.set(u, dest_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void foerstnerCornerDetector)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
foerstnerCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as, foerstnerCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
DestIterator dul, DestAccessor ad, DestIterator dul, DestAccessor ad,
double scale) double scale)
{ {
vigra_precondition(scale > 0.0, vigra_precondition(scale > 0.0,
"foerstnerCornerDetector(): Scale must be > 0"); "foerstnerCornerDetector(): Scale must be > 0");
skipping to change at line 463 skipping to change at line 464
This algorithm implements yet another structure tensor-based corner det ector, This algorithm implements yet another structure tensor-based corner det ector,
according to [K. Rohr: <em>"Untersuchung von grauwertabh&auml;ngigen according to [K. Rohr: <em>"Untersuchung von grauwertabh&auml;ngigen
Transformationen zur Ermittlung der optischen Flusses in Bildfolgen"</e m>, Transformationen zur Ermittlung der optischen Flusses in Bildfolgen"</e m>,
Diploma thesis, Inst. f&uuml;r Nachrichtensysteme, Univ. Karlsruhe, 198 7, see also Diploma thesis, Inst. f&uuml;r Nachrichtensysteme, Univ. Karlsruhe, 198 7, see also
K. Rohr: <em>"Modelling and Identification of Characteristic Intensity Variations"</em>, K. Rohr: <em>"Modelling and Identification of Characteristic Intensity Variations"</em>,
Image and Vision Computing 10:2 (1992) 66-76 and K. Rohr: <em>"Localiza tion Properties of Image and Vision Computing 10:2 (1992) 66-76 and K. Rohr: <em>"Localiza tion Properties of
Direct Corner Detectors"</em>, J. of Mathematical Imaging and Vision 4: 2 (1994) 139-150]. Direct Corner Detectors"</em>, J. of Mathematical Imaging and Vision 4: 2 (1994) 139-150].
The algorithm first determines the structure tensor at each pixel by ca lling The algorithm first determines the structure tensor at each pixel by ca lling
\link CommonConvolutionFilters#structureTensor structureTensor\endlink( \ref structureTensor(). Then the entries of the structure tensor are co
). mbined as
Then the entries of the structure tensor are combined as
\f[ \f[
\mbox{\rm RohrCornerStrength} = \mbox{\rm det(StructureTensor)} = A B - C^2 \mbox{\rm RohrCornerStrength} = \mbox{\rm det(StructureTensor)} = A B - C^2
\f] \f]
The local maxima of the corner strength denote the corners in the gray level The local maxima of the corner strength denote the corners in the gray level
image. Its performance is similar to the image. Its performance is similar to the \ref cornerResponseFunction().
\link CornerDetection#cornerResponseFunction cornerResponseFunction\end
link().
The source value type must be a linear algebra, i.e. addition, subtract ion, and The source value type must be a linear algebra, i.e. addition, subtract ion, and
multiplication with itself, multiplication with doubles and multiplication with itself, multiplication with doubles and
\ref NumericTraits "NumericTraits" must \ref NumericTraits "NumericTraits" must
be defined. be defined.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
rohrCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as , rohrCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as ,
DestIterator dul, DestAccessor ad, DestIterator dul, DestAccessor ad,
double scale) double scale)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline inline
void rohrCornerDetector( void rohrCornerDetector(
triple<SrcIterator, SrcIterator, SrcAccessor> src, triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale) double scale)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/ cornerdetection.hxx</a>"<br> <b>\#include</b> \<<a href="cornerdetection_8hxx-source.html">vigra /cornerdetection.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), corners(w,h); vigra::BImage src(w,h), corners(w,h);
vigra::FImage rohr_corner_strength(w,h); vigra::FImage rohr_corner_strength(w,h);
// empty corner image // empty corner image
corners.init(0.0); corners.init(0.0);
... ...
skipping to change at line 547 skipping to change at line 546
double d; double d;
u = u + u u = u + u
u = u - u u = u - u
u = u * u u = u * u
u = d * u u = d * u
dest_accessor.set(u, dest_upperleft); dest_accessor.set(u, dest_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void rohrCornerDetector)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
rohrCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as, rohrCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
DestIterator dul, DestAccessor ad, DestIterator dul, DestAccessor ad,
double scale) double scale)
{ {
vigra_precondition(scale > 0.0, vigra_precondition(scale > 0.0,
"rohrCornerDetector(): Scale must be > 0"); "rohrCornerDetector(): Scale must be > 0");
skipping to change at line 606 skipping to change at line 607
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Find corners in an image (4). /** \brief Find corners in an image (4).
This algorithm implements a corner detector This algorithm implements a corner detector
according to [P.R. Beaudet: <em> "Rotationally Invariant Image Operator s"</em>, according to [P.R. Beaudet: <em> "Rotationally Invariant Image Operator s"</em>,
Proc. Intl. Joint Conf. on Pattern Recognition, Kyoto, Japan, 1978, pp. 579-583]. Proc. Intl. Joint Conf. on Pattern Recognition, Kyoto, Japan, 1978, pp. 579-583].
The algorithm calculates the corner strength as the negative determinan t of the The algorithm calculates the corner strength as the negative determinan t of the
\link CommonConvolutionFilters#hessianMatrixOfGaussian Hessian Matrix\e ndlink. \link hessianMatrixOfGaussian() Hessian Matrix\endlink.
The local maxima of the corner strength denote the corners in the gray level The local maxima of the corner strength denote the corners in the gray level
image. image.
The source value type must be a linear algebra, i.e. addition, subtract ion, and The source value type must be a linear algebra, i.e. addition, subtract ion, and
multiplication with itself, multiplication with doubles and multiplication with itself, multiplication with doubles and
\ref NumericTraits "NumericTraits" must \ref NumericTraits "NumericTraits" must
be defined. be defined.
<b> Declarations:</b> <b> Declarations:</b>
skipping to change at line 629 skipping to change at line 630
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
beaudetCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as, beaudetCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
DestIterator dul, DestAccessor ad, DestIterator dul, DestAccessor ad,
double scale) double scale)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline inline
void beaudetCornerDetector( void beaudetCornerDetector(
triple<SrcIterator, SrcIterator, SrcAccessor> src, triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale) double scale)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="cornerdetection_8hxx-source.html">vigra/ cornerdetection.hxx</a>"<br> <b>\#include</b> \<<a href="cornerdetection_8hxx-source.html">vigra /cornerdetection.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), corners(w,h); vigra::BImage src(w,h), corners(w,h);
vigra::FImage beaudet_corner_strength(w,h); vigra::FImage beaudet_corner_strength(w,h);
// empty corner image // empty corner image
corners.init(0.0); corners.init(0.0);
... ...
skipping to change at line 683 skipping to change at line 684
double d; double d;
u = u + u u = u + u
u = u - u u = u - u
u = u * u u = u * u
u = d * u u = d * u
dest_accessor.set(u, dest_upperleft); dest_accessor.set(u, dest_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void beaudetCornerDetector)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
beaudetCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as, beaudetCornerDetector(SrcIterator sul, SrcIterator slr, SrcAccessor as,
DestIterator dul, DestAccessor ad, DestIterator dul, DestAccessor ad,
double scale) double scale)
{ {
vigra_precondition(scale > 0.0, vigra_precondition(scale > 0.0,
"beaudetCornerDetector(): Scale must be > 0"); "beaudetCornerDetector(): Scale must be > 0");
 End of changes. 21 change blocks. 
28 lines changed or deleted 29 lines changed or added


 diff2d.hxx   diff2d.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2003 by Hans Meine */ /* Copyright 1998-2003 by Hans Meine */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 181 skipping to change at line 181
Diff2D is also returned by <TT>image.size()</TT>, so that we can create Diff2D is also returned by <TT>image.size()</TT>, so that we can create
new images by calculating their size using Diff2D's arithmetic new images by calculating their size using Diff2D's arithmetic
functions: functions:
\code \code
// create an image that is 10 pixels smaller in each direction // create an image that is 10 pixels smaller in each direction
Image new_image(old_image.size() - Diff2D(10,10)); Image new_image(old_image.size() - Diff2D(10,10));
\endcode \endcode
<b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx </a>"<br> <b>\#include</b> \<<a href="diff2d_8hxx-source.html">vigra/utilities.hx x</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
class Diff2D class Diff2D
{ {
public: public:
/** The iterator's value type: a coordinate. /** The iterator's value type: a coordinate.
*/ */
typedef Diff2D PixelType; typedef Diff2D PixelType;
/** The iterator's value type: a coordinate. /** The iterator's value type: a coordinate.
skipping to change at line 476 skipping to change at line 476
Specializes \ref Diff2D for the specification of a 2-dimensional Specializes \ref Diff2D for the specification of a 2-dimensional
extent, in contrast to a point or position (for the latter extent, in contrast to a point or position (for the latter
use \ref Point2D). use \ref Point2D).
\code \code
// create an image that is 10 pixels squared // create an image that is 10 pixels squared
Image new_image(Size2D(10,10)); Image new_image(Size2D(10,10));
\endcode \endcode
<b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx </a>"<br> <b>\#include</b> \<<a href="diff2d_8hxx-source.html">vigra/utilities.hx x</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
class Size2D : public Diff2D class Size2D : public Diff2D
{ {
public: public:
/** Default Constructor. Init point at position (0,0) /** Default Constructor. Init point at position (0,0)
*/ */
Size2D() Size2D()
{} {}
skipping to change at line 586 skipping to change at line 586
Specializes \ref Diff2D for the specification of a 2-dimensional Specializes \ref Diff2D for the specification of a 2-dimensional
point or position, in contrast to an extent (for the latter point or position, in contrast to an extent (for the latter
use \ref Size2D). use \ref Size2D).
\code \code
// access an image at a point // access an image at a point
value = image[Point2D(10, 20)]; value = image[Point2D(10, 20)];
\endcode \endcode
<b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx </a>"<br> <b>\#include</b> \<<a href="diff2d_8hxx-source.html">vigra/utilities.hx x</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
class Point2D : public Diff2D class Point2D : public Diff2D
{ {
public: public:
/** The iterator's value type: a coordinate. /** The iterator's value type: a coordinate.
*/ */
typedef Point2D PixelType; typedef Point2D PixelType;
/** The iterator's value type: a coordinate. /** The iterator's value type: a coordinate.
skipping to change at line 865 skipping to change at line 865
Point2D p(0,100); Point2D p(0,100);
Rect2D r3 = r1 | r2; // upper left is (0,0), lower right is (30, 35) Rect2D r3 = r1 | r2; // upper left is (0,0), lower right is (30, 35)
assert(r3.contains(r2)); assert(r3.contains(r2));
assert(!r3.contains(p)); assert(!r3.contains(p));
r3 |= p; // lower right now (30,101) so that p is inside r3 r3 |= p; // lower right now (30,101) so that p is inside r3
assert(r3.contains(p)); assert(r3.contains(p));
\endcode \endcode
<b>\#include</b> "<a href="diff2d_8hxx-source.html">vigra/utilities.hxx </a>"<br> <b>\#include</b> \<<a href="diff2d_8hxx-source.html">vigra/utilities.hx x</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
class Rect2D class Rect2D
{ {
Point2D upperLeft_, lowerRight_; Point2D upperLeft_, lowerRight_;
public: public:
/** Construct a null rectangle (isEmpty() will return true) /** Construct a null rectangle (isEmpty() will return true)
*/ */
Rect2D() Rect2D()
 End of changes. 6 change blocks. 
7 lines changed or deleted 7 lines changed or added


 distancetransform.hxx   distancetransform.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 277 skipping to change at line 277
/********************************************************/ /********************************************************/
/* */ /* */
/* distanceTransform */ /* distanceTransform */
/* */ /* */
/********************************************************/ /********************************************************/
/** \addtogroup DistanceTransform Distance Transform /** \addtogroup DistanceTransform Distance Transform
Perform a distance transform using either the Euclidean, Manhattan, Perform a distance transform using either the Euclidean, Manhattan,
or chessboard metrics. or chessboard metrics.
See also: \ref MultiArrayDistanceTransform "multi-dimensional distance
transforms"
*/ */
//@{ //@{
/** For all background pixels, calculate the distance to /** For all background pixels, calculate the distance to
the nearest object or contour. The label of the pixels to be considered the nearest object or contour. The label of the pixels to be considered
background in the source image is passed in the parameter 'background'. background in the source image is passed in the parameter 'background'.
Source pixels with other labels will be considered objects. In the Source pixels with other labels will be considered objects. In the
destination image, all pixels corresponding to background will be assig ned destination image, all pixels corresponding to background will be assig ned
the their distance value, all pixels corresponding to objects will be the their distance value, all pixels corresponding to objects will be
assigned 0. assigned 0.
skipping to change at line 316 skipping to change at line 318
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class ValueType> class ValueType>
void distanceTransform(SrcImageIterator src_upperleft, void distanceTransform(SrcImageIterator src_upperleft,
SrcImageIterator src_lowerright, SrcAccessor sa, SrcImageIterator src_lowerright, SrcAccessor sa,
DestImageIterator dest_upperleft, DestAccessor da, DestImageIterator dest_upperleft, DestAccessor da,
ValueType background, int norm) ValueType background, int norm)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class ValueType> class ValueType>
void distanceTransform( void distanceTransform(
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
ValueType background, int norm) ValueType background, int norm)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="distancetransform_8hxx-source.html">vigra/di stancetransform.hxx</a>"<br> <b>\#include</b> \<<a href="distancetransform_8hxx-source.html">vigra/d istancetransform.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), edges(w,h); vigra::BImage src(w,h), edges(w,h);
vigra::FImage distance(w, h); vigra::FImage distance(w, h);
// empty edge image // empty edge image
edges = 0; edges = 0;
... ...
skipping to change at line 372 skipping to change at line 374
ValueType background; ValueType background;
float distance; float distance;
sa(src_upperleft) != background; sa(src_upperleft) != background;
da(dest_upperleft) < distance; da(dest_upperleft) < distance;
da.set(distance, dest_upperleft); da.set(distance, dest_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void distanceTransform)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class ValueType> class ValueType>
inline void inline void
distanceTransform(SrcImageIterator src_upperleft, distanceTransform(SrcImageIterator src_upperleft,
SrcImageIterator src_lowerright, SrcAccessor sa, SrcImageIterator src_lowerright, SrcAccessor sa,
DestImageIterator dest_upperleft, DestAccessor da, DestImageIterator dest_upperleft, DestAccessor da,
ValueType background, int norm) ValueType background, int norm)
{ {
if(norm == 1) if(norm == 1)
 End of changes. 6 change blocks. 
5 lines changed or deleted 10 lines changed or added


 edgedetection.hxx   edgedetection.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 116 skipping to change at line 116
class GradValue, class GradValue,
class DestValue = DestAccessor::value_type> class DestValue = DestAccessor::value_type>
void differenceOfExponentialEdgeImage( void differenceOfExponentialEdgeImage(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
double scale, GradValue gradient_threshold, double scale, GradValue gradient_threshold,
DestValue edge_marker = NumericTraits<DestValue>::one()) DestValue edge_marker = NumericTraits<DestValue>::one())
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class GradValue, class GradValue,
class DestValue = DestAccessor::value_type> class DestValue = DestAccessor::value_type>
inline
void differenceOfExponentialEdgeImage( void differenceOfExponentialEdgeImage(
triple<SrcIterator, SrcIterator, SrcAccessor> src, triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale, GradValue gradient_threshold, double scale, GradValue gradient_threshold,
DestValue edge_marker = NumericTraits<DestValue>::one()) DestValue edge_marker = NumericTraits<DestValue>::one())
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="edgedetection_8hxx-source.html">vigra/ed gedetection.hxx</a>"<br> <b>\#include</b> \<<a href="edgedetection_8hxx-source.html">vigra/e dgedetection.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), edges(w,h); vigra::BImage src(w,h), edges(w,h);
// empty edge image // empty edge image
edges = 0; edges = 0;
... ...
// find edges at scale 0.8 with gradient larger than 4.0, mark with 1 // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
skipping to change at line 179 skipping to change at line 178
dest_accessor.set(edge_marker, dest_upperleft); dest_accessor.set(edge_marker, dest_upperleft);
\endcode \endcode
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
scale > 0 scale > 0
gradient_threshold > 0 gradient_threshold > 0
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void differenceOfExponentialEdge
Image)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class GradValue, class DestValue> class GradValue, class DestValue>
void differenceOfExponentialEdgeImage( void differenceOfExponentialEdgeImage(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
double scale, GradValue gradient_threshold, DestValue edge_marke r) double scale, GradValue gradient_threshold, DestValue edge_marke r)
{ {
vigra_precondition(scale > 0, vigra_precondition(scale > 0,
"differenceOfExponentialEdgeImage(): scale > 0 required.") ; "differenceOfExponentialEdgeImage(): scale > 0 required.") ;
skipping to change at line 393 skipping to change at line 394
class GradValue, class GradValue,
class DestValue = DestAccessor::value_type> class DestValue = DestAccessor::value_type>
void differenceOfExponentialCrackEdgeImage( void differenceOfExponentialCrackEdgeImage(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
double scale, GradValue gradient_threshold, double scale, GradValue gradient_threshold,
DestValue edge_marker = NumericTraits<DestValue>::one()) DestValue edge_marker = NumericTraits<DestValue>::one())
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class GradValue, class GradValue,
class DestValue = DestAccessor::value_type> class DestValue = DestAccessor::value_type>
inline
void differenceOfExponentialCrackEdgeImage( void differenceOfExponentialCrackEdgeImage(
triple<SrcIterator, SrcIterator, SrcAccessor> src, triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale, GradValue gradient_threshold, double scale, GradValue gradient_threshold,
DestValue edge_marker = NumericTraits<DestValue>::one()) DestValue edge_marker = NumericTraits<DestValue>::one())
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="edgedetection_8hxx-source.html">vigra/ed gedetection.hxx</a>"<br> <b>\#include</b> \<<a href="edgedetection_8hxx-source.html">vigra/e dgedetection.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), edges(2*w-1,2*h-1); vigra::BImage src(w,h), edges(2*w-1,2*h-1);
// empty edge image // empty edge image
edges = 0; edges = 0;
... ...
// find edges at scale 0.8 with gradient larger than 4.0, mark with 1 // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
skipping to change at line 462 skipping to change at line 462
scale > 0 scale > 0
gradient_threshold > 0 gradient_threshold > 0
\endcode \endcode
The destination image must have twice the size of the source: The destination image must have twice the size of the source:
\code \code
w_dest = 2 * w_src - 1 w_dest = 2 * w_src - 1
h_dest = 2 * h_src - 1 h_dest = 2 * h_src - 1
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void differenceOfExponentialCrac
kEdgeImage)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class GradValue, class DestValue> class GradValue, class DestValue>
void differenceOfExponentialCrackEdgeImage( void differenceOfExponentialCrackEdgeImage(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
double scale, GradValue gradient_threshold, double scale, GradValue gradient_threshold,
DestValue edge_marker) DestValue edge_marker)
{ {
vigra_precondition(scale > 0, vigra_precondition(scale > 0,
skipping to change at line 697 skipping to change at line 699
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class Iterator, class Accessor, class SrcValue> template <class Iterator, class Accessor, class SrcValue>
void removeShortEdges( void removeShortEdges(
Iterator sul, Iterator slr, Accessor sa, Iterator sul, Iterator slr, Accessor sa,
int min_edge_length, SrcValue non_edge_marker) int min_edge_length, SrcValue non_edge_marker)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class Iterator, class Accessor, class SrcValue> template <class Iterator, class Accessor, class SrcValue>
inline
void removeShortEdges( void removeShortEdges(
triple<Iterator, Iterator, Accessor> src, triple<Iterator, Iterator, Accessor> src,
int min_edge_length, SrcValue non_edge_marker) int min_edge_length, SrcValue non_edge_marker)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="edgedetection_8hxx-source.html">vigra/ed gedetection.hxx</a>"<br> <b>\#include</b> \<<a href="edgedetection_8hxx-source.html">vigra/e dgedetection.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), edges(w,h); vigra::BImage src(w,h), edges(w,h);
// empty edge image // empty edge image
edges = 0; edges = 0;
... ...
// find edges at scale 0.8 with gradient larger than 4.0, mark with 1 // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
skipping to change at line 745 skipping to change at line 746
DestAccessor dest_accessor; DestAccessor dest_accessor;
SrcAccessor::value_type u = src_accessor(src_upperleft); SrcAccessor::value_type u = src_accessor(src_upperleft);
u == u u == u
SrcValue non_edge_marker; SrcValue non_edge_marker;
src_accessor.set(non_edge_marker, src_upperleft); src_accessor.set(non_edge_marker, src_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void removeShortEdges)
template <class Iterator, class Accessor, class Value> template <class Iterator, class Accessor, class Value>
void removeShortEdges( void removeShortEdges(
Iterator sul, Iterator slr, Accessor sa, Iterator sul, Iterator slr, Accessor sa,
unsigned int min_edge_length, Value non_edge_marker) unsigned int min_edge_length, Value non_edge_marker)
{ {
int w = slr.x - sul.x; int w = slr.x - sul.x;
int h = slr.y - sul.y; int h = slr.y - sul.y;
int x,y; int x,y;
IImage labels(w, h); IImage labels(w, h);
skipping to change at line 829 skipping to change at line 832
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, class SrcValue> template <class SrcIterator, class SrcAccessor, class SrcValue>
void closeGapsInCrackEdgeImage( void closeGapsInCrackEdgeImage(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
SrcValue edge_marker) SrcValue edge_marker)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, class SrcValue> template <class SrcIterator, class SrcAccessor, class SrcValue>
inline
void closeGapsInCrackEdgeImage( void closeGapsInCrackEdgeImage(
triple<SrcIterator, SrcIterator, SrcAccessor> src, triple<SrcIterator, SrcIterator, SrcAccessor> src,
SrcValue edge_marker) SrcValue edge_marker)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="edgedetection_8hxx-source.html">vigra/ed gedetection.hxx</a>"<br> <b>\#include</b> \<<a href="edgedetection_8hxx-source.html">vigra/e dgedetection.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), edges(2*w-1, 2*h-1); vigra::BImage src(w,h), edges(2*w-1, 2*h-1);
// empty edge image // empty edge image
edges = 0; edges = 0;
... ...
// find edges at scale 0.8 with gradient larger than 4.0, mark with 1 // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
skipping to change at line 880 skipping to change at line 882
SrcAccessor::value_type u = src_accessor(src_upperleft); SrcAccessor::value_type u = src_accessor(src_upperleft);
u == u u == u
u != u u != u
SrcValue edge_marker; SrcValue edge_marker;
src_accessor.set(edge_marker, src_upperleft); src_accessor.set(edge_marker, src_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void closeGapsInCrackEdgeImage)
template <class SrcIterator, class SrcAccessor, class SrcValue> template <class SrcIterator, class SrcAccessor, class SrcValue>
void closeGapsInCrackEdgeImage( void closeGapsInCrackEdgeImage(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
SrcValue edge_marker) SrcValue edge_marker)
{ {
int w = (slr.x - sul.x) / 2; int w = (slr.x - sul.x) / 2;
int h = (slr.y - sul.y) / 2; int h = (slr.y - sul.y) / 2;
int x, y; int x, y;
int count1, count2, count3; int count1, count2, count3;
skipping to change at line 1041 skipping to change at line 1045
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, class SrcValue> template <class SrcIterator, class SrcAccessor, class SrcValue>
void beautifyCrackEdgeImage( void beautifyCrackEdgeImage(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
SrcValue edge_marker, SrcValue background_marker) SrcValue edge_marker, SrcValue background_marker)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, class SrcValue> template <class SrcIterator, class SrcAccessor, class SrcValue>
inline
void beautifyCrackEdgeImage( void beautifyCrackEdgeImage(
triple<SrcIterator, SrcIterator, SrcAccessor> src, triple<SrcIterator, SrcIterator, SrcAccessor> src,
SrcValue edge_marker, SrcValue background_marker) SrcValue edge_marker, SrcValue background_marker)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="edgedetection_8hxx-source.html">vigra/ed gedetection.hxx</a>"<br> <b>\#include</b> \<<a href="edgedetection_8hxx-source.html">vigra/e dgedetection.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), edges(2*w-1, 2*h-1); vigra::BImage src(w,h), edges(2*w-1, 2*h-1);
// empty edge image // empty edge image
edges = 0; edges = 0;
... ...
// find edges at scale 0.8 with gradient larger than 4.0, mark with 1 // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
skipping to change at line 1092 skipping to change at line 1095
SrcAccessor::value_type u = src_accessor(src_upperleft); SrcAccessor::value_type u = src_accessor(src_upperleft);
u == u u == u
u != u u != u
SrcValue background_marker; SrcValue background_marker;
src_accessor.set(background_marker, src_upperleft); src_accessor.set(background_marker, src_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void beautifyCrackEdgeImage)
template <class SrcIterator, class SrcAccessor, class SrcValue> template <class SrcIterator, class SrcAccessor, class SrcValue>
void beautifyCrackEdgeImage( void beautifyCrackEdgeImage(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
SrcValue edge_marker, SrcValue background_marker) SrcValue edge_marker, SrcValue background_marker)
{ {
int w = (slr.x - sul.x) / 2; int w = (slr.x - sul.x) / 2;
int h = (slr.y - sul.y) / 2; int h = (slr.y - sul.y) / 2;
int x, y; int x, y;
SrcIterator sy = sul + Diff2D(1,1); SrcIterator sy = sul + Diff2D(1,1);
skipping to change at line 1208 skipping to change at line 1213
typedef typename Image1::value_type PixelType; typedef typename Image1::value_type PixelType;
double t = 0.5 / VIGRA_CSTD::sin(M_PI/8.0); double t = 0.5 / VIGRA_CSTD::sin(M_PI/8.0);
for(int y=1; y<gx.height()-1; ++y) for(int y=1; y<gx.height()-1; ++y)
{ {
for(int x=1; x<gx.width()-1; ++x) for(int x=1; x<gx.width()-1; ++x)
{ {
PixelType gradx = gx(x,y); PixelType gradx = gx(x,y);
PixelType grady = gy(x,y); PixelType grady = gy(x,y);
double mag = magnitude(x, y); double mag = magnitude(x, y);
if(mag == 0.0)
continue;
int dx = (int)VIGRA_CSTD::floor(gradx*t/mag + 0.5); int dx = (int)VIGRA_CSTD::floor(gradx*t/mag + 0.5);
int dy = (int)VIGRA_CSTD::floor(grady*t/mag + 0.5); int dy = (int)VIGRA_CSTD::floor(grady*t/mag + 0.5);
int x1 = x - dx, int x1 = x - dx,
x2 = x + dx, x2 = x + dx,
y1 = y - dy, y1 = y - dy,
y2 = y + dy; y2 = y + dy;
PixelType m1 = magnitude(x1, y1); PixelType m1 = magnitude(x1, y1);
skipping to change at line 1257 skipping to change at line 1264
This operator first calculates the gradient vector for each This operator first calculates the gradient vector for each
pixel of the image using first derivatives of a Gaussian at the pixel of the image using first derivatives of a Gaussian at the
given scale. Then a very simple non-maxima supression is performed: given scale. Then a very simple non-maxima supression is performed:
for each 3x3 neighborhood, it is determined whether the center pixel ha s for each 3x3 neighborhood, it is determined whether the center pixel ha s
larger gradient magnitude than its two neighbors in gradient direction larger gradient magnitude than its two neighbors in gradient direction
(where the direction is rounded into octands). If this is the case, (where the direction is rounded into octands). If this is the case,
a new \ref Edgel is appended to the given vector of <TT>edgels</TT>. Th e subpixel a new \ref Edgel is appended to the given vector of <TT>edgels</TT>. Th e subpixel
edgel position is determined by fitting a parabola edgel position is determined by fitting a parabola
to the three gradient magnitude values to the three gradient magnitude values
mentioned above. The sub-pixel location of the parabola's tip mentioned above. The sub-pixel location of the parabola's tip
and the gradient magnitude and direction are written in the newly creat and the gradient magnitude and direction (from the pixel center)
ed edgel. are written in the newly created edgel.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, class BackInsertabl e> template <class SrcIterator, class SrcAccessor, class BackInsertabl e>
void cannyEdgelList(SrcIterator ul, SrcIterator lr, SrcAccessor src , void cannyEdgelList(SrcIterator ul, SrcIterator lr, SrcAccessor src ,
BackInsertable & edgels, double scale); BackInsertable & edgels, double scale);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, class BackInsertabl e> template <class SrcIterator, class SrcAccessor, class BackInsertabl e>
void void
cannyEdgelList(triple<SrcIterator, SrcIterator, SrcAccessor> src, cannyEdgelList(triple<SrcIterator, SrcIterator, SrcAccessor> src,
BackInsertable & edgels, double scale); BackInsertable & edgels, double scale);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="edgedetection_8hxx-source.html">vigra/edgede tection.hxx</a>"<br> <b>\#include</b> \<<a href="edgedetection_8hxx-source.html">vigra/edged etection.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h); vigra::BImage src(w,h);
// empty edgel list // empty edgel list
std::vector<vigra::Edgel> edgels; std::vector<vigra::Edgel> edgels;
... ...
// find edgels at scale 0.8 // find edgels at scale 0.8
skipping to change at line 1316 skipping to change at line 1324
\endcode \endcode
SrcAccessor::value_type must be a type convertible to float SrcAccessor::value_type must be a type convertible to float
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
scale > 0 scale > 0
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void cannyEdgelList)
template <class SrcIterator, class SrcAccessor, class BackInsertable> template <class SrcIterator, class SrcAccessor, class BackInsertable>
void cannyEdgelList(SrcIterator ul, SrcIterator lr, SrcAccessor src, void cannyEdgelList(SrcIterator ul, SrcIterator lr, SrcAccessor src,
BackInsertable & edgels, double scale) BackInsertable & edgels, double scale)
{ {
int w = lr.x - ul.x; int w = lr.x - ul.x;
int h = lr.y - ul.y; int h = lr.y - ul.y;
// calculate image gradients // calculate image gradients
typedef typename typedef typename
NumericTraits<typename SrcAccessor::value_type>::RealPromote NumericTraits<typename SrcAccessor::value_type>::RealPromote
skipping to change at line 1385 skipping to change at line 1395
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class GradValue, class DestValue> class GradValue, class DestValue>
void cannyEdgeImage( void cannyEdgeImage(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
double scale, GradValue gradient_threshold, DestValue ed ge_marker); double scale, GradValue gradient_threshold, DestValue ed ge_marker);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class GradValue, class DestValue> class GradValue, class DestValue>
inline void cannyEdgeImage( void cannyEdgeImage(
triple<SrcIterator, SrcIterator, SrcAccessor> src, triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale, GradValue gradient_threshold, DestValue ed ge_marker); double scale, GradValue gradient_threshold, DestValue ed ge_marker);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="edgedetection_8hxx-source.html">vigra/edgede tection.hxx</a>"<br> <b>\#include</b> \<<a href="edgedetection_8hxx-source.html">vigra/edged etection.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), edges(w,h); vigra::BImage src(w,h), edges(w,h);
// empty edge image // empty edge image
edges = 0; edges = 0;
... ...
// find edges at scale 0.8 with gradient larger than 4.0, mark with 1 // find edges at scale 0.8 with gradient larger than 4.0, mark with 1
skipping to change at line 1434 skipping to change at line 1444
dest_accessor.set(edge_marker, dest_upperleft, vigra::Diff2D(1,1)); dest_accessor.set(edge_marker, dest_upperleft, vigra::Diff2D(1,1));
\endcode \endcode
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
scale > 0 scale > 0
gradient_threshold > 0 gradient_threshold > 0
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void cannyEdgeImage)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class GradValue, class DestValue> class GradValue, class DestValue>
void cannyEdgeImage( void cannyEdgeImage(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
double scale, GradValue gradient_threshold, DestValue edge_marke r) double scale, GradValue gradient_threshold, DestValue edge_marke r)
{ {
std::vector<Edgel> edgels; std::vector<Edgel> edgels;
skipping to change at line 1614 skipping to change at line 1626
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class GradValue, class DestValue> class GradValue, class DestValue>
void cannyEdgeImageFromGradWithThinning( void cannyEdgeImageFromGradWithThinning(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
GradValue gradient_threshold, GradValue gradient_threshold,
DestValue edge_marker, bool addBorder = true); DestValue edge_marker, bool addBorder = true);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class GradValue, class DestValue> class GradValue, class DestValue>
void cannyEdgeImageFromGradWithThinning( void cannyEdgeImageFromGradWithThinning(
triple<SrcIterator, SrcIterator, SrcAccessor> src, triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
GradValue gradient_threshold, GradValue gradient_threshold,
DestValue edge_marker, bool addBorder = true); DestValue edge_marker, bool addBorder = true);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="edgedetection_8hxx-source.html">vigra/edgede tection.hxx</a>"<br> <b>\#include</b> \<<a href="edgedetection_8hxx-source.html">vigra/edged etection.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), edges(w,h); vigra::BImage src(w,h), edges(w,h);
vigra::FVector2Image grad(w,h); vigra::FVector2Image grad(w,h);
// compute the image gradient at scale 0.8 // compute the image gradient at scale 0.8
vigra::gaussianGradient(srcImageRange(src), destImage(grad), 0.8); vigra::gaussianGradient(srcImageRange(src), destImage(grad), 0.8);
// empty edge image // empty edge image
skipping to change at line 1673 skipping to change at line 1685
dest_accessor.set(edge_marker, dest_upperleft, vigra::Diff2D(1,1)); dest_accessor.set(edge_marker, dest_upperleft, vigra::Diff2D(1,1));
\endcode \endcode
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
gradient_threshold > 0 gradient_threshold > 0
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void cannyEdgeImageFromGradWithT
hinning)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class GradValue, class DestValue> class GradValue, class DestValue>
void cannyEdgeImageFromGradWithThinning( void cannyEdgeImageFromGradWithThinning(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
GradValue gradient_threshold, GradValue gradient_threshold,
DestValue edge_marker, bool addBorder) DestValue edge_marker, bool addBorder)
{ {
int w = slr.x - sul.x; int w = slr.x - sul.x;
skipping to change at line 1841 skipping to change at line 1855
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class GradValue, class DestValue> class GradValue, class DestValue>
void cannyEdgeImageWithThinning( void cannyEdgeImageWithThinning(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
double scale, GradValue gradient_threshold, double scale, GradValue gradient_threshold,
DestValue edge_marker, bool addBorder = true); DestValue edge_marker, bool addBorder = true);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class GradValue, class DestValue> class GradValue, class DestValue>
void cannyEdgeImageWithThinning( void cannyEdgeImageWithThinning(
triple<SrcIterator, SrcIterator, SrcAccessor> src, triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale, GradValue gradient_threshold, double scale, GradValue gradient_threshold,
DestValue edge_marker, bool addBorder = true); DestValue edge_marker, bool addBorder = true);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="edgedetection_8hxx-source.html">vigra/edgede tection.hxx</a>"<br> <b>\#include</b> \<<a href="edgedetection_8hxx-source.html">vigra/edged etection.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), edges(w,h); vigra::BImage src(w,h), edges(w,h);
// empty edge image // empty edge image
edges = 0; edges = 0;
... ...
// find edges at scale 0.8 with gradient larger than 4.0, mark with 1, annd add border // find edges at scale 0.8 with gradient larger than 4.0, mark with 1, annd add border
skipping to change at line 1891 skipping to change at line 1905
dest_accessor.set(edge_marker, dest_upperleft, vigra::Diff2D(1,1)); dest_accessor.set(edge_marker, dest_upperleft, vigra::Diff2D(1,1));
\endcode \endcode
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
scale > 0 scale > 0
gradient_threshold > 0 gradient_threshold > 0
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void cannyEdgeImageWithThinning)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class GradValue, class DestValue> class GradValue, class DestValue>
void cannyEdgeImageWithThinning( void cannyEdgeImageWithThinning(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
double scale, GradValue gradient_threshold, double scale, GradValue gradient_threshold,
DestValue edge_marker, bool addBorder) DestValue edge_marker, bool addBorder)
{ {
// mark pixels that are higher than their neighbors in gradient directi on // mark pixels that are higher than their neighbors in gradient directi on
skipping to change at line 1967 skipping to change at line 1983
for(int y=1; y<grad.height()-1; ++y) for(int y=1; y<grad.height()-1; ++y)
{ {
for(int x=1; x<grad.width()-1; ++x) for(int x=1; x<grad.width()-1; ++x)
{ {
if(!mask(x,y)) if(!mask(x,y))
continue; continue;
ValueType gradx = grad(x,y)[0]; ValueType gradx = grad(x,y)[0];
ValueType grady = grad(x,y)[1]; ValueType grady = grad(x,y)[1];
double mag = hypot(gradx, grady), double mag = hypot(gradx, grady);
c = gradx / mag, if(mag == 0.0)
continue;
double c = gradx / mag,
s = grady / mag; s = grady / mag;
Matrix<double> ml(3,3), mr(3,1), l(3,1), r(3,1); Matrix<double> ml(3,3), mr(3,1), l(3,1), r(3,1);
l(0,0) = 1.0; l(0,0) = 1.0;
for(int yy = -1; yy <= 1; ++yy) for(int yy = -1; yy <= 1; ++yy)
{ {
for(int xx = -1; xx <= 1; ++xx) for(int xx = -1; xx <= 1; ++xx)
{ {
double u = c*xx + s*yy; double u = c*xx + s*yy;
skipping to change at line 1992 skipping to change at line 2010
ml += outer(l); ml += outer(l);
mr += v*l; mr += v*l;
} }
} }
linearSolve(ml, mr, r); linearSolve(ml, mr, r);
Edgel edgel; Edgel edgel;
// local maximum => quadratic interpolation of sub-pixel locati on // local maximum => quadratic interpolation of sub-pixel locati on
ValueType del = -r(1,0) / 2.0 / r(2,0); double del = -r(1,0) / 2.0 / r(2,0);
if(std::fabs(del) > 1.5) // don't move by more than about a pi
xel diameter
del = 0.0;
edgel.x = x + c*del; edgel.x = x + c*del;
edgel.y = y + s*del; edgel.y = y + s*del;
edgel.strength = mag; edgel.strength = mag;
double orientation = VIGRA_CSTD::atan2(-grady, gradx) - M_PI * 1.5; double orientation = VIGRA_CSTD::atan2(-grady, gradx) - M_PI * 1.5;
if(orientation < 0.0) if(orientation < 0.0)
orientation += 2.0*M_PI; orientation += 2.0*M_PI;
edgel.orientation = orientation; edgel.orientation = orientation;
edgels.push_back(edgel); edgels.push_back(edgel);
} }
} }
skipping to change at line 2032 skipping to change at line 2052
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, class BackInsertabl e> template <class SrcIterator, class SrcAccessor, class BackInsertabl e>
void cannyEdgelList3x3(SrcIterator ul, SrcIterator lr, SrcAccessor src, void cannyEdgelList3x3(SrcIterator ul, SrcIterator lr, SrcAccessor src,
BackInsertable & edgels, double scale); BackInsertable & edgels, double scale);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, class BackInsertabl e> template <class SrcIterator, class SrcAccessor, class BackInsertabl e>
void void
cannyEdgelList3x3(triple<SrcIterator, SrcIterator, SrcAccessor> src , cannyEdgelList3x3(triple<SrcIterator, SrcIterator, SrcAccessor> src ,
BackInsertable & edgels, double scale); BackInsertable & edgels, double scale);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="edgedetection_8hxx-source.html">vigra/edgede tection.hxx</a>"<br> <b>\#include</b> \<<a href="edgedetection_8hxx-source.html">vigra/edged etection.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h); vigra::BImage src(w,h);
// empty edgel list // empty edgel list
std::vector<vigra::Edgel> edgels; std::vector<vigra::Edgel> edgels;
... ...
// find edgels at scale 0.8 // find edgels at scale 0.8
skipping to change at line 2078 skipping to change at line 2098
\endcode \endcode
SrcAccessor::value_type must be a type convertible to float SrcAccessor::value_type must be a type convertible to float
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
scale > 0 scale > 0
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void cannyEdgelList3x3)
template <class SrcIterator, class SrcAccessor, class BackInsertable> template <class SrcIterator, class SrcAccessor, class BackInsertable>
void cannyEdgelList3x3(SrcIterator ul, SrcIterator lr, SrcAccessor src, void cannyEdgelList3x3(SrcIterator ul, SrcIterator lr, SrcAccessor src,
BackInsertable & edgels, double scale) BackInsertable & edgels, double scale)
{ {
int w = lr.x - ul.x; int w = lr.x - ul.x;
int h = lr.y - ul.y; int h = lr.y - ul.y;
typedef typename NumericTraits<typename SrcAccessor::value_type>::RealP romote TmpType; typedef typename NumericTraits<typename SrcAccessor::value_type>::RealP romote TmpType;
BasicImage<TinyVector<TmpType, 2> > grad(lr-ul); BasicImage<TinyVector<TmpType, 2> > grad(lr-ul);
gaussianGradient(srcIterRange(ul, lr, src), destImage(grad), scale); gaussianGradient(srcIterRange(ul, lr, src), destImage(grad), scale);
 End of changes. 42 change blocks. 
34 lines changed or deleted 59 lines changed or added


 eigensystem.hxx   eigensystem.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2004 by Ullrich Koethe */ /* Copyright 2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 987 skipping to change at line 987
z = z + V(i, k) * H(k, j); z = z + V(i, k) * H(k, j);
} }
V(i, j) = z; V(i, j) = z;
} }
} }
return true; return true;
} }
} // namespace detail } // namespace detail
/** \addtogroup LinearAlgebraFunctions Matrix functions /** \addtogroup MatrixAlgebra
*/ */
//@{ //@{
/** Compute the eigensystem of a symmetric matrix. /** Compute the eigensystem of a symmetric matrix.
\a a is a real symmetric matrix, \a ew is a single-column matrix \a a is a real symmetric matrix, \a ew is a single-column matrix
holding the eigenvalues, and \a ev is a matrix of the same size as holding the eigenvalues, and \a ev is a matrix of the same size as
\a a whose columns are the corresponding eigenvectors. Eigenvalues \a a whose columns are the corresponding eigenvectors. Eigenvalues
will be sorted from largest to smallest magnitude. will be sorted from largest to smallest magnitude.
The algorithm returns <tt>false</tt> when it doesn't The algorithm returns <tt>false</tt> when it doesn't
converge. It can be applied in-place, i.e. <tt>&a == &ev</tt> is al lowed. converge. It can be applied in-place, i.e. <tt>&a == &ev</tt> is al lowed.
The code of this function was adapted from JAMA. The code of this function was adapted from JAMA.
<b>\#include</b> "<a href="eigensystem_8hxx-source.html">vigra/eigensys <b>\#include</b> \<<a href="eigensystem_8hxx-source.html">vigra/eigensy
tem.hxx</a>" or<br> stem.hxx</a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1, class C2, class C3> template <class T, class C1, class C2, class C3>
bool bool
symmetricEigensystem(MultiArrayView<2, T, C1> const & a, symmetricEigensystem(MultiArrayView<2, T, C1> const & a,
MultiArrayView<2, T, C2> & ew, MultiArrayView<2, T, C3> & ev) MultiArrayView<2, T, C2> & ew, MultiArrayView<2, T, C3> & ev)
{ {
vigra_precondition(isSymmetric(a), vigra_precondition(isSymmetric(a),
"symmetricEigensystem(): symmetric input matrix required."); "symmetricEigensystem(): symmetric input matrix required.");
unsigned int acols = columnCount(a); unsigned int acols = columnCount(a);
skipping to change at line 1037 skipping to change at line 1037
not necessarily symmetric matrix. not necessarily symmetric matrix.
\a a is a real square matrix, \a ew is a single-column matrix \a a is a real square matrix, \a ew is a single-column matrix
holding the possibly complex eigenvalues, and \a ev is a matrix of holding the possibly complex eigenvalues, and \a ev is a matrix of
the same size as \a a whose columns are the corresponding eigenvect ors. the same size as \a a whose columns are the corresponding eigenvect ors.
Eigenvalues will be sorted from largest to smallest magnitude. Eigenvalues will be sorted from largest to smallest magnitude.
The algorithm returns <tt>false</tt> when it doesn't The algorithm returns <tt>false</tt> when it doesn't
converge. It can be applied in-place, i.e. <tt>&a == &ev</tt> is al lowed. converge. It can be applied in-place, i.e. <tt>&a == &ev</tt> is al lowed.
The code of this function was adapted from JAMA. The code of this function was adapted from JAMA.
<b>\#include</b> "<a href="eigensystem_8hxx-source.html">vigra/eigensys <b>\#include</b> \<<a href="eigensystem_8hxx-source.html">vigra/eigensy
tem.hxx</a>" or<br> stem.hxx</a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1, class C2, class C3> template <class T, class C1, class C2, class C3>
bool bool
nonsymmetricEigensystem(MultiArrayView<2, T, C1> const & a, nonsymmetricEigensystem(MultiArrayView<2, T, C1> const & a,
MultiArrayView<2, std::complex<T>, C2> & ew, MultiArrayView<2, T, C3> & ev) MultiArrayView<2, std::complex<T>, C2> & ew, MultiArrayView<2, T, C3> & ev)
{ {
unsigned int acols = columnCount(a); unsigned int acols = columnCount(a);
vigra_precondition(acols == rowCount(a), vigra_precondition(acols == rowCount(a),
"nonsymmetricEigensystem(): square input matrix required."); "nonsymmetricEigensystem(): square input matrix required.");
skipping to change at line 1075 skipping to change at line 1075
/** Compute the roots of a polynomial using the eigenvalue method. /** Compute the roots of a polynomial using the eigenvalue method.
\a poly is a real polynomial (compatible to \ref vigra::PolynomialV iew), \a poly is a real polynomial (compatible to \ref vigra::PolynomialV iew),
and \a roots a complex valued vector (compatible to <tt>std::vector </tt> and \a roots a complex valued vector (compatible to <tt>std::vector </tt>
with a <tt>value_type</tt> compatible to the type <tt>POLYNOMIAL::C omplex</tt>) to which with a <tt>value_type</tt> compatible to the type <tt>POLYNOMIAL::C omplex</tt>) to which
the roots are appended. The function calls \ref nonsymmetricEigensy stem() with the standard the roots are appended. The function calls \ref nonsymmetricEigensy stem() with the standard
companion matrix yielding the roots as eigenvalues. It returns <tt> false</tt> if companion matrix yielding the roots as eigenvalues. It returns <tt> false</tt> if
it fails to converge. it fails to converge.
<b>\#include</b> "<a href="eigensystem_8hxx-source.html">vigra/eige <b>\#include</b> \<<a href="eigensystem_8hxx-source.html">vigra/eig
nsystem.hxx</a>" or<br> ensystem.hxx</a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/ <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra
linear_algebra.hxx</a>"<br> /linear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
\see polynomialRoots(), vigra::Polynomial \see polynomialRoots(), vigra::Polynomial
*/ */
template <class POLYNOMIAL, class VECTOR> template <class POLYNOMIAL, class VECTOR>
bool polynomialRootsEigenvalueMethod(POLYNOMIAL const & poly, VECTOR & root s, bool polishRoots) bool polynomialRootsEigenvalueMethod(POLYNOMIAL const & poly, VECTOR & root s, bool polishRoots)
{ {
typedef typename POLYNOMIAL::value_type T; typedef typename POLYNOMIAL::value_type T;
typedef typename POLYNOMIAL::Real Real; typedef typename POLYNOMIAL::Real Real;
typedef typename POLYNOMIAL::Complex Complex; typedef typename POLYNOMIAL::Complex Complex;
skipping to change at line 1127 skipping to change at line 1127
} }
/** Compute the real roots of a real polynomial using the eigenvalue me thod. /** Compute the real roots of a real polynomial using the eigenvalue me thod.
\a poly is a real polynomial (compatible to \ref vigra::PolynomialV iew), \a poly is a real polynomial (compatible to \ref vigra::PolynomialV iew),
and \a roots a real valued vector (compatible to <tt>std::vector</t t> and \a roots a real valued vector (compatible to <tt>std::vector</t t>
with a <tt>value_type</tt> compatible to the type <tt>POLYNOMIAL::R eal</tt>) to which with a <tt>value_type</tt> compatible to the type <tt>POLYNOMIAL::R eal</tt>) to which
the roots are appended. The function calls \ref polynomialRootsEige nvalueMethod() and the roots are appended. The function calls \ref polynomialRootsEige nvalueMethod() and
throws away all complex roots. It returns <tt>false</tt> if it fail s to converge. throws away all complex roots. It returns <tt>false</tt> if it fail s to converge.
<b>\#include</b> "<a href="eigensystem_8hxx-source.html">vigra/eige <b>\#include</b> \<<a href="eigensystem_8hxx-source.html">vigra/eig
nsystem.hxx</a>" or<br> ensystem.hxx</a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/ <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra
linear_algebra.hxx</a>"<br> /linear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
\see polynomialRealRoots(), vigra::Polynomial \see polynomialRealRoots(), vigra::Polynomial
*/ */
template <class POLYNOMIAL, class VECTOR> template <class POLYNOMIAL, class VECTOR>
bool polynomialRealRootsEigenvalueMethod(POLYNOMIAL const & p, VECTOR & roo ts, bool polishRoots) bool polynomialRealRootsEigenvalueMethod(POLYNOMIAL const & p, VECTOR & roo ts, bool polishRoots)
{ {
typedef typename NumericTraits<typename VECTOR::value_type>::ComplexPro mote Complex; typedef typename NumericTraits<typename VECTOR::value_type>::ComplexPro mote Complex;
ArrayVector<Complex> croots; ArrayVector<Complex> croots;
if(!polynomialRootsEigenvalueMethod(p, croots)) if(!polynomialRootsEigenvalueMethod(p, croots))
 End of changes. 7 change blocks. 
21 lines changed or deleted 21 lines changed or added


 error.hxx   error.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 49 skipping to change at line 49
#define VIGRA_ERROR_HXX #define VIGRA_ERROR_HXX
#include <stdexcept> #include <stdexcept>
#include <stdio.h> #include <stdio.h>
#include <string> #include <string>
#include "config.hxx" #include "config.hxx"
/*! \page ErrorReporting Error Reporting /*! \page ErrorReporting Error Reporting
Exceptions and assertions provided by VIGRA Exceptions and assertions provided by VIGRA
<b>\#include</b> "<a href="error_8hxx-source.html">vigra/error.hxx</a>" <b>\#include</b> \<<a href="error_8hxx-source.html">vigra/error.hxx</a> \>
VIGRA defines the following exception classes: VIGRA defines the following exception classes:
\code \code
namespace vigra { namespace vigra {
class ContractViolation : public std::exception; class ContractViolation : public std::exception;
class PreconditionViolation : public ContractViolation; class PreconditionViolation : public ContractViolation;
class PostconditionViolation : public ContractViolation; class PostconditionViolation : public ContractViolation;
class InvariantViolation : public ContractViolation; class InvariantViolation : public ContractViolation;
} }
skipping to change at line 94 skipping to change at line 94
\code \code
vigra_fail(MESSAGE); vigra_fail(MESSAGE);
\endcode \endcode
unconditionally throws a '<TT>std::runtime_error</TT>' constructed from the message unconditionally throws a '<TT>std::runtime_error</TT>' constructed from the message
(along with file name and line number, if NDEBUG is not set). (along with file name and line number, if NDEBUG is not set).
<b> Usage:</b> <b> Usage:</b>
Include-File: Include-File:
"<a href="error_8hxx-source.html">vigra/error.hxx</a>" \<<a href="error_8hxx-source.html">vigra/error.hxx</a>\>
<p> <p>
Namespace: vigra (except for the macros, of course) Namespace: vigra (except for the macros, of course)
\code \code
int main(int argc, char ** argv) int main(int argc, char ** argv)
{ {
try try
{ {
const char* input_file_name = argv[1]; const char* input_file_name = argv[1];
 End of changes. 4 change blocks. 
5 lines changed or deleted 5 lines changed or added


 fftw.hxx   fftw.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 671 skipping to change at line 671
More information on using FFTW can be found <a href="http://www.fftw.or g/doc/">here</a>. More information on using FFTW can be found <a href="http://www.fftw.or g/doc/">here</a>.
FFTW produces fourier images that have the DC component (the FFTW produces fourier images that have the DC component (the
origin of the Fourier space) in the upper left corner. Often, one origin of the Fourier space) in the upper left corner. Often, one
wants the origin in the center of the image, so that frequencies wants the origin in the center of the image, so that frequencies
always increase towards the border of the image. This can be always increase towards the border of the image. This can be
achieved by calling \ref moveDCToCenter(). The inverse achieved by calling \ref moveDCToCenter(). The inverse
transformation is done by \ref moveDCToUpperLeft(). transformation is done by \ref moveDCToUpperLeft().
<b>\#include</b> "<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>"<b r> <b>\#include</b> \<<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>\> <br>
Namespace: vigra Namespace: vigra
*/ */
/********************************************************/ /********************************************************/
/* */ /* */
/* moveDCToCenter */ /* moveDCToCenter */
/* */ /* */
/********************************************************/ /********************************************************/
/* documentation: see fftw3.hxx /* documentation: see fftw3.hxx
 End of changes. 3 change blocks. 
4 lines changed or deleted 4 lines changed or added


 fftw3.hxx   fftw3.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2004 by Ullrich Koethe */ /* Copyright 1998-2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 83 skipping to change at line 83
\ref DivisionAlgebra. The standard image types <tt>FFTWRealImage</tt> \ref DivisionAlgebra. The standard image types <tt>FFTWRealImage</tt>
and <tt>FFTWComplexImage</tt> are defined. and <tt>FFTWComplexImage</tt> are defined.
<b>See also:</b> <b>See also:</b>
<ul> <ul>
<li> \ref FFTWComplexTraits <li> \ref FFTWComplexTraits
<li> \ref FFTWComplexOperators <li> \ref FFTWComplexOperators
<li> \ref FFTWComplexAccessors <li> \ref FFTWComplexAccessors
</ul> </ul>
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>" <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>
(for FFTW 3) or<br> \> (for FFTW 3) or<br>
<b>\#include</b> "<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>" ( <b>\#include</b> \<<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>\>
for deprecated FFTW 2)<br> (for deprecated FFTW 2)<br>
Namespace: vigra Namespace: vigra
*/ */
class FFTWComplex class FFTWComplex
{ {
fftw_complex data_; fftw_complex data_;
public: public:
/** The complex' component type, as defined in '<TT>fftw3.h</TT>' /** The complex' component type, as defined in '<TT>fftw3.h</TT>'
*/ */
typedef fftw_real value_type; typedef fftw_real value_type;
skipping to change at line 351 skipping to change at line 351
typedef FFTWComplex Promote; typedef FFTWComplex Promote;
}; };
template <> template <>
struct PromoteTraits<double, FFTWComplex> struct PromoteTraits<double, FFTWComplex>
{ {
typedef FFTWComplex Promote; typedef FFTWComplex Promote;
}; };
\endcode \endcode
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>" <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>
(for FFTW 3) or<br> \> (for FFTW 3) or<br>
<b>\#include</b> "<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>" ( <b>\#include</b> \<<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>\>
for deprecated FFTW 2)<br> (for deprecated FFTW 2)<br>
Namespace: vigra Namespace: vigra
*/ */
template<> template<>
struct NumericTraits<fftw_complex> struct NumericTraits<fftw_complex>
{ {
typedef fftw_complex Type; typedef fftw_complex Type;
typedef fftw_complex Promote; typedef fftw_complex Promote;
typedef fftw_complex RealPromote; typedef fftw_complex RealPromote;
typedef fftw_complex ComplexPromote; typedef fftw_complex ComplexPromote;
skipping to change at line 466 skipping to change at line 466
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* FFTWComplex Operations */ /* FFTWComplex Operations */
/* */ /* */
/********************************************************/ /********************************************************/
/** \addtogroup FFTWComplexOperators Functions for FFTWComplex /** \addtogroup FFTWComplexOperators Functions for FFTWComplex
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>" <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>
(for FFTW 3) or<br> \> (for FFTW 3) or<br>
<b>\#include</b> "<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>" ( <b>\#include</b> \<<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>\>
for deprecated FFTW 2)<br> (for deprecated FFTW 2)<br>
These functions fulfill the requirements of an Algebraic Field. These functions fulfill the requirements of an Algebraic Field.
Return types are determined according to \ref FFTWComplexTraits. Return types are determined according to \ref FFTWComplexTraits.
Namespace: vigra Namespace: vigra
<p> <p>
*/ */
//@{ //@{
/// equal /// equal
skipping to change at line 619 skipping to change at line 619
/* */ /* */
/********************************************************/ /********************************************************/
/** Float (<tt>fftw_real</tt>) image. /** Float (<tt>fftw_real</tt>) image.
The type <tt>fftw_real</tt> is defined as <tt>double</tt> (in FFTW 2 it used to be The type <tt>fftw_real</tt> is defined as <tt>double</tt> (in FFTW 2 it used to be
either <tt>float</tt> or <tt>double</tt>, as specified during compi lation of FFTW). either <tt>float</tt> or <tt>double</tt>, as specified during compi lation of FFTW).
FFTWRealImage uses \ref vigra::BasicImageIterator and \ref vigra::S tandardAccessor and FFTWRealImage uses \ref vigra::BasicImageIterator and \ref vigra::S tandardAccessor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx< <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx
/a>" (for FFTW 3) or<br> </a>\> (for FFTW 3) or<br>
<b>\#include</b> "<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a <b>\#include</b> \<<a href="fftw_8hxx-source.html">vigra/fftw.hxx</
>" (for deprecated FFTW 2)<br> a>\> (for deprecated FFTW 2)<br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<fftw_real> FFTWRealImage; typedef BasicImage<fftw_real> FFTWRealImage;
/********************************************************/ /********************************************************/
/* */ /* */
/* FFTWComplexImage */ /* FFTWComplexImage */
/* */ /* */
/********************************************************/ /********************************************************/
skipping to change at line 677 skipping to change at line 677
typedef iterator::column_iterator column_iterator; typedef iterator::column_iterator column_iterator;
typedef VectorAccessor<FFTWComplex> default_accessor; typedef VectorAccessor<FFTWComplex> default_accessor;
typedef VectorAccessor<FFTWComplex> DefaultAccessor; typedef VectorAccessor<FFTWComplex> DefaultAccessor;
typedef VigraTrueType hasConstantStrides; typedef VigraTrueType hasConstantStrides;
}; };
/** Complex (FFTWComplex) image. /** Complex (FFTWComplex) image.
It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx< <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx
/a>" (for FFTW 3) or<br> </a>\> (for FFTW 3) or<br>
<b>\#include</b> "<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a <b>\#include</b> \<<a href="fftw_8hxx-source.html">vigra/fftw.hxx</
>" (for deprecated FFTW 2)<br> a>\> (for deprecated FFTW 2)<br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<FFTWComplex> FFTWComplexImage; typedef BasicImage<FFTWComplex> FFTWComplexImage;
//@} //@}
/********************************************************/ /********************************************************/
/* */ /* */
/* FFTWComplex-Accessors */ /* FFTWComplex-Accessors */
/* */ /* */
skipping to change at line 701 skipping to change at line 701
/** \addtogroup DataAccessors /** \addtogroup DataAccessors
*/ */
//@{ //@{
/** \defgroup FFTWComplexAccessors Accessors for FFTWComplex /** \defgroup FFTWComplexAccessors Accessors for FFTWComplex
Encapsulate access to pixels of type FFTWComplex Encapsulate access to pixels of type FFTWComplex
*/ */
//@{ //@{
/** Encapsulate access to the the real part of a complex number. /** Encapsulate access to the the real part of a complex number.
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>" <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>
(for FFTW 3) or<br> \> (for FFTW 3) or<br>
<b>\#include</b> "<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>" ( <b>\#include</b> \<<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>\>
for deprecated FFTW 2)<br> (for deprecated FFTW 2)<br>
Namespace: vigra Namespace: vigra
*/ */
class FFTWRealAccessor class FFTWRealAccessor
{ {
public: public:
/// The accessor's value type. /// The accessor's value type.
typedef fftw_real value_type; typedef fftw_real value_type;
/// Read real part at iterator position. /// Read real part at iterator position.
skipping to change at line 739 skipping to change at line 739
/// Write real part at offset from iterator position. /// Write real part at offset from iterator position.
template <class ITERATOR, class DIFFERENCE> template <class ITERATOR, class DIFFERENCE>
void set(value_type const & v, ITERATOR const & i, DIFFERENCE d) const { void set(value_type const & v, ITERATOR const & i, DIFFERENCE d) const {
i[d].re()= v; i[d].re()= v;
} }
}; };
/** Encapsulate access to the the imaginary part of a complex number. /** Encapsulate access to the the imaginary part of a complex number.
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>" <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>
(for FFTW 3) or<br> \> (for FFTW 3) or<br>
<b>\#include</b> "<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>" ( <b>\#include</b> \<<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>\>
for deprecated FFTW 2)<br> (for deprecated FFTW 2)<br>
Namespace: vigra Namespace: vigra
*/ */
class FFTWImaginaryAccessor class FFTWImaginaryAccessor
{ {
public: public:
/// The accessor's value type. /// The accessor's value type.
typedef fftw_real value_type; typedef fftw_real value_type;
/// Read imaginary part at iterator position. /// Read imaginary part at iterator position.
template <class ITERATOR> template <class ITERATOR>
skipping to change at line 777 skipping to change at line 777
/// Write imaginary part at offset from iterator position. /// Write imaginary part at offset from iterator position.
template <class ITERATOR, class DIFFERENCE> template <class ITERATOR, class DIFFERENCE>
void set(value_type const & v, ITERATOR const & i, DIFFERENCE d) const { void set(value_type const & v, ITERATOR const & i, DIFFERENCE d) const {
i[d].im()= v; i[d].im()= v;
} }
}; };
/** Write a real number into a complex one. The imaginary part is set /** Write a real number into a complex one. The imaginary part is set
to 0. to 0.
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>" <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>
(for FFTW 3) or<br> \> (for FFTW 3) or<br>
<b>\#include</b> "<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>" ( <b>\#include</b> \<<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>\>
for deprecated FFTW 2)<br> (for deprecated FFTW 2)<br>
Namespace: vigra Namespace: vigra
*/ */
class FFTWWriteRealAccessor: public FFTWRealAccessor class FFTWWriteRealAccessor: public FFTWRealAccessor
{ {
public: public:
/// The accessor's value type. /// The accessor's value type.
typedef fftw_real value_type; typedef fftw_real value_type;
/** Write real number at iterator position. Set imaginary part /** Write real number at iterator position. Set imaginary part
to 0. to 0.
skipping to change at line 808 skipping to change at line 808
*/ */
template <class ITERATOR, class DIFFERENCE> template <class ITERATOR, class DIFFERENCE>
void set(value_type const & v, ITERATOR const & i, DIFFERENCE d) const { void set(value_type const & v, ITERATOR const & i, DIFFERENCE d) const {
i[d].re()= v; i[d].re()= v;
i[d].im()= 0; i[d].im()= 0;
} }
}; };
/** Calculate magnitude of complex number on the fly. /** Calculate magnitude of complex number on the fly.
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>" <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>
(for FFTW 3) or<br> \> (for FFTW 3) or<br>
<b>\#include</b> "<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>" ( <b>\#include</b> \<<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>\>
for deprecated FFTW 2)<br> (for deprecated FFTW 2)<br>
Namespace: vigra Namespace: vigra
*/ */
class FFTWMagnitudeAccessor class FFTWMagnitudeAccessor
{ {
public: public:
/// The accessor's value type. /// The accessor's value type.
typedef fftw_real value_type; typedef fftw_real value_type;
/// Read magnitude at iterator position. /// Read magnitude at iterator position.
template <class ITERATOR> template <class ITERATOR>
skipping to change at line 833 skipping to change at line 833
/// Read magnitude at offset from iterator position. /// Read magnitude at offset from iterator position.
template <class ITERATOR, class DIFFERENCE> template <class ITERATOR, class DIFFERENCE>
value_type operator()(ITERATOR const & i, DIFFERENCE d) const { value_type operator()(ITERATOR const & i, DIFFERENCE d) const {
return (i[d]).magnitude(); return (i[d]).magnitude();
} }
}; };
/** Calculate phase of complex number on the fly. /** Calculate phase of complex number on the fly.
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>" <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>
(for FFTW 3) or<br> \> (for FFTW 3) or<br>
<b>\#include</b> "<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>" ( <b>\#include</b> \<<a href="fftw_8hxx-source.html">vigra/fftw.hxx</a>\>
for deprecated FFTW 2)<br> (for deprecated FFTW 2)<br>
Namespace: vigra Namespace: vigra
*/ */
class FFTWPhaseAccessor class FFTWPhaseAccessor
{ {
public: public:
/// The accessor's value type. /// The accessor's value type.
typedef fftw_real value_type; typedef fftw_real value_type;
/// Read phase at iterator position. /// Read phase at iterator position.
template <class ITERATOR> template <class ITERATOR>
skipping to change at line 867 skipping to change at line 867
//@} //@}
/********************************************************/ /********************************************************/
/* */ /* */
/* Fourier Transform */ /* Fourier Transform */
/* */ /* */
/********************************************************/ /********************************************************/
/** \addtogroup FourierTransform Fast Fourier Transform /** \addtogroup FourierTransform Fast Fourier Transform
This documentation describes the VIGRA interface to FFTW 3. There is al This documentation describes the VIGRA interface to FFTW version 3. The
so an interface
\link FourierTransformFFTW2 interface to the older version FFTW 2\endli to the old FFTW version 2 (file "vigra/fftw.hxx") is deprecated.
nk
VIGRA uses the <a href="http://www.fftw.org/">FFTW Fast Fourier VIGRA uses the <a href="http://www.fftw.org/">FFTW Fast Fourier
Transform</a> package to perform Fourier transformations. VIGRA Transform</a> package to perform Fourier transformations. VIGRA
provides a wrapper for FFTW's complex number type (FFTWComplex), provides a wrapper for FFTW's complex number type (FFTWComplex),
but FFTW's functions are used verbatim. If the image is stored as but FFTW's functions are used verbatim. If the image is stored as
a FFTWComplexImage, the simplest call to an FFT function is like this: a FFTWComplexImage, the simplest call to an FFT function is like this:
\code \code
vigra::FFTWComplexImage spatial(width,height), fourier(width,height); vigra::FFTWComplexImage spatial(width,height), fourier(width,height);
... // fill image with data ... // fill image with data
skipping to change at line 919 skipping to change at line 919
More information on using FFTW can be found <a href="http://www.fftw.or g/doc/">here</a>. More information on using FFTW can be found <a href="http://www.fftw.or g/doc/">here</a>.
FFTW produces fourier images that have the DC component (the FFTW produces fourier images that have the DC component (the
origin of the Fourier space) in the upper left corner. Often, one origin of the Fourier space) in the upper left corner. Often, one
wants the origin in the center of the image, so that frequencies wants the origin in the center of the image, so that frequencies
always increase towards the border of the image. This can be always increase towards the border of the image. This can be
achieved by calling \ref moveDCToCenter(). The inverse achieved by calling \ref moveDCToCenter(). The inverse
transformation is done by \ref moveDCToUpperLeft(). transformation is done by \ref moveDCToUpperLeft().
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>" <br> <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a> \><br>
Namespace: vigra Namespace: vigra
*/ */
/** \addtogroup FourierTransform /** \addtogroup FourierTransform
*/ */
//@{ //@{
/********************************************************/ /********************************************************/
/* */ /* */
/* moveDCToCenter */ /* moveDCToCenter */
skipping to change at line 974 skipping to change at line 974
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void moveDCToCenter(SrcImageIterator src_upperleft, void moveDCToCenter(SrcImageIterator src_upperleft,
SrcImageIterator src_lowerright, SrcAccessor sa, SrcImageIterator src_lowerright, SrcAccessor sa,
DestImageIterator dest_upperleft, DestAccess or da); DestImageIterator dest_upperleft, DestAccess or da);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void moveDCToCenter( void moveDCToCenter(
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<DestImageIterator, DestAccessor> dest); pair<DestImageIterator, DestAccessor> dest);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx< /a>"<br> <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx </a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::FFTWComplexImage spatial(width,height), fourier(width,height); vigra::FFTWComplexImage spatial(width,height), fourier(width,height);
... // fill image with data ... // fill image with data
// create a plan with estimated performance optimization // create a plan with estimated performance optimization
fftw_plan forwardPlan = fftw_plan_dft_2d(height, width, fftw_plan forwardPlan = fftw_plan_dft_2d(height, width,
(fftw_complex *)spatial.begin(), (fftw_comp lex *)fourier.begin(), (fftw_complex *)spatial.begin(), (fftw_comp lex *)fourier.begin(),
FFTW_FORWARD, FFTW_ESTIMATE ); FFTW_FORWARD, FFTW_ESTIMATE );
// calculate FFT // calculate FFT
fftw_execute(forwardPlan); fftw_execute(forwardPlan);
vigra::FFTWComplexImage rearrangedFourier(width, height); vigra::FFTWComplexImage rearrangedFourier(width, height);
moveDCToCenter(srcImageRange(fourier), destImage(rearrangedFourier)); moveDCToCenter(srcImageRange(fourier), destImage(rearrangedFourier));
// delete the plan // delete the plan
fftw_destroy_plan(forwardPlan); fftw_destroy_plan(forwardPlan);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void moveDCToCenter)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void moveDCToCenter(SrcImageIterator src_upperleft, void moveDCToCenter(SrcImageIterator src_upperleft,
SrcImageIterator src_lowerright, SrcAccessor sa, SrcImageIterator src_lowerright, SrcAccessor sa,
DestImageIterator dest_upperleft, DestAccess or da) DestImageIterator dest_upperleft, DestAccess or da)
{ {
int w= src_lowerright.x - src_upperleft.x; int w= src_lowerright.x - src_upperleft.x;
int h= src_lowerright.y - src_upperleft.y; int h= src_lowerright.y - src_upperleft.y;
int w1 = w/2; int w1 = w/2;
int h1 = h/2; int h1 = h/2;
skipping to change at line 1064 skipping to change at line 1066
/* moveDCToUpperLeft */ /* moveDCToUpperLeft */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Rearrange the quadrants of a Fourier image so that the origin is /** \brief Rearrange the quadrants of a Fourier image so that the origin is
in the image's upper left. in the image's upper left.
This function is the inversion of \ref moveDCToCenter(). See there This function is the inversion of \ref moveDCToCenter(). See there
for declarations and a usage example. for declarations and a usage example.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void moveDCToUpperLeft(SrcImageIterator src_upperleft, void moveDCToUpperLeft(SrcImageIterator src_upperleft,
SrcImageIterator src_lowerright, SrcAccessor SrcImageIterator src_lowerright, SrcAcce
sa, ssor sa,
DestImageIterator dest_upperleft, DestAccess DestImageIterator dest_upperleft, DestAc
or da); cessor da);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories
\code :
namespace vigra { \code
template <class SrcImageIterator, class SrcAccessor, namespace vigra {
class DestImageIterator, class DestAccessor> template <class SrcImageIterator, class SrcAccessor,
void moveDCToUpperLeft( class DestImageIterator, class DestAccessor>
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, void moveDCToUpperLeft(
pair<DestImageIterator, DestAccessor> dest); triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src
} ,
\endcode pair<DestImageIterator, DestAccessor> dest);
}
\endcode
*/ */
doxygen_overloaded_function(template <...> void moveDCToUpperLeft)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void moveDCToUpperLeft(SrcImageIterator src_upperleft, void moveDCToUpperLeft(SrcImageIterator src_upperleft,
SrcImageIterator src_lowerright, SrcAccessor sa, SrcImageIterator src_lowerright, SrcAccessor sa,
DestImageIterator dest_upperleft, DestAccess or da) DestImageIterator dest_upperleft, DestAccess or da)
{ {
int w= src_lowerright.x - src_upperleft.x; int w= src_lowerright.x - src_upperleft.x;
int h= src_lowerright.y - src_upperleft.y; int h= src_lowerright.y - src_upperleft.y;
int w2 = w/2; int w2 = w/2;
int h2 = h/2; int h2 = h/2;
skipping to change at line 1175 skipping to change at line 1179
if (&(*(dul + Diff2D(w, 0))) != &(*(dul + Diff2D(0, 1)))) if (&(*(dul + Diff2D(w, 0))) != &(*(dul + Diff2D(0, 1))))
{ {
copyImage(srcImageRange(dworkImage), destIter(dul, dest)); copyImage(srcImageRange(dworkImage), destIter(dul, dest));
} }
} }
} // namespace detail } // namespace detail
/********************************************************/ /********************************************************/
/* */ /* */
/* fourierTrasform */ /* fourierTransform */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Compute forward and inverse Fourier transforms. /** \brief Compute forward and inverse Fourier transforms.
In the forward direction, the input image may be scalar or complex, and the output image In the forward direction, the input image may be scalar or complex, and the output image
is always complex. In the inverse direction, both input and output must be complex. is always complex. In the inverse direction, both input and output must be complex.
<b> Declarations:</b> <b> Declarations:</b>
skipping to change at line 1201 skipping to change at line 1205
SrcImageIterator srcLowerRight, SrcAccessor s rc, SrcImageIterator srcLowerRight, SrcAccessor s rc,
FFTWComplexImage::traverser destUpperLeft, FF TWComplexImage::Accessor dest); FFTWComplexImage::traverser destUpperLeft, FF TWComplexImage::Accessor dest);
void void
fourierTransformInverse(FFTWComplexImage::const_traverser sul, fourierTransformInverse(FFTWComplexImage::const_traverser sul,
FFTWComplexImage::const_traverser slr, FFTW ComplexImage::ConstAccessor src, FFTWComplexImage::const_traverser slr, FFTW ComplexImage::ConstAccessor src,
FFTWComplexImage::traverser dul, FFTWComple xImage::Accessor dest) FFTWComplexImage::traverser dul, FFTWComple xImage::Accessor dest)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor> template <class SrcImageIterator, class SrcAccessor>
void fourierTransform(triple<SrcImageIterator, SrcImageIterator, Sr cAccessor> src, void fourierTransform(triple<SrcImageIterator, SrcImageIterator, Sr cAccessor> src,
pair<FFTWComplexImage::traverser, FFTWComplex Image::Accessor> dest); pair<FFTWComplexImage::traverser, FFTWComplex Image::Accessor> dest);
void void
fourierTransformInverse(triple<FFTWComplexImage::const_traverser, fourierTransformInverse(triple<FFTWComplexImage::const_traverser,
FFTWComplexImage::const_traverser, F FTWComplexImage::ConstAccessor> src, FFTWComplexImage::const_traverser, F FTWComplexImage::ConstAccessor> src,
pair<FFTWComplexImage::traverser, FFTWCompl exImage::Accessor> dest); pair<FFTWComplexImage::traverser, FFTWCompl exImage::Accessor> dest);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>" <br> <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a> \><br>
Namespace: vigra Namespace: vigra
\code \code
// compute complex Fourier transform of a real image // compute complex Fourier transform of a real image
vigra::DImage src(w, h); vigra::DImage src(w, h);
vigra::FFTWComplexImage fourier(w, h); vigra::FFTWComplexImage fourier(w, h);
fourierTransform(srcImageRange(src), destImage(fourier)); fourierTransform(srcImageRange(src), destImage(fourier));
// compute inverse Fourier transform // compute inverse Fourier transform
// note that both source and destination image must be of type vigra::F FTWComplexImage // note that both source and destination image must be of type vigra::F FTWComplexImage
vigra::FFTWComplexImage inverseFourier(w, h); vigra::FFTWComplexImage inverseFourier(w, h);
fourierTransform(srcImageRange(fourier), destImage(inverseFourier)); fourierTransform(srcImageRange(fourier), destImage(inverseFourier));
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void fourierTransform)
inline void inline void
fourierTransform(FFTWComplexImage::const_traverser sul, fourierTransform(FFTWComplexImage::const_traverser sul,
FFTWComplexImage::const_traverser slr, FFTWComplexImage::C onstAccessor src, FFTWComplexImage::const_traverser slr, FFTWComplexImage::C onstAccessor src,
FFTWComplexImage::traverser dul, FFTWComplexImage::Accesso r dest) FFTWComplexImage::traverser dul, FFTWComplexImage::Accesso r dest)
{ {
detail::fourierTransformImpl(sul, slr, src, dul, dest, FFTW_FORWARD); detail::fourierTransformImpl(sul, slr, src, dul, dest, FFTW_FORWARD);
} }
template <class SrcImageIterator, class SrcAccessor> template <class SrcImageIterator, class SrcAccessor>
void fourierTransform(SrcImageIterator srcUpperLeft, void fourierTransform(SrcImageIterator srcUpperLeft,
skipping to change at line 1269 skipping to change at line 1275
} }
template <class SrcImageIterator, class SrcAccessor> template <class SrcImageIterator, class SrcAccessor>
inline inline
void fourierTransform(triple<SrcImageIterator, SrcImageIterator, SrcAccesso r> src, void fourierTransform(triple<SrcImageIterator, SrcImageIterator, SrcAccesso r> src,
pair<FFTWComplexImage::traverser, FFTWComplexImage::A ccessor> dest) pair<FFTWComplexImage::traverser, FFTWComplexImage::A ccessor> dest)
{ {
fourierTransform(src.first, src.second, src.third, dest.first, dest.sec ond); fourierTransform(src.first, src.second, src.third, dest.first, dest.sec ond);
} }
/** \brief Compute inverse Fourier transforms.
See \ref fourierTransform() for details.
*/
inline void inline void
fourierTransformInverse(FFTWComplexImage::const_traverser sul, fourierTransformInverse(FFTWComplexImage::const_traverser sul,
FFTWComplexImage::const_traverser slr, FFTWComplexI mage::ConstAccessor src, FFTWComplexImage::const_traverser slr, FFTWComplexI mage::ConstAccessor src,
FFTWComplexImage::traverser dul, FFTWComplexImage:: Accessor dest) FFTWComplexImage::traverser dul, FFTWComplexImage:: Accessor dest)
{ {
detail::fourierTransformImpl(sul, slr, src, dul, dest, FFTW_BACKWARD); detail::fourierTransformImpl(sul, slr, src, dul, dest, FFTW_BACKWARD);
} }
inline void inline void
fourierTransformInverse(triple<FFTWComplexImage::const_traverser, fourierTransformInverse(triple<FFTWComplexImage::const_traverser,
skipping to change at line 1321 skipping to change at line 1331
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class FilterImageIterator, class FilterAccessor, class FilterImageIterator, class FilterAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void applyFourierFilter(SrcImageIterator srcUpperLeft, void applyFourierFilter(SrcImageIterator srcUpperLeft,
SrcImageIterator srcLowerRight, SrcAccessor sa, SrcImageIterator srcLowerRight, SrcAccessor sa,
FilterImageIterator filterUpperLeft, Filter Accessor fa, FilterImageIterator filterUpperLeft, Filter Accessor fa,
DestImageIterator destUpperLeft, DestAccess or da); DestImageIterator destUpperLeft, DestAccess or da);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class FilterImageIterator, class FilterAccessor, class FilterImageIterator, class FilterAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void applyFourierFilter(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, void applyFourierFilter(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<FilterImageIterator, FilterAccessor> f ilter, pair<FilterImageIterator, FilterAccessor> f ilter,
pair<DestImageIterator, DestAccessor> dest) ; pair<DestImageIterator, DestAccessor> dest) ;
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>" <br> <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a> \><br>
Namespace: vigra Namespace: vigra
\code \code
// create a Gaussian filter in Fourier space // create a Gaussian filter in Fourier space
vigra::FImage gaussFilter(w, h), filter(w, h); vigra::FImage gaussFilter(w, h), filter(w, h);
for(int y=0; y<h; ++y) for(int y=0; y<h; ++y)
for(int x=0; x<w; ++x) for(int x=0; x<w; ++x)
{ {
xx = float(x - w / 2) / w; xx = float(x - w / 2) / w;
yy = float(y - h / 2) / h; yy = float(y - h / 2) / h;
skipping to change at line 1363 skipping to change at line 1373
vigra::FFTWComplexImage result(w, h); vigra::FFTWComplexImage result(w, h);
vigra::applyFourierFilter(srcImageRange(image), srcImage(filter), resul t); vigra::applyFourierFilter(srcImageRange(image), srcImage(filter), resul t);
\endcode \endcode
For inspection of the result, \ref FFTWMagnitudeAccessor might be For inspection of the result, \ref FFTWMagnitudeAccessor might be
useful. If you want to apply the same filter repeatedly, it may be more useful. If you want to apply the same filter repeatedly, it may be more
efficient to use the FFTW functions directly with FFTW plans optimized efficient to use the FFTW functions directly with FFTW plans optimized
for good performance. for good performance.
*/ */
doxygen_overloaded_function(template <...> void applyFourierFilter)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class FilterImageIterator, class FilterAccessor, class FilterImageIterator, class FilterAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void applyFourierFilter(SrcImageIterator srcUpperLeft, void applyFourierFilter(SrcImageIterator srcUpperLeft,
SrcImageIterator srcLowerRight, SrcAccessor sa, SrcImageIterator srcLowerRight, SrcAccessor sa,
FilterImageIterator filterUpperLeft, FilterAccessor fa, FilterImageIterator filterUpperLeft, FilterAccessor fa,
DestImageIterator destUpperLeft, DestAccessor da) DestImageIterator destUpperLeft, DestAccessor da)
{ {
// copy real input images into a complex one... // copy real input images into a complex one...
int w= srcLowerRight.x - srcUpperLeft.x; int w= srcLowerRight.x - srcUpperLeft.x;
skipping to change at line 1547 skipping to change at line 1559
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, class FilterTy pe> template <class SrcImageIterator, class SrcAccessor, class FilterTy pe>
void applyFourierFilterFamily(SrcImageIterator srcUpperLeft, void applyFourierFilterFamily(SrcImageIterator srcUpperLeft,
SrcImageIterator srcLowerRight, SrcAc cessor sa, SrcImageIterator srcLowerRight, SrcAc cessor sa,
const ImageArray<FilterType> &filters , const ImageArray<FilterType> &filters ,
ImageArray<FFTWComplexImage> &results ) ImageArray<FFTWComplexImage> &results )
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, class FilterTy pe> template <class SrcImageIterator, class SrcAccessor, class FilterTy pe>
inline
void applyFourierFilterFamily(triple<SrcImageIterator, SrcImageIter ator, SrcAccessor> src, void applyFourierFilterFamily(triple<SrcImageIterator, SrcImageIter ator, SrcAccessor> src,
const ImageArray<FilterType> &filters , const ImageArray<FilterType> &filters ,
ImageArray<FFTWComplexImage> &results ) ImageArray<FFTWComplexImage> &results )
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a>" <br> <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx</a> \><br>
Namespace: vigra Namespace: vigra
\code \code
// assuming the presence of a real-valued image named "image" to // assuming the presence of a real-valued image named "image" to
// be filtered in this example // be filtered in this example
vigra::ImageArray<vigra::FImage> filters(16, image.size()); vigra::ImageArray<vigra::FImage> filters(16, image.size());
for (int i=0; i<filters.size(); i++) for (int i=0; i<filters.size(); i++)
// create some meaningful filters here // create some meaningful filters here
createMyFilterOfScale(i, destImage(filters[i])); createMyFilterOfScale(i, destImage(filters[i]));
vigra::ImageArray<vigra::FFTWComplexImage> results(); vigra::ImageArray<vigra::FFTWComplexImage> results();
vigra::applyFourierFilterFamily(srcImageRange(image), filters, results) ; vigra::applyFourierFilterFamily(srcImageRange(image), filters, results) ;
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void applyFourierFilterFamily)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class FilterType, class DestImage> class FilterType, class DestImage>
inline inline
void applyFourierFilterFamily(triple<SrcImageIterator, SrcImageIterator, Sr cAccessor> src, void applyFourierFilterFamily(triple<SrcImageIterator, SrcImageIterator, Sr cAccessor> src,
const ImageArray<FilterType> &filters, const ImageArray<FilterType> &filters,
ImageArray<DestImage> &results) ImageArray<DestImage> &results)
{ {
applyFourierFilterFamily(src.first, src.second, src.third, applyFourierFilterFamily(src.first, src.second, src.third,
filters, results); filters, results);
} }
skipping to change at line 1644 skipping to change at line 1657
} }
template <class FilterType, class DestImage> template <class FilterType, class DestImage>
void applyFourierFilterFamilyImpl( void applyFourierFilterFamilyImpl(
FFTWComplexImage::const_traverser srcUpperLeft, FFTWComplexImage::const_traverser srcUpperLeft,
FFTWComplexImage::const_traverser srcLowerRight, FFTWComplexImage::const_traverser srcLowerRight,
FFTWComplexImage::ConstAccessor sa, FFTWComplexImage::ConstAccessor sa,
const ImageArray<FilterType> &filters, const ImageArray<FilterType> &filters,
ImageArray<DestImage> &results) ImageArray<DestImage> &results)
{ {
// FIXME: sa is not used
// (maybe check if StandardAccessor, else copy?)
// make sure the filter images have the right dimensions // make sure the filter images have the right dimensions
vigra_precondition((srcLowerRight - srcUpperLeft) == filters.imageSize( ), vigra_precondition((srcLowerRight - srcUpperLeft) == filters.imageSize( ),
"applyFourierFilterFamily called with src image size != filters.imageSize()!"); "applyFourierFilterFamily called with src image size != filters.imageSize()!");
// make sure the result image array has the right dimensions // make sure the result image array has the right dimensions
results.resize(filters.size()); results.resize(filters.size());
results.resizeImages(filters.imageSize()); results.resizeImages(filters.imageSize());
// FFT from srcImage to freqImage // FFT from srcImage to freqImage
int w= srcLowerRight.x - srcUpperLeft.x; int w= srcLowerRight.x - srcUpperLeft.x;
skipping to change at line 1763 skipping to change at line 1779
template <class SrcTraverser, class SrcAccessor, template <class SrcTraverser, class SrcAccessor,
class DestTraverser, class DestAccessor> class DestTraverser, class DestAccessor>
void void
fourierTransformRealEE(SrcTraverser sul, SrcTraverser slr, SrcAcces sor src, fourierTransformRealEE(SrcTraverser sul, SrcTraverser slr, SrcAcces sor src,
DestTraverser dul, DestAccessor dest, fftw_r eal norm); DestTraverser dul, DestAccessor dest, fftw_r eal norm);
fourierTransformRealEO, fourierTransformRealOE, fourierTransformRea lOO likewise fourierTransformRealEO, fourierTransformRealOE, fourierTransformRea lOO likewise
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcTraverser, class SrcAccessor, template <class SrcTraverser, class SrcAccessor,
class DestTraverser, class DestAccessor> class DestTraverser, class DestAccessor>
void void
fourierTransformRealEE(triple<SrcTraverser, SrcTraverser, SrcAccess or> src, fourierTransformRealEE(triple<SrcTraverser, SrcTraverser, SrcAccess or> src,
pair<DestTraverser, DestAccessor> dest, fftw _real norm); pair<DestTraverser, DestAccessor> dest, fftw _real norm);
fourierTransformRealEO, fourierTransformRealOE, fourierTransformRea lOO likewise fourierTransformRealEO, fourierTransformRealOE, fourierTransformRea lOO likewise
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx< /a>"<br> <b>\#include</b> \<<a href="fftw3_8hxx-source.html">vigra/fftw3.hxx </a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::FImage spatial(width,height), fourier(width,height); vigra::FImage spatial(width,height), fourier(width,height);
... // fill image with data ... // fill image with data
// forward cosine transform == reflective boundary conditions // forward cosine transform == reflective boundary conditions
fourierTransformRealEE(srcImageRange(spatial), destImage(fourier), (fft w_real)1.0); fourierTransformRealEE(srcImageRange(spatial), destImage(fourier), (fft w_real)1.0);
// multiply with a first derivative of Gaussian in x-direction // multiply with a first derivative of Gaussian in x-direction
skipping to change at line 1806 skipping to change at line 1822
} }
fourier(width-1, y) = 0.0; fourier(width-1, y) = 0.0;
} }
// inverse transform -- odd symmetry in x-direction, even in y, // inverse transform -- odd symmetry in x-direction, even in y,
// due to symmetry of the filter // due to symmetry of the filter
fourierTransformRealOE(srcImageRange(fourier), destImage(spatial), fourierTransformRealOE(srcImageRange(fourier), destImage(spatial),
(fftw_real)-4.0 * (width+1) * (height-1)); (fftw_real)-4.0 * (width+1) * (height-1));
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void fourierTransformReal)
template <class SrcTraverser, class SrcAccessor, template <class SrcTraverser, class SrcAccessor,
class DestTraverser, class DestAccessor> class DestTraverser, class DestAccessor>
inline void inline void
fourierTransformRealEE(triple<SrcTraverser, SrcTraverser, SrcAccessor> src, fourierTransformRealEE(triple<SrcTraverser, SrcTraverser, SrcAccessor> src,
pair<DestTraverser, DestAccessor> dest, fftw _real norm) pair<DestTraverser, DestAccessor> dest, fftw _real norm)
{ {
fourierTransformRealEE(src.first, src.second, src.third, fourierTransformRealEE(src.first, src.second, src.third,
dest.first, dest.second, norm); dest.first, dest.second, norm);
} }
 End of changes. 38 change blocks. 
85 lines changed or deleted 104 lines changed or added


 fixedpoint.hxx   fixedpoint.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2004-2005 by Ullrich Koethe */ /* Copyright 2004-2005 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 185 skipping to change at line 185
Fixed point arithmetic is used when computations with fractional accura cy Fixed point arithmetic is used when computations with fractional accura cy
must be made at the highest speed possible (e.g. in the inner loop must be made at the highest speed possible (e.g. in the inner loop
of a volume rendering routine). The speed-up relative to floating of a volume rendering routine). The speed-up relative to floating
point arithmetic can be dramatic, especially when one can avoid point arithmetic can be dramatic, especially when one can avoid
conversions between integer anfloating point numbers (these are conversions between integer anfloating point numbers (these are
very expensive because integer and floating point arithmetic very expensive because integer and floating point arithmetic
resides in different pipelines). resides in different pipelines).
The template wraps an <tt>int</tt> and uses <tt>IntBits</tt> to The template wraps an <tt>int</tt> and uses <tt>IntBits</tt> to
represent the integral part of a number, and <tt>FractionalBits</tt> represent the integral part of a number, and <tt>FractionalBits</tt>
for the fractional part, where <tt>IntBits + FractionalBits < 32</tt >. for the fractional part, where <tt>IntBits + FractionalBits < 32</tt>.
(The 32rd bit is reserved because FixedPoint is a signed type). (The 32rd bit is reserved because FixedPoint is a signed type).
These numbers will be automatically allocated in an intelligent way These numbers will be automatically allocated in an intelligent way
in the result of an arithmetic operation. For example, when two in the result of an arithmetic operation. For example, when two
fixed point numbers are multiplied, the required number of integer fixed point numbers are multiplied, the required number of integer
bits in the result is the sum of the number of integer bits of the bits in the result is the sum of the number of integer bits of the
arguments, but only when so many bits are avaiable. This is figured out arguments, but only when so many bits are avaiable. This is figured out
by means of FixedPointTraits, and a compile-time error is raised by means of FixedPointTraits, and a compile-time error is raised
when no suitable representation can be found. The idea is that the righ t when no suitable representation can be found. The idea is that the righ t
thing happens automatically as often as possible. thing happens automatically as often as possible.
skipping to change at line 212 skipping to change at line 212
<tt>unsigned char, signed char, unsigned short, signed short, int</tt> can be <tt>unsigned char, signed char, unsigned short, signed short, int</tt> can be
transformed into a FixedPoint with appropriate layout by means of the f actory transformed into a FixedPoint with appropriate layout by means of the f actory
function <tt>fixedPoint()</tt>. function <tt>fixedPoint()</tt>.
<b>See also:</b> <b>See also:</b>
<ul> <ul>
<li> \ref FixedPointOperations <li> \ref FixedPointOperations
<li> \ref FixedPointTraits <li> \ref FixedPointTraits
</ul> </ul>
<b>\#include</b> "<a href="fixedpoint_8hxx-source.html">vigra/fixedpoin t.hxx</a>"<br> <b>\#include</b> \<<a href="fixedpoint_8hxx-source.html">vigra/fixedpoi nt.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <unsigned IntBits, unsigned FractionalBits> template <unsigned IntBits, unsigned FractionalBits>
class FixedPoint class FixedPoint
{ {
public: public:
enum { enum {
INT_BITS = IntBits, INT_BITS = IntBits,
FRACTIONAL_BITS = FractionalBits, FRACTIONAL_BITS = FractionalBits,
TOTAL_BITS = IntBits + FractionalBits, TOTAL_BITS = IntBits + FractionalBits,
skipping to change at line 465 skipping to change at line 465
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* FixedPointOperations */ /* FixedPointOperations */
/* */ /* */
/********************************************************/ /********************************************************/
/** \addtogroup FixedPointOperations Functions for FixedPoint /** \addtogroup FixedPointOperations Functions for FixedPoint
\brief <b>\#include</b> "<a href="fixedpoint_8hxx-source.html">vigr a/fixedpoint.hxx</a>"<br> \brief <b>\#include</b> \<<a href="fixedpoint_8hxx-source.html">vig ra/fixedpoint.hxx</a>\><br>
These functions fulfill the requirements of an \ref AlgebraicRing. These functions fulfill the requirements of an \ref AlgebraicRing.
Namespace: vigra Namespace: vigra
<p> <p>
*/ */
//@{ //@{
/** Convert a FixedPoint to a built-in type. /** Convert a FixedPoint to a built-in type.
skipping to change at line 758 skipping to change at line 758
template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, uns igned FracBits2> template <unsigned IntBits1, unsigned FracBits1, unsigned IntBits2, uns igned FracBits2>
struct PromoteTraits<FixedPoint<IntBits1, FracBits1>, struct PromoteTraits<FixedPoint<IntBits1, FracBits1>,
FixedPoint<IntBits2, FracBits2> > FixedPoint<IntBits2, FracBits2> >
{ {
typedef typename typedef typename
FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<In tBits2, FracBits2> >::PlusType FixedPointTraits<FixedPoint<IntBits1, FracBits1>, FixedPoint<In tBits2, FracBits2> >::PlusType
Promote; Promote;
}; };
\endcode \endcode
<b>\#include</b> "<a href="fixedpoint_8hxx-source.html">vigra/fixedpoin t.hxx</a>"<br> <b>\#include</b> \<<a href="fixedpoint_8hxx-source.html">vigra/fixedpoi nt.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <unsigned IntBits, unsigned FracBits> template <unsigned IntBits, unsigned FracBits>
struct NumericTraits<FixedPoint<IntBits, FracBits> > struct NumericTraits<FixedPoint<IntBits, FracBits> >
{ {
typedef FixedPoint<IntBits, FracBits> Type; typedef FixedPoint<IntBits, FracBits> Type;
//typedef FixedPoint<IntBits, FracBits> Promote; //typedef FixedPoint<IntBits, FracBits> Promote;
//typedef FixedPoint<IntBits, FracBits> RealPromote; //typedef FixedPoint<IntBits, FracBits> RealPromote;
//typedef std::complex<RealPromote> ComplexPromote; //typedef std::complex<RealPromote> ComplexPromote;
 End of changes. 6 change blocks. 
7 lines changed or deleted 7 lines changed or added


 flatmorphology.hxx   flatmorphology.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 49 skipping to change at line 49
#define VIGRA_FLATMORPHOLOGY_HXX #define VIGRA_FLATMORPHOLOGY_HXX
#include <cmath> #include <cmath>
#include <vector> #include <vector>
#include "utilities.hxx" #include "utilities.hxx"
namespace vigra { namespace vigra {
/** \addtogroup Morphology Basic Morphological Operations /** \addtogroup Morphology Basic Morphological Operations
Perform erosion, dilation, and median with disc structuring functions Perform erosion, dilation, and median with disc structuring functions
See also: \ref MultiArrayMorphology Separable morphology with parabola
structuring functions in arbitrary dimensions
*/ */
//@{ //@{
/********************************************************/ /********************************************************/
/* */ /* */
/* discRankOrderFilter */ /* discRankOrderFilter */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Apply rank order filter with disc structuring function to the im age. /** \brief Apply rank order filter with disc structuring function to the im age.
skipping to change at line 81 skipping to change at line 83
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
discRankOrderFilter(SrcIterator upperleft1, discRankOrderFilter(SrcIterator upperleft1,
SrcIterator lowerright1, SrcAccessor sa, SrcIterator lowerright1, SrcAccessor sa,
DestIterator upperleft2, DestAccessor da, DestIterator upperleft2, DestAccessor da,
int radius, float rank) int radius, float rank)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
discRankOrderFilter(triple<SrcIterator, SrcIterator, SrcAccessor> s rc, discRankOrderFilter(triple<SrcIterator, SrcIterator, SrcAccessor> s rc,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
int radius, float rank) int radius, float rank)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="flatmorphology_8hxx-source.html">vigra/f latmorphology.hxx</a>"<br> <b>\#include</b> \<<a href="flatmorphology_8hxx-source.html">vigra/ flatmorphology.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::CImage src, dest; vigra::CImage src, dest;
// do median filtering // do median filtering
vigra::discRankOrderFilter(srcImageRange(src), destImage(dest), 10, 0.5 ); vigra::discRankOrderFilter(srcImageRange(src), destImage(dest), 10, 0.5 );
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
skipping to change at line 132 skipping to change at line 134
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
for all source pixels: 0 <= value <= 255 for all source pixels: 0 <= value <= 255
(rank >= 0.0) && (rank <= 1.0) (rank >= 0.0) && (rank <= 1.0)
radius >= 0 radius >= 0
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void discRankOrderFilter)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
discRankOrderFilter(SrcIterator upperleft1, discRankOrderFilter(SrcIterator upperleft1,
SrcIterator lowerright1, SrcAccessor sa, SrcIterator lowerright1, SrcAccessor sa,
DestIterator upperleft2, DestAccessor da, DestIterator upperleft2, DestAccessor da,
int radius, float rank) int radius, float rank)
{ {
vigra_precondition((rank >= 0.0) && (rank <= 1.0), vigra_precondition((rank >= 0.0) && (rank <= 1.0),
"discRankOrderFilter(): Rank must be between 0 and 1" "discRankOrderFilter(): Rank must be between 0 and 1"
skipping to change at line 379 skipping to change at line 383
This is an abbreviation vor the rank order filter with rank = 0.0. This is an abbreviation vor the rank order filter with rank = 0.0.
See \ref discRankOrderFilter() for more information. See \ref discRankOrderFilter() for more information.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitely: pass arguments explicitely:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void void
discErosion(SrcIterator upperleft1, discErosion(SrcIterator upperleft1,
SrcIterator lowerright1, SrcAccessor sa, SrcIterator lowerright1, SrcAccessor sa,
DestIterator upperleft2, DestAccessor da, DestIterator upperleft2, DestAccessor da,
int radius) int radius)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
discErosion(triple<SrcIterator, SrcIterator, SrcAccessor> src, discErosion(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
int radius) int radius)
} }
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void discErosion)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void inline void
discErosion(SrcIterator upperleft1, discErosion(SrcIterator upperleft1,
SrcIterator lowerright1, SrcAccessor sa, SrcIterator lowerright1, SrcAccessor sa,
DestIterator upperleft2, DestAccessor da, DestIterator upperleft2, DestAccessor da,
int radius) int radius)
{ {
vigra_precondition(radius >= 0, "discErosion(): Radius must be >= 0."); vigra_precondition(radius >= 0, "discErosion(): Radius must be >= 0.");
skipping to change at line 446 skipping to change at line 452
This is an abbreviation vor the rank order filter with rank = 1.0. This is an abbreviation vor the rank order filter with rank = 1.0.
See \ref discRankOrderFilter() for more information. See \ref discRankOrderFilter() for more information.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitely: pass arguments explicitely:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void void
discDilation(SrcIterator upperleft1, discDilation(SrcIterator upperleft1,
SrcIterator lowerright1, SrcAccessor sa, SrcIterator lowerright1, SrcAccessor sa,
DestIterator upperleft2, DestAccessor da, DestIterator upperleft2, DestAccessor da,
int radius) int radius)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
discDilation(triple<SrcIterator, SrcIterator, SrcAccessor> src, discDilation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
int radius) int radius)
} }
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void discDilation)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void inline void
discDilation(SrcIterator upperleft1, discDilation(SrcIterator upperleft1,
SrcIterator lowerright1, SrcAccessor sa, SrcIterator lowerright1, SrcAccessor sa,
DestIterator upperleft2, DestAccessor da, DestIterator upperleft2, DestAccessor da,
int radius) int radius)
{ {
vigra_precondition(radius >= 0, "discDilation(): Radius must be >= 0.") ; vigra_precondition(radius >= 0, "discDilation(): Radius must be >= 0.") ;
skipping to change at line 513 skipping to change at line 521
This is an abbreviation vor the rank order filter with rank = 0.5. This is an abbreviation vor the rank order filter with rank = 0.5.
See \ref discRankOrderFilter() for more information. See \ref discRankOrderFilter() for more information.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitely: pass arguments explicitely:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void void
discMedian(SrcIterator upperleft1, discMedian(SrcIterator upperleft1,
SrcIterator lowerright1, SrcAccessor sa, SrcIterator lowerright1, SrcAccessor sa,
DestIterator upperleft2, DestAccessor da, DestIterator upperleft2, DestAccessor da,
int radius) int radius)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
discMedian(triple<SrcIterator, SrcIterator, SrcAccessor> src, discMedian(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
int radius) int radius)
} }
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void discMedian)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void inline void
discMedian(SrcIterator upperleft1, discMedian(SrcIterator upperleft1,
SrcIterator lowerright1, SrcAccessor sa, SrcIterator lowerright1, SrcAccessor sa,
DestIterator upperleft2, DestAccessor da, DestIterator upperleft2, DestAccessor da,
int radius) int radius)
{ {
vigra_precondition(radius >= 0, "discMedian(): Radius must be >= 0."); vigra_precondition(radius >= 0, "discMedian(): Radius must be >= 0.");
skipping to change at line 615 skipping to change at line 625
void void
discRankOrderFilterWithMask(triple<SrcIterator, SrcIterator, SrcAcc essor> src, discRankOrderFilterWithMask(triple<SrcIterator, SrcIterator, SrcAcc essor> src,
pair<MaskIterator, MaskAccessor> mask, pair<MaskIterator, MaskAccessor> mask,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
int radius, float rank) int radius, float rank)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="flatmorphology_8hxx-source.html">vigra/f latmorphology.hxx</a>"<br> <b>\#include</b> \<<a href="flatmorphology_8hxx-source.html">vigra/flat morphology.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::CImage src, dest, mask; vigra::CImage src, dest, mask;
// do median filtering // do median filtering
vigra::discRankOrderFilterWithMask(srcImageRange(src), vigra::discRankOrderFilterWithMask(srcImageRange(src),
maskImage(mask), destImage(dest), 10, 0.5); maskImage(mask), destImage(dest), 10, 0.5);
\endcode \endcode
skipping to change at line 657 skipping to change at line 667
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
for all source pixels: 0 <= value <= 255 for all source pixels: 0 <= value <= 255
(rank >= 0.0) && (rank <= 1.0) (rank >= 0.0) && (rank <= 1.0)
radius >= 0 radius >= 0
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void discRankOrderFilterWithMask
)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
discRankOrderFilterWithMask(SrcIterator upperleft1, discRankOrderFilterWithMask(SrcIterator upperleft1,
SrcIterator lowerright1, SrcAccessor sa, SrcIterator lowerright1, SrcAccessor sa,
MaskIterator upperleftm, MaskAccessor mask, MaskIterator upperleftm, MaskAccessor mask,
DestIterator upperleft2, DestAccessor da, DestIterator upperleft2, DestAccessor da,
int radius, float rank) int radius, float rank)
{ {
skipping to change at line 949 skipping to change at line 961
rank = 0.0. See \ref discRankOrderFilterWithMask() for more information . rank = 0.0. See \ref discRankOrderFilterWithMask() for more information .
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitely: pass arguments explicitely:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void void
discErosionWithMask(SrcIterator upperleft1, discErosionWithMask(SrcIterator upperleft1,
SrcIterator lowerright1, SrcAccessor sa, SrcIterator lowerright1, SrcAccessor sa,
MaskIterator upperleftm, MaskAccessor mask, MaskIterator upperleftm, MaskAccessor mask,
DestIterator upperleft2, DestAccessor da, DestIterator upperleft2, DestAccessor da,
int radius) int radius)
} }
\endcode \endcode
group arguments (use in conjunction with \ref ArgumentObjectFactories): group arguments (use in conjunction with \ref ArgumentObjectFactories):
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void void
discErosionWithMask(triple<SrcIterator, SrcIterator, SrcAccessor> s rc, discErosionWithMask(triple<SrcIterator, SrcIterator, SrcAccessor> s rc,
pair<MaskIterator, MaskAccessor> mask, pair<MaskIterator, MaskAccessor> mask,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
int radius) int radius)
} }
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void discErosionWithMask)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void inline void
discErosionWithMask(SrcIterator upperleft1, discErosionWithMask(SrcIterator upperleft1,
SrcIterator lowerright1, SrcAccessor sa, SrcIterator lowerright1, SrcAccessor sa,
MaskIterator upperleftm, MaskAccessor mask, MaskIterator upperleftm, MaskAccessor mask,
DestIterator upperleft2, DestAccessor da, DestIterator upperleft2, DestAccessor da,
int radius) int radius)
{ {
skipping to change at line 1028 skipping to change at line 1042
rank = 1.0. See \ref discRankOrderFilterWithMask() for more information . rank = 1.0. See \ref discRankOrderFilterWithMask() for more information .
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitely: pass arguments explicitely:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void void
discDilationWithMask(SrcIterator upperleft1, discDilationWithMask(SrcIterator upperleft1,
SrcIterator lowerright1, SrcAccessor sa, SrcIterator lowerright1, SrcAccessor sa,
MaskIterator upperleftm, MaskAccessor mask, MaskIterator upperleftm, MaskAccessor mask,
DestIterator upperleft2, DestAccessor da, DestIterator upperleft2, DestAccessor da,
int radius) int radius)
} }
\endcode \endcode
group arguments (use in conjunction with \ref ArgumentObjectFactories): group arguments (use in conjunction with \ref ArgumentObjectFactories):
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void void
discDilationWithMask(triple<SrcIterator, SrcIterator, SrcAccessor> src, discDilationWithMask(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<MaskIterator, MaskAccessor> mask, pair<MaskIterator, MaskAccessor> mask,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
int radius) int radius)
} }
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void discDilationWithMask)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void inline void
discDilationWithMask(SrcIterator upperleft1, discDilationWithMask(SrcIterator upperleft1,
SrcIterator lowerright1, SrcAccessor sa, SrcIterator lowerright1, SrcAccessor sa,
MaskIterator upperleftm, MaskAccessor mask, MaskIterator upperleftm, MaskAccessor mask,
DestIterator upperleft2, DestAccessor da, DestIterator upperleft2, DestAccessor da,
int radius) int radius)
{ {
skipping to change at line 1107 skipping to change at line 1123
rank = 0.5. See \ref discRankOrderFilterWithMask() for more information . rank = 0.5. See \ref discRankOrderFilterWithMask() for more information .
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitely: pass arguments explicitely:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void void
discMedianWithMask(SrcIterator upperleft1, discMedianWithMask(SrcIterator upperleft1,
SrcIterator lowerright1, SrcAccessor sa, SrcIterator lowerright1, SrcAccessor sa,
MaskIterator upperleftm, MaskAccessor mask, MaskIterator upperleftm, MaskAccessor mask,
DestIterator upperleft2, DestAccessor da, DestIterator upperleft2, DestAccessor da,
int radius) int radius)
} }
\endcode \endcode
group arguments (use in conjunction with \ref ArgumentObjectFactories): group arguments (use in conjunction with \ref ArgumentObjectFactories):
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void void
discMedianWithMask(triple<SrcIterator, SrcIterator, SrcAccessor> sr c, discMedianWithMask(triple<SrcIterator, SrcIterator, SrcAccessor> sr c,
pair<MaskIterator, MaskAccessor> mask, pair<MaskIterator, MaskAccessor> mask,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
int radius) int radius)
} }
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void discMedianWithMask)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void inline void
discMedianWithMask(SrcIterator upperleft1, discMedianWithMask(SrcIterator upperleft1,
SrcIterator lowerright1, SrcAccessor sa, SrcIterator lowerright1, SrcAccessor sa,
MaskIterator upperleftm, MaskAccessor mask, MaskIterator upperleftm, MaskAccessor mask,
DestIterator upperleft2, DestAccessor da, DestIterator upperleft2, DestAccessor da,
int radius) int radius)
{ {
 End of changes. 26 change blocks. 
18 lines changed or deleted 38 lines changed or added


 functorexpression.hxx   functorexpression.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 46 skipping to change at line 46
/************************************************************************/ /************************************************************************/
#ifndef VIGRA_FUNCTOREXPRESSION_HXX #ifndef VIGRA_FUNCTOREXPRESSION_HXX
#define VIGRA_FUNCTOREXPRESSION_HXX #define VIGRA_FUNCTOREXPRESSION_HXX
/** \page FunctorExpressions Functor Expressions /** \page FunctorExpressions Functor Expressions
Simple automatic functor creation by means of expression templates Simple automatic functor creation by means of expression templates
(also known as a "lambda library"). (also known as a "lambda library").
<b>\#include</b> "<a href="functorexpression_8hxx-source.html">vigra/fu nctorexpression.hxx</a>"<br> <b>\#include</b> \<<a href="functorexpression_8hxx-source.html">vigra/f unctorexpression.hxx</a>\><br>
Namespace: vigra::functor Namespace: vigra::functor
<b> Note:</b> This functionality is not available under Microsoft Visua l C++, <b> Note:</b> This functionality is not available under Microsoft Visua l C++,
because support for partial template specialization is required. because support for partial template specialization is required.
<b> Motivation</b> <b> Motivation</b>
Many generic algorithms are made more flexible by means of functors Many generic algorithms are made more flexible by means of functors
which define part of the algorithms' behavior according to the which define part of the algorithms' behavior according to the
needs of a specific situation. For example, we can apply an exponential needs of a specific situation. For example, we can apply an exponential
skipping to change at line 411 skipping to change at line 411
template <class T1, class T2, class T3> template <class T1, class T2, class T3>
typename ResultTraits3<EXPR, T1, T2, T3>::Res typename ResultTraits3<EXPR, T1, T2, T3>::Res
operator()(T1 const & v1, T2 const & v2, T3 const & v3) const operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
{ {
return expr_(v1, v2, v3); return expr_(v1, v2, v3);
} }
protected: protected:
EXPR expr_; EXPR expr_;
private:
UnaryFunctor & operator=(UnaryFunctor const &); // not implemented
}; };
template <class Expr> template <class Expr>
struct ResultTraits0<UnaryFunctor<Expr> > struct ResultTraits0<UnaryFunctor<Expr> >
{ {
typedef typename ResultTraits0<Expr>::Res Res; typedef typename ResultTraits0<Expr>::Res Res;
}; };
template <class Expr, class T1> template <class Expr, class T1>
struct ResultTraits1<UnaryFunctor<Expr>, T1> struct ResultTraits1<UnaryFunctor<Expr>, T1>
skipping to change at line 470 skipping to change at line 473
T1 const & operator()(T1 const & v1, T2 const &) const T1 const & operator()(T1 const & v1, T2 const &) const
{ {
return v1; return v1;
} }
template <class T1, class T2, class T3> template <class T1, class T2, class T3>
T1 const & operator()(T1 const & v1, T2 const &, T3 const &) const T1 const & operator()(T1 const & v1, T2 const &, T3 const &) const
{ {
return v1; return v1;
} }
private:
UnaryFunctor & operator=(UnaryFunctor const &); // not implemented
}; };
template <> template <>
struct ResultTraits0<UnaryFunctor<ArgumentFunctor1> > struct ResultTraits0<UnaryFunctor<ArgumentFunctor1> >
{ {
typedef ErrorType Res; typedef ErrorType Res;
}; };
template <class T1> template <class T1>
struct ResultTraits1<UnaryFunctor<ArgumentFunctor1>, T1> struct ResultTraits1<UnaryFunctor<ArgumentFunctor1>, T1>
skipping to change at line 524 skipping to change at line 530
T2 const & operator()(T1 const &, T2 const & v2) const T2 const & operator()(T1 const &, T2 const & v2) const
{ {
return v2; return v2;
} }
template <class T1, class T2, class T3> template <class T1, class T2, class T3>
T2 const & operator()(T1 const &, T2 const & v2, T3 const &) const T2 const & operator()(T1 const &, T2 const & v2, T3 const &) const
{ {
return v2; return v2;
} }
private:
UnaryFunctor & operator=(UnaryFunctor const &); // not implemented
}; };
template <> template <>
struct ResultTraits0<UnaryFunctor<ArgumentFunctor2> > struct ResultTraits0<UnaryFunctor<ArgumentFunctor2> >
{ {
typedef ErrorType Res; typedef ErrorType Res;
}; };
template <class T1> template <class T1>
struct ResultTraits1<UnaryFunctor<ArgumentFunctor2>, T1> struct ResultTraits1<UnaryFunctor<ArgumentFunctor2>, T1>
skipping to change at line 572 skipping to change at line 581
struct UnaryFunctor<ArgumentFunctor3> struct UnaryFunctor<ArgumentFunctor3>
{ {
UnaryFunctor() UnaryFunctor()
{} {}
template <class T1, class T2, class T3> template <class T1, class T2, class T3>
T3 const & operator()(T1 const &, T2 const &, T3 const & v3) const T3 const & operator()(T1 const &, T2 const &, T3 const & v3) const
{ {
return v3; return v3;
} }
private:
UnaryFunctor & operator=(UnaryFunctor const &); // not implemented
}; };
template <> template <>
struct ResultTraits0<UnaryFunctor<ArgumentFunctor3> > struct ResultTraits0<UnaryFunctor<ArgumentFunctor3> >
{ {
typedef ErrorType Res; typedef ErrorType Res;
}; };
template <class T1> template <class T1>
struct ResultTraits1<UnaryFunctor<ArgumentFunctor3>, T1> struct ResultTraits1<UnaryFunctor<ArgumentFunctor3>, T1>
skipping to change at line 645 skipping to change at line 657
} }
template <class U1, class U2, class U3> template <class U1, class U2, class U3>
T const & operator()(U1 const &, U2 const &, U3 const &) const T const & operator()(U1 const &, U2 const &, U3 const &) const
{ {
return value_; return value_;
} }
protected: protected:
T value_; T value_;
private:
ParameterFunctor & operator=(ParameterFunctor const &); // not implemen
ted
}; };
template <class T> template <class T>
struct ResultTraits0<ParameterFunctor<T> > struct ResultTraits0<ParameterFunctor<T> >
{ {
typedef T Res; typedef T Res;
}; };
template <class T, class T1> template <class T, class T1>
struct ResultTraits1<ParameterFunctor<T>, T1> struct ResultTraits1<ParameterFunctor<T>, T1>
skipping to change at line 672 skipping to change at line 687
typedef T Res; typedef T Res;
}; };
template <class T, class T1, class T2, class T3> template <class T, class T1, class T2, class T3>
struct ResultTraits3<ParameterFunctor<T>, T1, T2, T3> struct ResultTraits3<ParameterFunctor<T>, T1, T2, T3>
{ {
typedef T Res; typedef T Res;
}; };
template <class T> template <class T>
UnaryFunctor<ParameterFunctor<T> > inline UnaryFunctor<ParameterFunctor<T> >
Param(T const & v) Param(T const & v)
{ {
ParameterFunctor<T> fv(v); ParameterFunctor<T> fv(v);
return UnaryFunctor<ParameterFunctor<T> >(fv); return UnaryFunctor<ParameterFunctor<T> >(fv);
} }
/************************************************************/ /************************************************************/
/* */ /* */
/* unary analyser base template */ /* unary analyser base template */
/* */ /* */
skipping to change at line 718 skipping to change at line 733
} }
template <class T1, class T2, class T3> template <class T1, class T2, class T3>
void operator()(T1 const & v1, T2 const & v2, T3 const & v3) const void operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
{ {
expr_(v1, v2, v3); expr_(v1, v2, v3);
} }
protected: protected:
EXPR expr_; EXPR expr_;
private:
UnaryAnalyser & operator=(UnaryAnalyser const &); // not implemented
}; };
/************************************************************/ /************************************************************/
/* */ /* */
/* variable assignment */ /* variable assignment */
/* */ /* */
/************************************************************/ /************************************************************/
template <class T> template <class T>
struct VarFunctor; struct VarFunctor;
skipping to change at line 773 skipping to change at line 791
template <class T1, class T2, class T3> \ template <class T1, class T2, class T3> \
V & operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \ V & operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
{ \ { \
const_cast<V &>(value_) op expr_(v1, v2, v3); \ const_cast<V &>(value_) op expr_(v1, v2, v3); \
return const_cast<V &>(value_); \ return const_cast<V &>(value_); \
} \ } \
\ \
private: \ private: \
V & value_; \ V & value_; \
UnaryFunctor<EXPR> expr_; \ UnaryFunctor<EXPR> expr_; \
\
AssignmentFunctor_##name & operator=(AssignmentFunctor_##name const
&);\
}; };
/************************************************************/ /************************************************************/
MAKE_ASSIGNMENT_FUNCTOR(assign, =) MAKE_ASSIGNMENT_FUNCTOR(assign, =)
MAKE_ASSIGNMENT_FUNCTOR(add, +=) MAKE_ASSIGNMENT_FUNCTOR(add, +=)
MAKE_ASSIGNMENT_FUNCTOR(subtract, -=) MAKE_ASSIGNMENT_FUNCTOR(subtract, -=)
MAKE_ASSIGNMENT_FUNCTOR(multiply, *=) MAKE_ASSIGNMENT_FUNCTOR(multiply, *=)
MAKE_ASSIGNMENT_FUNCTOR(divide, /=) MAKE_ASSIGNMENT_FUNCTOR(divide, /=)
skipping to change at line 864 skipping to change at line 884
return value_; return value_;
} }
template <class U1, class U2, class U3> template <class U1, class U2, class U3>
T const & operator()(U1 const &, U2 const &, U3 const &) const T const & operator()(U1 const &, U2 const &, U3 const &) const
{ {
return value_; return value_;
} }
T & value_; T & value_;
private:
UnaryFunctor & operator=(UnaryFunctor const &); // not implemented
}; };
template <class T> template <class T>
struct ResultTraits0<UnaryFunctor<VarFunctor<T> > > struct ResultTraits0<UnaryFunctor<VarFunctor<T> > >
{ {
typedef T Res; typedef T Res;
}; };
template <class T, class T1> template <class T, class T1>
struct ResultTraits1<UnaryFunctor<VarFunctor<T> >, T1> struct ResultTraits1<UnaryFunctor<VarFunctor<T> >, T1>
skipping to change at line 891 skipping to change at line 914
typedef T Res; typedef T Res;
}; };
template <class T, class T1, class T2, class T3> template <class T, class T1, class T2, class T3>
struct ResultTraits3<UnaryFunctor<VarFunctor<T> >, T1, T2, T3> struct ResultTraits3<UnaryFunctor<VarFunctor<T> >, T1, T2, T3>
{ {
typedef T Res; typedef T Res;
}; };
template <class T> template <class T>
UnaryFunctor<VarFunctor<T> > inline UnaryFunctor<VarFunctor<T> >
Var(T & v) Var(T & v)
{ {
return UnaryFunctor<VarFunctor<T> >(v); return UnaryFunctor<VarFunctor<T> >(v);
} }
/************************************************************/ /************************************************************/
/* */ /* */
/* if then */ /* if then */
/* */ /* */
/************************************************************/ /************************************************************/
skipping to change at line 939 skipping to change at line 962
template <class T1, class T2, class T3> template <class T1, class T2, class T3>
void operator()(T1 const & v1, T2 const & v2, T3 const & v3) const void operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
{ {
if( expr1_(v1, v2, v3) ) expr2_(v1, v2, v3); if( expr1_(v1, v2, v3) ) expr2_(v1, v2, v3);
} }
private: private:
EXPR1 expr1_; EXPR1 expr1_;
EXPR2 expr2_; EXPR2 expr2_;
private:
IfThenFunctor & operator=(IfThenFunctor const &); // not implemented
}; };
template <class EXPR1, class EXPR2> template <class EXPR1, class EXPR2>
UnaryAnalyser<IfThenFunctor<UnaryFunctor<EXPR1>, UnaryAnalyser<IfThenFunctor<UnaryFunctor<EXPR1>,
UnaryAnalyser<EXPR2> > > UnaryAnalyser<EXPR2> > >
ifThen(UnaryFunctor<EXPR1> const & e1, ifThen(UnaryFunctor<EXPR1> const & e1,
UnaryAnalyser<EXPR2> const & e2) UnaryAnalyser<EXPR2> const & e2)
{ {
IfThenFunctor<UnaryFunctor<EXPR1>, IfThenFunctor<UnaryFunctor<EXPR1>,
UnaryAnalyser<EXPR2> > p(e1, e2); UnaryAnalyser<EXPR2> > p(e1, e2);
skipping to change at line 1057 skipping to change at line 1083
ResultTraits3<IfThenElseFunctor, T1, T2, T3>::Res ResultTraits3<IfThenElseFunctor, T1, T2, T3>::Res
r3(expr3_(v1, v2, v3)); r3(expr3_(v1, v2, v3));
return expr1_(v1, v2, v3) ? r2 : r3; return expr1_(v1, v2, v3) ? r2 : r3;
} }
private: private:
EXPR1 expr1_; EXPR1 expr1_;
EXPR2 expr2_; EXPR2 expr2_;
EXPR3 expr3_; EXPR3 expr3_;
IfThenElseFunctor & operator=(IfThenElseFunctor const &); // not implem
ented
}; };
template <class EXPR1, class EXPR2, class EXPR3> template <class EXPR1, class EXPR2, class EXPR3>
UnaryFunctor<IfThenElseFunctor<UnaryFunctor<EXPR1>, UnaryFunctor<IfThenElseFunctor<UnaryFunctor<EXPR1>,
UnaryFunctor<EXPR2>, UnaryFunctor<EXPR2>,
UnaryFunctor<EXPR3> > > UnaryFunctor<EXPR3> > >
ifThenElse(UnaryFunctor<EXPR1> const & e1, ifThenElse(UnaryFunctor<EXPR1> const & e1,
UnaryFunctor<EXPR2> const & e2, UnaryFunctor<EXPR2> const & e2,
UnaryFunctor<EXPR3> const & e3) UnaryFunctor<EXPR3> const & e3)
{ {
skipping to change at line 1151 skipping to change at line 1179
template <class T1, class T2, class T3> \ template <class T1, class T2, class T3> \
typename ResultTraits3<Functor_##function, T1, T2, T3>::Res \ typename ResultTraits3<Functor_##function, T1, T2, T3>::Res \
operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \ operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
{ \ { \
return function(expr_(v1, v2, v3)); \ return function(expr_(v1, v2, v3)); \
} \ } \
\ \
protected: \ protected: \
\ \
EXPR expr_; \ EXPR expr_; \
\
private: \
Functor_##function & operator=(Functor_##function const &); \
}; \ }; \
\ \
template <class EXPR> \ template <class EXPR> \
UnaryFunctor<Functor_##function<UnaryFunctor<EXPR> > > \ inline UnaryFunctor<Functor_##function<UnaryFunctor<EXPR> > > \
function(UnaryFunctor<EXPR> const & e) \ function(UnaryFunctor<EXPR> const & e) \
{ \ { \
Functor_##function<UnaryFunctor<EXPR> > p(e); \ Functor_##function<UnaryFunctor<EXPR> > p(e); \
return UnaryFunctor<Functor_##function<UnaryFunctor<EXPR> > >(p); \ return UnaryFunctor<Functor_##function<UnaryFunctor<EXPR> > >(p); \
} }
/************************************************************/ /************************************************************/
MAKE_FUNCTOR_UNARY_FUNCTION(sqrt, std) MAKE_FUNCTOR_UNARY_FUNCTION(sqrt, std)
MAKE_FUNCTOR_UNARY_FUNCTION(exp, std) MAKE_FUNCTOR_UNARY_FUNCTION(exp, std)
skipping to change at line 1251 skipping to change at line 1282
\ \
template <class T1, class T2, class T3> \ template <class T1, class T2, class T3> \
typename ResultTraits3<Functor_##name, T1, T2, T3>::Res \ typename ResultTraits3<Functor_##name, T1, T2, T3>::Res \
operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \ operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
{ \ { \
return op expr_(v1, v2, v3); \ return op expr_(v1, v2, v3); \
} \ } \
protected: \ protected: \
\ \
EXPR expr_; \ EXPR expr_; \
\
private: \
Functor_##name & operator=(Functor_##name const &);\
}; \ }; \
\ \
template <class EXPR> \ template <class EXPR> \
UnaryFunctor<Functor_##name<UnaryFunctor<EXPR> > > \ inline UnaryFunctor<Functor_##name<UnaryFunctor<EXPR> > > \
operator op(UnaryFunctor<EXPR> const & e) \ operator op(UnaryFunctor<EXPR> const & e) \
{ \ { \
Functor_##name<UnaryFunctor<EXPR> > p(e); \ Functor_##name<UnaryFunctor<EXPR> > p(e); \
return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR> > >(p); \ return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR> > >(p); \
} }
/************************************************************/ /************************************************************/
MAKE_FUNCTOR_UNARY_OPERATOR(minus, -) MAKE_FUNCTOR_UNARY_OPERATOR(minus, -)
MAKE_FUNCTOR_UNARY_OPERATOR(negate, !) MAKE_FUNCTOR_UNARY_OPERATOR(negate, !)
skipping to change at line 1354 skipping to change at line 1388
typename ResultTraits3<Functor_##function, T1, T2, T3>::Res \ typename ResultTraits3<Functor_##function, T1, T2, T3>::Res \
operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \ operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
{ \ { \
return function(expr1_(v1, v2, v3), expr2_(v1, v2, v3)); \ return function(expr1_(v1, v2, v3), expr2_(v1, v2, v3)); \
} \ } \
\ \
private: \ private: \
\ \
EXPR1 expr1_; \ EXPR1 expr1_; \
EXPR2 expr2_; \ EXPR2 expr2_; \
\
Functor_##function & operator=(Functor_##function const &); \
}; \ }; \
\ \
template <class EXPR1, class EXPR2> \ template <class EXPR1, class EXPR2> \
UnaryFunctor<Functor_##function<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2 > > > \ inline UnaryFunctor<Functor_##function<UnaryFunctor<EXPR1>, UnaryFuncto r<EXPR2> > > \
function(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2 ) \ function(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2 ) \
{ \ { \
Functor_##function<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2); \ Functor_##function<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2); \
return UnaryFunctor<Functor_##function<UnaryFunctor<EXPR1>, \ return UnaryFunctor<Functor_##function<UnaryFunctor<EXPR1>, \
UnaryFunctor<EXPR2> > >(p); \ UnaryFunctor<EXPR2> > >(p); \
} }
/************************************************************/ /************************************************************/
MAKE_FUNCTOR_BINARY_FUNCTION(pow) MAKE_FUNCTOR_BINARY_FUNCTION(pow)
skipping to change at line 1465 skipping to change at line 1501
ResultTraits3<Functor_##name<EXPR1, EXPR2>, T1, T2, T3>::R1 r1( expr1_(v1, v2, v3)); \ ResultTraits3<Functor_##name<EXPR1, EXPR2>, T1, T2, T3>::R1 r1( expr1_(v1, v2, v3)); \
typename \ typename \
ResultTraits3<Functor_##name<EXPR1, EXPR2>, T1, T2, T3>::R2 r2( expr2_(v1, v2, v3)); \ ResultTraits3<Functor_##name<EXPR1, EXPR2>, T1, T2, T3>::R2 r2( expr2_(v1, v2, v3)); \
return (r1 op r2) ? r1 : r2; \ return (r1 op r2) ? r1 : r2; \
} \ } \
\ \
private: \ private: \
\ \
EXPR1 expr1_; \ EXPR1 expr1_; \
EXPR2 expr2_; \ EXPR2 expr2_; \
\
Functor_##name & operator=(Functor_##name const &); \
}; \ }; \
\ \
template <class EXPR1, class EXPR2> \ template <class EXPR1, class EXPR2> \
UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > > \ inline UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EX PR2> > > \
name(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2) \ name(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2) \
{ \ { \
Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2) ; \ Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2) ; \
return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, \ return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, \
UnaryFunctor<EXPR2> > >(p); \ UnaryFunctor<EXPR2> > >(p); \
} }
MAKE_FUNCTOR_MINMAX(min, <) MAKE_FUNCTOR_MINMAX(min, <)
MAKE_FUNCTOR_MINMAX(max, >) MAKE_FUNCTOR_MINMAX(max, >)
skipping to change at line 1561 skipping to change at line 1599
typename ResultTraits3<Functor_##name, T1, T2, T3>::Res \ typename ResultTraits3<Functor_##name, T1, T2, T3>::Res \
operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \ operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
{ \ { \
return expr1_(v1, v2, v3) op expr2_(v1, v2, v3); \ return expr1_(v1, v2, v3) op expr2_(v1, v2, v3); \
} \ } \
\ \
private: \ private: \
\ \
EXPR1 expr1_; \ EXPR1 expr1_; \
EXPR2 expr2_; \ EXPR2 expr2_; \
\
Functor_##name & operator=(Functor_##name const &); \
}; \ }; \
\ \
template <class EXPR1, class EXPR2> \ template <class EXPR1, class EXPR2> \
UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > > \ inline UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EX PR2> > > \
operator op(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2) \ operator op(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2) \
{ \ { \
Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2) ; \ Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2) ; \
return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, \ return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, \
UnaryFunctor<EXPR2> > >(p); \ UnaryFunctor<EXPR2> > >(p); \
} }
/************************************************************/ /************************************************************/
MAKE_FUNCTOR_BINARY_OPERATOR(add, +) MAKE_FUNCTOR_BINARY_OPERATOR(add, +)
skipping to change at line 1649 skipping to change at line 1689
template <class T1, class T2, class T3> \ template <class T1, class T2, class T3> \
bool operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \ bool operator()(T1 const & v1, T2 const & v2, T3 const & v3) const \
{ \ { \
return expr1_(v1, v2, v3) op expr2_(v1, v2, v3); \ return expr1_(v1, v2, v3) op expr2_(v1, v2, v3); \
} \ } \
\ \
private: \ private: \
\ \
EXPR1 expr1_; \ EXPR1 expr1_; \
EXPR2 expr2_; \ EXPR2 expr2_; \
\
Functor_##name & operator=(Functor_##name const &); \
}; \ }; \
\ \
template <class EXPR1, class EXPR2> \ template <class EXPR1, class EXPR2> \
UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > > \ inline UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EX PR2> > > \
operator op(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2) \ operator op(UnaryFunctor<EXPR1> const & e1, UnaryFunctor<EXPR2> const & e2) \
{ \ { \
Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2) ; \ Functor_##name<UnaryFunctor<EXPR1>, UnaryFunctor<EXPR2> > p(e1, e2) ; \
return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, \ return UnaryFunctor<Functor_##name<UnaryFunctor<EXPR1>, \
UnaryFunctor<EXPR2> > >(p); \ UnaryFunctor<EXPR2> > >(p); \
} }
/************************************************************/ /************************************************************/
MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(equals, ==) MAKE_FUNCTOR_BINARY_OPERATOR_BOOL(equals, ==)
skipping to change at line 1712 skipping to change at line 1754
template <class T1, class T2, class T3> template <class T1, class T2, class T3>
RES operator()(T1 const & v1, T2 const & v2, T3 const & v3) const RES operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
{ {
return f_(expr_(v1, v2, v3)); return f_(expr_(v1, v2, v3));
} }
protected: protected:
EXPR expr_; EXPR expr_;
RES (*f_)(ARG); RES (*f_)(ARG);
private:
UnaryFctPtrFunctor & operator=(UnaryFctPtrFunctor const &); // not impl
emented
}; };
template <class EXPR, class RES, class ARG> template <class EXPR, class RES, class ARG>
struct ResultTraits0<UnaryFctPtrFunctor<EXPR, RES, ARG> > struct ResultTraits0<UnaryFctPtrFunctor<EXPR, RES, ARG> >
{ {
typedef RES Res; typedef RES Res;
}; };
template <class EXPR, class RES, class ARG, class T1> template <class EXPR, class RES, class ARG, class T1>
struct ResultTraits1<UnaryFctPtrFunctor<EXPR, RES, ARG>, T1> struct ResultTraits1<UnaryFctPtrFunctor<EXPR, RES, ARG>, T1>
skipping to change at line 1739 skipping to change at line 1784
typedef RES Res; typedef RES Res;
}; };
template <class EXPR, class RES, class ARG, class T1, class T2, class T3> template <class EXPR, class RES, class ARG, class T1, class T2, class T3>
struct ResultTraits3<UnaryFctPtrFunctor<EXPR, RES, ARG>, T1, T2, T3> struct ResultTraits3<UnaryFctPtrFunctor<EXPR, RES, ARG>, T1, T2, T3>
{ {
typedef RES Res; typedef RES Res;
}; };
template <class EXPR, class RES, class ARG> template <class EXPR, class RES, class ARG>
UnaryFunctor<UnaryFctPtrFunctor<UnaryFunctor<EXPR>, RES, ARG> > inline UnaryFunctor<UnaryFctPtrFunctor<UnaryFunctor<EXPR>, RES, ARG> >
applyFct(RES (*f)(ARG), UnaryFunctor<EXPR> const & e) applyFct(RES (*f)(ARG), UnaryFunctor<EXPR> const & e)
{ {
UnaryFctPtrFunctor<UnaryFunctor<EXPR>, RES, ARG> p(e, f); UnaryFctPtrFunctor<UnaryFunctor<EXPR>, RES, ARG> p(e, f);
return UnaryFunctor<UnaryFctPtrFunctor<UnaryFunctor<EXPR>, RES, ARG> >( p); return UnaryFunctor<UnaryFctPtrFunctor<UnaryFunctor<EXPR>, RES, ARG> >( p);
} }
/************************************************************/ /************************************************************/
/* */ /* */
/* binary apply */ /* binary apply */
/* */ /* */
skipping to change at line 1782 skipping to change at line 1827
RES operator()(T1 const & v1, T2 const & v2) const RES operator()(T1 const & v1, T2 const & v2) const
{ {
return f_(expr1_(v1, v2), expr2_(v1, v2)); return f_(expr1_(v1, v2), expr2_(v1, v2));
} }
template <class T1, class T2, class T3> template <class T1, class T2, class T3>
RES operator()(T1 const & v1, T2 const & v2, T3 const & v3) const RES operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
{ {
return f_(expr1_(v1, v2, v3), expr2_(v1, v2, v3)); return f_(expr1_(v1, v2, v3), expr2_(v1, v2, v3));
} }
protected: protected:
EXPR1 expr1_; EXPR1 expr1_;
EXPR2 expr2_; EXPR2 expr2_;
RES (*f_)(ARG1, ARG2); RES (*f_)(ARG1, ARG2);
private:
BinaryFctPtrFunctor & operator=(BinaryFctPtrFunctor const &); // not im
plemented
}; };
template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2> template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2>
struct ResultTraits0<BinaryFctPtrFunctor<EXPR1, EXPR2, RES, ARG1, ARG2> > struct ResultTraits0<BinaryFctPtrFunctor<EXPR1, EXPR2, RES, ARG1, ARG2> >
{ {
typedef RES Res; typedef RES Res;
}; };
template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2, template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2,
class T1> class T1>
skipping to change at line 1817 skipping to change at line 1866
}; };
template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2, template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2,
class T1, class T2, class T3> class T1, class T2, class T3>
struct ResultTraits3<BinaryFctPtrFunctor<EXPR1, EXPR2, RES, ARG1, ARG2>, T1 , T2, T3> struct ResultTraits3<BinaryFctPtrFunctor<EXPR1, EXPR2, RES, ARG1, ARG2>, T1 , T2, T3>
{ {
typedef RES Res; typedef RES Res;
}; };
template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2> template <class EXPR1, class EXPR2, class RES, class ARG1, class ARG2>
UnaryFunctor<BinaryFctPtrFunctor<UnaryFunctor<EXPR1>, inline UnaryFunctor<BinaryFctPtrFunctor<UnaryFunctor<EXPR1>,
UnaryFunctor<EXPR2>, UnaryFunctor<EXPR2>,
RES, ARG1, ARG2> > RES, ARG1, ARG2> >
applyFct(RES (*f)(ARG1, ARG2), UnaryFunctor<EXPR1> const & e1, applyFct(RES (*f)(ARG1, ARG2), UnaryFunctor<EXPR1> const & e1,
UnaryFunctor<EXPR2> const & e2) UnaryFunctor<EXPR2> const & e2)
{ {
BinaryFctPtrFunctor<UnaryFunctor<EXPR1>, BinaryFctPtrFunctor<UnaryFunctor<EXPR1>,
UnaryFunctor<EXPR2>, UnaryFunctor<EXPR2>,
RES, ARG1, ARG2> p(e1, e2, f); RES, ARG1, ARG2> p(e1, e2, f);
return UnaryFunctor<BinaryFctPtrFunctor<UnaryFunctor<EXPR1>, return UnaryFunctor<BinaryFctPtrFunctor<UnaryFunctor<EXPR1>,
UnaryFunctor<EXPR2>, UnaryFunctor<EXPR2>,
skipping to change at line 1879 skipping to change at line 1928
operator()(T1 const & v1, T2 const & v2, T3 const & v3) const operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
{ {
expr1_(v1, v2, v3); expr1_(v1, v2, v3);
return expr2_(v1, v2, v3); return expr2_(v1, v2, v3);
} }
protected: protected:
EXPR1 expr1_; EXPR1 expr1_;
EXPR2 expr2_; EXPR2 expr2_;
private:
CommaFunctor & operator=(CommaFunctor const &); // not implemented
}; };
template <class Expr1, class Expr2> template <class Expr1, class Expr2>
struct ResultTraits0<CommaFunctor<Expr1, Expr2> > struct ResultTraits0<CommaFunctor<Expr1, Expr2> >
{ {
typedef typename ResultTraits0<Expr2>::Res Res; typedef typename ResultTraits0<Expr2>::Res Res;
}; };
template <class Expr1, class Expr2, class T1> template <class Expr1, class Expr2, class T1>
struct ResultTraits1<CommaFunctor<Expr1, Expr2>, T1> struct ResultTraits1<CommaFunctor<Expr1, Expr2>, T1>
skipping to change at line 1906 skipping to change at line 1958
typedef typename ResultTraits2<Expr2, T1, T2>::Res Res; typedef typename ResultTraits2<Expr2, T1, T2>::Res Res;
}; };
template <class Expr1, class Expr2, class T1, class T2, class T3> template <class Expr1, class Expr2, class T1, class T2, class T3>
struct ResultTraits3<CommaFunctor<Expr1, Expr2>, T1, T2, T3> struct ResultTraits3<CommaFunctor<Expr1, Expr2>, T1, T2, T3>
{ {
typedef typename ResultTraits3<Expr2, T1, T2, T3>::Res Res; typedef typename ResultTraits3<Expr2, T1, T2, T3>::Res Res;
}; };
template <class EXPR1, class EXPR2> template <class EXPR1, class EXPR2>
UnaryFunctor<CommaFunctor<UnaryAnalyser<EXPR1>, inline UnaryFunctor<CommaFunctor<UnaryAnalyser<EXPR1>,
UnaryFunctor<EXPR2> > > UnaryFunctor<EXPR2> > >
operator,(UnaryAnalyser<EXPR1> const & e1, operator,(UnaryAnalyser<EXPR1> const & e1,
UnaryFunctor<EXPR2> const & e2) UnaryFunctor<EXPR2> const & e2)
{ {
CommaFunctor<UnaryAnalyser<EXPR1>, CommaFunctor<UnaryAnalyser<EXPR1>,
UnaryFunctor<EXPR2> > p(e1, e2); UnaryFunctor<EXPR2> > p(e1, e2);
return UnaryFunctor<CommaFunctor<UnaryAnalyser<EXPR1>, return UnaryFunctor<CommaFunctor<UnaryAnalyser<EXPR1>,
UnaryFunctor<EXPR2> > >(p); UnaryFunctor<EXPR2> > >(p);
} }
skipping to change at line 1957 skipping to change at line 2009
void operator()(T1 const & v1, T2 const & v2, T3 const & v3) const void operator()(T1 const & v1, T2 const & v2, T3 const & v3) const
{ {
expr1_(v1, v2, v3); expr1_(v1, v2, v3);
expr2_(v1, v2, v3); expr2_(v1, v2, v3);
} }
protected: protected:
EXPR1 expr1_; EXPR1 expr1_;
EXPR2 expr2_; EXPR2 expr2_;
private:
CommaAnalyser & operator=(CommaAnalyser const &); // not implemented
}; };
template <class EXPR1, class EXPR2> template <class EXPR1, class EXPR2>
UnaryAnalyser<CommaAnalyser<UnaryAnalyser<EXPR1>, inline UnaryAnalyser<CommaAnalyser<UnaryAnalyser<EXPR1>,
UnaryAnalyser<EXPR2> > > UnaryAnalyser<EXPR2> > >
operator,(UnaryAnalyser<EXPR1> const & e1, operator,(UnaryAnalyser<EXPR1> const & e1,
UnaryAnalyser<EXPR2> const & e2) UnaryAnalyser<EXPR2> const & e2)
{ {
CommaAnalyser<UnaryAnalyser<EXPR1>, CommaAnalyser<UnaryAnalyser<EXPR1>,
UnaryAnalyser<EXPR2> > p(e1, e2); UnaryAnalyser<EXPR2> > p(e1, e2);
return UnaryAnalyser<CommaAnalyser<UnaryAnalyser<EXPR1>, return UnaryAnalyser<CommaAnalyser<UnaryAnalyser<EXPR1>,
UnaryAnalyser<EXPR2> > >(p); UnaryAnalyser<EXPR2> > >(p);
} }
 End of changes. 36 change blocks. 
16 lines changed or deleted 76 lines changed or added


 functortraits.hxx   functortraits.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2005 by Ullrich Koethe */ /* Copyright 1998-2005 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 90 skipping to change at line 90
typedef ... isTernaryFunctor; typedef ... isTernaryFunctor;
typedef ... isUnaryAnalyser; typedef ... isUnaryAnalyser;
typedef ... isBinaryAnalyser; typedef ... isBinaryAnalyser;
typedef ... isTernaryAnalyser; typedef ... isTernaryAnalyser;
}; };
\endcode \endcode
Where the dots are either <tt>VigraTrueType</tt> or <tt>VigraFalseType< /tt> Where the dots are either <tt>VigraTrueType</tt> or <tt>VigraFalseType< /tt>
depending on whether the functor supports the respective functionality or not. depending on whether the functor supports the respective functionality or not.
If a functor <tt>f<tt> is a model of these categories, it supports the following If a functor <tt>f</tt> is a model of these categories, it supports the following
calls (<tt>v</tt> is a variable such that the result type of the functo r calls (<tt>v</tt> is a variable such that the result type of the functo r
calls can be converted into <tt>v</tt>'s type, and <tt>a1, a2, a3</tt> are calls can be converted into <tt>v</tt>'s type, and <tt>a1, a2, a3</tt> are
variables convertible into the functor's argument types): variables convertible into the functor's argument types):
<DL> <DL>
<DT><b>Initializer</b> <DT><b>Initializer</b>
<DD> <tt>v = f()</tt> (used with initImageWithFunctor()) <DD> <tt>v = f()</tt> (used with initImageWithFunctor())
<DT><b>UnaryFunctor</b> <DT><b>UnaryFunctor</b>
<DD> <tt>v = f(a1)</tt> (used with transformImage()) <DD> <tt>v = f(a1)</tt> (used with transformImage())
<DT><b>BinaryFunctor</b> <DT><b>BinaryFunctor</b>
<DD> <tt>v = f(a1, a2)</tt> (used with combineTwoImages()) <DD> <tt>v = f(a1, a2)</tt> (used with combineTwoImages())
<DT><b>TernaryFunctor</b> <DT><b>TernaryFunctor</b>
<DD> <tt>v = f(a1, a2, a3)</tt> (used with combineThreeImages()) <DD> <tt>v = f(a1, a2, a3)</tt> (used with combineThreeImages())
<DT><b>UnaryAnalyser</b> <DT><b>UnaryAnalyser</b>
<DD> <tt>f(a1)</tt> (return type <tt>void>/tt>, used with inspectIm age()) <DD> <tt>f(a1)</tt> (return type <tt>void</tt>, used with inspectIm age())
<DT><b>BinaryAnalyser</b> <DT><b>BinaryAnalyser</b>
<DD> <tt>f(a1, a2)</tt> (return type <tt>void>/tt>, used with inspe ctTwoImages()) <DD> <tt>f(a1, a2)</tt> (return type <tt>void</tt>, used with inspe ctTwoImages())
<DT><b>TernaryAnalyser</b> <DT><b>TernaryAnalyser</b>
<DD> <tt>f(a1, a2, a3)</tt> (return type <tt>void>/tt>) <DD> <tt>f(a1, a2, a3)</tt> (return type <tt>void</tt>)
</DL> </DL>
It should be noted that the functor's argument and result types are not contained It should be noted that the functor's argument and result types are not contained
in the traits class: Since the function calls are often member template functions in in the traits class: Since the function calls are often member template functions in
VIGRA, many functors do not have fixed argument types. Neither are the result VIGRA, many functors do not have fixed argument types. Neither are the result
types fixed in this case because they are computed (via a template meta -program) types fixed in this case because they are computed (via a template meta -program)
from the argument types. from the argument types.
<b>\#include</b> "<a href="functortraits_8hxx-source.html">vigra/functo rtraits.hxx</a>" <b>\#include</b> \<<a href="functortraits_8hxx-source.html">vigra/funct ortraits.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class T> template <class T>
class FunctorTraits class FunctorTraits
: public FunctorTraitsBase<T> : public FunctorTraitsBase<T>
{}; {};
#define VIGRA_DEFINE_STL_FUNCTOR(name, unary, binary) \ #define VIGRA_DEFINE_STL_FUNCTOR(name, unary, binary) \
template <class T> \ template <class T> \
class FunctorTraits<name<T> > \ class FunctorTraits<name<T> > \
 End of changes. 7 change blocks. 
8 lines changed or deleted 8 lines changed or added


 gaborfilter.hxx   gaborfilter.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2002-2004 by Ullrich Koethe and Hans Meine */ /* Copyright 2002-2004 by Ullrich Koethe and Hans Meine */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 89 skipping to change at line 89
namespace vigra { namespace vigra {
template <class DestImageIterator, class DestAccessor> template <class DestImageIterator, class DestAccessor>
void createGaborFilter(DestImageIterator destUpperLeft, void createGaborFilter(DestImageIterator destUpperLeft,
DestImageIterator destLowerRight, DestImageIterator destLowerRight,
DestAccessor da, DestAccessor da,
double orientation, double centerFrequency, double orientation, double centerFrequency,
double angularSigma, double radialSigma) double angularSigma, double radialSigma)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class DestImageIterator, class DestAccessor> template <class DestImageIterator, class DestAccessor>
inline
void createGaborFilter(triple<DestImageIterator, void createGaborFilter(triple<DestImageIterator,
DestImageIterator, DestImageIterator,
DestAccessor> dest, DestAccessor> dest,
double orientation, double centerFrequency, double orientation, double centerFrequency,
double angularSigma, double radialSigma) double angularSigma, double radialSigma)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="gaborfilter_8hxx-source.html">vigra/gaborfil ter.hxx</a>"<br> <b>\#include</b> \<<a href="gaborfilter_8hxx-source.html">vigra/gaborfi lter.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::FImage gabor(w,h); vigra::FImage gabor(w,h);
vigra::createGaborFilter(destImageRange(gabor), orient, freq, vigra::createGaborFilter(destImageRange(gabor), orient, freq,
angularGaborSigma(directionCount, freq) angularGaborSigma(directionCount, freq)
radialGaborSigma(freq)); radialGaborSigma(freq));
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void createGaborFilter)
template <class DestImageIterator, class DestAccessor> template <class DestImageIterator, class DestAccessor>
void createGaborFilter(DestImageIterator destUpperLeft, void createGaborFilter(DestImageIterator destUpperLeft,
DestImageIterator destLowerRight, DestAccessor da, DestImageIterator destLowerRight, DestAccessor da,
double orientation, double centerFrequency, double orientation, double centerFrequency,
double angularSigma, double radialSigma) double angularSigma, double radialSigma)
{ {
int w= destLowerRight.x - destUpperLeft.x; int w= destLowerRight.x - destUpperLeft.x;
int h= destLowerRight.y - destUpperLeft.y; int h= destLowerRight.y - destUpperLeft.y;
skipping to change at line 208 skipping to change at line 208
/** \brief Calculate sensible radial sigma for given parameters. /** \brief Calculate sensible radial sigma for given parameters.
For a brief introduction what is meant with "sensible" sigmas, see For a brief introduction what is meant with "sensible" sigmas, see
\ref angularGaborSigma(). \ref angularGaborSigma().
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
inline
double radialGaborSigma(double centerFrequency) double radialGaborSigma(double centerFrequency)
} }
\endcode \endcode
*/ */
inline double radialGaborSigma(double centerFrequency) inline double radialGaborSigma(double centerFrequency)
{ {
static double sfactor = 3.0 * VIGRA_CSTD::sqrt(VIGRA_CSTD::log(4.0)); static double sfactor = 3.0 * VIGRA_CSTD::sqrt(VIGRA_CSTD::log(4.0));
return centerFrequency / sfactor; return centerFrequency / sfactor;
} }
skipping to change at line 252 skipping to change at line 251
\code \code
sigma_angular= 1/sqrt(ln(4)) * tan(pi/(directions*2)) sigma_angular= 1/sqrt(ln(4)) * tan(pi/(directions*2))
* sqrt(8/9) * centerFrequency * sqrt(8/9) * centerFrequency
\endcode \endcode
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
inline
double angularGaborSigma(int directionCount, double centerFrequency ) double angularGaborSigma(int directionCount, double centerFrequency )
} }
\endcode \endcode
*/ */
inline double angularGaborSigma(int directionCount, double centerFrequency) inline double angularGaborSigma(int directionCount, double centerFrequency)
{ {
return VIGRA_CSTD::tan(M_PI/directionCount/2.0) * centerFrequency return VIGRA_CSTD::tan(M_PI/directionCount/2.0) * centerFrequency
* VIGRA_CSTD::sqrt(8.0 / (9 * VIGRA_CSTD::log(4.0))); * VIGRA_CSTD::sqrt(8.0 / (9 * VIGRA_CSTD::log(4.0)));
} }
skipping to change at line 286 skipping to change at line 284
The filter parameters are chosen to make the center frequencies The filter parameters are chosen to make the center frequencies
decrease in octaves with increasing scale indices, and to make the decrease in octaves with increasing scale indices, and to make the
half-peak-magnitude ellipses touch each other to somewhat reduce half-peak-magnitude ellipses touch each other to somewhat reduce
redundancy in the filter answers. This is done by using \ref redundancy in the filter answers. This is done by using \ref
angularGaborSigma() and \ref radialGaborSigma(), you'll find more angularGaborSigma() and \ref radialGaborSigma(), you'll find more
information there. information there.
The template parameter ImageType should be a scalar image type suitable for filling in The template parameter ImageType should be a scalar image type suitable for filling in
<b>\#include</b> "<a href="gaborfilter_8hxx-source.html">vigra/gaborfil ter.hxx</a>" <b>\#include</b> \<<a href="gaborfilter_8hxx-source.html">vigra/gaborfi lter.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class ImageType, template <class ImageType,
class Alloc = typename ImageType::allocator_type::template rebind<Ima geType>::other > class Alloc = typename ImageType::allocator_type::template rebind<Ima geType>::other >
class GaborFilterFamily class GaborFilterFamily
: public ImageArray<ImageType, Alloc> : public ImageArray<ImageType, Alloc>
{ {
typedef ImageArray<ImageType, Alloc> ParentClass; typedef ImageArray<ImageType, Alloc> ParentClass;
int scaleCount_, directionCount_; int scaleCount_, directionCount_;
 End of changes. 9 change blocks. 
9 lines changed or deleted 7 lines changed or added


 gaussians.hxx   gaussians.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2004 by Ullrich Koethe */ /* Copyright 1998-2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 59 skipping to change at line 59
#if 0 #if 0
/** \addtogroup MathFunctions Mathematical Functions /** \addtogroup MathFunctions Mathematical Functions
*/ */
//@{ //@{
#endif #endif
/*! The Gaussian function and its derivatives. /*! The Gaussian function and its derivatives.
Implemented as a unary functor. Since it supports the <tt>radius()</tt> function Implemented as a unary functor. Since it supports the <tt>radius()</tt> function
it can also be used as a kernel in \ref resamplingConvolveImage(). it can also be used as a kernel in \ref resamplingConvolveImage().
<b>\#include</b> "<a href="gaussians_8hxx-source.html">vigra/gaussians. hxx</a>"<br> <b>\#include</b> \<<a href="gaussians_8hxx-source.html">vigra/gaussians .hxx</a>\><br>
Namespace: vigra Namespace: vigra
\ingroup MathFunctions \ingroup MathFunctions
*/ */
template <class T = double> template <class T = double>
class Gaussian class Gaussian
{ {
public: public:
/** the value type if used as a kernel in \ref resamplingConvolveIm age(). /** the value type if used as a kernel in \ref resamplingConvolveIm age().
 End of changes. 3 change blocks. 
4 lines changed or deleted 4 lines changed or added


 gradient_energy_tensor.hxx   gradient_energy_tensor.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2004-2005 by Ullrich Koethe */ /* Copyright 2004-2005 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 96 skipping to change at line 96
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void gradientEnergyTensor(SrcIterator supperleft, SrcIterator slowe rright, SrcAccessor src, void gradientEnergyTensor(SrcIterator supperleft, SrcIterator slowe rright, SrcAccessor src,
DestIterator dupperleft, DestAccessor des t, DestIterator dupperleft, DestAccessor des t,
Kernel1D<double> const & derivKernel, Ker nel1D<double> const & smoothKernel); Kernel1D<double> const & derivKernel, Ker nel1D<double> const & smoothKernel);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void gradientEnergyTensor(triple<SrcIterator, SrcIterator, SrcAcces sor> src, void gradientEnergyTensor(triple<SrcIterator, SrcIterator, SrcAcces sor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
Kernel1D<double> const & derivKernel, Ker nel1D<double> const & smoothKernel); Kernel1D<double> const & derivKernel, Ker nel1D<double> const & smoothKernel);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="gradient__energy__tensor_8hxx-source.html">v igra/gradient_energy_tensor.hxx</a>" <b>\#include</b> \<<a href="gradient__energy__tensor_8hxx-source.html"> vigra/gradient_energy_tensor.hxx</a>\>
\code \code
FImage img(w,h); FImage img(w,h);
FVector3Image get(w,h); FVector3Image get(w,h);
Kernel1D<double> grad, smooth; Kernel1D<double> grad, smooth;
grad.initGaussianDerivative(0.7, 1); grad.initGaussianDerivative(0.7, 1);
smooth.initGaussian(0.7); smooth.initGaussian(0.7);
... ...
gradientEnergyTensor(srcImageRange(img), destImage(get), grad, smooth); gradientEnergyTensor(srcImageRange(img), destImage(get), grad, smooth);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void gradientEnergyTensor)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void gradientEnergyTensor(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src, void gradientEnergyTensor(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
DestIterator dupperleft, DestAccessor dest, DestIterator dupperleft, DestAccessor dest,
Kernel1D<double> const & derivKernel, Kernel1D<do uble> const & smoothKernel) Kernel1D<double> const & derivKernel, Kernel1D<do uble> const & smoothKernel)
{ {
vigra_precondition(dest.size(dupperleft) == 3, vigra_precondition(dest.size(dupperleft) == 3,
"gradientEnergyTensor(): output image must have 3 ba nds."); "gradientEnergyTensor(): output image must have 3 ba nds.");
int w = slowerright.x - supperleft.x; int w = slowerright.x - supperleft.x;
 End of changes. 5 change blocks. 
5 lines changed or deleted 7 lines changed or added


 imagecontainer.hxx   imagecontainer.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 43 skipping to change at line 43
/* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
/* OTHER DEALINGS IN THE SOFTWARE. */ /* OTHER DEALINGS IN THE SOFTWARE. */
/* */ /* */
/************************************************************************/ /************************************************************************/
#ifndef VIGRA_IMAGECONTAINER_HXX #ifndef VIGRA_IMAGECONTAINER_HXX
#define VIGRA_IMAGECONTAINER_HXX #define VIGRA_IMAGECONTAINER_HXX
#include "utilities.hxx" #include "utilities.hxx"
#include "array_vector.hxx" #include "array_vector.hxx"
#include "copyimage.hxx"
namespace vigra { namespace vigra {
/** \addtogroup ImageContainers Image Containers /** \addtogroup ImageContainers Image Containers
Classes to manage multiple images (ImageArray..) Classes to manage multiple images (ImageArray..)
*/ */
//@{ //@{
/********************************************************/ /********************************************************/
/* */ /* */
skipping to change at line 68 skipping to change at line 69
An ImageArray manages an array of images of the type given as An ImageArray manages an array of images of the type given as
template parameter. Use it like a ArrayVector<ImageType>, it has template parameter. Use it like a ArrayVector<ImageType>, it has
the same interface, only operator< is missing from ImageArray. It the same interface, only operator< is missing from ImageArray. It
offers additional functions for resizing the images and querying offers additional functions for resizing the images and querying
their common size. See \ref imageSize() for additional notes. their common size. See \ref imageSize() for additional notes.
A custimized allocator can be passed as a template argument and via the constructor. A custimized allocator can be passed as a template argument and via the constructor.
By default, the allocator of the <tt>ImageType</tt> is reused. By default, the allocator of the <tt>ImageType</tt> is reused.
<b>\#include</b> "<a href="imagecontainer_8hxx-source.html">vigra/image container.hxx</a>" <b>\#include</b> \<<a href="imagecontainer_8hxx-source.html">vigra/imag econtainer.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class ImageType, template <class ImageType,
class Alloc = typename ImageType::allocator_type::template rebind<Ima geType>::other > class Alloc = typename ImageType::allocator_type::template rebind<Ima geType>::other >
class ImageArray class ImageArray
{ {
Size2D imageSize_; Size2D imageSize_;
protected: protected:
skipping to change at line 443 skipping to change at line 444
(Convenience function, same as calling (Convenience function, same as calling
<tt>resizeImages(Diff2D(width, height));</tt>.) <tt>resizeImages(Diff2D(width, height));</tt>.)
*/ */
void resizeImages(int width, int height) void resizeImages(int width, int height)
{ {
resizeImages(Size2D(width, height)); resizeImages(Size2D(width, height));
} }
}; };
/********************************************************/
/* */
/* ImagePyramid */
/* */
/********************************************************/
/** \brief Class template for logarithmically tapering image pyramids.
An ImagePyramid manages an array of images of the type given as
template parameter, where each level has half the width and height
of its predecessor. It actually represents a sequence of pyramid
levels whose start and end index are configurable. For Burt-style
pyramids, see also \ref pyramidReduceBurtFilter and \ref
pyramidExpandBurtFilter.
A custimized allocator can be passed as a template argument and
via the constructor. By default, the allocator of the
<tt>ImageType</tt> is reused.
<b>\#include</b> \<<a href="imagecontainer_8hxx-source.html">vigra/imag
econtainer.hxx</a>\>
Namespace: vigra
*/
template <class ImageType,
class Alloc = typename ImageType::allocator_type::template rebind<Ima
geType>::other >
class ImagePyramid
{
int lowestLevel_, highestLevel_;
protected:
typedef ArrayVector<ImageType, Alloc> ImageVector;
ImageVector images_;
public:
/** the type of the contained values/images
*/
typedef ImageType value_type;
typedef typename ImageVector::iterator iterator;
typedef typename ImageVector::const_iterator const_iterator;
typedef typename ImageVector::reverse_iterator reverse_iterator;
typedef typename ImageVector::const_reverse_iterator const_reverse_iter
ator;
typedef typename ImageVector::reference reference;
typedef typename ImageVector::const_reference const_reference;
#if !defined(_MSC_VER) || _MSC_VER >= 1300
typedef typename ImageVector::pointer pointer;
#endif
typedef typename ImageVector::difference_type difference_type;
typedef int size_type;
/** Init a pyramid between the given levels (inclusive).
*
* Allocate the given \a imageSize at the pyramid level given
* in \a sizeAppliesToLevel (default: level 0 / bottom) and
* size the other levels using recursive reduction/expansion
* by factors of 2. Use the specified allocator for image
* creation. The image type must be default constructible and
* resizable. sizeAppliesToLevel must be the in range
* lowestLevel..highestLevel (inclusive).
*/
ImagePyramid(int lowestLevel, int highestLevel,
const Diff2D &imageSize, int sizeAppliesToLevel = 0,
Alloc const & alloc = Alloc())
: lowestLevel_(0), highestLevel_(-1),
images_(alloc)
{
resize(lowestLevel, highestLevel, imageSize, sizeAppliesToLevel);
}
/**
* Init a pyramid between the given levels (inclusive).
*
* Copy the given \a image into the pyramid level given in \a
* copyImageToLevel (default: level 0 / bottom) and size the
* other levels using recursive reduction/expansion by factors
* of 2 (their image data is not initialized). Use the
* specified allocator for image creation. The image type
* must be default constructible and resizable.
* sizeAppliesToLevel must be the in range
* lowestLevel..highestLevel (inclusive).
*/
ImagePyramid(int lowestLevel, int highestLevel,
const ImageType &image, int copyImageToLevel = 0,
Alloc const & alloc = Alloc())
: lowestLevel_(0), highestLevel_(-1),
images_(alloc)
{
resize(lowestLevel, highestLevel, image.size(), copyImageToLevel);
copyImage(srcImageRange(image), destImage((*this)[copyImageToLevel]
));
}
/**
* Init a pyramid between the given levels (inclusive).
*
* Copy the image given by the range \a ul to \a lr into the
* pyramid level given in \a copyImageToLevel (default: level
* 0 / bottom) and size the other levels using recursive
* reduction/expansion by factors of 2 (their image data is
* not initialized). Use the specified allocator for image
* creation. The image type must be default constructible and
* resizable. sizeAppliesToLevel must be the in range
* lowestLevel..highestLevel (inclusive).
*/
template <class SrcIterator, class SrcAccessor>
ImagePyramid(int lowestLevel, int highestLevel,
SrcIterator ul, SrcIterator lr, SrcAccessor src,
int copyImageToLevel = 0,
Alloc const & alloc = Alloc())
: lowestLevel_(0), highestLevel_(-1),
images_(alloc)
{
resize(lowestLevel, highestLevel, lr - ul, copyImageToLevel);
copyImage(srcIterRange(ul, lr, src), destImage((*this)[copyImageToL
evel]));
}
/** Init an empty pyramid. Use the specified allocator.
*/
ImagePyramid(Alloc const & alloc = Alloc())
: lowestLevel_(0), highestLevel_(-1),
images_(alloc)
{}
virtual ~ImagePyramid() {}
/** Get the index of the lowest allocated level of the pyramid.
*/
int lowestLevel() const
{
return lowestLevel_;
}
/** Get the index of the highest allocated level of the pyramid.
*/
int highestLevel() const
{
return highestLevel_;
}
/** Operator for a vector-like access to the contained images
(STL-Vector interface)
*/
reference operator [](size_type index)
{
return images_[index - lowestLevel_];
}
/** Operator for a vector-like access to the contained images
(STL-Vector interface)
*/
const_reference operator [](size_type index) const
{
return images_[index - lowestLevel_];
}
/** Returns an iterator pointing to the first image
(STL-Container interface)
*/
iterator begin()
{
return images_.begin();
}
/** Returns an iterator pointing to the first image
(STL-Container interface)
*/
const_iterator begin() const
{
return images_.begin();
}
/** Returns an iterator pointing behind the last image
(STL-Container interface)
*/
iterator end()
{
return images_.end();
}
/** Returns an iterator pointing behind the last image
(STL-Container interface)
*/
const_iterator end() const
{
return images_.end();
}
/** Returns a reverse_iterator pointing to the first image of
the reversed view of this array (STL-Reversable Container
interface)
*/
reverse_iterator rbegin()
{
return images_.rbegin();
}
/** Returns a reverse_iterator pointing to the first image of
the reversed view of this array (STL-Reversable Container
interface)
*/
const_reverse_iterator rbegin() const
{
return images_.rbegin();
}
/** Returns a reverse_iterator pointing behind the last image
of the reversed view of this array (STL-Reversable
Container interface)
*/
reverse_iterator rend()
{
return images_.rend();
}
/** Returns a reverse_iterator pointing behind the last image
of the reversed view of this array (STL-Reversable
Container interface)
*/
const_reverse_iterator rend() const
{
return images_.rend();
}
/** Query size of this ImageArray, that is: the number of
images. (STL-Container interface)
*/
size_type size() const
{
return images_.size();
}
/** Returns true if and only if there are no contained
images. (STL-Container interface)
*/
bool empty()
{
return images_.empty();
}
/** Returns true if and only if both ImageArrays have exactly
the same contents and all images did compare equal with the
corresponding image in the other ImageArray. (STL-Forward
Container interface)
*/
bool operator ==(const ImagePyramid<ImageType, Alloc> &other) const
{
return (lowestLevel_ == other.lowestLevel_) && (highestLevel_ == ot
her.highestLevel_) &&
(images_ == other.images_);
}
/** Empty this array. (STL-Sequence interface)
*/
void clear()
{
images_.clear();
lowestLevel_ = 0;
highestLevel_ = -1;
}
/** Resize this ImageArray, throwing the last images away if
you make the array smaller or appending new images of the
right size at the end of the array if you make it
larger. (STL-Sequence interface)
*/
void resize(int lowestLevel, int highestLevel,
const Diff2D &imageSize, int sizeAppliesToLevel = 0)
{
vigra_precondition(lowestLevel <= highestLevel,
"ImagePyramid::resize(): lowestLevel <= highestLevel required.")
;
vigra_precondition(lowestLevel <= sizeAppliesToLevel && sizeApplies
ToLevel <= highestLevel,
"ImagePyramid::resize(): sizeAppliesToLevel must be between lowe
st and highest level (inclusive).");
ImageVector images(highestLevel - lowestLevel + 1, ImageType());
images[sizeAppliesToLevel - lowestLevel].resize(imageSize);
for(int i=sizeAppliesToLevel + 1; i<=highestLevel; ++i)
{
unsigned int w = (images[i - 1 - lowestLevel].width() + 1) / 2;
unsigned int h = (images[i - 1 - lowestLevel].height() + 1) / 2
;
images[i - lowestLevel].resize(w, h);
}
for(int i=sizeAppliesToLevel - 1; i>=lowestLevel; --i)
{
unsigned int w = 2*images[i + 1 - lowestLevel].width() - 1;
unsigned int h = 2*images[i + 1 - lowestLevel].height() - 1;
images[i - lowestLevel].resize(w, h);
}
images_.swap(images);
lowestLevel_ = lowestLevel;
highestLevel_ = highestLevel;
}
/** return the first image (lowestLevel()). (STL-Sequence interface
)
*/
reference front()
{
return images_.front();
}
/** return the first image (lowestLevel()). (STL-Sequence interface
)
*/
const_reference front() const
{
return images_.front();
}
/** return the last image (highestLevel()). (STL-Vector interface)
*/
reference back()
{
return images_.back();
}
/** return the last image (highestLevel()). (STL-Vector interface)
*/
const_reference back() const
{
return images_.back();
}
/** swap contents of this array with the contents of other
(STL-Container interface)
*/
void swap(const ImagePyramid<ImageType, Alloc> &other)
{
images_.swap(other.images_);
std::swap(lowestLevel_, other.lowestLevel_);
std::swap(highestLevel_, other.highestLevel_);
}
};
//@} //@}
} // namespace vigra } // namespace vigra
#endif // VIGRA_IMAGECONTAINER_HXX #endif // VIGRA_IMAGECONTAINER_HXX
 End of changes. 5 change blocks. 
4 lines changed or deleted 348 lines changed or added


 imageinfo.hxx   imageinfo.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2001 by Ullrich Koethe */ /* Copyright 1998-2001 by Ullrich Koethe */
/* Copyright 2001-2002 by Gunnar Kedenburg */ /* Copyright 2001-2002 by Gunnar Kedenburg */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 76 skipping to change at line 76
**/ **/
//@{ //@{
/** \brief List the image formats VIGRA can read and write. /** \brief List the image formats VIGRA can read and write.
This is useful for creating error messages if VIGRA encounters an This is useful for creating error messages if VIGRA encounters an
image format it doesn't recognize. image format it doesn't recognize.
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="imageinfo_8hxx-source.html">vigra/imagei nfo.hxx</a>"<br> <b>\#include</b> \<<a href="imageinfo_8hxx-source.html">vigra/image info.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
std::cout << "supported formats: " << vigra::impexListFormats() << std::endl; std::cout << "supported formats: " << vigra::impexListFormats() << std::endl;
\endcode \endcode
**/ **/
VIGRA_EXPORT std::string impexListFormats(); VIGRA_EXPORT std::string impexListFormats();
/** \brief List the file extension VIGRA understands. /** \brief List the file extension VIGRA understands.
This is useful for creating file dialogs that only list image files This is useful for creating file dialogs that only list image files
VIGRA can actually import. VIGRA can actually import.
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="imageinfo_8hxx-source.html">vigra/imagei nfo.hxx</a>"<br> <b>\#include</b> \<<a href="imageinfo_8hxx-source.html">vigra/image info.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
std::cout << "supported extensions: " << vigra::impexListExtensions () << std::endl; std::cout << "supported extensions: " << vigra::impexListExtensions () << std::endl;
\endcode \endcode
**/ **/
VIGRA_EXPORT std::string impexListExtensions(); VIGRA_EXPORT std::string impexListExtensions();
/** \brief Test whether a file is an image format known to VIGRA. /** \brief Test whether a file is an image format known to VIGRA.
This checks the first few bytes of the file and compares them with the This checks the first few bytes of the file and compares them with the
"magic strings" of each recognized image format. "magic strings" of each recognized image format.
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="imageinfo_8hxx-source.html">vigra/imageinfo. hxx</a>"<br> <b>\#include</b> \<<a href="imageinfo_8hxx-source.html">vigra/imageinfo .hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
std::cout << "is image: " << vigra::isImage("foo.bmp") << std::endl; std::cout << "is image: " << vigra::isImage("foo.bmp") << std::endl;
\endcode \endcode
**/ **/
VIGRA_EXPORT bool isImage(char const * filename); VIGRA_EXPORT bool isImage(char const * filename);
/********************************************************/ /********************************************************/
skipping to change at line 127 skipping to change at line 127
**/ **/
VIGRA_EXPORT bool isImage(char const * filename); VIGRA_EXPORT bool isImage(char const * filename);
/********************************************************/ /********************************************************/
/* */ /* */
/* ImageExportInfo */ /* ImageExportInfo */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Argument object for the function exportImage(). /** \brief Argument object for the function exportImage().
See \ref exportImage() for usage example. This object must be used See \ref exportImage() for usage example. This object must be used
to define the properties of an image to be written to disk. to define the properties of an image to be written to disk.
<b>\#include</b> "<a href="imageinfo_8hxx-source.html">vigra/imageinfo. hxx</a>"<br> <b>\#include</b> \<<a href="imageinfo_8hxx-source.html">vigra/imageinfo .hxx</a>\><br>
Namespace: vigra Namespace: vigra
**/ **/
class ImageExportInfo class ImageExportInfo
{ {
public: public:
/** Construct ImageExportInfo object. /** Construct ImageExportInfo object.
The image will be stored under the given filename. The image will be stored under the given filename.
The file type will be guessed from the extension unless overrid den The file type will be guessed from the extension unless overrid den
by \ref setFileType(). Recognized extensions: '.bmp', '.gif', by \ref setFileType(). Recognized extensions: '.bmp', '.gif',
'.jpeg', '.jpg', '.p7', '.png', '.pbm', '.pgm', '.pnm', '.ppm', '.ras', '.jpeg', '.jpg', '.p7', '.png', '.pbm', '.pgm', '.pnm', '.ppm', '.ras',
'.tif', '.tiff', '.xv', '.hdr'. '.tif', '.tiff', '.xv', '.hdr'.
JPEG support requires libjpeg, PNG support requires libpng, and JPEG support requires libjpeg, PNG support requires libpng, and
TIFF support requires libtiff. TIFF support requires libtiff.
**/ **/
VIGRA_EXPORT ImageExportInfo( const char * ); VIGRA_EXPORT ImageExportInfo( const char * );
VIGRA_EXPORT ~ImageExportInfo(); VIGRA_EXPORT ~ImageExportInfo();
/** Set image file name.
The file type will be guessed from the extension unless overrid
den
by \ref setFileType(). Recognized extensions: '.bmp', '.gif',
'.jpeg', '.jpg', '.p7', '.png', '.pbm', '.pgm', '.pnm', '.ppm',
'.ras',
'.tif', '.tiff', '.xv', '.hdr'.
JPEG support requires libjpeg, PNG support requires libpng, and
TIFF support requires libtiff.
**/
VIGRA_EXPORT ImageExportInfo & setFileName(const char * filename);
VIGRA_EXPORT const char * getFileName() const; VIGRA_EXPORT const char * getFileName() const;
/** Store image as given file type. /** Store image as given file type.
This will override any type guessed This will override any type guessed
from the file name's extension. Recognized file types: from the file name's extension. Recognized file types:
<DL> <DL>
<DT>"BMP"<DD> Microsoft Windows bitmap image file. <DT>"BMP"<DD> Microsoft Windows bitmap image file.
<DT>"GIF"<DD> CompuServe graphics interchange format; 8-bit col or. <DT>"GIF"<DD> CompuServe graphics interchange format; 8-bit col or.
skipping to change at line 233 skipping to change at line 244
<DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char) <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char)
<DT>"INT16"<DD> 16-bit signed integer (short) <DT>"INT16"<DD> 16-bit signed integer (short)
<DT>"UINT16"<DD> 16-bit unsigned integer (unsigned short) <DT>"UINT16"<DD> 16-bit unsigned integer (unsigned short)
<DT>"INT32"<DD> 32-bit signed integer (long) <DT>"INT32"<DD> 32-bit signed integer (long)
<DT>"UINT32"<DD> 32-bit unsigned integer (unsigned long) <DT>"UINT32"<DD> 32-bit unsigned integer (unsigned long)
<DT>"FLOAT"<DD> 32-bit floating point (float) <DT>"FLOAT"<DD> 32-bit floating point (float)
<DT>"DOUBLE"<DD> 64-bit floating point (double) <DT>"DOUBLE"<DD> 64-bit floating point (double)
</DL> </DL>
<b>Usage:</b> <b>Usage:</b>
\code
FImage img(w,h); FImage img(w,h);
// by default, float images are exported with pixeltype float // by default, float images are exported with pixeltype float
// when the target format support this type, i.e. is TIFF or VI FF. // when the target format support this type, i.e. is TIFF or VI FF.
exportImage(srcImageRange(img), ImageExportInfo("asFloat.tif")) ; exportImage(srcImageRange(img), ImageExportInfo("asFloat.tif")) ;
// if this is not desired, force a different pixeltype // if this is not desired, force a different pixeltype
exportImage(srcImageRange(img), ImageExportInfo("asByte.tif").s etPixelType("UINT8")); exportImage(srcImageRange(img), ImageExportInfo("asByte.tif").s etPixelType("UINT8"));
\endcode
**/ **/
VIGRA_EXPORT ImageExportInfo & setPixelType( const char * ); VIGRA_EXPORT ImageExportInfo & setPixelType( const char * );
/** Get the pixel type of the image. Possible values are: /** Get the pixel type of the image. Possible values are:
<DL> <DL>
<DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char) <DT>"UINT8"<DD> 8-bit unsigned integer (unsigned char)
<DT>"INT16"<DD> 16-bit signed integer (short) <DT>"INT16"<DD> 16-bit signed integer (short)
<DT>"INT32"<DD> 32-bit signed integer (long) <DT>"INT32"<DD> 32-bit signed integer (long)
<DT>"FLOAT"<DD> 32-bit floating point (float) <DT>"FLOAT"<DD> 32-bit floating point (float)
<DT>"DOUBLE"<DD> 64-bit floating point (double) <DT>"DOUBLE"<DD> 64-bit floating point (double)
</DL> </DL>
**/ **/
VIGRA_EXPORT const char * getPixelType() const; VIGRA_EXPORT const char * getPixelType() const;
VIGRA_EXPORT ImageExportInfo & setForcedRangeMapping(double fromMin, do
uble fromMax,
double toMin, double t
oMax);
VIGRA_EXPORT bool hasForcedRangeMapping() const;
VIGRA_EXPORT double getFromMin() const;
VIGRA_EXPORT double getFromMax() const;
VIGRA_EXPORT double getToMin() const;
VIGRA_EXPORT double getToMax() const;
/** Set the image resolution in horizontal direction /** Set the image resolution in horizontal direction
**/ **/
VIGRA_EXPORT ImageExportInfo & setXResolution( float ); VIGRA_EXPORT ImageExportInfo & setXResolution( float );
VIGRA_EXPORT float getXResolution() const; VIGRA_EXPORT float getXResolution() const;
/** Set the image resolution in vertical direction /** Set the image resolution in vertical direction
**/ **/
VIGRA_EXPORT ImageExportInfo & setYResolution( float ); VIGRA_EXPORT ImageExportInfo & setYResolution( float );
VIGRA_EXPORT float getYResolution() const; VIGRA_EXPORT float getYResolution() const;
/** Set the position of the upper Left corner on a global /** Set the position of the upper Left corner on a global
canvas. canvas.
Currently only supported by TIFF and PNG files. Currently only supported by TIFF and PNG files.
The offset is encoded in the XPosition and YPosition TIFF tags. The offset is encoded in the XPosition and YPosition TIFF tags.
@param position of the upper left corner in pixels @param pos position of the upper left corner in pixels
must be >= 0 (must be >= 0)
**/ **/
VIGRA_EXPORT ImageExportInfo & setPosition(const Diff2D & pos); VIGRA_EXPORT ImageExportInfo & setPosition(const Diff2D & pos);
/** Get the position of the upper left corner on /** Get the position of the upper left corner on
a global canvas. a global canvas.
**/ **/
VIGRA_EXPORT Diff2D getPosition() const; VIGRA_EXPORT Diff2D getPosition() const;
/** /**
ICC profiles (handled as raw data so far). ICC profiles (handled as raw data so far).
skipping to change at line 303 skipping to change at line 325
ICC profiles are currently supported by TIFF, PNG and JPEG imag es. ICC profiles are currently supported by TIFF, PNG and JPEG imag es.
(Otherwise, the profile data is silently ignored.) (Otherwise, the profile data is silently ignored.)
**/ **/
VIGRA_EXPORT ImageExportInfo & setICCProfile(const ICCProfile & profile ); VIGRA_EXPORT ImageExportInfo & setICCProfile(const ICCProfile & profile );
private: private:
std::string m_filename, m_filetype, m_pixeltype, m_comp; std::string m_filename, m_filetype, m_pixeltype, m_comp;
float m_x_res, m_y_res; float m_x_res, m_y_res;
Diff2D m_pos; Diff2D m_pos;
ICCProfile m_icc_profile; ICCProfile m_icc_profile;
double fromMin_, fromMax_, toMin_, toMax_;
}; };
// return an encoder for a given ImageExportInfo object // return an encoder for a given ImageExportInfo object
VIGRA_EXPORT std::auto_ptr<Encoder> encoder( const ImageExportInfo & info ) ; VIGRA_EXPORT std::auto_ptr<Encoder> encoder( const ImageExportInfo & info ) ;
/********************************************************/ /********************************************************/
/* */ /* */
/* ImageImportInfo */ /* ImageImportInfo */
/* */ /* */
/********************************************************/ /********************************************************/
skipping to change at line 315 skipping to change at line 338
// return an encoder for a given ImageExportInfo object // return an encoder for a given ImageExportInfo object
VIGRA_EXPORT std::auto_ptr<Encoder> encoder( const ImageExportInfo & info ) ; VIGRA_EXPORT std::auto_ptr<Encoder> encoder( const ImageExportInfo & info ) ;
/********************************************************/ /********************************************************/
/* */ /* */
/* ImageImportInfo */ /* ImageImportInfo */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Argument object for the function importImage(). /** \brief Argument object for the function importImage().
See \ref importImage() for a usage example. This object must be See \ref importImage() for a usage example. This object must be
used to read an image from disk and enquire about its properties. used to read an image from disk and enquire about its properties.
<b>\#include</b> "<a href="imageinfo_8hxx-source.html">vigra/imageinfo.hxx< /a>"<br> <b>\#include</b> \<<a href="imageinfo_8hxx-source.html">vigra/imageinfo.hxx </a>\><br>
Namespace: vigra Namespace: vigra
**/ **/
class ImageImportInfo class ImageImportInfo
{ {
public: public:
enum PixelType { UINT8, INT16, UINT16, INT32, UINT32, FLOAT, DOUBLE }; enum PixelType { UINT8, INT16, UINT16, INT32, UINT32, FLOAT, DOUBLE };
/** Construct ImageImportInfo object. /** Construct ImageImportInfo object.
The image with the given filename is read into memory. The image with the given filename is read into memory.
skipping to change at line 450 skipping to change at line 474
std::string m_filename, m_filetype, m_pixeltype; std::string m_filename, m_filetype, m_pixeltype;
int m_width, m_height, m_num_bands, m_num_extra_bands; int m_width, m_height, m_num_bands, m_num_extra_bands;
float m_x_res, m_y_res; float m_x_res, m_y_res;
Diff2D m_pos; Diff2D m_pos;
ICCProfile m_icc_profile; ICCProfile m_icc_profile;
}; };
// return a decoder for a given ImageImportInfo object // return a decoder for a given ImageImportInfo object
VIGRA_EXPORT std::auto_ptr<Decoder> decoder( const ImageImportInfo & info ) ; VIGRA_EXPORT std::auto_ptr<Decoder> decoder( const ImageImportInfo & info ) ;
//@}
} // namespace vigra } // namespace vigra
#endif // VIGRA_IMAGEINFO_HXX #endif // VIGRA_IMAGEINFO_HXX
 End of changes. 16 change blocks. 
10 lines changed or deleted 40 lines changed or added


 imageiterator.hxx   imageiterator.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 115 skipping to change at line 115
The following tables describe the general requirements for image iterat ors The following tables describe the general requirements for image iterat ors
and their iterator traits. The iterator implementations provided here and their iterator traits. The iterator implementations provided here
may be used for any image data type that stores its may be used for any image data type that stores its
data as a linear array of pixels. The array will be interpreted as a data as a linear array of pixels. The array will be interpreted as a
row-major matrix with a particular width. row-major matrix with a particular width.
</p> </p>
<h3>Requirements for Image Iterators</h3> <h3>Requirements for Image Iterators</h3>
<p> <p>
<table border=2 cellspacing=0 cellpadding=2 width="100%"> <table border=2 cellspacing=0 cellpadding=2 width="100%">
<tr><td> <tr><th colspan=2>
\htmlonly
<th colspan=2>
\endhtmlonly
Local Types Local Types
\htmlonly
</th><th> </th><th>
\endhtmlonly
Meaning Meaning
\htmlonly
</th> </th>
\endhtmlonly </tr>
</td></tr> <tr><td colspan=2>
<tr><td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>ImageIterator::value_type</tt></td><td>the underlying image's pixel type</td> <tt>ImageIterator::value_type</tt></td><td>the underlying image's pixel type</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>ImageIterator::PixelType</tt></td><td>the underlying image's pixel type</td> <tt>ImageIterator::PixelType</tt></td><td>the underlying image's pixel type</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>ImageIterator::reference</tt></td> <tt>ImageIterator::reference</tt></td>
<td>the iterator's reference type (return type of <TT>*iter</TT>). Will be <td>the iterator's reference type (return type of <TT>*iter</TT>). Will be
<tt>value_type &</tt> for a mutable iterator, and convertible to <tt>value_type &</tt> for a mutable iterator, and convertible to
<tt>value_type const &</tt> for a const iterator.</td> <tt>value_type const &</tt> for a const iterator.</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>ImageIterator::index_reference</tt></td> <tt>ImageIterator::index_reference</tt></td>
<td>the iterator's index reference type (return type of <TT>iter[diff]< /TT>). Will be <td>the iterator's index reference type (return type of <TT>iter[diff]< /TT>). Will be
<tt>value_type &</tt> for a mutable iterator, and convertible to <tt>value_type &</tt> for a mutable iterator, and convertible to
<tt>value_type const &</tt> for a const iterator.</td> <tt>value_type const &</tt> for a const iterator.</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>ImageIterator::pointer</tt></td> <tt>ImageIterator::pointer</tt></td>
<td>the iterator's pointer type (return type of <TT>iter.operator->()</ TT>). Will be <td>the iterator's pointer type (return type of <TT>iter.operator->()</ TT>). Will be
<tt>value_type *</tt> for a mutable iterator, and convertible to <tt>value_type *</tt> for a mutable iterator, and convertible to
<tt>value_type const *</tt> for a const iterator.</td> <tt>value_type const *</tt> for a const iterator.</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>ImageIterator::difference_type</tt></td> <tt>ImageIterator::difference_type</tt></td>
<td>the iterator's difference type (<TT>vigra::Diff2D</TT>)</td> <td>the iterator's difference type (<TT>vigra::Diff2D</TT>)</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>ImageIterator::iterator_category</tt></td> <tt>ImageIterator::iterator_category</tt></td>
<td>the iterator tag (<tt>vigra::image_traverser_tag</tt>)</td> <td>the iterator tag (<tt>vigra::image_traverser_tag</tt>)</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>ImageIterator::row_iterator</tt></td><td>the associated row iterato r</td> <tt>ImageIterator::row_iterator</tt></td><td>the associated row iterato r</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>ImageIterator::column_iterator</tt></td><td>the associated column i terator</td> <tt>ImageIterator::column_iterator</tt></td><td>the associated column i terator</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>ImageIterator::MoveX</tt></td><td>type of the horizontal navigator< /td> <tt>ImageIterator::MoveX</tt></td><td>type of the horizontal navigator< /td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>ImageIterator::MoveY</tt></td><td>type of the vertical navigator</t d> <tt>ImageIterator::MoveY</tt></td><td>type of the vertical navigator</t d>
</tr> </tr>
<tr><td> <tr><th>
\htmlonly
<th>
\endhtmlonly
Operation Operation
\htmlonly
</th><th> </th><th>
\endhtmlonly
Result Result
\htmlonly
</th><th> </th><th>
\endhtmlonly
Semantics Semantics
\htmlonly
</th> </th>
\endhtmlonly </tr>
</td></tr>
<tr> <tr>
<td><tt>++i.x<br>i.x--</tt></td><td><tt>void</tt></td><td>increment x-c oordinate</td> <td><tt>++i.x<br>i.x--</tt></td><td><tt>void</tt></td><td>increment x-c oordinate</td>
</tr> </tr>
<tr> <tr>
<td><tt>--i.x<br>i.x--</tt></td><td><tt>void</tt></td><td>decrement x-c oordinate</td> <td><tt>--i.x<br>i.x--</tt></td><td><tt>void</tt></td><td>decrement x-c oordinate</td>
</tr> </tr>
<tr> <tr>
<td><tt>i.x += dx</tt></td><td><tt>ImageIterator::MoveX &</tt></td> <td><tt>i.x += dx</tt></td><td><tt>ImageIterator::MoveX &</tt></td>
<td>add <tt>dx</tt> to x-coordinate</td> <td>add <tt>dx</tt> to x-coordinate</td>
</tr> </tr>
skipping to change at line 289 skipping to change at line 230
<tr> <tr>
<td><tt>i.y = j.y</tt></td><td><tt>ImageIterator::MoveY &</tt></td><td> <tt>i.y += j.y - i.y</tt></td> <td><tt>i.y = j.y</tt></td><td><tt>ImageIterator::MoveY &</tt></td><td> <tt>i.y += j.y - i.y</tt></td>
</tr> </tr>
<tr> <tr>
<td><tt>i.y == j.y</tt></td><td><tt>bool</tt></td><td><tt>j.y - i.y == 0</tt></td> <td><tt>i.y == j.y</tt></td><td><tt>bool</tt></td><td><tt>j.y - i.y == 0</tt></td>
</tr> </tr>
<tr> <tr>
<td><tt>i.y < j.y</tt></td><td><tt>bool</tt></td><td><tt>j.y - i.y > 0< /tt></td> <td><tt>i.y < j.y</tt></td><td><tt>bool</tt></td><td><tt>j.y - i.y > 0< /tt></td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>ImageIterator k(i)</tt></td><td>copy constructor</td> <tt>ImageIterator k(i)</tt></td><td>copy constructor</td>
</tr> </tr>
<tr> <tr>
<td><tt>k = i</tt></td><td><tt>ImageIterator &</tt></td><td>assignment< /td> <td><tt>k = i</tt></td><td><tt>ImageIterator &</tt></td><td>assignment< /td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>ImageIterator k</tt></td><td>default constructor</td> <tt>ImageIterator k</tt></td><td>default constructor</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>ImageIterator::row_iterator r(i)</tt></td><td>construction of row i terator</td> <tt>ImageIterator::row_iterator r(i)</tt></td><td>construction of row i terator</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>ImageIterator::column_iterator c(i)</tt></td><td>construction of co lumn iterator</td> <tt>ImageIterator::column_iterator c(i)</tt></td><td>construction of co lumn iterator</td>
</tr> </tr>
<tr> <tr>
<td><tt>i += diff</tt></td><td><tt>ImageIterator &</tt></td> <td><tt>i += diff</tt></td><td><tt>ImageIterator &</tt></td>
<td><tt>{ i.x += diff.x<br>i.y += diff.y; }</tt></td> <td><tt>{ i.x += diff.x<br>i.y += diff.y; }</tt></td>
</tr> </tr>
<tr> <tr>
<td><tt>i -= diff</tt></td><td><tt>ImageIterator &</tt></td> <td><tt>i -= diff</tt></td><td><tt>ImageIterator &</tt></td>
<td><tt>{ i.x -= diff.x<br>i.y -= diff.y; }</tt></td> <td><tt>{ i.x -= diff.x<br>i.y -= diff.y; }</tt></td>
</tr> </tr>
skipping to change at line 360 skipping to change at line 285
<td>access pixel at offset <tt>diff</tt></td> <td>access pixel at offset <tt>diff</tt></td>
</tr> </tr>
<tr> <tr>
<td><tt>i(dx, dy)</tt></td><td><tt>ImageIterator::index_reference</tt>< /td> <td><tt>i(dx, dy)</tt></td><td><tt>ImageIterator::index_reference</tt>< /td>
<td>access pixel at offset <tt>(dx, dy)</tt></td> <td>access pixel at offset <tt>(dx, dy)</tt></td>
</tr> </tr>
<tr> <tr>
<td><tt>i->member()</tt></td><td>depends on operation</td> <td><tt>i->member()</tt></td><td>depends on operation</td>
<td>call member function of underlying pixel type via <tt>operator-></t t> of iterator</td> <td>call member function of underlying pixel type via <tt>operator-></t t> of iterator</td>
</tr> </tr>
<tr> <tr><td colspan=3>
<td>
\htmlonly
<td colspan=3>
\endhtmlonly
<tt>i, j, k</tt> are of type <tt>ImageIterator</tt><br> <tt>i, j, k</tt> are of type <tt>ImageIterator</tt><br>
<tt>diff</tt> is of type <tt>ImageIterator::difference_type</tt><br> <tt>diff</tt> is of type <tt>ImageIterator::difference_type</tt><br>
<tt>dx, dy</tt> are of type <tt>int</tt><br> <tt>dx, dy</tt> are of type <tt>int</tt><br>
</td> </td>
</tr> </tr>
</table> </table>
</p> </p>
<h3>Requirements for Image Iterator Traits</h3> <h3>Requirements for Image Iterator Traits</h3>
<p> <p>
The following iterator traits must be defined for an image iterator: The following iterator traits must be defined for an image iterator:
</p> </p>
<p> <p>
<table border=2 cellspacing=0 cellpadding=2 width="100%"> <table border=2 cellspacing=0 cellpadding=2 width="100%">
<tr><td> <tr><th>
\htmlonly
<th>
\endhtmlonly
Types Types
\htmlonly
</th><th> </th><th>
\endhtmlonly
Meaning Meaning
\htmlonly
</th> </th>
\endhtmlonly </tr>
</td></tr>
<tr> <tr>
<td><tt>IteratorTraits<ImageIterator&gt;::Iterator</tt></td><td>the iterator type the traits are referring to</td> <td><tt>IteratorTraits<ImageIterator>::Iterator</tt></td><td>the iterat or type the traits are referring to</td>
</tr> </tr>
<tr> <tr>
<td><tt>IteratorTraits<ImageIterator&gt;::iterator</tt></td><td>the iterator type the traits are referring to</td> <td><tt>IteratorTraits<ImageIterator>::iterator</tt></td><td>the iterat or type the traits are referring to</td>
</tr> </tr>
<tr> <tr>
<td><tt>IteratorTraits<ImageIterator&gt;::value_type</tt></td><td>th e underlying image's pixel type</td> <td><tt>IteratorTraits<ImageIterator>::value_type</tt></td><td>the unde rlying image's pixel type</td>
</tr> </tr>
<tr> <tr>
<td><tt>IteratorTraits<ImageIterator&gt;::reference</tt></td> <td><tt>IteratorTraits<ImageIterator&gt;::reference</tt></td>
<td>the iterator's reference type (return type of <TT>*iter</TT>)</td> <td>the iterator's reference type (return type of <TT>*iter</TT>)</td>
</tr> </tr>
<tr> <tr>
<td><tt>IteratorTraits<ImageIterator&gt;::index_reference</tt></td> <td><tt>IteratorTraits<ImageIterator&gt;::index_reference</tt></td>
<td>the iterator's index reference type (return type of <TT>iter[diff]< /TT>)</td> <td>the iterator's index reference type (return type of <TT>iter[diff]< /TT>)</td>
</tr> </tr>
<tr> <tr>
<td><tt>IteratorTraits<ImageIterator&gt;::pointer</tt></td> <td><tt>IteratorTraits<ImageIterator&gt;::pointer</tt></td>
<td>the iterator's pointer type (return type of <TT>iter.operator->()</ TT>)</td> <td>the iterator's pointer type (return type of <TT>iter.operator->()</ TT>)</td>
</tr> </tr>
<tr> <tr>
<td><tt>IteratorTraits<ImageIterator&gt;::difference_type</tt></td> <td><tt>IteratorTraits<ImageIterator&gt;::difference_type</tt></td>
<td>the iterator's difference type</td> <td>the iterator's difference type</td>
</tr> </tr>
<tr> <tr>
<td><tt>IteratorTraits<ImageIterator&gt;::iterator_category</tt></td > <td><tt>IteratorTraits<ImageIterator>::iterator_category</tt></td>
<td>the iterator tag (<tt>vigra::image_traverser_tag</tt>)</td> <td>the iterator tag (<tt>vigra::image_traverser_tag</tt>)</td>
</tr> </tr>
<tr> <tr>
<td><tt>IteratorTraits<ImageIterator&gt;::row_iterator</tt></td><td> the associated row iterator</td> <td><tt>IteratorTraits<ImageIterator>::row_iterator</tt></td><td>the as sociated row iterator</td>
</tr> </tr>
<tr> <tr>
<td><tt>IteratorTraits<ImageIterator&gt;::column_iterator</tt></td>< td>the associated column iterator</td> <td><tt>IteratorTraits<ImageIterator>::column_iterator</tt></td><td>the associated column iterator</td>
</tr> </tr>
<tr> <tr>
<td><tt>IteratorTraits<ImageIterator&gt;::DefaultAccessor</tt></td> <td><tt>IteratorTraits<ImageIterator&gt;::DefaultAccessor</tt></td>
<td>the default accessor to be used with the iterator</td> <td>the default accessor to be used with the iterator</td>
</tr> </tr>
<tr> <tr>
<td><tt>IteratorTraits<ImageIterator&gt;::default_accessor</tt></td> <td><tt>IteratorTraits<ImageIterator&gt;::default_accessor</tt></td>
<td>the default accessor to be used with the iterator</td> <td>the default accessor to be used with the iterator</td>
</tr> </tr>
<tr> <tr>
<td><tt>IteratorTraits<ImageIterator&gt;::hasConstantStrides</tt></t d> <td><tt>IteratorTraits<ImageIterator>::hasConstantStrides</tt></td>
<td>whether the iterator uses constant strides on the underlying memory <td>whether the iterator uses constant strides on the underlying memory
(always <tt>VigraTrueType</tt> for <tt>ImageIterator</tt>s).</td> (always <tt>VigraTrueType</tt> for <tt>ImageIterator</tt>s).</td>
</tr> </tr>
</table> </table>
</p> </p>
*/ */
//@{ //@{
namespace detail { namespace detail {
skipping to change at line 629 skipping to change at line 543
/* ImageIteratorBase */ /* ImageIteratorBase */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Base class for 2D random access iterators. /** \brief Base class for 2D random access iterators.
This class contains the navigational part of the iterator. This class contains the navigational part of the iterator.
It is usually not constructed directly, but via some derived class such as It is usually not constructed directly, but via some derived class such as
\ref ImageIterator or \ref StridedImageIterator. \ref ImageIterator or \ref StridedImageIterator.
<b>\#include</b> "<a href="imageiterator_8hxx-source.html">vigra/imagei terator.hxx</a>" <b>\#include</b> \<<a href="imageiterator_8hxx-source.html">vigra/image iterator.hxx</a>\>
Namespace: vigra Namespace: vigra
The usage examples assume that you constructed two iterators like The usage examples assume that you constructed two iterators like
this: this:
\code \code
vigra::ImageIterator<SomePixelType> iterator(base, width); vigra::ImageIterator<SomePixelType> iterator(base, width);
vigra::ImageIterator<SomePixelType> iterator1(base, width); vigra::ImageIterator<SomePixelType> iterator1(base, width);
\endcode \endcode
skipping to change at line 929 skipping to change at line 843
/** \brief Standard 2D random access iterator for images that store the /** \brief Standard 2D random access iterator for images that store the
data in a linear array. data in a linear array.
Most functions and local types are inherited from ImageIteratorBase. Most functions and local types are inherited from ImageIteratorBase.
See the paper: U. Koethe: See the paper: U. Koethe:
<a href="documents/GenericProg2D.ps">Reusable Algorithms in Image Proce ssing</a> <a href="documents/GenericProg2D.ps">Reusable Algorithms in Image Proce ssing</a>
for a discussion of the concepts behind ImageIterators. for a discussion of the concepts behind ImageIterators.
<b>\#include</b> "<a href="imageiterator_8hxx-source.html">vigra/imagei terator.hxx</a>" <b>\#include</b> \<<a href="imageiterator_8hxx-source.html">vigra/image iterator.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class PIXELTYPE> template <class PIXELTYPE>
class ImageIterator class ImageIterator
: public ImageIteratorBase<ImageIterator<PIXELTYPE>, : public ImageIteratorBase<ImageIterator<PIXELTYPE>,
PIXELTYPE, PIXELTYPE &, PIXELTYPE *> PIXELTYPE, PIXELTYPE &, PIXELTYPE *>
{ {
public: public:
skipping to change at line 975 skipping to change at line 889
/* */ /* */
/* ConstImageIterator */ /* ConstImageIterator */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Standard 2D random access const iterator for images that /** \brief Standard 2D random access const iterator for images that
store the data as a linear array. store the data as a linear array.
Most functions are inherited from ImageIteratorBase. Most functions are inherited from ImageIteratorBase.
<b>\#include</b> "<a href="imageiterator_8hxx-source.html">vigra/imagei terator.hxx</a>" <b>\#include</b> \<<a href="imageiterator_8hxx-source.html">vigra/image iterator.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class PIXELTYPE> template <class PIXELTYPE>
class ConstImageIterator class ConstImageIterator
: public ImageIteratorBase<ConstImageIterator<PIXELTYPE>, : public ImageIteratorBase<ConstImageIterator<PIXELTYPE>,
PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *> PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *>
{ {
public: public:
skipping to change at line 1049 skipping to change at line 963
int xskip = 2, yskip = 2; int xskip = 2, yskip = 2;
int wskip = w / xskip + 1, hskip = h / yskip + 1; int wskip = w / xskip + 1, hskip = h / yskip + 1;
StridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, xskip, yskip); StridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, xskip, yskip);
StridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2 D(wskip, hskip); StridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2 D(wskip, hskip);
// now navigation with upperLeft and lowerRight lets the image appear t o have half // now navigation with upperLeft and lowerRight lets the image appear t o have half
// the original resolution in either dimension // the original resolution in either dimension
\endcode \endcode
<b>\#include</b> "<a href="imageiterator_8hxx-source.html">vigra/imagei terator.hxx</a>" <b>\#include</b> \<<a href="imageiterator_8hxx-source.html">vigra/image iterator.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class PIXELTYPE> template <class PIXELTYPE>
class StridedImageIterator class StridedImageIterator
: public ImageIteratorBase<StridedImageIterator<PIXELTYPE>, : public ImageIteratorBase<StridedImageIterator<PIXELTYPE>,
PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArra yTag> PIXELTYPE, PIXELTYPE &, PIXELTYPE *, StridedArra yTag>
{ {
public: public:
skipping to change at line 1110 skipping to change at line 1024
int xskip = 2, yskip = 2; int xskip = 2, yskip = 2;
int wskip = w / xskip + 1, hskip = h / yskip + 1; int wskip = w / xskip + 1, hskip = h / yskip + 1;
ConstStridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, x skip, yskip); ConstStridedImageIterator<BImage::value_type> upperLeft(&img(0,0), w, x skip, yskip);
ConstStridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2D(wskip, hskip); ConstStridedImageIterator<BImage::value_type> lowerRight = upperLeft + Diff2D(wskip, hskip);
// now navigation with upperLeft and lowerRight lets the image appear t o have half // now navigation with upperLeft and lowerRight lets the image appear t o have half
// the original resolution in either dimension // the original resolution in either dimension
\endcode \endcode
<b>\#include</b> "<a href="imageiterator_8hxx-source.html">vigra/imagei terator.hxx</a>" <b>\#include</b> \<<a href="imageiterator_8hxx-source.html">vigra/image iterator.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class PIXELTYPE> template <class PIXELTYPE>
class ConstStridedImageIterator class ConstStridedImageIterator
: public ImageIteratorBase<ConstStridedImageIterator<PIXELTYPE>, : public ImageIteratorBase<ConstStridedImageIterator<PIXELTYPE>,
PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *, PIXELTYPE, PIXELTYPE const &, PIXELTYPE const *,
StridedArrayTag> StridedArrayTag>
{ {
skipping to change at line 1373 skipping to change at line 1287
/* ConstValueIterator */ /* ConstValueIterator */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Iterator that always returns the constant specified in the /** \brief Iterator that always returns the constant specified in the
constructor. constructor.
This iterator can be used to simulate an image that This iterator can be used to simulate an image that
does not actually exist. does not actually exist.
<b>\#include</b> "<a href="imageiterator_8hxx-source.html">vigra/imagei terator.hxx</a>" <b>\#include</b> \<<a href="imageiterator_8hxx-source.html">vigra/image iterator.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class PIXELTYPE> template <class PIXELTYPE>
class ConstValueIterator class ConstValueIterator
{ {
public: public:
/** The type of the constant the iterator holds. /** The type of the constant the iterator holds.
*/ */
skipping to change at line 1588 skipping to change at line 1502
typedef typename iterator::difference_type difference_type; typedef typename iterator::difference_type difference_type;
typedef typename iterator::row_iterator row_iterator; typedef typename iterator::row_iterator row_iterator;
typedef typename iterator::column_iterator column_iterator; typedef typename iterator::column_iterator column_iterator;
typedef StandardConstAccessor<T> DefaultAccessor; typedef StandardConstAccessor<T> DefaultAccessor;
typedef StandardConstAccessor<T> default_accessor; typedef StandardConstAccessor<T> default_accessor;
typedef VigraTrueType hasConstantStride s; typedef VigraTrueType hasConstantStride s;
}; };
#endif #endif
typedef Diff2D CoordinateIterator; /** \brief Simulate an image where each pixel contains its coordinate.
/** \class CoordinateIterator
This used to be a separate class, CoordinateIterator used to be a separate class,
but has now become an alias for \ref vigra::Diff2D. This is possible be cause but has now become an alias for \ref vigra::Diff2D. This is possible be cause
Diff2D now provides all the necessary functionality. Diff2D now provides all the necessary functionality.
CoordinateIterator behaves like a read-only \ref ImageIterator for CoordinateIterator behaves like a read-only \ref vigra::ImageIterator f or
an image in which each pixel contains its coordinate. This is useful fo r an image in which each pixel contains its coordinate. This is useful fo r
algorithms that need access to the current pixel's location. algorithms that need access to the current pixel's location.
For example, you can use CoordinateIterator/Diff2D to For example, you can use CoordinateIterator/Diff2D to
find the center of mass of an image region. To implement this, find the center of mass of an image region. To implement this,
we first need a functor for center-of-mass calculations: we first need a functor for center-of-mass calculations:
\code \code
struct CenterOfMassFunctor struct CenterOfMassFunctor
{ {
skipping to change at line 1647 skipping to change at line 1559
vigra::inspectImageIf( vigra::inspectImageIf(
srcIterRange(Diff2D(), Diff2D() + img.size()), srcIterRange(Diff2D(), Diff2D() + img.size()),
srcImage(img), srcImage(img),
center); center);
std::cout << "Center of mass: " << center.xCenter() << std::cout << "Center of mass: " << center.xCenter() <<
", " << center.yCenter() << std::endl; ", " << center.yCenter() << std::endl;
\endcode \endcode
<b>\#include</b> "<a href="imageiterator_8hxx-source.html">vigra/imagei terator.hxx</a>" <b>\#include</b> \<<a href="imageiterator_8hxx-source.html">vigra/image iterator.hxx</a>\>
Namespace: vigra Namespace: vigra
\brief Simulate an image where each pixel contains its coordinate
*/ */
typedef Diff2D CoordinateIterator;
//@} //@}
} // namespace vigra } // namespace vigra
#endif // VIGRA_IMAGEITERATOR_HXX #endif // VIGRA_IMAGEITERATOR_HXX
 End of changes. 59 change blocks. 
138 lines changed or deleted 49 lines changed or added


 imageiteratoradapter.hxx   imageiteratoradapter.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 72 skipping to change at line 72
one column of the image. If the underlying iterator is a const iterator , one column of the image. If the underlying iterator is a const iterator ,
the column iterator will also be const (i.e. doesn't allow to change the column iterator will also be const (i.e. doesn't allow to change
the values it points to). the values it points to).
The iterator gets associated with the accessor of the base iterator. The iterator gets associated with the accessor of the base iterator.
Note that image iterators usually have a member <TT>columnIterator()</T T> Note that image iterators usually have a member <TT>columnIterator()</T T>
which returns a column iterator optimized for that particular image cla ss. which returns a column iterator optimized for that particular image cla ss.
ColumnIterator is only necessary if this 'native' column iterator ColumnIterator is only necessary if this 'native' column iterator
is not usable in a particular situation or is not provided. is not usable in a particular situation or is not provided.
<b>\#include</b> "<a href="imageiteratoradapter_8hxx-source.html">vigra /imageiteratoradapter.hxx</a>" <b>\#include</b> \<<a href="imageiteratoradapter_8hxx-source.html">vigr a/imageiteratoradapter.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class IMAGE_ITERATOR> template <class IMAGE_ITERATOR>
class ColumnIterator : private IMAGE_ITERATOR class ColumnIterator : private IMAGE_ITERATOR
{ {
public: public:
/** the iterator's value type /** the iterator's value type
*/ */
skipping to change at line 278 skipping to change at line 278
one row of the image. If the underlying iterator is a const iterator, one row of the image. If the underlying iterator is a const iterator,
the row iterator will also be const (i.e. doesn't allow to change the row iterator will also be const (i.e. doesn't allow to change
the values it points to). the values it points to).
The iterator gets associated with the accessor of the base iterator. The iterator gets associated with the accessor of the base iterator.
Note that image iterators usually have a member <TT>rowIterator()</TT> Note that image iterators usually have a member <TT>rowIterator()</TT>
which returns a row iterator optimized for that particular image class. which returns a row iterator optimized for that particular image class.
RowIterator is only necessary if this 'native' row iterator RowIterator is only necessary if this 'native' row iterator
is not usable in a particular situation or is not provided. is not usable in a particular situation or is not provided.
<b>\#include</b> "<a href="imageiteratoradapter_8hxx-source.html">vigra /imageiteratoradapter.hxx</a>" <b>\#include</b> \<<a href="imageiteratoradapter_8hxx-source.html">vigr a/imageiteratoradapter.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class IMAGE_ITERATOR> template <class IMAGE_ITERATOR>
class RowIterator : private IMAGE_ITERATOR class RowIterator : private IMAGE_ITERATOR
{ {
public: public:
/** the iterator's value type /** the iterator's value type
*/ */
skipping to change at line 477 skipping to change at line 477
/********************************************************/ /********************************************************/
/** \brief Iterator adapter to iterate along an arbitrary line on the image . /** \brief Iterator adapter to iterate along an arbitrary line on the image .
This iterator may be initialized from a standard ImageIterator, This iterator may be initialized from a standard ImageIterator,
a MultibandImageIterator and so on. a MultibandImageIterator and so on.
It gives you STL-compatible (forward iterator) access to It gives you STL-compatible (forward iterator) access to
an arbitraty line on the image. an arbitraty line on the image.
The iterator gets associated with the accessor of the base iterator. The iterator gets associated with the accessor of the base iterator.
<b>\#include</b> "<a href="imageiteratoradapter_8hxx-source.html">vigra /imageiteratoradapter.hxx</a>" <b>\#include</b> \<<a href="imageiteratoradapter_8hxx-source.html">vigr a/imageiteratoradapter.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class IMAGE_ITERATOR> template <class IMAGE_ITERATOR>
class LineIterator : private IMAGE_ITERATOR class LineIterator : private IMAGE_ITERATOR
{ {
public: public:
/** the iterator's value type /** the iterator's value type
*/ */
 End of changes. 5 change blocks. 
6 lines changed or deleted 6 lines changed or added


 impex.hxx   impex.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2001-2002 by Gunnar Kedenburg */ /* Copyright 2001-2002 by Gunnar Kedenburg */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 89 skipping to change at line 89
namespace vigra namespace vigra
{ {
/** \addtogroup VigraImpex /** \addtogroup VigraImpex
**/ **/
//@{ //@{
/*! /*!
\brief used for reading bands after the source data type has been fig ured out. \brief used for reading bands after the source data type has been fig ured out.
<b>\#include</b> "<a href="impex_8hxx-source.html">vigra/impex.hxx< /a>"<br> <b>\#include</b> \<<a href="impex_8hxx-source.html">vigra/impex.hxx </a>\><br>
Namespace: vigra Namespace: vigra
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
template< class ImageIterator, class Accessor, class SrcValueTy pe > template< class ImageIterator, class Accessor, class SrcValueTy pe >
void read_bands( Decoder * dec, ImageIterator ys, Accessor a, S rcValueType ) void read_bands( Decoder * dec, ImageIterator ys, Accessor a, S rcValueType )
} }
\endcode \endcode
skipping to change at line 181 skipping to change at line 181
scanline += dec->getOffset(); scanline += dec->getOffset();
} }
} }
} }
} }
} // read_bands() } // read_bands()
/*! /*!
\brief used for reading bands after the source data type has been fig ured out. \brief used for reading bands after the source data type has been fig ured out.
<b>\#include</b> "<a href="impex_8hxx-source.html">vigra/impex.hxx< /a>"<br> <b>\#include</b> \<<a href="impex_8hxx-source.html">vigra/impex.hxx </a>\><br>
Namespace: vigra Namespace: vigra
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
template< class ImageIterator, class Accessor, class SrcValueTy pe > template< class ImageIterator, class Accessor, class SrcValueTy pe >
void read_band( Decoder * dec, ImageIterator ys, Accessor a, Sr cValueType ) void read_band( Decoder * dec, ImageIterator ys, Accessor a, Sr cValueType )
} }
\endcode \endcode
skipping to change at line 222 skipping to change at line 222
xs = ys.rowIterator(); xs = ys.rowIterator();
scanline = static_cast< SrcValueType const * >(dec->currentScan lineOfBand(0)); scanline = static_cast< SrcValueType const * >(dec->currentScan lineOfBand(0));
for( size_type x = 0; x < width; ++x, ++xs ) for( size_type x = 0; x < width; ++x, ++xs )
a.set( scanline[x], xs ); a.set( scanline[x], xs );
} }
} // read_band() } // read_band()
/*! /*!
\brief used for reading images of vector type, such as integer of flo at rgb. \brief used for reading images of vector type, such as integer of flo at rgb.
<b>\#include</b> "<a href="impex_8hxx-source.html">vigra/impex.hxx< /a>"<br> <b>\#include</b> \<<a href="impex_8hxx-source.html">vigra/impex.hxx </a>\><br>
Namespace: vigra Namespace: vigra
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
template< class ImageIterator, class Accessor > template< class ImageIterator, class Accessor >
void importVectorImage( const ImageImportInfo & info, ImageIter ator iter, Accessor a ) void importVectorImage( const ImageImportInfo & info, ImageIter ator iter, Accessor a )
} }
\endcode \endcode
\param ImageIterator the image iterator type for the destination imag <b> Paramters:</b>
e
\param Accessor the image accessor type for the destination imag <DL>
e <DT>ImageIterator<DD> the image iterator type for the destination i
\param info user supplied image import information mage
\param iter image iterator referencing the upper left pixel <DT>Accessor<DD> the image accessor type for the destination image
of the destination image <DT>info<DD> user supplied image import information
\param a image accessor for the destination image <DT>iter<DD> image iterator referencing the upper left pixel of the
destination image
<DT>a<DD> image accessor for the destination image
</DL>
*/ */
doxygen_overloaded_function(template <...> void importVectorImage)
template< class ImageIterator, class Accessor > template< class ImageIterator, class Accessor >
void importVectorImage( const ImageImportInfo & info, ImageIterator ite r, Accessor a ) void importVectorImage( const ImageImportInfo & info, ImageIterator ite r, Accessor a )
{ {
std::auto_ptr<Decoder> dec = decoder(info); std::auto_ptr<Decoder> dec = decoder(info);
std::string pixeltype = dec->getPixelType(); std::string pixeltype = dec->getPixelType();
if ( pixeltype == "UINT8" ) if ( pixeltype == "UINT8" )
read_bands( dec.get(), iter, a, (UInt8)0 ); read_bands( dec.get(), iter, a, (UInt8)0 );
else if ( pixeltype == "INT16" ) else if ( pixeltype == "INT16" )
read_bands( dec.get(), iter, a, Int16() ); read_bands( dec.get(), iter, a, Int16() );
skipping to change at line 270 skipping to change at line 276
else else
vigra_precondition( false, "invalid pixeltype" ); vigra_precondition( false, "invalid pixeltype" );
// close the decoder // close the decoder
dec->close(); dec->close();
} }
/*! /*!
\brief used for reading images of scalar type, such as integer and f loat grayscale. \brief used for reading images of scalar type, such as integer and f loat grayscale.
<b>\#include</b> "<a href="impex_8hxx-source.html">vigra/impex.hxx< /a>"<br> <b>\#include</b> \<<a href="impex_8hxx-source.html">vigra/impex.hxx </a>\><br>
Namespace: vigra Namespace: vigra
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
template < class ImageIterator, class Accessor > template < class ImageIterator, class Accessor >
void importScalarImage( const ImageImportInfo & info, ImageIter ator iter, Accessor a ) void importScalarImage( const ImageImportInfo & info, ImageIter ator iter, Accessor a )
} }
\endcode \endcode
\param ImageIterator the image iterator type for the destination imag <b> Paramters:</b>
e
\param Accessor the image accessor type for the destination imag <DL>
e <DT>ImageIterator<DD> the image iterator type for the destination i
\param info user supplied image import information mage
\param iter image iterator referencing the upper left pixel <DT>Accessor<DD> the image accessor type for the destination image
of the destination image <DT>info<DD> user supplied image import information
\param a image accessor for the destination image <DT>iter<DD> image iterator referencing the upper left pixel of the
destination image
<DT>a<DD> image accessor for the destination image
</DL>
*/ */
doxygen_overloaded_function(template <...> void importScalarImage)
template < class ImageIterator, class Accessor > template < class ImageIterator, class Accessor >
void importScalarImage( const ImageImportInfo & info, ImageIterator ite r, Accessor a ) void importScalarImage( const ImageImportInfo & info, ImageIterator ite r, Accessor a )
{ {
std::auto_ptr<Decoder> dec = decoder(info); std::auto_ptr<Decoder> dec = decoder(info);
std::string pixeltype = dec->getPixelType(); std::string pixeltype = dec->getPixelType();
if ( pixeltype == "UINT8" ) if ( pixeltype == "UINT8" )
read_band( dec.get(), iter, a, (UInt8)0 ); read_band( dec.get(), iter, a, (UInt8)0 );
else if ( pixeltype == "INT16" ) else if ( pixeltype == "INT16" )
read_band( dec.get(), iter, a, Int16() ); read_band( dec.get(), iter, a, Int16() );
skipping to change at line 315 skipping to change at line 327
read_band( dec.get(), iter, a, float() ); read_band( dec.get(), iter, a, float() );
else if ( pixeltype == "DOUBLE" ) else if ( pixeltype == "DOUBLE" )
read_band( dec.get(), iter, a, double() ); read_band( dec.get(), iter, a, double() );
else else
vigra_precondition( false, "invalid pixeltype" ); vigra_precondition( false, "invalid pixeltype" );
// close the decoder // close the decoder
dec->close(); dec->close();
} }
template < class ImageIterator, class Accessor >
void importImage( const ImageImportInfo & info, ImageIterator iter, Acc
essor a, VigraFalseType )
{
importVectorImage( info, iter, a );
}
template < class ImageIterator, class Accessor >
void importImage( const ImageImportInfo & info, ImageIterator iter, Acc
essor a, VigraTrueType )
{
importScalarImage( info, iter, a );
}
/********************************************************/ /********************************************************/
/* */ /* */
/* importImage */ /* importImage */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Read an image, given an \ref vigra::ImageImportInfo object. /** \brief Read the image specified by the given \ref vigra::ImageImpor tInfo object.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
void void
importImage(ImageImportInfo const & image, ImageIterator iter, Accessor a) importImage(ImageImportInfo const & image, ImageIterator iter, Accessor a)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactori es: use argument objects in conjunction with \ref ArgumentObjectFactori es :
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
inline void inline void
importImage(ImageImportInfo const & image, pair<ImageIterator, Accessor> dest) importImage(ImageImportInfo const & image, pair<ImageIterator, Accessor> dest)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="impex_8hxx-source.html">vigra/impex.hxx< /a>"<br> <b>\#include</b> \<<a href="impex_8hxx-source.html">vigra/impex.hxx </a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::ImageImportInfo info("myimage.gif"); vigra::ImageImportInfo info("myimage.gif");
if(info.isGrayscale()) if(info.isGrayscale())
{ {
// create byte image of appropriate size // create byte image of appropriate size
vigra::BImage in(info.width(), info.height()); vigra::BImage in(info.width(), info.height());
skipping to change at line 405 skipping to change at line 405
<DT>"PBM"<DD> Portable bitmap format (black and white). <DT>"PBM"<DD> Portable bitmap format (black and white).
<DT>"PGM"<DD> Portable graymap format (gray scale). <DT>"PGM"<DD> Portable graymap format (gray scale).
<DT>"PNM"<DD> Portable anymap. <DT>"PNM"<DD> Portable anymap.
<DT>"PPM"<DD> Portable pixmap format (color). <DT>"PPM"<DD> Portable pixmap format (color).
<DT>"SUN"<DD> SUN Rasterfile. <DT>"SUN"<DD> SUN Rasterfile.
<DT>"TIFF"<DD> Tagged Image File Format. (only available if libtiff is installed.) <DT>"TIFF"<DD> Tagged Image File Format. (only available if libtiff is installed.)
<DT>"VIFF"<DD> Khoros Visualization image file. <DT>"VIFF"<DD> Khoros Visualization image file.
</DL> </DL>
</UL> </UL>
**/ **/
doxygen_overloaded_function(template <...> void importImage)
template < class ImageIterator, class Accessor > template < class ImageIterator, class Accessor >
void importImage( const ImageImportInfo & info, ImageIterator iter, Acc essor a ) void importImage( const ImageImportInfo & info, ImageIterator iter, Acc essor a )
{ {
typedef typename NumericTraits<typename Accessor::value_type>::isSc alar is_scalar; typedef typename NumericTraits<typename Accessor::value_type>::isSc alar is_scalar;
importImage( info, iter, a, is_scalar() ); importImage( info, iter, a, is_scalar() );
} }
template < class ImageIterator, class Accessor > template < class ImageIterator, class Accessor >
void importImage( const ImageImportInfo & info, pair< ImageIterator, Ac cessor > dest ) void importImage( const ImageImportInfo & info, pair< ImageIterator, Ac cessor > dest )
{ {
importImage( info, dest.first, dest.second ); importImage( info, dest.first, dest.second );
} }
template < class ImageIterator, class Accessor >
void importImage( const ImageImportInfo & info, ImageIterator iter, Acc
essor a, VigraFalseType )
{
importVectorImage( info, iter, a );
}
template < class ImageIterator, class Accessor >
void importImage( const ImageImportInfo & info, ImageIterator iter, Acc
essor a, VigraTrueType )
{
importScalarImage( info, iter, a );
}
/*! /*!
\brief used for writing bands after the source data type has been fig ured out. \brief used for writing bands after the source data type has been fig ured out.
<b>\#include</b> "<a href="impex_8hxx-source.html">vigra/impex.hxx< /a>"<br> <b>\#include</b> \<<a href="impex_8hxx-source.html">vigra/impex.hxx </a>\><br>
Namespace: vigra Namespace: vigra
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
template< class ImageIterator, class Accessor, class DstValueTy pe > template< class ImageIterator, class Accessor, class DstValueTy pe >
void write_bands( Encoder * enc, ImageIterator ul, ImageIterato r lr, Accessor a, DstValueType ) void write_bands( Encoder * enc, ImageIterator ul, ImageIterato r lr, Accessor a, DstValueType )
} }
\endcode \endcode
skipping to change at line 548 skipping to change at line 562
scanline += enc->getOffset(); scanline += enc->getOffset();
} }
} }
enc->nextScanline(); enc->nextScanline();
} }
} // write_bands() } // write_bands()
/*! /*!
\brief used for writing bands after the source data type has been fig ured out. \brief used for writing bands after the source data type has been fig ured out.
<b>\#include</b> "<a href="impex_8hxx-source.html">vigra/impex.hxx< /a>"<br> <b>\#include</b> \<<a href="impex_8hxx-source.html">vigra/impex.hxx </a>\><br>
Namespace: vigra Namespace: vigra
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
template< class ImageIterator, class Accessor, class DstValueTy pe > template< class ImageIterator, class Accessor, class DstValueTy pe >
void write_band( Encoder * enc, ImageIterator ul, ImageIterator lr, Accessor a, DstValueType ) void write_band( Encoder * enc, ImageIterator ul, ImageIterator lr, Accessor a, DstValueType )
} }
\endcode \endcode
skipping to change at line 598 skipping to change at line 612
xs = ys.rowIterator(); xs = ys.rowIterator();
scanline = static_cast< DstValueType * >(enc->currentScanlineOf Band(0)); scanline = static_cast< DstValueType * >(enc->currentScanlineOf Band(0));
for( size_type x = 0; x < width; ++x, ++xs, ++scanline ) for( size_type x = 0; x < width; ++x, ++xs, ++scanline )
*scanline = detail::RequiresExplicitCast<DstValueType>::cas t(a(xs)); *scanline = detail::RequiresExplicitCast<DstValueType>::cas t(a(xs));
enc->nextScanline(); enc->nextScanline();
} }
} // write_band() } // write_band()
namespace detail { namespace detail {
template < class SrcIterator, class SrcAccessor, // export scalar images without conversion
class DestIterator, class DestAccessor >
void mapScalarImageToLowerPixelType( SrcIterator sul, SrcIterator slr,
SrcAccessor sget,
DestIterator dul, DestAccessor dge
t )
{
typedef typename SrcAccessor::value_type SrcValue;
typedef typename DestAccessor::value_type DestValue;
typedef typename NumericTraits<SrcValue>::RealPromote PromoteValue;
FindMinMax<SrcValue> minmax;
inspectImage( sul, slr, sget, minmax );
double scale = (double)NumericTraits<DestValue>::max() / (minmax.ma
x - minmax.min) -
(double)NumericTraits<DestValue>::min() / (minmax.ma
x - minmax.min);
double offset = (NumericTraits<DestValue>::min() / scale) - minmax.
min ;
transformImage( sul, slr, sget, dul, dget,
linearIntensityTransform( scale, offset ) );
}
// export scalar images with conversion (if necessary)
template < class SrcIterator, class SrcAccessor, class T > template < class SrcIterator, class SrcAccessor, class T >
void exportScalarImage(SrcIterator sul, SrcIterator slr, SrcAccessor sg et, void exportScalarImage(SrcIterator sul, SrcIterator slr, SrcAccessor sg et,
Encoder * enc, bool downcast, T zero) Encoder * enc, T zero)
{ {
if (!downcast) { write_band( enc, sul, slr, sget, zero );
write_band( enc, sul, slr, sget, zero );
} else {
// convert to unsigned char in the usual way
BasicImage<T> image(slr-sul);
mapScalarImageToLowerPixelType(sul, slr, sget, image.upperLeft(
), image.accessor());
write_band( enc, image.upperLeft(),
image.lowerRight(), image.accessor(), zero );
}
} }
template < class SrcIterator, class SrcAccessor, // export scalar images with conversion
class MArray> template < class SrcIterator, class SrcAccessor, class T >
void mapVectorImageToLowerPixelType( SrcIterator sul, SrcIterator slr, void exportScalarImage(SrcIterator sul, SrcIterator slr, SrcAccessor sg
SrcAccessor sget, et,
MArray & array ) Encoder * enc,
const ImageExportInfo & info,
T zero)
{ {
typedef typename SrcAccessor::value_type SrcValue; double fromMin, fromMax, toMin, toMax;
typedef typename SrcValue::value_type SrcComponent; if(info.hasForcedRangeMapping())
typedef typename MArray::value_type DestValue;
FindMinMax<SrcComponent> minmax;
for(unsigned int i=0; i<sget.size(sul); ++i)
{ {
// FIXME dangelo - This will break with vector accessors that h fromMin = info.getFromMin();
ave a "by value" interface. fromMax = info.getFromMax();
// use VectorComponentValueAccessor instead, since it should wo toMin = info.getToMin();
rk in both cases, even toMax = info.getToMax();
// if it might be a bit slower..
//VectorElementAccessor<SrcAccessor> band(i, sget);
VectorComponentValueAccessor<typename SrcAccessor::value_type>
band(i);
inspectImage( sul, slr, band, minmax );
} }
double scale = (double)NumericTraits<DestValue>::max() / (minmax.ma else
x - minmax.min) -
(double)NumericTraits<DestValue>::min() / (minmax.ma
x - minmax.min);
// FIXME DGSW - Original was not correct. Is this what was intended?
// double offset = -minmax.min + NumericTraits<DestValue>::min() / s
cale;
double offset = (NumericTraits<DestValue>::min() / scale) - minmax.
min ;
for(unsigned int i=0; i<sget.size(sul); ++i)
{ {
BasicImageView<DestValue> subImage = makeBasicImageView(array.b typedef typename SrcAccessor::value_type SrcValue;
indOuter(i)); FindMinMax<SrcValue> minmax;
// FIXME dangelo: use VectorComponentValueAccessor inspectImage( sul, slr, sget, minmax );
//VectorElementAccessor<SrcAccessor> band(i, sget);
VectorComponentValueAccessor<typename SrcAccessor::value_type> fromMin = (double)minmax.min;
band(i); fromMax = (double)minmax.max;
transformImage( sul, slr, band, subImage.upperLeft(), subImage. toMin = (double)NumericTraits<T>::min();
accessor(), toMax = (double)NumericTraits<T>::max();
linearIntensityTransform( scale, offset ) );
} }
double scale = (toMax - toMin) / (fromMax - fromMin);
double offset = (toMin / scale) - fromMin;
BasicImage<T> image(slr-sul);
transformImage( sul, slr, sget, image.upperLeft(), image.accessor()
,
linearIntensityTransform(scale, offset));
write_band( enc, image.upperLeft(),
image.lowerRight(), image.accessor(), zero );
} }
// export vector images with conversion (if necessary) // export vector images without conversion
template < class SrcIterator, class SrcAccessor, class T > template < class SrcIterator, class SrcAccessor, class T >
void exportVectorImage(SrcIterator sul, SrcIterator slr, SrcAccessor sg et, void exportVectorImage(SrcIterator sul, SrcIterator slr, SrcAccessor sg et,
Encoder * enc, bool downcast, T zero) Encoder * enc, T zero)
{ {
int bands = sget.size(sul); int bands = sget.size(sul);
vigra_precondition(isBandNumberSupported(enc->getFileType(), bands) , vigra_precondition(isBandNumberSupported(enc->getFileType(), bands) ,
"exportImage(): file format does not support requested number of bands (color channels)"); "exportImage(): file format does not support requested number of bands (color channels)");
if ( !downcast ) write_bands( enc, sul, slr, sget, zero );
}
// export vector images with conversion
template < class SrcIterator, class SrcAccessor, class T >
void exportVectorImage(SrcIterator sul, SrcIterator slr, SrcAccessor sg
et,
Encoder * enc,
const ImageExportInfo & info,
T zero)
{
unsigned int bands = sget.size(sul);
vigra_precondition(isBandNumberSupported(enc->getFileType(), bands)
,
"exportImage(): file format does not support requested number of
bands (color channels)");
typedef typename SrcAccessor::value_type SrcValue;
double fromMin, fromMax, toMin, toMax;
if(info.hasForcedRangeMapping())
{ {
write_bands( enc, sul, slr, sget, zero ); fromMin = info.getFromMin();
fromMax = info.getFromMax();
toMin = info.getToMin();
toMax = info.getToMax();
} }
else else
{ {
// convert to unsigned char in the usual way typedef typename SrcValue::value_type SrcComponent;
int w = slr.x - sul.x;
int h = slr.y - sul.y;
typedef vigra::MultiArray<3, T> MArray; FindMinMax<SrcComponent> minmax;
MArray array(typename MArray::difference_type(w, h, bands)); for(unsigned int i=0; i<bands; ++i)
{
VectorComponentValueAccessor<SrcValue> band(i);
inspectImage( sul, slr, band, minmax );
}
mapVectorImageToLowerPixelType(sul, slr, sget, array); fromMin = (double)minmax.min;
fromMax = (double)minmax.max;
toMin = (double)NumericTraits<T>::min();
toMax = (double)NumericTraits<T>::max();
}
double scale = (toMax - toMin) / (fromMax - fromMin);
double offset = (toMin / scale) - fromMin;
int w = slr.x - sul.x;
int h = slr.y - sul.y;
write_bands( enc, array, zero ); typedef vigra::MultiArray<3, T> MArray;
MArray array(typename MArray::difference_type(w, h, bands));
for(unsigned int i=0; i<bands; ++i)
{
BasicImageView<T> subImage = makeBasicImageView(array.bindOuter
(i));
VectorComponentValueAccessor<SrcValue> band(i);
transformImage( sul, slr, band, subImage.upperLeft(), subImage.
accessor(),
linearIntensityTransform( scale, offset ) );
} }
write_bands( enc, array, zero );
} }
} // namespace detail } // namespace detail
/*! /*!
\brief Deprecated. \brief Deprecated.
Use \ref exportImage() instead. Use \ref exportImage() instead.
<b> Declaration:</b> <b> Declaration:</b>
\code \code
skipping to change at line 710 skipping to change at line 737
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
template < class SrcIterator, class SrcAccessor > template < class SrcIterator, class SrcAccessor >
void exportFloatingVectorImage( SrcIterator sul, SrcIterator sl r, SrcAccessor sget, void exportFloatingVectorImage( SrcIterator sul, SrcIterator sl r, SrcAccessor sget,
const ImageExportInfo & info ) const ImageExportInfo & info )
} }
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void exportFloatingVectorImage)
template < class SrcIterator, class SrcAccessor > template < class SrcIterator, class SrcAccessor >
void exportFloatingVectorImage( SrcIterator sul, SrcIterator slr, SrcAc cessor sget, void exportFloatingVectorImage( SrcIterator sul, SrcIterator slr, SrcAc cessor sget,
const ImageExportInfo & info ) const ImageExportInfo & info )
{ {
exportImage(sul, slr, sget, info); exportImage(sul, slr, sget, info);
} }
/*! /*!
\brief Deprecated. \brief Deprecated.
skipping to change at line 732 skipping to change at line 761
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
template < class SrcIterator, class SrcAccessor > template < class SrcIterator, class SrcAccessor >
void exportIntegralVectorImage( SrcIterator sul, SrcIterator sl r, SrcAccessor sget, void exportIntegralVectorImage( SrcIterator sul, SrcIterator sl r, SrcAccessor sget,
const ImageExportInfo & info ) const ImageExportInfo & info )
} }
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void exportIntegralVectorImage)
template < class SrcIterator, class SrcAccessor > template < class SrcIterator, class SrcAccessor >
void exportIntegralVectorImage( SrcIterator sul, SrcIterator slr, SrcAc cessor sget, void exportIntegralVectorImage( SrcIterator sul, SrcIterator slr, SrcAc cessor sget,
const ImageExportInfo & info ) const ImageExportInfo & info )
{ {
exportImage(sul, slr, sget, info); exportImage(sul, slr, sget, info);
} }
/*! /*!
\brief Deprecated. \brief Deprecated.
skipping to change at line 754 skipping to change at line 785
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
template < class SrcIterator, class SrcAccessor > template < class SrcIterator, class SrcAccessor >
void exportFloatingScalarImage( SrcIterator sul, SrcIterator sl r, SrcAccessor sget, void exportFloatingScalarImage( SrcIterator sul, SrcIterator sl r, SrcAccessor sget,
const ImageExportInfo & info ) const ImageExportInfo & info )
} }
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void exportFloatingScalarImage)
template < class SrcIterator, class SrcAccessor > template < class SrcIterator, class SrcAccessor >
void exportFloatingScalarImage( SrcIterator sul, SrcIterator slr, SrcAc cessor sget, void exportFloatingScalarImage( SrcIterator sul, SrcIterator slr, SrcAc cessor sget,
const ImageExportInfo & info ) const ImageExportInfo & info )
{ {
exportImage(sul, slr, sget, info); exportImage(sul, slr, sget, info);
} }
/*! /*!
\brief Deprecated. \brief Deprecated.
skipping to change at line 776 skipping to change at line 809
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
template < class SrcIterator, class SrcAccessor > template < class SrcIterator, class SrcAccessor >
void exportIntegralScalarImage( SrcIterator sul, SrcIterator sl r, SrcAccessor sget, void exportIntegralScalarImage( SrcIterator sul, SrcIterator sl r, SrcAccessor sget,
const ImageExportInfo & info ) const ImageExportInfo & info )
} }
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void exportIntegralScalarImage)
template < class SrcIterator, class SrcAccessor > template < class SrcIterator, class SrcAccessor >
void exportIntegralScalarImage( SrcIterator sul, SrcIterator slr, SrcAc cessor sget, void exportIntegralScalarImage( SrcIterator sul, SrcIterator slr, SrcAc cessor sget,
const ImageExportInfo & info ) const ImageExportInfo & info )
{ {
exportImage(sul, slr, sget, info); exportImage(sul, slr, sget, info);
} }
template < class SrcIterator, class SrcAccessor >
void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
const ImageExportInfo & info, VigraFalseType /*not sc
alar */)
{
typedef typename SrcAccessor::value_type AccessorValueType;
typedef typename AccessorValueType::value_type SrcValueType;
std::string pixeltype = info.getPixelType();
std::auto_ptr<Encoder> enc = encoder(info);
bool downcast = negotiatePixelType(enc->getFileType(),
TypeAsString<SrcValueType>::result(), pixeltype);
enc->setPixelType(pixeltype);
if(pixeltype == "UINT8")
detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
(UInt8)0);
else if(pixeltype == "INT16")
detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
Int16());
else if(pixeltype == "UINT16")
detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
(UInt16)0);
else if(pixeltype == "INT32")
detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
Int32());
else if(pixeltype == "UINT32")
detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
(UInt32)0);
else if(pixeltype == "FLOAT")
detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
float());
else if(pixeltype == "DOUBLE")
detail::exportVectorImage( sul, slr, sget, enc.get(), downcast,
double());
enc->close();
}
template < class SrcIterator, class SrcAccessor >
void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
const ImageExportInfo & info, VigraTrueType /*scalar*
/ )
{
typedef typename SrcAccessor::value_type SrcValueType;
std::string pixeltype = info.getPixelType();
std::auto_ptr<Encoder> enc = encoder(info);
bool downcast = negotiatePixelType(enc->getFileType(),
TypeAsString<SrcValueType>::result(), pixeltype)
;
enc->setPixelType(pixeltype);
if(pixeltype == "UINT8")
detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
(UInt8)0);
else if(pixeltype == "INT16")
detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
Int16());
else if(pixeltype == "UINT16")
detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
(UInt16)0);
else if(pixeltype == "INT32")
detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
Int32());
else if(pixeltype == "UINT32")
detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
(UInt32)0);
else if(pixeltype == "FLOAT")
detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
float());
else if(pixeltype == "DOUBLE")
detail::exportScalarImage( sul, slr, sget, enc.get(), downcast,
double());
enc->close();
}
/********************************************************/ /********************************************************/
/* */ /* */
/* exportImage */ /* exportImage */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Write an image, given an \ref vigra::ImageExportInfo object. /** \brief Write an image, given an \ref vigra::ImageExportInfo object.
If the file format to be exported to supports the pixel type of the If the file format to be exported to supports the pixel type of the
source image, the pixel type will be kept (e.g. <tt>float</tt> source image, the pixel type will be kept (e.g. <tt>float</tt>
skipping to change at line 884 skipping to change at line 864
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor> template <class SrcIterator, class SrcAccessor>
void exportImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget , void exportImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget ,
ImageExportInfo const & info) ImageExportInfo const & info)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor> template <class SrcIterator, class SrcAccessor>
void exportImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget , void exportImage(SrcIterator sul, SrcIterator slr, SrcAccessor sget ,
ImageExportInfo const & info) ImageExportInfo const & info)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="impex_8hxx-source.html">vigra/impex.hxx</a>" <br> <b>\#include</b> \<<a href="impex_8hxx-source.html">vigra/impex.hxx</a> \><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BRGBImage out(w, h); vigra::BRGBImage out(w, h);
... ...
// write as JPEG image, using compression quality 80 // write as JPEG image, using compression quality 80
vigra::exportImage(srcImageRange(out), vigra::exportImage(srcImageRange(out),
vigra::ImageExportInfo("myimage.jpg").setCompression( "80")); vigra::ImageExportInfo("myimage.jpg").setCompression( "80"));
skipping to change at line 922 skipping to change at line 902
<b> Preconditions:</b> <b> Preconditions:</b>
<UL> <UL>
<LI> the image file must be writable. <LI> the image file must be writable.
<LI> the file type must be one of the supported file types. <LI> the file type must be one of the supported file types.
</UL> </UL>
**/ **/
doxygen_overloaded_function(template <...> void exportImage)
template < class SrcIterator, class SrcAccessor > template < class SrcIterator, class SrcAccessor >
inline
void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget, void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
const ImageExportInfo & info ) const ImageExportInfo & info )
{ {
typedef typename NumericTraits<typename SrcAccessor::value_type>::i sScalar is_scalar; typedef typename NumericTraits<typename SrcAccessor::value_type>::i sScalar is_scalar;
try try
{ {
exportImage( sul, slr, sget, info, is_scalar() ); exportImage( sul, slr, sget, info, is_scalar() );
} }
catch(Encoder::TIFFCompressionException &) catch(Encoder::TIFFCompressionException &)
skipping to change at line 948 skipping to change at line 929
} }
template < class SrcIterator, class SrcAccessor > template < class SrcIterator, class SrcAccessor >
inline inline
void exportImage( triple<SrcIterator, SrcIterator, SrcAccessor> src, void exportImage( triple<SrcIterator, SrcIterator, SrcAccessor> src,
const ImageExportInfo & info ) const ImageExportInfo & info )
{ {
exportImage( src.first, src.second, src.third, info ); exportImage( src.first, src.second, src.third, info );
} }
template < class SrcIterator, class SrcAccessor >
void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
const ImageExportInfo & info, VigraFalseType /*not sc
alar */)
{
typedef typename SrcAccessor::value_type AccessorValueType;
typedef typename AccessorValueType::value_type SrcValueType;
std::string pixeltype = info.getPixelType();
std::auto_ptr<Encoder> enc = encoder(info);
bool downcast = negotiatePixelType(enc->getFileType(),
TypeAsString<SrcValueType>::result(), pixeltype);
enc->setPixelType(pixeltype);
if(downcast || info.hasForcedRangeMapping())
{
if(pixeltype == "UINT8")
detail::exportVectorImage( sul, slr, sget, enc.get(), info,
(UInt8)0);
else if(pixeltype == "INT16")
detail::exportVectorImage( sul, slr, sget, enc.get(), info,
Int16());
else if(pixeltype == "UINT16")
detail::exportVectorImage( sul, slr, sget, enc.get(), info,
(UInt16)0);
else if(pixeltype == "INT32")
detail::exportVectorImage( sul, slr, sget, enc.get(), info,
Int32());
else if(pixeltype == "UINT32")
detail::exportVectorImage( sul, slr, sget, enc.get(), info,
(UInt32)0);
else if(pixeltype == "FLOAT")
detail::exportVectorImage( sul, slr, sget, enc.get(), info,
float());
else if(pixeltype == "DOUBLE")
detail::exportVectorImage( sul, slr, sget, enc.get(), info,
double());
}
else
{
if(pixeltype == "UINT8")
detail::exportVectorImage( sul, slr, sget, enc.get(), (UInt
8)0);
else if(pixeltype == "INT16")
detail::exportVectorImage( sul, slr, sget, enc.get(), Int16
());
else if(pixeltype == "UINT16")
detail::exportVectorImage( sul, slr, sget, enc.get(), (UInt
16)0);
else if(pixeltype == "INT32")
detail::exportVectorImage( sul, slr, sget, enc.get(), Int32
());
else if(pixeltype == "UINT32")
detail::exportVectorImage( sul, slr, sget, enc.get(), (UInt
32)0);
else if(pixeltype == "FLOAT")
detail::exportVectorImage( sul, slr, sget, enc.get(), float
());
else if(pixeltype == "DOUBLE")
detail::exportVectorImage( sul, slr, sget, enc.get(), doubl
e());
}
enc->close();
}
template < class SrcIterator, class SrcAccessor >
void exportImage( SrcIterator sul, SrcIterator slr, SrcAccessor sget,
const ImageExportInfo & info, VigraTrueType /*scalar*
/ )
{
typedef typename SrcAccessor::value_type SrcValueType;
std::string pixeltype = info.getPixelType();
std::auto_ptr<Encoder> enc = encoder(info);
bool downcast = negotiatePixelType(enc->getFileType(),
TypeAsString<SrcValueType>::result(), pixeltype)
;
enc->setPixelType(pixeltype);
if(downcast || info.hasForcedRangeMapping())
{
if(pixeltype == "UINT8")
detail::exportScalarImage( sul, slr, sget, enc.get(), info,
(UInt8)0);
else if(pixeltype == "INT16")
detail::exportScalarImage( sul, slr, sget, enc.get(), info,
Int16());
else if(pixeltype == "UINT16")
detail::exportScalarImage( sul, slr, sget, enc.get(), info,
(UInt16)0);
else if(pixeltype == "INT32")
detail::exportScalarImage( sul, slr, sget, enc.get(), info,
Int32());
else if(pixeltype == "UINT32")
detail::exportScalarImage( sul, slr, sget, enc.get(), info,
(UInt32)0);
else if(pixeltype == "FLOAT")
detail::exportScalarImage( sul, slr, sget, enc.get(), info,
float());
else if(pixeltype == "DOUBLE")
detail::exportScalarImage( sul, slr, sget, enc.get(), info,
double());
}
else
{
if(pixeltype == "UINT8")
detail::exportScalarImage( sul, slr, sget, enc.get(), (UInt
8)0);
else if(pixeltype == "INT16")
detail::exportScalarImage( sul, slr, sget, enc.get(), Int16
());
else if(pixeltype == "UINT16")
detail::exportScalarImage( sul, slr, sget, enc.get(), (UInt
16)0);
else if(pixeltype == "INT32")
detail::exportScalarImage( sul, slr, sget, enc.get(), Int32
());
else if(pixeltype == "UINT32")
detail::exportScalarImage( sul, slr, sget, enc.get(), (UInt
32)0);
else if(pixeltype == "FLOAT")
detail::exportScalarImage( sul, slr, sget, enc.get(), float
());
else if(pixeltype == "DOUBLE")
detail::exportScalarImage( sul, slr, sget, enc.get(), doubl
e());
}
enc->close();
}
//@} //@}
} // namespace vigra } // namespace vigra
#endif /* VIGRA_IMPEX_HXX */ #endif /* VIGRA_IMPEX_HXX */
 End of changes. 47 change blocks. 
202 lines changed or deleted 280 lines changed or added


 initimage.hxx   initimage.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 60 skipping to change at line 60
*/ */
//@{ //@{
/********************************************************/ /********************************************************/
/* */ /* */
/* initLine */ /* initLine */
/* */ /* */
/********************************************************/ /********************************************************/
template <class DestIterator, class DestAccessor, class VALUETYPE> template <class DestIterator, class DestAccessor, class VALUETYPE>
void inline void
initLineImpl(DestIterator d, DestIterator dend, DestAccessor dest, initLineImpl(DestIterator d, DestIterator dend, DestAccessor dest,
VALUETYPE v, VigraFalseType) VALUETYPE const & v, VigraFalseType)
{ {
for(; d != dend; ++d) for(; d != dend; ++d)
dest.set(v, d); dest.set(v, d);
} }
template <class DestIterator, class DestAccessor, class FUNCTOR> template <class DestIterator, class DestAccessor, class FUNCTOR>
void inline void
initLineImpl(DestIterator d, DestIterator dend, DestAccessor dest, initLineImpl(DestIterator d, DestIterator dend, DestAccessor dest,
FUNCTOR const & f, VigraTrueType) FUNCTOR const & f, VigraTrueType)
{ {
for(; d != dend; ++d) for(; d != dend; ++d)
dest.set(f(), d); dest.set(f(), d);
} }
template <class DestIterator, class DestAccessor, class VALUETYPE> template <class DestIterator, class DestAccessor, class VALUETYPE>
inline void inline void
initLine(DestIterator d, DestIterator dend, DestAccessor dest, initLine(DestIterator d, DestIterator dend, DestAccessor dest,
VALUETYPE v) VALUETYPE const & v)
{ {
initLineImpl(d, dend, dest, v, typename FunctorTraits<VALUETYPE>::isIni tializer()); initLineImpl(d, dend, dest, v, typename FunctorTraits<VALUETYPE>::isIni tializer());
} }
template <class DestIterator, class DestAccessor, class FUNCTOR> template <class DestIterator, class DestAccessor, class FUNCTOR>
inline void inline void
initLineFunctor(DestIterator d, DestIterator dend, DestAccessor dest, initLineFunctor(DestIterator d, DestIterator dend, DestAccessor dest,
FUNCTOR f) FUNCTOR & f)
{ {
initLineImpl(d, dend, dest, f, VigraTrueType()); for(; d != dend; ++d)
dest.set(f(), d);
} }
template <class DestIterator, class DestAccessor, template <class DestIterator, class DestAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class VALUETYPE> class VALUETYPE>
void inline void
initLineIfImpl(DestIterator d, DestIterator dend, DestAccessor dest, initLineIfImpl(DestIterator d, DestIterator dend, DestAccessor dest,
MaskIterator m, MaskAccessor mask, MaskIterator m, MaskAccessor mask,
VALUETYPE v, VigraFalseType) VALUETYPE const & v, VigraFalseType)
{ {
for(; d != dend; ++d, ++m) for(; d != dend; ++d, ++m)
if(mask(m)) if(mask(m))
dest.set(v, d); dest.set(v, d);
} }
template <class DestIterator, class DestAccessor, template <class DestIterator, class DestAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class FUNCTOR> class FUNCTOR>
void inline void
initLineIfImpl(DestIterator d, DestIterator dend, DestAccessor dest, initLineIfImpl(DestIterator d, DestIterator dend, DestAccessor dest,
MaskIterator m, MaskAccessor mask, MaskIterator m, MaskAccessor mask,
FUNCTOR const & f, VigraTrueType) FUNCTOR const & f, VigraTrueType)
{ {
for(; d != dend; ++d, ++m) for(; d != dend; ++d, ++m)
if(mask(m)) if(mask(m))
dest.set(f(), d); dest.set(f(), d);
} }
template <class DestIterator, class DestAccessor, template <class DestIterator, class DestAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class VALUETYPE> class VALUETYPE>
inline void inline void
initLineIf(DestIterator d, DestIterator dend, DestAccessor dest, initLineIf(DestIterator d, DestIterator dend, DestAccessor dest,
MaskIterator m, MaskAccessor mask, MaskIterator m, MaskAccessor mask,
VALUETYPE v) VALUETYPE const & v)
{ {
initLineIfImpl(d, dend, dest, m, mask, v, typename FunctorTraits<VALUET YPE>::isInitializer()); initLineIfImpl(d, dend, dest, m, mask, v, typename FunctorTraits<VALUET YPE>::isInitializer());
} }
template <class DestIterator, class DestAccessor, template <class DestIterator, class DestAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class FUNCTOR> class FUNCTOR>
void inline void
initLineFunctorIf(DestIterator d, DestIterator dend, DestAccessor dest, initLineFunctorIf(DestIterator d, DestIterator dend, DestAccessor dest,
MaskIterator m, MaskAccessor mask, MaskIterator m, MaskAccessor mask,
FUNCTOR f) FUNCTOR & f)
{ {
initLineIfImpl(d, dend, dest, m, mask, f, VigraTrueType()); for(; d != dend; ++d, ++m)
if(mask(m))
dest.set(f(), d);
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* initImage */ /* initImage */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Write a value to every pixel in an image or rectangular ROI. /** \brief Write a value to every pixel in an image or rectangular ROI.
This function can be used to init the image. This function can be used to init the image.
It uses an accessor to access the pixel data. It uses an accessor to access the pixel data.
The initial value can either be a constant of appropriate type (compati
ble with
the destination's value_type), or a functor with compatible result_type
. These two
cases are automatically distinguished when <tt>FunctorTraits<FUNCTOR>::
isInitializer</tt>
yields <tt>VigraTrueType</tt>. Since the functor is passed by <tt>const
</tt> reference, its
<tt>operator()</tt> must be const, and its internal state may need to b
e <tt>mutable</tt>.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor, class VALUETYPE> template <class ImageIterator, class Accessor, class VALUETYPE>
void void initImage(ImageIterator upperleft, ImageIterator lowerright,
initImage(ImageIterator upperleft, ImageIterator lowerright, Accessor a, VALUETYPE const & v);
Accessor a, VALUETYPE v)
template <class ImageIterator, class Accessor, class FUNCTOR>
void initImage(ImageIterator upperleft, ImageIterator lowerright,
Accessor a, FUNCTOR const & v);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor, class VALUETYPE> template <class ImageIterator, class Accessor, class VALUETYPE>
void void initImage(triple<ImageIterator, ImageIterator, Accessor> img,
initImage(triple<ImageIterator, ImageIterator, Accessor> img, VALUE VALUETYPE const & v);
TYPE v)
template <class ImageIterator, class Accessor, class FUNCTOR>
void initImage(triple<ImageIterator, ImageIterator, Accessor> img,
FUNCTOR const & v);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="initimage_8hxx-source.html">vigra/initim age.hxx</a>"<br> <b>\#include</b> \<<a href="initimage_8hxx-source.html">vigra/initi mage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
Initialize with a constant:
\code \code
vigra::BImage img(100, 100); vigra::BImage img(100, 100);
// zero the image // init the image with the value 128
vigra::initImage(destImageRange(img), vigra::initImage(destImageRange(img), 128);
vigra::NumericTraits<vigra::BImage::PixelType>::zero() \endcode
);
Initialize with a functor:
\code
struct Counter {
Counter() : count(0) {}
int operator()() const { return count++; }
mutable int count;
};
vigra::IImage img(100, 100);
// write the current count in every pixel
vigra::initImage(destImageRange(img), Counter());
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
\code \code
ImageIterator upperleft, lowerright; ImageIterator upperleft, lowerright;
ImageIterator::row_iterator ix = upperleft.rowIterator(); ImageIterator::row_iterator ix = upperleft.rowIterator();
Accessor accessor; Accessor accessor;
VALUETYPE v; VALUETYPE v;
accessor.set(v, ix); accessor.set(v, ix);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void initImage)
template <class ImageIterator, class Accessor, class VALUETYPE> template <class ImageIterator, class Accessor, class VALUETYPE>
void void
initImage(ImageIterator upperleft, ImageIterator lowerright, initImage(ImageIterator upperleft, ImageIterator lowerright,
Accessor a, VALUETYPE v) Accessor a, VALUETYPE const & v)
{ {
int w = lowerright.x - upperleft.x; int w = lowerright.x - upperleft.x;
for(; upperleft.y < lowerright.y; ++upperleft.y) for(; upperleft.y < lowerright.y; ++upperleft.y)
{ {
initLine(upperleft.rowIterator(), initLineImpl(upperleft.rowIterator(), upperleft.rowIterator() + w,
upperleft.rowIterator() + w, a, v); a,
v, typename FunctorTraits<VALUETYPE>::isInitializer())
;
} }
} }
template <class ImageIterator, class Accessor, class VALUETYPE> template <class ImageIterator, class Accessor, class VALUETYPE>
inline inline
void void
initImage(triple<ImageIterator, ImageIterator, Accessor> img, VALUETYPE v) initImage(triple<ImageIterator, ImageIterator, Accessor> img, VALUETYPE con st & v)
{ {
initImage(img.first, img.second, img.third, v); initImage(img.first, img.second, img.third, v);
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* initImage */ /* initImageWithFunctor */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Write the result of a functor call to every pixel in an image or rectangular ROI. /** \brief Write the result of a functor call to every pixel in an image or rectangular ROI.
This function can be used to init the image by calling the given This function can be used to init the image by calling the given
functor for each pixel. functor for each pixel. It uses an accessor to access the pixel data. T
It uses an accessor to access the pixel data. he functor is
passed by reference, so that its internal state can be updated in each
call.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor, class FUNCTOR> template <class ImageIterator, class Accessor, class FUNCTOR>
void void
initImageWithFunctor(ImageIterator upperleft, ImageIterator lowerri ght, initImageWithFunctor(ImageIterator upperleft, ImageIterator lowerri ght,
Accessor a, FUNCTOR f); Accessor a, FUNCTOR & f);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor, class FUNCTOR> template <class ImageIterator, class Accessor, class FUNCTOR>
void void
initImageWithFunctor(triple<ImageIterator, ImageIterator, Accessor> img, FUNCTOR f); initImageWithFunctor(triple<ImageIterator, ImageIterator, Accessor> img, FUNCTOR & f);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="initimage_8hxx-source.html">vigra/initim age.hxx</a>"<br> <b>\#include</b> \<<a href="initimage_8hxx-source.html">vigra/initi mage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
struct Counter { struct Counter {
Counter() : count(0) {} Counter() : count(0) {}
int operator()() const { return count++; } int operator()() const { return count++; }
mutable int count; mutable int count;
}; };
vigra::IImage img(100, 100); vigra::IImage img(100, 100);
// write the current count in every pixel // write the current count in every pixel
vigra::initImageWithFunctor(destImageRange(img), Counter()); Counter counter;
vigra::initImageWithFunctor(destImageRange(img), counter);
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
\code \code
ImageIterator upperleft, lowerright; ImageIterator upperleft, lowerright;
ImageIterator::row_iterator ix = upperleft.rowIterator(); ImageIterator::row_iterator ix = upperleft.rowIterator();
Accessor accessor; Accessor accessor;
Functor f; Functor f;
accessor.set(f(), ix); accessor.set(f(), ix);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void initImageWithFunctor)
template <class ImageIterator, class Accessor, class FUNCTOR> template <class ImageIterator, class Accessor, class FUNCTOR>
void void
initImageWithFunctor(ImageIterator upperleft, ImageIterator lowerright, initImageWithFunctor(ImageIterator upperleft, ImageIterator lowerright,
Accessor a, FUNCTOR f) Accessor a, FUNCTOR & f)
{ {
int w = lowerright.x - upperleft.x; int w = lowerright.x - upperleft.x;
for(; upperleft.y < lowerright.y; ++upperleft.y) for(; upperleft.y < lowerright.y; ++upperleft.y)
{ {
initLineFunctor(upperleft.rowIterator(), initLineFunctor(upperleft.rowIterator(), upperleft.rowIterator() +
upperleft.rowIterator() + w, a, f); w, a, f);
} }
} }
template <class ImageIterator, class Accessor, class FUNCTOR> template <class ImageIterator, class Accessor, class FUNCTOR>
inline inline
void void
initImageWithFunctor(triple<ImageIterator, ImageIterator, Accessor> img, FU NCTOR f) initImageWithFunctor(triple<ImageIterator, ImageIterator, Accessor> img, FU NCTOR & f)
{ {
initImageWithFunctor(img.first, img.second, img.third, f); initImageWithFunctor(img.first, img.second, img.third, f);
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* initImageIf */ /* initImageIf */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Write value to pixel in the image if mask is true. /** \brief Write value to pixel in the image if mask is true.
This function can be used to init a region-of-interest of the image. This function can be used to init a region-of-interest of the image.
It uses an accessor to access the pixel data. It uses an accessor to access the pixel data.
The initial value can either be a constant of appropriate type (compati
ble with
the destination's value_type), or a functor with compatible result_type
. These two
cases are automatically distinguished when <tt>FunctorTraits<FUNCTOR>::
isInitializer</tt>
yields <tt>VigraTrueType</tt>. Since the functor is passed by <tt>const
</tt> reference, its
<tt>operator()</tt> must be const, and its internal state may need to b
e <tt>mutable</tt>.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor, template <class ImageIterator, class Accessor,
class MaskImageIterator, class MaskAccessor, class MaskImageIterator, class MaskAccessor,
class VALUETYPE> class VALUETYPE>
void void initImageIf(ImageIterator upperleft, ImageIterator lowerright,
initImageIf(ImageIterator upperleft, ImageIterator lowerright, Acce Accessor a,
ssor a, MaskImageIterator mask_upperleft, MaskAccessor ma,
MaskImageIterator mask_upperleft, MaskAccessor ma, VALUETYPE const & v);
VALUETYPE v)
template <class ImageIterator, class Accessor,
class MaskImageIterator, class MaskAccessor,
class FUNCTOR>
void initImageIf(ImageIterator upperleft, ImageIterator lowerright,
Accessor a,
MaskImageIterator mask_upperleft, MaskAccessor ma,
FUNCTOR const & v);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor, template <class ImageIterator, class Accessor,
class MaskImageIterator, class MaskAccessor, class MaskImageIterator, class MaskAccessor,
class VALUETYPE> class VALUETYPE>
void void initImageIf(triple<ImageIterator, ImageIterator, Accessor> img
initImageIf(triple<ImageIterator, ImageIterator, Accessor> img, ,
pair<MaskImageIterator, MaskAccessor> mask, pair<MaskImageIterator, MaskAccessor> mask,
VALUETYPE v) VALUETYPE const & v);
template <class ImageIterator, class Accessor,
class MaskImageIterator, class MaskAccessor,
class FUNCTOR>
void initImageIf(triple<ImageIterator, ImageIterator, Accessor> img
,
pair<MaskImageIterator, MaskAccessor> mask,
FUNCTOR const & v);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="initimage_8hxx-source.html">vigra/initim age.hxx</a>"<br> <b>\#include</b> \<<a href="initimage_8hxx-source.html">vigra/initi mage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage img(100, 100); vigra::BImage img(100, 100);
vigra::BImage mask(100, 100); vigra::BImage mask(100, 100);
// zero the ROI // zero the ROI
vigra::initImageIf(destImageRange(img), vigra::initImageIf(destImageRange(img),
maskImage(mask), maskImage(mask),
vigra::NumericTraits<vigra::BImage::PixelType>::zero()); vigra::NumericTraits<vigra::BImage::PixelType>::zero());
skipping to change at line 379 skipping to change at line 433
MaskImageIterator::row_iterator mx = mask_upperleft.rowIterator(); MaskImageIterator::row_iterator mx = mask_upperleft.rowIterator();
Accessor accessor; Accessor accessor;
MaskAccessor mask_accessor; MaskAccessor mask_accessor;
VALUETYPE v; VALUETYPE v;
if(mask_accessor(mx)) accessor.set(v, ix); if(mask_accessor(mx)) accessor.set(v, ix);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void initImageIf)
template <class ImageIterator, class Accessor, template <class ImageIterator, class Accessor,
class MaskImageIterator, class MaskAccessor, class MaskImageIterator, class MaskAccessor,
class VALUETYPE> class VALUETYPE>
void void
initImageIf(ImageIterator upperleft, ImageIterator lowerright, Accessor a, initImageIf(ImageIterator upperleft, ImageIterator lowerright, Accessor a,
MaskImageIterator mask_upperleft, MaskAccessor ma, MaskImageIterator mask_upperleft, MaskAccessor ma,
VALUETYPE v) VALUETYPE const & v)
{ {
int w = lowerright.x - upperleft.x; int w = lowerright.x - upperleft.x;
for(; upperleft.y < lowerright.y; ++upperleft.y, ++mask_upperleft.y) for(; upperleft.y < lowerright.y; ++upperleft.y, ++mask_upperleft.y)
{ {
initLineIf(upperleft.rowIterator(), initLineIfImpl(upperleft.rowIterator(),
upperleft.rowIterator() + w, a, upperleft.rowIterator() + w, a,
mask_upperleft.rowIterator(), ma, v); mask_upperleft.rowIterator(), ma,
v, typename FunctorTraits<VALUETYPE>::isInitializer());
} }
} }
template <class ImageIterator, class Accessor, template <class ImageIterator, class Accessor,
class MaskImageIterator, class MaskAccessor, class MaskImageIterator, class MaskAccessor,
class VALUETYPE> class VALUETYPE>
inline inline
void void
initImageIf(triple<ImageIterator, ImageIterator, Accessor> img, initImageIf(triple<ImageIterator, ImageIterator, Accessor> img,
pair<MaskImageIterator, MaskAccessor> mask, pair<MaskImageIterator, MaskAccessor> mask,
VALUETYPE v) VALUETYPE const & v)
{ {
initImageIf(img.first, img.second, img.third, mask.first, mask.second, v); initImageIf(img.first, img.second, img.third, mask.first, mask.second, v);
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* initImageBorder */ /* initImageBorder */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Write value to the specified border pixels in the image. /** \brief Write value to the specified border pixels in the image.
A pixel is initialized if its distance to the border A pixel is initialized if its distance to the border
is at most 'borderwidth'. is at most 'borderwidth'. It uses an accessor to access the pixel data.
It uses an accessor to access the pixel data.
The initial value can either be a constant of appropriate type (compati
ble with
the destination's value_type), or a functor with compatible result_type
. These two
cases are automatically distinguished when <tt>FunctorTraits<FUNCTOR>::
isInitializer</tt>
yields <tt>VigraTrueType</tt>. Since the functor is passed by <tt>const
</tt> reference, its
<tt>operator()</tt> must be const, and its internal state may need to b
e <tt>mutable</tt>.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor, class VALUETYPE> template <class ImageIterator, class Accessor, class VALUETYPE>
void void initImageBorder(ImageIterator upperleft, ImageIterator lowerri
initImageBorder(ImageIterator upperleft, ImageIterator lowerright, ght, Accessor a,
Accessor a, int border_width, VALUETYPE v) int border_width, VALUETYPE const & v);
template <class ImageIterator, class Accessor, class FUNCTOR>
void initImageBorder(ImageIterator upperleft, ImageIterator lowerri
ght, Accessor a,
int border_width, FUNCTOR const & v);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor, class VALUETYPE> template <class ImageIterator, class Accessor, class VALUETYPE>
void void initImageBorder(triple<ImageIterator, ImageIterator, Accessor>
initImageBorder(triple<ImageIterator, ImageIterator, Accessor> img, img,
int border_width, VALUETYPE v) int border_width, VALUETYPE const & v);
template <class ImageIterator, class Accessor, class FUNCTOR>
void initImageBorder(triple<ImageIterator, ImageIterator, Accessor>
img,
int border_width, FUNCTOR const & v);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="initimage_8hxx-source.html">vigra/initim age.hxx</a>"<br> <b>\#include</b> \<<a href="initimage_8hxx-source.html">vigra/initi mage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage img(100, 100); vigra::BImage img(100, 100);
// zero a border of 5 pixel // zero a border of 5 pixel
vigra::initImageBorder(destImageRange(img), vigra::initImageBorder(destImageRange(img),
5, vigra::NumericTraits<vigra::BImage::PixelType>::zero ()); 5, vigra::NumericTraits<vigra::BImage::PixelType>::zero ());
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
see \ref initImage() see \ref initImage()
*/ */
doxygen_overloaded_function(template <...> void initImageBorder)
template <class ImageIterator, class Accessor, class VALUETYPE> template <class ImageIterator, class Accessor, class VALUETYPE>
inline inline
void void
initImageBorder(ImageIterator upperleft, ImageIterator lowerright, initImageBorder(ImageIterator upperleft, ImageIterator lowerright,
Accessor a, int border_width, VALUETYPE v) Accessor a, int border_width, VALUETYPE const & v)
{ {
int w = lowerright.x - upperleft.x; int w = lowerright.x - upperleft.x;
int h = lowerright.y - upperleft.y; int h = lowerright.y - upperleft.y;
int hb = (border_width > h) ? h : border_width; int hb = (border_width > h) ? h : border_width;
int wb = (border_width > w) ? w : border_width; int wb = (border_width > w) ? w : border_width;
initImage(upperleft, upperleft+Diff2D(w,hb), a, v); initImage(upperleft, upperleft+Diff2D(w,hb), a, v);
initImage(upperleft, upperleft+Diff2D(wb,h), a, v); initImage(upperleft, upperleft+Diff2D(wb,h), a, v);
initImage(upperleft+Diff2D(0,h-hb), lowerright, a, v); initImage(upperleft+Diff2D(0,h-hb), lowerright, a, v);
initImage(upperleft+Diff2D(w-wb,0), lowerright, a, v); initImage(upperleft+Diff2D(w-wb,0), lowerright, a, v);
} }
template <class ImageIterator, class Accessor, class VALUETYPE> template <class ImageIterator, class Accessor, class VALUETYPE>
inline inline
void void
initImageBorder(triple<ImageIterator, ImageIterator, Accessor> img, initImageBorder(triple<ImageIterator, ImageIterator, Accessor> img,
int border_width, VALUETYPE v) int border_width, VALUETYPE const & v)
{ {
initImageBorder(img.first, img.second, img.third, border_width, v); initImageBorder(img.first, img.second, img.third, border_width, v);
} }
//@} //@}
} // namespace vigra } // namespace vigra
#endif // VIGRA_INITIMAGE_HXX #endif // VIGRA_INITIMAGE_HXX
 End of changes. 55 change blocks. 
75 lines changed or deleted 172 lines changed or added


 inspectimage.hxx   inspectimage.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 41 skipping to change at line 41
/* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
/* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
/* OTHER DEALINGS IN THE SOFTWARE. */ /* OTHER DEALINGS IN THE SOFTWARE. */
/* */ /* */
/************************************************************************/ /************************************************************************/
#ifndef VIGRA_INSPECTIMAGE_HXX #ifndef VIGRA_INSPECTIMAGE_HXX
#define VIGRA_INSPECTIMAGE_HXX #define VIGRA_INSPECTIMAGE_HXX
#pragma warning (disable: 4350)
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include "utilities.hxx" #include "utilities.hxx"
#include "numerictraits.hxx" #include "numerictraits.hxx"
#include "iteratortraits.hxx" #include "iteratortraits.hxx"
#include "functortraits.hxx" #include "functortraits.hxx"
#include "rgbvalue.hxx" #include "rgbvalue.hxx"
namespace vigra { namespace vigra {
skipping to change at line 141 skipping to change at line 143
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor, class Functor> template <class ImageIterator, class Accessor, class Functor>
void void
inspectImage(ImageIterator upperleft, ImageIterator lowerright, inspectImage(ImageIterator upperleft, ImageIterator lowerright,
Accessor a, Functor & f) Accessor a, Functor & f)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor, class Functor> template <class ImageIterator, class Accessor, class Functor>
void void
inspectImage(triple<ImageIterator, ImageIterator, Accessor> img, inspectImage(triple<ImageIterator, ImageIterator, Accessor> img,
Functor & f) Functor & f)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/ins pectimage.hxx</a>"<br> <b>\#include</b> \<<a href="inspectimage_8hxx-source.html">vigra/in spectimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
// init functor // init functor
vigra::BImage img; vigra::BImage img;
vigra::FindMinMax<vigra::BImage::PixelType> minmax; vigra::FindMinMax<vigra::BImage::PixelType> minmax;
vigra::inspectImage(srcImageRange(img), minmax); vigra::inspectImage(srcImageRange(img), minmax);
skipping to change at line 181 skipping to change at line 183
ConstImageIterator upperleft, lowerright; ConstImageIterator upperleft, lowerright;
ConstImageIterator::row_iterator ix = upperleft.rowIterator(); ConstImageIterator::row_iterator ix = upperleft.rowIterator();
Accessor accessor; Accessor accessor;
Functor functor; Functor functor;
functor(accessor(ix)); // return not used functor(accessor(ix)); // return not used
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void inspectImage)
template <class ImageIterator, class Accessor, class Functor> template <class ImageIterator, class Accessor, class Functor>
void void
inspectImage(ImageIterator upperleft, ImageIterator lowerright, inspectImage(ImageIterator upperleft, ImageIterator lowerright,
Accessor a, Functor & f) Accessor a, Functor & f)
{ {
int w = lowerright.x - upperleft.x; int w = lowerright.x - upperleft.x;
for(; upperleft.y<lowerright.y; ++upperleft.y) for(; upperleft.y<lowerright.y; ++upperleft.y)
{ {
inspectLine(upperleft.rowIterator(), inspectLine(upperleft.rowIterator(),
skipping to change at line 258 skipping to change at line 262
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor, template <class ImageIterator, class Accessor,
class MaskImageIterator, class MaskAccessor, class Functo r> class MaskImageIterator, class MaskAccessor, class Functo r>
void void
inspectImageIf(ImageIterator upperleft, ImageIterator lowerright, inspectImageIf(ImageIterator upperleft, ImageIterator lowerright,
MaskImageIterator mask_upperleft, MaskAccessor ma, MaskImageIterator mask_upperleft, MaskAccessor ma,
Functor & f) Functor & f)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor, template <class ImageIterator, class Accessor,
class MaskImageIterator, class MaskAccessor, class Functor> class MaskImageIterator, class MaskAccessor, class Functor>
void void
inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img, inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img,
pair<MaskImageIterator, MaskAccessor> mask, pair<MaskImageIterator, MaskAccessor> mask,
Functor & f) Functor & f)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/ins pectimage.hxx</a>"<br> <b>\#include</b> \<<a href="inspectimage_8hxx-source.html">vigra/in spectimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage img(100, 100); vigra::BImage img(100, 100);
vigra::BImage mask(100, 100); vigra::BImage mask(100, 100);
// init functor // init functor
vigra::FindMinMax<vigra::BImage::PixelType> minmax(); vigra::FindMinMax<vigra::BImage::PixelType> minmax();
vigra::inspectImageIf(srcImageRange(img), vigra::inspectImageIf(srcImageRange(img),
skipping to change at line 306 skipping to change at line 310
Accessor accessor; Accessor accessor;
MaskAccessor mask_accessor; MaskAccessor mask_accessor;
Functor functor; Functor functor;
if(mask_accessor(mx)) functor(accessor(ix)); if(mask_accessor(mx)) functor(accessor(ix));
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void inspectImageIf)
template <class ImageIterator, class Accessor, template <class ImageIterator, class Accessor,
class MaskImageIterator, class MaskAccessor, class Functor> class MaskImageIterator, class MaskAccessor, class Functor>
void void
inspectImageIf(ImageIterator upperleft, inspectImageIf(ImageIterator upperleft,
ImageIterator lowerright, Accessor a, ImageIterator lowerright, Accessor a,
MaskImageIterator mask_upperleft, MaskAccessor ma, MaskImageIterator mask_upperleft, MaskAccessor ma,
Functor & f) Functor & f)
{ {
int w = lowerright.x - upperleft.x; int w = lowerright.x - upperleft.x;
skipping to change at line 336 skipping to change at line 342
inline inline
void void
inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img, inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img,
pair<MaskImageIterator, MaskAccessor> mask, pair<MaskImageIterator, MaskAccessor> mask,
Functor & f) Functor & f)
{ {
inspectImageIf(img.first, img.second, img.third, inspectImageIf(img.first, img.second, img.third,
mask.first, mask.second, f); mask.first, mask.second, f);
} }
template <class ImageIterator, class Accessor,
class MaskImageIterator, class MaskAccessor, class Functor>
inline void
inspectImageIf(ImageIterator upperleft,
ImageIterator lowerright, Accessor a,
MaskImageIterator mask_upperleft, MaskAccessor ma,
functor::UnaryAnalyser<Functor> const & f)
{
inspectImageIf(upperleft, lowerright, a,
mask_upperleft, ma, const_cast<functor::UnaryAnalyser<Fu
nctor> &>(f));
}
template <class ImageIterator, class Accessor,
class MaskImageIterator, class MaskAccessor, class Functor>
inline void
inspectImageIf(triple<ImageIterator, ImageIterator, Accessor> img,
pair<MaskImageIterator, MaskAccessor> mask,
functor::UnaryAnalyser<Functor> const & f)
{
inspectImageIf(img.first, img.second, img.third,
mask.first, mask.second, const_cast<functor::UnaryAnalys
er<Functor> &>(f));
}
/********************************************************/ /********************************************************/
/* */ /* */
/* inspectTwoImages */ /* inspectTwoImages */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Apply read-only functor to every pixel of both images. /** \brief Apply read-only functor to every pixel of both images.
This function can be used to collect statistics for each region of a This function can be used to collect statistics for each region of a
labeled image, especially in conjunction with labeled image, especially in conjunction with
skipping to change at line 365 skipping to change at line 394
template <class ImageIterator1, class Accessor1, template <class ImageIterator1, class Accessor1,
class ImageIterator2, class Accessor2, class ImageIterator2, class Accessor2,
class Functor> class Functor>
void void
inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerrig ht1, Accessor1 a1, inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerrig ht1, Accessor1 a1,
ImageIterator2 upperleft2, Accessor2 a2, ImageIterator2 upperleft2, Accessor2 a2,
Functor & f) Functor & f)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator1, class Accessor1, template <class ImageIterator1, class Accessor1,
class ImageIterator2, class Accessor2, class ImageIterator2, class Accessor2,
class Functor> class Functor>
void void
inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1, inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
pair<ImageIterator2, Accessor2> img2, pair<ImageIterator2, Accessor2> img2,
Functor & f) Functor & f)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/ins pectimage.hxx</a>"<br> <b>\#include</b> \<<a href="inspectimage_8hxx-source.html">vigra/in spectimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage image1; vigra::BImage image1;
vigra::BImage image2; vigra::BImage image2;
SomeStatisticsFunctor stats(...); // init functor SomeStatisticsFunctor stats(...); // init functor
vigra::inspectTwoImages(srcImageRange(image1), srcImage(image2), vigra::inspectTwoImages(srcImageRange(image1), srcImage(image2),
stats); stats);
skipping to change at line 410 skipping to change at line 439
ImageIterator2::row_iterator ix2 = upperleft2.rowIterator(); ImageIterator2::row_iterator ix2 = upperleft2.rowIterator();
Accessor1 accessor1; Accessor1 accessor1;
Accessor2 accessor2; Accessor2 accessor2;
Functor functor; Functor functor;
functor(accessor1(ix1), accessor2(ix2)); // return not used functor(accessor1(ix1), accessor2(ix2)); // return not used
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void inspectTwoImages)
template <class ImageIterator1, class Accessor1, template <class ImageIterator1, class Accessor1,
class ImageIterator2, class Accessor2, class ImageIterator2, class Accessor2,
class Functor> class Functor>
void void
inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Acc essor1 a1, inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Acc essor1 a1,
ImageIterator2 upperleft2, Accessor2 a2, ImageIterator2 upperleft2, Accessor2 a2,
Functor & f) Functor & f)
{ {
int w = lowerright1.x - upperleft1.x; int w = lowerright1.x - upperleft1.x;
for(; upperleft1.y<lowerright1.y; ++upperleft1.y, ++upperleft2.y) for(; upperleft1.y<lowerright1.y; ++upperleft1.y, ++upperleft2.y)
{ {
inspectTwoLines(upperleft1.rowIterator(), inspectTwoLines(upperleft1.rowIterator(),
upperleft1.rowIterator() + w, a1, upperleft1.rowIterator() + w, a1,
upperleft2.rowIterator(), a2, f); upperleft2.rowIterator(), a2, f);
} }
} }
skipping to change at line 441 skipping to change at line 472
inline inline
void void
inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1, inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
pair<ImageIterator2, Accessor2> img2, pair<ImageIterator2, Accessor2> img2,
Functor & f) Functor & f)
{ {
inspectTwoImages(img1.first, img1.second, img1.third, inspectTwoImages(img1.first, img1.second, img1.third,
img2.first, img2.second, f); img2.first, img2.second, f);
} }
template <class ImageIterator1, class Accessor1,
class ImageIterator2, class Accessor2,
class Functor>
inline void
inspectTwoImages(ImageIterator1 upperleft1, ImageIterator1 lowerright1, Acc
essor1 a1,
ImageIterator2 upperleft2, Accessor2 a2,
functor::UnaryAnalyser<Functor> const & f)
{
inspectTwoImages(upperleft1, lowerright1, a1,
upperleft2, a2, const_cast<functor::UnaryAnalyser<Func
tor> &>(f));
}
template <class ImageIterator1, class Accessor1,
class ImageIterator2, class Accessor2,
class Functor>
inline
void
inspectTwoImages(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
pair<ImageIterator2, Accessor2> img2,
functor::UnaryAnalyser<Functor> const & f)
{
inspectTwoImages(img1.first, img1.second, img1.third,
img2.first, img2.second, const_cast<functor::UnaryAnal
yser<Functor> &>(f));
}
/********************************************************/ /********************************************************/
/* */ /* */
/* inspectTwoImagesIf */ /* inspectTwoImagesIf */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Apply read-only functor to those pixels of both images where /** \brief Apply read-only functor to those pixels of both images where
the mask image is non-zero. the mask image is non-zero.
This function can be used to collect statistics for selected regions of a This function can be used to collect statistics for selected regions of a
skipping to change at line 473 skipping to change at line 529
class MaskImageIterator, class MaskAccessor, class MaskImageIterator, class MaskAccessor,
class Functor> class Functor>
void void
inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerr ight1, Accessor1 a1, inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerr ight1, Accessor1 a1,
ImageIterator2 upperleft2, Accessor2 a2, ImageIterator2 upperleft2, Accessor2 a2,
MaskImageIterator mupperleft, MaskAccessor mask, MaskImageIterator mupperleft, MaskAccessor mask,
Functor & f) Functor & f)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator1, class Accessor1, template <class ImageIterator1, class Accessor1,
class ImageIterator2, class Accessor2, class ImageIterator2, class Accessor2,
class MaskImageIterator, class MaskAccessor, class MaskImageIterator, class MaskAccessor,
class Functor> class Functor>
void void
inspectTwoImagesIf(triple<ImageIterator1, ImageIterator1, Accessor1 > img1, inspectTwoImagesIf(triple<ImageIterator1, ImageIterator1, Accessor1 > img1,
pair<ImageIterator2, Accessor2> img2, pair<ImageIterator2, Accessor2> img2,
pair<MaskImageIterator, MaskAccessor> mimg, pair<MaskImageIterator, MaskAccessor> mimg,
Functor & f) Functor & f)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/ins pectimage.hxx</a>"<br> <b>\#include</b> \<<a href="inspectimage_8hxx-source.html">vigra/in spectimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage image1; vigra::BImage image1;
vigra::BImage image2; vigra::BImage image2;
vigra::BImage maskimage; vigra::BImage maskimage;
SomeStatisticsFunctor stats(...); // init functor SomeStatisticsFunctor stats(...); // init functor
vigra::inspectTwoImagesIf(srcImageRange(image1), srcImage(image2), vigra::inspectTwoImagesIf(srcImageRange(image1), srcImage(image2),
skipping to change at line 525 skipping to change at line 581
Accessor1 accessor1; Accessor1 accessor1;
Accessor2 accessor2; Accessor2 accessor2;
MaskAccessor mask; MaskAccessor mask;
Functor functor; Functor functor;
if(mask(mx)) if(mask(mx))
functor(accessor1(ix1), accessor2(ix2)); functor(accessor1(ix1), accessor2(ix2));
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void inspectTwoImagesIf)
template <class ImageIterator1, class Accessor1, template <class ImageIterator1, class Accessor1,
class ImageIterator2, class Accessor2, class ImageIterator2, class Accessor2,
class MaskImageIterator, class MaskAccessor, class MaskImageIterator, class MaskAccessor,
class Functor> class Functor>
void void
inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1, A ccessor1 a1, inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1, A ccessor1 a1,
ImageIterator2 upperleft2, Accessor2 a2, ImageIterator2 upperleft2, Accessor2 a2,
MaskImageIterator mupperleft, MaskAccessor mask, MaskImageIterator mupperleft, MaskAccessor mask,
Functor & f) Functor & f)
{ {
skipping to change at line 563 skipping to change at line 621
pair<ImageIterator2, Accessor2> img2, pair<ImageIterator2, Accessor2> img2,
pair<MaskImageIterator, MaskAccessor> m, pair<MaskImageIterator, MaskAccessor> m,
Functor & f) Functor & f)
{ {
inspectTwoImagesIf(img1.first, img1.second, img1.third, inspectTwoImagesIf(img1.first, img1.second, img1.third,
img2.first, img2.second, img2.first, img2.second,
m.first, m.second, m.first, m.second,
f); f);
} }
template <class ImageIterator1, class Accessor1,
class ImageIterator2, class Accessor2,
class MaskImageIterator, class MaskAccessor,
class Functor>
inline void
inspectTwoImagesIf(ImageIterator1 upperleft1, ImageIterator1 lowerright1, A
ccessor1 a1,
ImageIterator2 upperleft2, Accessor2 a2,
MaskImageIterator mupperleft, MaskAccessor mask,
functor::UnaryAnalyser<Functor> const & f)
{
inspectTwoImagesIf(upperleft1, lowerright1, a1,
upperleft2, a2,
mupperleft, mask,
const_cast<functor::UnaryAnalyser<Functor> &>(f));
}
template <class ImageIterator1, class Accessor1,
class ImageIterator2, class Accessor2,
class MaskImageIterator, class MaskAccessor,
class Functor>
inline
void
inspectTwoImagesIf(triple<ImageIterator1, ImageIterator1, Accessor1> img1,
pair<ImageIterator2, Accessor2> img2,
pair<MaskImageIterator, MaskAccessor> m,
functor::UnaryAnalyser<Functor> const & f)
{
inspectTwoImagesIf(img1.first, img1.second, img1.third,
img2.first, img2.second,
m.first, m.second,
const_cast<functor::UnaryAnalyser<Functor> &>(f));
}
//@} //@}
/** \addtogroup InspectFunctor Functors To Inspect Images /** \addtogroup InspectFunctor Functors To Inspect Images
Functors which report image statistics Functors which report image statistics
*/ */
//@{ //@{
/********************************************************/ /********************************************************/
/* */ /* */
/* FindMinMax */ /* FindMinMax */
skipping to change at line 585 skipping to change at line 676
/** \brief Find the minimum and maximum pixel value in an image or ROI. /** \brief Find the minimum and maximum pixel value in an image or ROI.
In addition the size of the ROI is calculated. In addition the size of the ROI is calculated.
These functors can also be used in conjunction with These functors can also be used in conjunction with
\ref ArrayOfRegionStatistics to find the extremes of all regions in \ref ArrayOfRegionStatistics to find the extremes of all regions in
a labeled image. a labeled image.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryAnalyser</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryAnalyser</tt> is true (<tt>VigraTrueType</tt> )
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/ins pectimage.hxx</a>"<br> <b>\#include</b> \<<a href="inspectimage_8hxx-source.html">vigra/in spectimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage img; vigra::BImage img;
vigra::FindMinMax<vigra::BImage::PixelType> minmax; // init functor vigra::FindMinMax<vigra::BImage::PixelType> minmax; // init functor
vigra::inspectImage(srcImageRange(img), minmax); vigra::inspectImage(srcImageRange(img), minmax);
cout << "Min: " << minmax.min << " Max: " << minmax.max; cout << "Min: " << minmax.min << " Max: " << minmax.max;
skipping to change at line 633 skipping to change at line 724
*/ */
typedef VALUETYPE result_type; typedef VALUETYPE result_type;
/** \deprecated use argument_type /** \deprecated use argument_type
*/ */
typedef VALUETYPE value_type; typedef VALUETYPE value_type;
/** init min and max /** init min and max
*/ */
FindMinMax() FindMinMax()
: count(0) : min( NumericTraits<value_type>::max() ),
max( NumericTraits<value_type>::min() ),
count(0)
{} {}
/** (re-)init functor (clear min, max) /** (re-)init functor (clear min, max)
*/ */
void reset() void reset()
{ {
count = 0; count = 0;
} }
/** update min and max /** update min and max
skipping to change at line 727 skipping to change at line 820
/** \brief Find the average pixel value in an image or ROI. /** \brief Find the average pixel value in an image or ROI.
In addition the size of the ROI is calculated. In addition the size of the ROI is calculated.
This Functor can also be used in conjunction with This Functor can also be used in conjunction with
\ref ArrayOfRegionStatistics to find the average of all regions in \ref ArrayOfRegionStatistics to find the average of all regions in
a labeled image. a labeled image.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitia lizer</tt> <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitia lizer</tt>
are true (<tt>VigraTrueType<tt>) are true (<tt>VigraTrueType</tt>)
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/ins pectimage.hxx</a>"<br> <b>\#include</b> \<<a href="inspectimage_8hxx-source.html">vigra/in spectimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage img; vigra::BImage img;
vigra::FindAverage<vigra::BImage::PixelType> average; // init functor vigra::FindAverage<vigra::BImage::PixelType> average; // init functor
vigra::inspectImage(srcImageRange(img), average); vigra::inspectImage(srcImageRange(img), average);
cout << "Average: " << average(); cout << "Average: " << average();
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
\code \code
VALUETYPE v1, v2(v1); VALUETYPE v1, v2(v1);
double d;
v1 < v2; v1 += v2;
v1 = v2; v1 / d;
\endcode \endcode
*/ */
template <class VALUETYPE> template <class VALUETYPE>
class FindAverage class FindAverage
{ {
public: public:
/** the functor's argument type /** the functor's argument type
*/ */
typedef VALUETYPE argument_type; typedef VALUETYPE argument_type;
/** the functor's first argument type (for calls with a weight)
*/
typedef VALUETYPE first_argument_type;
/** the functor's second argument type (for calls with a weight)
*/
typedef double second_argument_type;
/** the functor's result type /** the functor's result type
*/ */
typedef typename NumericTraits<VALUETYPE>::RealPromote result_type; typedef typename NumericTraits<VALUETYPE>::RealPromote result_type;
/** \deprecated use argument_type and result_type /** \deprecated use argument_type and result_type
*/ */
typedef typename NumericTraits<VALUETYPE>::RealPromote value_type; typedef typename NumericTraits<VALUETYPE>::RealPromote value_type;
/** init average /** init average
*/ */
FindAverage() FindAverage()
: count(0), sum(NumericTraits<result_type>::zero()) : sum_(NumericTraits<result_type>::zero()), count_(0)
{} {}
/** (re-)init average /** (re-)init average
*/ */
void reset() void reset()
{ {
count = 0; count_ = 0;
sum = NumericTraits<result_type>::zero(); sum_ = NumericTraits<result_type>::zero();
} }
/** update average /** update average
*/ */
void operator()(argument_type const & v) void operator()(argument_type const & v)
{ {
sum += v; sum_ += v;
++count; ++count_;
}
/** update average, using weighted input.
* <tt>stats(value, 1.0)</tt> is equivalent to the unweighted
* call <tt>stats(value)</tt>, and <tt>stats(value, 2.0)</tt>
* is equivalent to two unweighted calls.
*/
void operator()(first_argument_type const & v, second_argument_type wei
ght)
{
sum_ += v * weight;
count_ += weight;
} }
/** merge two statistics /** merge two statistics
*/ */
void operator()(FindAverage const & v) void operator()(FindAverage const & v)
{ {
sum += v.sum; sum_ += v.sum_;
count += v.count; count_ += v.count_;
}
/** return number of values (sum of weights) seen so far
*/
double count() const
{
return count_;
} }
/** return current average /** return current average
*/ */
result_type average() const result_type average() const
{ {
return sum / (double)count; return sum_ / (double)count_;
} }
/** return current average /** return current average
*/ */
result_type operator()() const result_type operator()() const
{ {
return sum / (double)count; return sum_ / (double)count_;
} }
unsigned int count; result_type sum_;
result_type sum; double count_;
}; };
template <class VALUETYPE> template <class VALUETYPE>
class FunctorTraits<FindAverage<VALUETYPE> > class FunctorTraits<FindAverage<VALUETYPE> >
: public FunctorTraitsBase<FindAverage<VALUETYPE> > : public FunctorTraitsBase<FindAverage<VALUETYPE> >
{ {
public: public:
typedef VigraTrueType isInitializer; typedef VigraTrueType isInitializer;
typedef VigraTrueType isUnaryAnalyser; typedef VigraTrueType isUnaryAnalyser;
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* FindAverageAndVariance */
/* */
/********************************************************/
/** \brief Find the average pixel value and its variance in an image or RO
I.
This Functor uses West's algorithm to accumulate highly accurate values
for
the mean and the sum of squared differences of all values seen so far (
the
naive incremental algorithm for the computation of the sum of squares
produces large round-off errors when the mean is much larger than the
standard deviation of the data.) This Functor can also be used in
conjunction with \ref ArrayOfRegionStatistics to find the statistics of
all
regions in a labeled image.
<b> Traits defined:</b>
<tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitia
lizer</tt>
are true (<tt>VigraTrueType</tt>)
<b> Usage:</b>
<b>\#include</b> \<<a href="inspectimage_8hxx-source.html">vigra/in
spectimage.hxx</a>\><br>
Namespace: vigra
\code
vigra::BImage img;
vigra::FindAverageAndVariance<vigra::BImage::PixelType> averageAndVaria
nce; // init functor
vigra::inspectImage(srcImageRange(img), averageAndVariance);
cout << "Average: " << averageAndVariance.average() << "\n";
cout << "Standard deviation: " << sqrt(averageAndVariance.variance()) <
< "\n";
\endcode
<b> Required Interface:</b>
\code
VALUETYPE v1, v2(v1);
double d;
v1 += v2;
v1 + v2;
v1 - v2;
v1 * v2;
v1 / d;
d * v1;
\endcode
*/
template <class VALUETYPE>
class FindAverageAndVariance
{
public:
/** the functor's argument type
*/
typedef VALUETYPE argument_type;
/** the functor's first argument type (for calls with a weight)
*/
typedef VALUETYPE first_argument_type;
/** the functor's second argument type (for calls with a weight)
*/
typedef double second_argument_type;
/** the functor's result type
*/
typedef typename NumericTraits<VALUETYPE>::RealPromote result_type;
/** \deprecated use argument_type and result_type
*/
typedef typename NumericTraits<VALUETYPE>::RealPromote value_type;
/** init average
*/
FindAverageAndVariance()
: mean_(NumericTraits<result_type>::zero()),
sumOfSquaredDifferences_(NumericTraits<result_type>::zero()),
count_(0.0)
{}
/** (re-)init average and variance
*/
void reset()
{
count_ = 0.0;
mean_ = NumericTraits<result_type>::zero();
sumOfSquaredDifferences_ = NumericTraits<result_type>::zero();
}
/** update average and variance
*/
void operator()(argument_type const & v)
{
++count_;
result_type t1 = v - mean_;
result_type t2 = t1 / count_;
mean_ += t2;
sumOfSquaredDifferences_ += (count_-1.0)*t1*t2;
}
/** update average and variance, using weighted input.
* <tt>stats(value, 1.0)</tt> is equivalent to the unweighted
* call <tt>stats(value)</tt>, and <tt>stats(value, 2.0)</tt>
* is equivalent to two unweighted calls.
*/
void operator()(first_argument_type const & v, second_argument_type wei
ght)
{
count_ += weight;
result_type t1 = v - mean_;
result_type t2 = t1 * weight / count_;
mean_ += t2;
//sumOfSquaredDifferences_ += (count_ - weight)*t1*t2;
if(count_ > weight)
sumOfSquaredDifferences_ +=
(t1 * t1 * weight / count_) * (count_ - weight );
}
/** merge two statistics
*/
void operator()(FindAverageAndVariance const & v)
{
double newCount = count_ + v.count_;
sumOfSquaredDifferences_ += v.sumOfSquaredDifferences_ +
count_ / newCount * v.count_ * (mean_ -
v.mean_) * (mean_ - v.mean_);
mean_ = (count_ * mean_ + v.count_ * v.mean_) / newCount;
count_ += v.count_;
}
/** return number of values (sum of weights) seen so far
*/
unsigned int count() const
{
return (unsigned int)count_;
}
/** return current average
*/
result_type average() const
{
return mean_;
}
/** return current variance.
If <tt>unbiased = true</tt>, the sum of squared differences
is divided by <tt>count()-1</tt> instead of just <tt>count()</t
t>.
*/
result_type variance(bool unbiased = false) const
{
return unbiased
? sumOfSquaredDifferences_ / (count_ - 1.0)
: sumOfSquaredDifferences_ / count_;
}
/** return current variance. calls <tt>variance()</tt>.
*/
result_type operator()() const
{
return variance();
}
result_type mean_, sumOfSquaredDifferences_;
double count_;
};
template <class VALUETYPE>
class FunctorTraits<FindAverageAndVariance<VALUETYPE> >
: public FunctorTraitsBase<FindAverageAndVariance<VALUETYPE> >
{
public:
typedef VigraTrueType isInitializer;
typedef VigraTrueType isUnaryAnalyser;
};
/********************************************************/
/* */
/* FindROISize */ /* FindROISize */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Calculate the size of an ROI in an image. /** \brief Calculate the size of an ROI in an image.
This Functor is often used in conjunction with This Functor is often used in conjunction with
\ref ArrayOfRegionStatistics to find the sizes of all regions in \ref ArrayOfRegionStatistics to find the sizes of all regions in
a labeled image. a labeled image.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitia lizer</tt> <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitia lizer</tt>
are true (<tt>VigraTrueType<tt>) are true (<tt>VigraTrueType</tt>)
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/inspect image.hxx</a>"<br> <b>\#include</b> \<<a href="inspectimage_8hxx-source.html">vigra/inspec timage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage img, mask; vigra::BImage img, mask;
vigra::FindROISize<vigra::BImage::PixelType> roisize; // init functor vigra::FindROISize<vigra::BImage::PixelType> roisize; // init functor
vigra::inspectImageIf(srcImageRange(img), srcImage(mask), roisize); vigra::inspectImageIf(srcImageRange(img), srcImage(mask), roisize);
cout << "Size of ROI: " << roisize.count; cout << "Size of ROI: " << roisize.count;
skipping to change at line 954 skipping to change at line 1254
As always in VIGRA, <TT>roiRect.lowerRight</TT> is <em> just outside th e rectangle</em>. As always in VIGRA, <TT>roiRect.lowerRight</TT> is <em> just outside th e rectangle</em>.
That is, the last pixel actually in the rectangle is <TT>roiRect.lowerR ight - Diff2D(1,1)</TT>. That is, the last pixel actually in the rectangle is <TT>roiRect.lowerR ight - Diff2D(1,1)</TT>.
This Functor is often used in conjunction with This Functor is often used in conjunction with
\ref ArrayOfRegionStatistics to find the bounding rectangles \ref ArrayOfRegionStatistics to find the bounding rectangles
of all regions in a labeled image. of all regions in a labeled image.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitia lizer</tt> <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitia lizer</tt>
are true (<tt>VigraTrueType<tt>) are true (<tt>VigraTrueType</tt>)
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/inspect image.hxx</a>"<br> <b>\#include</b> \<<a href="inspectimage_8hxx-source.html">vigra/inspec timage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage img, mask; vigra::BImage img, mask;
... ...
vigra::FindBoundingRectangle roiRect; // init functor vigra::FindBoundingRectangle roiRect; // init functor
// Diff2D is used as the iterator for the source image. This // Diff2D is used as the iterator for the source image. This
// simulates an image where each pixel value equals that pixel's // simulates an image where each pixel value equals that pixel's
skipping to change at line 1100 skipping to change at line 1400
/********************************************************/ /********************************************************/
/** \brief Stores and returns the last value it has seen. /** \brief Stores and returns the last value it has seen.
This Functor is best used in conjunction with This Functor is best used in conjunction with
\ref ArrayOfRegionStatistics to realize a look-up table. \ref ArrayOfRegionStatistics to realize a look-up table.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitia lizer</tt> <tt>FunctorTraits::isUnaryAnalyser</tt> and <tt>FunctorTraits::isInitia lizer</tt>
are true (<tt>VigraTrueType<tt>) are true (<tt>VigraTrueType</tt>)
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/inspect image.hxx</a>"<br> <b>\#include</b> \<<a href="inspectimage_8hxx-source.html">vigra/inspec timage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage img; vigra::BImage img;
vigra::ArrayOfRegionStatistics<LastValueFunctor<unsigned char> > lut(25 5); vigra::ArrayOfRegionStatistics<LastValueFunctor<unsigned char> > lut(25 5);
for(int i=0; i<256; ++i) for(int i=0; i<256; ++i)
{ {
lut[i] = ...; // init look-up table lut[i] = ...; // init look-up table
skipping to change at line 1139 skipping to change at line 1439
typedef VALUETYPE argument_type; typedef VALUETYPE argument_type;
/** the functor's result type /** the functor's result type
*/ */
typedef VALUETYPE result_type; typedef VALUETYPE result_type;
/** \deprecated use argument_type and result_type /** \deprecated use argument_type and result_type
*/ */
typedef VALUETYPE value_type; typedef VALUETYPE value_type;
/** default initialization of value /** default construction of value (i.e. builtin types will be set t o zero)
*/ */
LastValueFunctor() LastValueFunctor(argument_type const &initial = argument_type())
: value(initial)
{} {}
/** replace value /** replace value
*/ */
void operator=(argument_type const & v) { value = v; } void operator=(argument_type const & v) { value = v; }
/** reset to initia /** reset to initial value (the same as after default construction)
*/ */
void reset() { value = VALUETYPE(); } void reset() { value = VALUETYPE(); }
/** replace value /** replace value
*/ */
void operator()(argument_type const & v) { value = v; } void operator()(argument_type const & v) { value = v; }
/** return current value /** return current value
*/ */
result_type const & operator()() const { return value; } result_type const & operator()() const { return value; }
skipping to change at line 1195 skipping to change at line 1496
and similar functions. This functor is initialized with a functor encod ing and similar functions. This functor is initialized with a functor encod ing
the expression to be applied, and an accumulator storing the current st ate the expression to be applied, and an accumulator storing the current st ate
of the reduction. For each element of the array, the embedded functor i s called of the reduction. For each element of the array, the embedded functor i s called
with the accumulator and the current element(s) of the array. The resul t with the accumulator and the current element(s) of the array. The resul t
of the reduction is available by calling <tt>reduceFunctor()</tt>. of the reduction is available by calling <tt>reduceFunctor()</tt>.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryAnalyser</tt>, <tt>FunctorTraits::isBinaryAna lyser</tt> <tt>FunctorTraits::isUnaryAnalyser</tt>, <tt>FunctorTraits::isBinaryAna lyser</tt>
and <tt>FunctorTraits::isInitializer</tt> and <tt>FunctorTraits::isInitializer</tt>
are true (<tt>VigraTrueType<tt>) are true (<tt>VigraTrueType</tt>)
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/inspect image.hxx</a>"<br> <b>\#include</b> \<<a href="inspectimage_8hxx-source.html">vigra/inspec timage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage img; vigra::BImage img;
... // fill the image ... // fill the image
// create a functor to sum the elements of the image // create a functor to sum the elements of the image
vigra::ReduceFunctor<std::plus<int>, int> sumElements(std::plus<int>, 0 ); vigra::ReduceFunctor<std::plus<int>, int> sumElements(std::plus<int>, 0 );
vigra::inspectImage(srcImageRange(img), sumElements); vigra::inspectImage(srcImageRange(img), sumElements);
skipping to change at line 1329 skipping to change at line 1630
/** \brief Calculate statistics for all regions of a labeled image. /** \brief Calculate statistics for all regions of a labeled image.
This Functor encapsulates an array of statistics functors, one This Functor encapsulates an array of statistics functors, one
for each label, and selects the one to be updated according to the for each label, and selects the one to be updated according to the
pixel's label. pixel's label.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isBinaryAnalyser</tt> and <tt>FunctorTraits::isUnary Functor</tt> <tt>FunctorTraits::isBinaryAnalyser</tt> and <tt>FunctorTraits::isUnary Functor</tt>
are true (<tt>VigraTrueType<tt>) are true (<tt>VigraTrueType</tt>)
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="inspectimage_8hxx-source.html">vigra/inspect image.hxx</a>"<br> <b>\#include</b> \<<a href="inspectimage_8hxx-source.html">vigra/inspec timage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage img; vigra::BImage img;
vigra::IImage labels; vigra::IImage labels;
int max_label; int max_label;
... ...
// init functor as an array of 'max_label' FindMinMax-Functors // init functor as an array of 'max_label' FindMinMax-Functors
vigra::ArrayOfRegionStatistics<vigra::FindMinMax<vigra::BImage::PixelTy pe> > vigra::ArrayOfRegionStatistics<vigra::FindMinMax<vigra::BImage::PixelTy pe> >
 End of changes. 49 change blocks. 
45 lines changed or deleted 364 lines changed or added


 interpolating_accessor.hxx   interpolating_accessor.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 65 skipping to change at line 65
/** \brief Bilinear interpolation at non-integer positions. /** \brief Bilinear interpolation at non-integer positions.
This accessor allows an image be accessed at arbitrary non-integer This accessor allows an image be accessed at arbitrary non-integer
coordinates and performs an bi-linear interpolation to coordinates and performs an bi-linear interpolation to
obtain a pixel value. obtain a pixel value.
It uses the given ACCESSOR (which is usually the It uses the given ACCESSOR (which is usually the
accessor originally associated with the iterator) accessor originally associated with the iterator)
to access data. to access data.
<b>\#include</b> "<a href="accessor_8hxx-source.html">vigra/accessor.hx x</a>" <b>\#include</b> \<<a href="accessor_8hxx-source.html">vigra/accessor.h xx</a>\>
Namespace: vigra Namespace: vigra
<b> Required Interface:</b> <b> Required Interface:</b>
\code \code
ITERATOR iter; ITERATOR iter;
ACCESSOR a; ACCESSOR a;
VALUETYPE destvalue; VALUETYPE destvalue;
float s; float s;
int x, y; int x, y;
 End of changes. 3 change blocks. 
4 lines changed or deleted 4 lines changed or added


 iteratoradapter.hxx   iteratoradapter.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 144 skipping to change at line 144
By changing the definition of the policy members, a wide range of By changing the definition of the policy members, a wide range of
adaptor behaviors can be achieved. If the base iterator isn't a adaptor behaviors can be achieved. If the base iterator isn't a
random access iterator, just drop the functions that cannot be implemen ted. random access iterator, just drop the functions that cannot be implemen ted.
This simply means that some adaptor functions may not be called, This simply means that some adaptor functions may not be called,
as one would expect from an iterator that doesn't support random access . as one would expect from an iterator that doesn't support random access .
Note also that the <TT>BaseType</TT> needs not be an iterator - Note also that the <TT>BaseType</TT> needs not be an iterator -
it can be any type that contains the information necessary for the it can be any type that contains the information necessary for the
adaptor to do it's work. adaptor to do it's work.
<b>\#include</b> "<a href="iteratoradapter_8hxx-source.html">vigra/iter atoradapter.hxx</a>"<br> <b>\#include</b> \<<a href="iteratoradapter_8hxx-source.html">vigra/ite ratoradapter.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class Policy> template <class Policy>
class IteratorAdaptor class IteratorAdaptor
{ {
public: public:
typedef typename Policy::BaseType BaseType; typedef typename Policy::BaseType BaseType;
typedef typename Policy::value_type value_type; typedef typename Policy::value_type value_type;
 End of changes. 3 change blocks. 
4 lines changed or deleted 4 lines changed or added


 iteratortags.hxx   iteratortags.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2003 by Ullrich Koethe */ /* Copyright 1998-2003 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
 End of changes. 2 change blocks. 
3 lines changed or deleted 3 lines changed or added


 iteratortraits.hxx   iteratortraits.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 67 skipping to change at line 67
typedef T Iterator; typedef T Iterator;
typedef Iterator iterator; typedef Iterator iterator;
typedef typename iterator::iterator_category iterator_category; typedef typename iterator::iterator_category iterator_category;
typedef typename iterator::value_type value_type; typedef typename iterator::value_type value_type;
typedef typename iterator::reference reference; typedef typename iterator::reference reference;
typedef typename iterator::index_reference index_reference; typedef typename iterator::index_reference index_reference;
typedef typename iterator::pointer pointer; typedef typename iterator::pointer pointer;
typedef typename iterator::difference_type difference_type; typedef typename iterator::difference_type difference_type;
typedef typename iterator::row_iterator row_iterator; typedef typename iterator::row_iterator row_iterator;
typedef typename iterator::column_iterator column_iterator; typedef typename iterator::column_iterator column_iterator;
typedef StandardAccessor<value_type> DefaultAccessor; typedef typename
typedef StandardAccessor<value_type> default_accessor; AccessorTraits<value_type>::default_accessor DefaultAccessor;
typedef DefaultAccessor default_accessor;
typedef VigraTrueType/VigraFalseType hasConstantStrides; typedef VigraTrueType/VigraFalseType hasConstantStrides;
}; };
\endcode \endcode
By (partially) specializing this template for an iterator class By (partially) specializing this template for an iterator class
the defaults given above can be changed as appropriate. For example, it erators the defaults given above can be changed as appropriate. For example, it erators
for rgb images are associated with <TT>RGBAccessor<value_type></TT> for rgb images are associated with <TT>RGBAccessor<value_type></TT>
instead of <TT>StandardAccessor<value_type></TT>. To get the accessor instead of <TT>StandardAccessor<value_type></TT>. To get the accessor
associated with a given iterator, use code like this: associated with a given iterator, use code like this:
skipping to change at line 97 skipping to change at line 98
} }
\endcode \endcode
This technique is, for example, used by the This technique is, for example, used by the
\ref IteratorBasedArgumentObjectFactories. The possibility to retrieve the default accessor by means of a traits \ref IteratorBasedArgumentObjectFactories. The possibility to retrieve the default accessor by means of a traits
class is especially important since this information is not class is especially important since this information is not
contained in the iterator directly. contained in the iterator directly.
The member <tt>hasConstantStrides</tt> is useful for certain The member <tt>hasConstantStrides</tt> is useful for certain
optimizations: it helps to decide whether we can replace iterator optimizations: it helps to decide whether we can replace iterator
operations such as <tt>iter++</tt> ot <tt>iter =+ n</tt> with operations such as <tt>iter++</tt> or <tt>iter += n</tt> with
corresponding pointer operations (which may be faster), where corresponding pointer operations (which may be faster), where
the pointer is obtained as the address of iterator's pointee the pointer is obtained as the address of iterator's pointee
(the object the iterator currently refers to). (the object the iterator currently refers to).
This flag would be tt>VigraFalseType</tt> for a This flag would be <tt>VigraFalseType</tt> for a
<tt>std::list&lt;int&gt;::iterator</tt>, but is <tt>VigraTrueType</tt> <tt>std::list<int>::iterator</tt>, but is <tt>VigraTrueType</tt>
for most VIGRA iterators. for most VIGRA iterators.
<b>\#include</b> "<a href="iteratortraits_8hxx-source.html">vigra/itera tortraits.hxx</a>" <b>\#include</b> \<<a href="iteratortraits_8hxx-source.html">vigra/iter atortraits.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class T> template <class T>
struct IteratorTraits struct IteratorTraits
{ {
typedef T Iterator; typedef T Iterator;
typedef Iterator iterator; typedef Iterator iterator;
typedef typename iterator::iterator_category iterator_category; typedef typename iterator::iterator_category iterator_category;
typedef typename iterator::value_type value_type; typedef typename iterator::value_type value_type;
typedef typename iterator::reference reference; typedef typename iterator::reference reference;
skipping to change at line 144 skipping to change at line 145
typedef typename iterator::iterator_category iterator_category; typedef typename iterator::iterator_category iterator_category;
typedef typename iterator::value_type value_type; typedef typename iterator::value_type value_type;
typedef typename iterator::reference reference; typedef typename iterator::reference reference;
typedef typename iterator::index_reference index_reference; typedef typename iterator::index_reference index_reference;
typedef typename iterator::pointer pointer; typedef typename iterator::pointer pointer;
typedef typename iterator::difference_type difference_type; typedef typename iterator::difference_type difference_type;
typedef typename iterator::row_iterator row_iterator; typedef typename iterator::row_iterator row_iterator;
typedef typename iterator::column_iterator column_iterator; typedef typename iterator::column_iterator column_iterator;
}; };
//@}
/***********************************************************/ /***********************************************************/
/** \page ArgumentObjectFactories Argument Object Factories /** \page ArgumentObjectFactories Argument Object Factories
Factory functions to create argument objects which simplify long argume nt lists. Factory functions to create argument objects which simplify long argume nt lists.
<DL> <UL style="list-style-image:url(documents/bullet.gif)">
<DT> <LI> \ref ImageBasedArgumentObjectFactories
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref MultiArrayBasedArgumentObjectFactories
\ref ImageBasedArgumentObjectFactories <LI> \ref IteratorBasedArgumentObjectFactories
<DD> </UL>
<DT>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref MultiArrayBasedArgumentObjectFactories
<DD>
<DT>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref IteratorBasedArgumentObjectFactories
<DD>
</DL>
Long argument lists provide for greater flexibility of functions, Long argument lists provide for greater flexibility of functions,
but they are also tedious and error prone, when we don't need but they are also tedious and error prone, when we don't need
the flexibility. Thus, we define argument objects which the flexibility. Thus, we define argument objects which
automatically provide reasonable defaults for those arguments that we automatically provide reasonable defaults for those arguments that we
didn't specify explicitly. didn't specify explicitly.
The argument objects are created via a number of factory functions. The argument objects are created via a number of factory functions.
Since these functions have descriptive names, they also serve Since these functions have descriptive names, they also serve
to improve readability: the name of each factory tells te purpose of it s to improve readability: the name of each factory tells te purpose of it s
skipping to change at line 259 skipping to change at line 253
These factories can be used to create argument objects when we These factories can be used to create argument objects when we
are given instances or subclasses of \ref vigra::BasicImage (see are given instances or subclasses of \ref vigra::BasicImage (see
\ref StandardImageTypes for instances defined per default). \ref StandardImageTypes for instances defined per default).
These factory functions access <TT>img.upperLeft()</TT>, These factory functions access <TT>img.upperLeft()</TT>,
<TT>img.lowerRight()</TT>, and <TT>img.accessor()</TT> to obtain the it erators <TT>img.lowerRight()</TT>, and <TT>img.accessor()</TT> to obtain the it erators
and accessor for the given image (unless the accessor is and accessor for the given image (unless the accessor is
given explicitly). The following factory functions are provided: given explicitly). The following factory functions are provided:
<table> <table>
<tr><td> <tr><th bgcolor="#f0e0c0" colspan=2 align=left>
\htmlonly
<th bgcolor="#f0e0c0" colspan=2 align=left>
\endhtmlonly
<TT>\ref vigra::BasicImage "vigra::BasicImage<SomeType>" img;</TT> or <br> <TT>\ref vigra::BasicImage "vigra::BasicImage<SomeType>" img;</TT> or <br>
<TT>\ref vigra::BasicImageView "vigra::BasicImageView<SomeType>" i mg;</TT> <TT>\ref vigra::BasicImageView "vigra::BasicImageView<SomeType>" i mg;</TT>
\htmlonly
</th> </th>
\endhtmlonly </tr>
</td></tr>
<tr><td> <tr><td>
<TT>srcImageRange(img)</TT> <TT>srcImageRange(img)</TT>
</td><td> </td><td>
create argument object containing upper left, lower right, and create argument object containing upper left, lower right, and
default accessor of source image default accessor of source image
</td></tr> </td></tr>
<tr><td> <tr><td>
skipping to change at line 434 skipping to change at line 423
</td><td> </td><td>
create argument object with upper left at point given by <tt>\ref v igra::Point2D</tt> of destination image, create argument object with upper left at point given by <tt>\ref v igra::Point2D</tt> of destination image,
and given accessor and given accessor
</td></tr> </td></tr>
</table> </table>
\section MultiArrayBasedArgumentObjectFactories MultiArrayView Based Argu ment Object Factories \section MultiArrayBasedArgumentObjectFactories MultiArrayView Based Argu ment Object Factories
<b>Include:</b> automatically included with <b>Include:</b> automatically included with
"<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>"< br> \<<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>\ ><br>
Namespace: vigra Namespace: vigra
These factories can be used to create argument objects when we These factories can be used to create argument objects when we
are given instances or subclasses of \ref vigra::MultiArrayView. are given instances or subclasses of \ref vigra::MultiArrayView.
These factory functions access <TT>array.traverser_begin()</TT>, These factory functions access <TT>array.traverser_begin()</TT>,
<TT>array.traverser_end()</TT> to obtain the iterators. If no accessor is <TT>array.traverser_end()</TT> to obtain the iterators. If no accessor is
given, they use the <tt>AccessorTraits<T></tt> to determine the default given, they use the <tt>AccessorTraits<T></tt> to determine the default
accessor associated with the array's value type <tt>T</tt>. accessor associated with the array's value type <tt>T</tt>.
The following factory functions are provided: The following factory functions are provided:
<table> <table>
<tr><td> <tr><th bgcolor="#f0e0c0" colspan=2 align=left>
\htmlonly
<th bgcolor="#f0e0c0" colspan=2 align=left>
\endhtmlonly
<TT>\ref vigra::MultiArrayView "vigra::MultiArrayView<N, SomeType>" array;</TT> <TT>\ref vigra::MultiArrayView "vigra::MultiArrayView<N, SomeType>" array;</TT>
\htmlonly
</th> </th>
\endhtmlonly </tr>
</td></tr>
<tr><td> <tr><td>
<TT>srcMultiArrayRange(img)</TT> <TT>srcMultiArrayRange(img)</TT>
</td><td> </td><td>
create argument object containing a \ref vigra::MultiIterator create argument object containing a \ref vigra::MultiIterator
marking the begin of the array, a shape object giving the desired marking the begin of the array, a shape object giving the desired
shape of the array (possibly a subarray) and the default const acce ssor for shape of the array (possibly a subarray) and the default const acce ssor for
<tt>SomeType</tt> <tt>SomeType</tt>
</td></tr> </td></tr>
skipping to change at line 531 skipping to change at line 515
<TT>destMultiArray(img, SomeAccessor())</TT> <TT>destMultiArray(img, SomeAccessor())</TT>
</td><td> </td><td>
create argument object containing a \ref vigra::MultiIterator's create argument object containing a \ref vigra::MultiIterator's
marking the begin of the array and the given accessor marking the begin of the array and the given accessor
</td></tr> </td></tr>
</table> </table>
\section IteratorBasedArgumentObjectFactories Iterator Based Argument Obj ect Factories \section IteratorBasedArgumentObjectFactories Iterator Based Argument Obj ect Factories
<b>\#include</b> "<a href="iteratortraits_8hxx-source.html">vigra/itera tortraits.hxx</a>" <b>\#include</b> \<<a href="iteratortraits_8hxx-source.html">vigra/iter atortraits.hxx</a>\>
Namespace: vigra Namespace: vigra
These factories can be used to create argument objects when we These factories can be used to create argument objects when we
are given \ref ImageIterators. are given \ref ImageIterators.
These factory functions use \ref vigra::IteratorTraits to These factory functions use \ref vigra::IteratorTraits to
get the default accessor for the given iterator unless the get the default accessor for the given iterator unless the
accessor is given explicitly. The following factory functions accessor is given explicitly. The following factory functions
are provided: are provided:
<table> <table>
<tr><td> <tr><th bgcolor="#f0e0c0" colspan=2 align=left>
\htmlonly
<th bgcolor="#f0e0c0" colspan=2 align=left>
\endhtmlonly
<TT>\ref vigra::BasicImage::Iterator "vigra::BasicImage<SomeType>:: Iterator" i1, i2;</TT> <TT>\ref vigra::BasicImage::Iterator "vigra::BasicImage<SomeType>:: Iterator" i1, i2;</TT>
\htmlonly
</th> </th>
\endhtmlonly </tr>
</td></tr>
<tr><td> <tr><td>
<TT>srcIterRange(i1, i2)</TT> <TT>srcIterRange(i1, i2)</TT>
</td><td> </td><td>
create argument object containing the given iterators and create argument object containing the given iterators and
corresponding default accessor (for source image) corresponding default accessor (for source image)
</td></tr> </td></tr>
<tr><td> <tr><td>
skipping to change at line 716 skipping to change at line 695
template <class Iterator> template <class Iterator>
inline triple<Iterator, Iterator, typename IteratorTraits<Iterator>::Defaul tAccessor> inline triple<Iterator, Iterator, typename IteratorTraits<Iterator>::Defaul tAccessor>
destIterRange(Iterator const & upperleft, Iterator const & lowerright) destIterRange(Iterator const & upperleft, Iterator const & lowerright)
{ {
return triple<Iterator, Iterator, return triple<Iterator, Iterator,
typename IteratorTraits<Iterator>::DefaultAccessor>( typename IteratorTraits<Iterator>::DefaultAccessor>(
upperleft, lowerright, upperleft, lowerright,
typename IteratorTraits<Iterator>::DefaultAccessor()); typename IteratorTraits<Iterator>::DefaultAccessor());
} }
//@}
} // namespace vigra } // namespace vigra
#endif // VIGRA_ITERATORTRAITS_HXX #endif // VIGRA_ITERATORTRAITS_HXX
 End of changes. 20 change blocks. 
48 lines changed or deleted 25 lines changed or added


 labelimage.hxx   labelimage.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 49 skipping to change at line 49
#define VIGRA_LABELIMAGE_HXX #define VIGRA_LABELIMAGE_HXX
#include <vector> #include <vector>
#include <functional> #include <functional>
#include "utilities.hxx" #include "utilities.hxx"
#include "stdimage.hxx" #include "stdimage.hxx"
namespace vigra { namespace vigra {
/** \addtogroup Labeling Connected Components Labeling /** \addtogroup Labeling Connected Components Labeling
The connected components algorithm may use either 4 or 8 connectivity. The 2-dimensional connected components algorithms may use either 4 or 8 connectivity.
By means of a functor the merge criterium can be defined arbitrarily. By means of a functor the merge criterium can be defined arbitrarily.
*/ */
//@{ //@{
/********************************************************/ /********************************************************/
/* */ /* */
/* labelImage */ /* labelImage */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Find the connected components of a segmented image. /** \brief Find the connected components of a segmented image.
Connected components are defined as regions with uniform pixel
values. Thus, <TT>SrcAccessor::value_type</TT> either must be
equality comparable (first form), or an EqualityFunctor must be
provided that realizes the desired predicate (second form). The
destination's value type should be large enough to hold the labels
without overflow. Region numbers will be a consecutive sequence
starting with one and ending with the region number returned by
the function (inclusive). The parameter '<TT>eight_neighbors</TT>'
determines whether the regions should be 4-connected or
8-connected. The function uses accessors.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
unsigned int labelImage(SrcIterator upperlefts, unsigned int labelImage(SrcIterator upperlefts,
SrcIterator lowerrights, SrcAccessor sa, SrcIterator lowerrights, SrcAccessor sa,
DestIterator upperleftd, DestAccessor da, DestIterator upperleftd, DestAccessor da,
skipping to change at line 95 skipping to change at line 84
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class EqualityFunctor> class EqualityFunctor>
unsigned int labelImage(SrcIterator upperlefts, unsigned int labelImage(SrcIterator upperlefts,
SrcIterator lowerrights, SrcAccessor sa, SrcIterator lowerrights, SrcAccessor sa,
DestIterator upperleftd, DestAccessor da, DestIterator upperleftd, DestAccessor da,
bool eight_neighbors, EqualityFunctor equal ); bool eight_neighbors, EqualityFunctor equal );
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
unsigned int labelImage(triple<SrcIterator, SrcIterator, SrcAccesso r> src, unsigned int labelImage(triple<SrcIterator, SrcIterator, SrcAccesso r> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
bool eight_neighbors); bool eight_neighbors);
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class EqualityFunctor> class EqualityFunctor>
unsigned int labelImage(triple<SrcIterator, SrcIterator, SrcAccesso r> src, unsigned int labelImage(triple<SrcIterator, SrcIterator, SrcAccesso r> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
bool eight_neighbors, EqualityFunctor equal ) bool eight_neighbors, EqualityFunctor equal )
} }
\endcode \endcode
Connected components are defined as regions with uniform pixel
values. Thus, <TT>SrcAccessor::value_type</TT> either must be
equality comparable (first form), or an EqualityFunctor must be
provided that realizes the desired predicate (second form). The
destination's value type should be large enough to hold the labels
without overflow. Region numbers will be a consecutive sequence
starting with one and ending with the region number returned by
the function (inclusive). The parameter '<TT>eight_neighbors</TT>'
determines whether the regions should be 4-connected or
8-connected. The function uses accessors.
Return: the number of regions found (= largest region label) Return: the number of regions found (= largest region label)
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="labelimage_8hxx-source.html">vigra/label image.hxx</a>"<br> <b>\#include</b> \<<a href="labelimage_8hxx-source.html">vigra/labe limage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h); vigra::BImage src(w,h);
vigra::IImage labels(w,h); vigra::IImage labels(w,h);
// threshold at 128 // threshold at 128
vigra::transformImage(srcImageRange(src), destImage(src), vigra::transformImage(srcImageRange(src), destImage(src),
vigra::Threshold<vigra::BImage::PixelType, vigra::BImage::PixelType> ( vigra::Threshold<vigra::BImage::PixelType, vigra::BImage::PixelType> (
128, 256, 0, 255)); 128, 256, 0, 255));
skipping to change at line 154 skipping to change at line 154
u == u // first form u == u // first form
EqualityFunctor equal; // second form EqualityFunctor equal; // second form
equal(u, u) // second form equal(u, u) // second form
int i; int i;
dest_accessor.set(i, dest_upperleft); dest_accessor.set(i, dest_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> unsigned int labelImage)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class EqualityFunctor> class EqualityFunctor>
unsigned int labelImage(SrcIterator upperlefts, unsigned int labelImage(SrcIterator upperlefts,
SrcIterator lowerrights, SrcAccessor sa, SrcIterator lowerrights, SrcAccessor sa,
DestIterator upperleftd, DestAccessor da, DestIterator upperleftd, DestAccessor da,
bool eight_neighbors, EqualityFunctor equal) bool eight_neighbors, EqualityFunctor equal)
{ {
int w = lowerrights.x - upperlefts.x; int w = lowerrights.x - upperlefts.x;
int h = lowerrights.y - upperlefts.y; int h = lowerrights.y - upperlefts.y;
skipping to change at line 340 skipping to change at line 342
/********************************************************/ /********************************************************/
/* */ /* */
/* labelImageWithBackground */ /* labelImageWithBackground */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Find the connected components of a segmented image, /** \brief Find the connected components of a segmented image,
excluding the background from labeling. excluding the background from labeling.
Connected components are defined as regions with uniform pixel
values. Thus, <TT>SrcAccessor::value_type</TT> either must be
equality comparable (first form), or an EqualityFunctor must be
provided that realizes the desired predicate (second form). All
pixel equal to the given '<TT>background_value</TT>' are ignored
when determining connected components and remain untouched in the
destination image and
The destination's value type should be large enough to hold the
labels without overflow. Region numbers will be a consecutive
sequence starting with one and ending with the region number
returned by the function (inclusive). The parameter
'<TT>eight_neighbors</TT>' determines whether the regions should
be 4-connected or 8-connected. The function uses accessors.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class ValueType> class ValueType>
int labelImageWithBackground(SrcIterator upperlefts, int labelImageWithBackground(SrcIterator upperlefts,
SrcIterator lowerrights, SrcAccessor sa, SrcIterator lowerrights, SrcAccessor sa,
skipping to change at line 380 skipping to change at line 367
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class ValueType, class EqualityFunctor> class ValueType, class EqualityFunctor>
int labelImageWithBackground(SrcIterator upperlefts, int labelImageWithBackground(SrcIterator upperlefts,
SrcIterator lowerrights, SrcAccessor sa, SrcIterator lowerrights, SrcAccessor sa,
DestIterator upperleftd, DestAccessor da, DestIterator upperleftd, DestAccessor da,
bool eight_neighbors, bool eight_neighbors,
ValueType background_value, EqualityFunctor equal); ValueType background_value, EqualityFunctor equal);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class ValueType> class ValueType>
inline
int labelImageWithBackground(triple<SrcIterator, SrcIterator, SrcAc cessor> src, int labelImageWithBackground(triple<SrcIterator, SrcIterator, SrcAc cessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
bool eight_neighbors, bool eight_neighbors,
ValueType background_value); ValueType background_value);
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class ValueType, class EqualityFunctor> class ValueType, class EqualityFunctor>
inline
int labelImageWithBackground(triple<SrcIterator, SrcIterator, SrcAc cessor> src, int labelImageWithBackground(triple<SrcIterator, SrcIterator, SrcAc cessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
bool eight_neighbors, bool eight_neighbors,
ValueType background_value, EqualityFu nctor equal); ValueType background_value, EqualityFu nctor equal);
} }
\endcode \endcode
Connected components are defined as regions with uniform pixel
values. Thus, <TT>SrcAccessor::value_type</TT> either must be
equality comparable (first form), or an EqualityFunctor must be
provided that realizes the desired predicate (second form). All
pixel equal to the given '<TT>background_value</TT>' are ignored
when determining connected components and remain untouched in the
destination image and
The destination's value type should be large enough to hold the
labels without overflow. Region numbers will be a consecutive
sequence starting with one and ending with the region number
returned by the function (inclusive). The parameter
'<TT>eight_neighbors</TT>' determines whether the regions should
be 4-connected or 8-connected. The function uses accessors.
Return: the number of regions found (= largest region label) Return: the number of regions found (= largest region label)
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="labelimage_8hxx-source.html">vigra/label image.hxx</a>"<br> <b>\#include</b> \<<a href="labelimage_8hxx-source.html">vigra/labe limage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h); vigra::BImage src(w,h);
vigra::IImage labels(w,h); vigra::IImage labels(w,h);
// threshold at 128 // threshold at 128
vigra::transformImage(srcImageRange(src), destImage(src), vigra::transformImage(srcImageRange(src), destImage(src),
vigra::Threshold<vigra::BImage::PixelType, vigra::BImage::PixelType >( vigra::Threshold<vigra::BImage::PixelType, vigra::BImage::PixelType >(
128, 256, 0, 255)); 128, 256, 0, 255));
skipping to change at line 448 skipping to change at line 448
EqualityFunctor equal; // second form EqualityFunctor equal; // second form
equal(u, u) // second form equal(u, u) // second form
equal(u, background_value) // second form equal(u, background_value) // second form
int i; int i;
dest_accessor.set(i, dest_upperleft); dest_accessor.set(i, dest_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> unsigned int labelImageWithBackg
round)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class ValueType, class EqualityFunctor> class ValueType, class EqualityFunctor>
unsigned int labelImageWithBackground( unsigned int labelImageWithBackground(
SrcIterator upperlefts, SrcIterator upperlefts,
SrcIterator lowerrights, SrcAccessor sa, SrcIterator lowerrights, SrcAccessor sa,
DestIterator upperleftd, DestAccessor da, DestIterator upperleftd, DestAccessor da,
bool eight_neighbors, bool eight_neighbors,
ValueType background_value, EqualityFunctor equal) ValueType background_value, EqualityFunctor equal)
{ {
skipping to change at line 639 skipping to change at line 641
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* regionImageToCrackEdgeImage */ /* regionImageToCrackEdgeImage */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Transform a labeled image into a crack edge image. /** \brief Transform a labeled image into a crack edge image.
This algorithm inserts border pixels (so called "crack edges")
between regions in a labeled image like this (<TT>a</TT> and
<TT>c</TT> are the original labels, and <TT>0</TT> is the value of
<TT>edge_marker</TT> and denotes the inserted edges):
\code
original image insert zero- and one-cells
a 0 c c c
a c c a 0 0 0 c
a a c => a a a 0 c
a a a a a a 0 0
a a a a a
\endcode
The algorithm assumes that the original labeled image contains
no background. Therefore, it is suitable as a post-processing
operation of \ref labelImage() or \ref seededRegionGrowing().
The destination image must be twice the size of the original
(precisely, <TT>(2*w-1)</TT> by <TT>(2*h-1)</TT> pixels). The
source value type (<TT>SrcAccessor::value-type</TT>) must be
equality-comparable.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestValue> class DestIterator, class DestAccessor, class DestValue>
void regionImageToCrackEdgeImage( void regionImageToCrackEdgeImage(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
DestValue edge_marker) DestValue edge_marker)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestValue> class DestIterator, class DestAccessor, class DestValue>
inline
void regionImageToCrackEdgeImage( void regionImageToCrackEdgeImage(
triple<SrcIterator, SrcIterator, SrcAccessor> src, triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
DestValue edge_marker) DestValue edge_marker)
} }
\endcode \endcode
This algorithm inserts border pixels (so called "crack edges")
between regions in a labeled image like this (<TT>a</TT> and
<TT>c</TT> are the original labels, and <TT>0</TT> is the value of
<TT>edge_marker</TT> and denotes the inserted edges):
\code
original image insert zero- and one-cells
a 0 c c c
a c c a 0 0 0 c
a a c => a a a 0 c
a a a a a a 0 0
a a a a a
\endcode
The algorithm assumes that the original labeled image contains
no background. Therefore, it is suitable as a post-processing
operation of \ref labelImage() or \ref seededRegionGrowing().
The destination image must be twice the size of the original
(precisely, <TT>(2*w-1)</TT> by <TT>(2*h-1)</TT> pixels). The
source value type (<TT>SrcAccessor::value-type</TT>) must be
equality-comparable.
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="labelimage_8hxx-source.html">vigra/label image.hxx</a>"<br> <b>\#include</b> \<<a href="labelimage_8hxx-source.html">vigra/labe limage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h); vigra::BImage src(w,h);
vigra::IImage labels(w,h); vigra::IImage labels(w,h);
vigra::IImage cellgrid(2*w-1, 2*h-1); vigra::IImage cellgrid(2*w-1, 2*h-1);
// threshold at 128 // threshold at 128
vigra::transformImage(srcImageRange(src), destImage(src), vigra::transformImage(srcImageRange(src), destImage(src),
vigra::Threshold<vigra::BImage::PixelType, vigra::BImage::PixelType> ( vigra::Threshold<vigra::BImage::PixelType, vigra::BImage::PixelType> (
skipping to change at line 737 skipping to change at line 738
\endcode \endcode
<b> Preconditions:</b> <b> Preconditions:</b>
The destination image must have twice the size of the source: The destination image must have twice the size of the source:
\code \code
w_dest = 2 * w_src - 1 w_dest = 2 * w_src - 1
h_dest = 2 * h_src - 1 h_dest = 2 * h_src - 1
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void regionImageToCrackEdgeImage
)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestValue> class DestIterator, class DestAccessor, class DestValue>
void regionImageToCrackEdgeImage( void regionImageToCrackEdgeImage(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
DestValue edge_marker) DestValue edge_marker)
{ {
int w = slr.x - sul.x; int w = slr.x - sul.x;
int h = slr.y - sul.y; int h = slr.y - sul.y;
int x,y; int x,y;
skipping to change at line 857 skipping to change at line 860
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* regionImageToEdgeImage */ /* regionImageToEdgeImage */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Transform a labeled image into an edge image. /** \brief Transform a labeled image into an edge image.
This algorithm marks all pixels with the given <TT>edge_marker</TT>
which belong to a different region (label) than their right or lower
neighbors:
\code
original image edges
(assuming edge_marker == 1)
a c c 1 1 *
a a c => * 1 1
a a a * * *
\endcode
The non-edge pixels of the destination image will not be touched.
The source value type (<TT>SrcAccessor::value-type</TT>) must be
equality-comparable.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestValue> class DestIterator, class DestAccessor, class DestValue>
void regionImageToEdgeImage( void regionImageToEdgeImage(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
DestValue edge_marker) DestValue edge_marker)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestValue> class DestIterator, class DestAccessor, class DestValue>
inline
void regionImageToEdgeImage( void regionImageToEdgeImage(
triple<SrcIterator, SrcIterator, SrcAccessor> src, triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
DestValue edge_marker) DestValue edge_marker)
} }
\endcode \endcode
This algorithm marks all pixels with the given <TT>edge_marker</TT>
which belong to a different region (label) than their right or lower
neighbors:
\code
original image edges
(assuming edge_marker == 1)
a c c 1 1 *
a a c => * 1 1
a a a * * *
\endcode
The non-edge pixels of the destination image will not be touched.
The source value type (<TT>SrcAccessor::value-type</TT>) must be
equality-comparable.
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="labelimage_8hxx-source.html">vigra/label image.hxx</a>"<br> <b>\#include</b> \<<a href="labelimage_8hxx-source.html">vigra/labe limage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h); vigra::BImage src(w,h);
vigra::IImage labels(w,h); vigra::IImage labels(w,h);
vigra::IImage edges(w, h); vigra::IImage edges(w, h);
edges = 255; // init background (non-edge) to 255 edges = 255; // init background (non-edge) to 255
// threshold at 128 // threshold at 128
vigra::transformImage(srcImageRange(src), destImage(src), vigra::transformImage(srcImageRange(src), destImage(src),
skipping to change at line 942 skipping to change at line 944
SrcAccessor::value_type u = src_accessor(src_upperleft); SrcAccessor::value_type u = src_accessor(src_upperleft);
u != u u != u
DestValue edge_marker; DestValue edge_marker;
dest_accessor.set(edge_marker, dest_upperleft); dest_accessor.set(edge_marker, dest_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void regionImageToEdgeImage)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestValue> class DestIterator, class DestAccessor, class DestValue>
void regionImageToEdgeImage( void regionImageToEdgeImage(
SrcIterator sul, SrcIterator slr, SrcAccessor sa, SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
DestValue edge_marker) DestValue edge_marker)
{ {
int w = slr.x - sul.x; int w = slr.x - sul.x;
int h = slr.y - sul.y; int h = slr.y - sul.y;
int x,y; int x,y;
 End of changes. 27 change blocks. 
83 lines changed or deleted 89 lines changed or added


 linear_algebra.hxx   linear_algebra.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2004 by Ullrich Koethe */ /* Copyright 2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
 End of changes. 2 change blocks. 
3 lines changed or deleted 3 lines changed or added


 linear_solve.hxx   linear_solve.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2004 by Gunnar Kedenburg and Ullrich Koethe */ /* Copyright 2003-2008 by Gunnar Kedenburg and Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 41 skipping to change at line 41
/* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */ /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
/* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
/* OTHER DEALINGS IN THE SOFTWARE. */ /* OTHER DEALINGS IN THE SOFTWARE. */
/* */ /* */
/************************************************************************/ /************************************************************************/
#ifndef VIGRA_LINEAR_SOLVE_HXX #ifndef VIGRA_LINEAR_SOLVE_HXX
#define VIGRA_LINEAR_SOLVE_HXX #define VIGRA_LINEAR_SOLVE_HXX
#include <ctype.h>
#include <string>
#include "mathutil.hxx"
#include "matrix.hxx" #include "matrix.hxx"
#include "singular_value_decomposition.hxx"
namespace vigra namespace vigra
{ {
namespace linalg namespace linalg
{ {
/** \addtogroup LinearAlgebraFunctions Matrix functions namespace detail {
template <class T, class C1>
T determinantByLUDecomposition(MultiArrayView<2, T, C1> const & a)
{
typedef MultiArrayShape<2>::type Shape;
MultiArrayIndex m = rowCount(a), n = columnCount(a);
vigra_precondition(n == m,
"determinant(): square matrix required.");
Matrix<T> LU(a);
T det = 1.0;
for (MultiArrayIndex j = 0; j < n; ++j)
{
// Apply previous transformations.
for (MultiArrayIndex i = 0; i < m; ++i)
{
MultiArrayIndex end = std::min(i, j);
T s = dot(rowVector(LU, Shape(i,0), end), columnVector(LU, Shap
e(0,j), end));
LU(i,j) = LU(i,j) -= s;
}
// Find pivot and exchange if necessary.
MultiArrayIndex p = j + argMax(abs(columnVector(LU, Shape(j,j), m))
);
if (p != j)
{
rowVector(LU, p).swapData(rowVector(LU, j));
det = -det;
}
det *= LU(j,j);
// Compute multipliers.
if (LU(j,j) != 0.0)
columnVector(LU, Shape(j+1,j), m) /= LU(j,j);
else
break; // det is zero
}
return det;
}
// returns the new value of 'a' (when this Givens rotation is applied to 'a
' and 'b')
// the new value of 'b' is zero, of course
template <class T>
T givensCoefficients(T a, T b, T & c, T & s)
{
if(abs(a) < abs(b))
{
T t = a/b,
r = std::sqrt(1.0 + t*t);
s = 1.0 / r;
c = t*s;
return r*b;
}
else if(a != 0.0)
{
T t = b/a,
r = std::sqrt(1.0 + t*t);
c = 1.0 / r;
s = t*c;
return r*a;
}
else // a == b == 0.0
{
c = 1.0;
s = 0.0;
return 0.0;
}
}
// see Golub, van Loan: Algorithm 5.1.3 (p. 216)
template <class T>
bool givensRotationMatrix(T a, T b, Matrix<T> & gTranspose)
{
if(b == 0.0)
return false; // no rotation needed
givensCoefficients(a, b, gTranspose(0,0), gTranspose(0,1));
gTranspose(1,1) = gTranspose(0,0);
gTranspose(1,0) = -gTranspose(0,1);
return true;
}
// reflections are symmetric matrices and can thus be applied to rows
// and columns in the same way => code simplification relative to rotations
template <class T>
inline bool
givensReflectionMatrix(T a, T b, Matrix<T> & g)
{
if(b == 0.0)
return false; // no reflection needed
givensCoefficients(a, b, g(0,0), g(0,1));
g(1,1) = -g(0,0);
g(1,0) = g(0,1);
return true;
}
// see Golub, van Loan: Algorithm 5.2.2 (p. 227) and Section 12.5.2 (p. 608
)
template <class T, class C1, class C2>
bool
qrGivensStepImpl(MultiArrayIndex i, MultiArrayView<2, T, C1> &r, MultiArray
View<2, T, C2> &rhs)
{
typedef typename Matrix<T>::difference_type Shape;
const MultiArrayIndex m = rowCount(r);
const MultiArrayIndex n = columnCount(r);
const MultiArrayIndex rhsCount = columnCount(rhs);
vigra_precondition(m == rowCount(rhs),
"qrGivensStepImpl(): Matrix shape mismatch.");
Matrix<T> givens(2,2);
for(int k=m-1; k>(int)i; --k)
{
if(!givensReflectionMatrix(r(k-1,i), r(k,i), givens))
continue; // r(k,i) was already zero
r(k-1,i) = givens(0,0)*r(k-1,i) + givens(0,1)*r(k,i);
r(k,i) = 0.0;
r.subarray(Shape(k-1,i+1), Shape(k+1,n)) = givens*r.subarray(Shape(
k-1,i+1), Shape(k+1,n));
rhs.subarray(Shape(k-1,0), Shape(k+1,rhsCount)) = givens*rhs.subarr
ay(Shape(k-1,0), Shape(k+1,rhsCount));
}
return r(i,i) != 0.0;
}
// see Golub, van Loan: Section 12.5.2 (p. 608)
template <class T, class C1, class C2, class Permutation>
void
upperTriangularCyclicShiftColumns(MultiArrayIndex i, MultiArrayIndex j,
MultiArrayView<2, T, C1> &r, MultiArrayVi
ew<2, T, C2> &rhs, Permutation & permutation)
{
typedef typename Matrix<T>::difference_type Shape;
const MultiArrayIndex m = rowCount(r);
const MultiArrayIndex n = columnCount(r);
const MultiArrayIndex rhsCount = columnCount(rhs);
vigra_precondition(i < n && j < n,
"upperTriangularCyclicShiftColumns(): Shift indices
out of range.");
vigra_precondition(m == rowCount(rhs),
"upperTriangularCyclicShiftColumns(): Matrix shape m
ismatch.");
if(j == i)
return;
if(j < i)
std::swap(j,i);
Matrix<T> t = columnVector(r, i);
MultiArrayIndex ti = permutation[i];
for(MultiArrayIndex k=i; k<j;++k)
{
columnVector(r, k) = columnVector(r, k+1);
permutation[k] = permutation[k+1];
}
columnVector(r, j) = t;
permutation[j] = ti;
Matrix<T> givens(2,2);
for(MultiArrayIndex k=i; k<j; ++k)
{
if(!givensReflectionMatrix(r(k,k), r(k+1,k), givens))
continue; // r(k+1,k) was already zero
r(k,k) = givens(0,0)*r(k,k) + givens(0,1)*r(k+1,k);
r(k+1,k) = 0.0;
r.subarray(Shape(k,k+1), Shape(k+2,n)) = givens*r.subarray(Shape(k,
k+1), Shape(k+2,n));
rhs.subarray(Shape(k,0), Shape(k+2,rhsCount)) = givens*rhs.subarray
(Shape(k,0), Shape(k+2,rhsCount));
}
}
// see Golub, van Loan: Section 12.5.2 (p. 608)
template <class T, class C1, class C2, class Permutation>
void
upperTriangularSwapColumns(MultiArrayIndex i, MultiArrayIndex j,
MultiArrayView<2, T, C1> &r, MultiArrayView<2, T
, C2> &rhs, Permutation & permutation)
{
typedef typename Matrix<T>::difference_type Shape;
const MultiArrayIndex m = rowCount(r);
const MultiArrayIndex n = columnCount(r);
const MultiArrayIndex rhsCount = columnCount(rhs);
vigra_precondition(i < n && j < n,
"upperTriangularSwapColumns(): Swap indices out of r
ange.");
vigra_precondition(m == rowCount(rhs),
"upperTriangularSwapColumns(): Matrix shape mismatch
.");
if(j == i)
return;
if(j < i)
std::swap(j,i);
columnVector(r, i).swapData(columnVector(r, j));
std::swap(permutation[i], permutation[j]);
Matrix<T> givens(2,2);
for(int k=m-1; k>(int)i; --k)
{
if(!givensReflectionMatrix(r(k-1,i), r(k,i), givens))
continue; // r(k,i) was already zero
r(k-1,i) = givens(0,0)*r(k-1,i) + givens(0,1)*r(k,i);
r(k,i) = 0.0;
r.subarray(Shape(k-1,i+1), Shape(k+1,n)) = givens*r.subarray(Shape(
k-1,i+1), Shape(k+1,n));
rhs.subarray(Shape(k-1,0), Shape(k+1,rhsCount)) = givens*rhs.subarr
ay(Shape(k-1,0), Shape(k+1,rhsCount));
}
MultiArrayIndex end = std::min(j, m-1);
for(MultiArrayIndex k=i+1; k<end; ++k)
{
if(!givensReflectionMatrix(r(k,k), r(k+1,k), givens))
continue; // r(k+1,k) was already zero
r(k,k) = givens(0,0)*r(k,k) + givens(0,1)*r(k+1,k);
r(k+1,k) = 0.0;
r.subarray(Shape(k,k+1), Shape(k+2,n)) = givens*r.subarray(Shape(k,
k+1), Shape(k+2,n));
rhs.subarray(Shape(k,0), Shape(k+2,rhsCount)) = givens*rhs.subarray
(Shape(k,0), Shape(k+2,rhsCount));
}
}
// see Lawson & Hanson: Algorithm H1 (p. 57)
template <class T, class C1, class C2, class U>
bool householderVector(MultiArrayView<2, T, C1> const & v, MultiArrayView<2
, T, C2> & u, U & vnorm)
{
vnorm = (v(0,0) > 0.0)
? -norm(v)
: norm(v);
U f = std::sqrt(vnorm*(vnorm - v(0,0)));
if(f == NumericTraits<U>::zero())
{
u.init(NumericTraits<T>::zero());
return false;
}
else
{
u(0,0) = (v(0,0) - vnorm) / f;
for(MultiArrayIndex k=1; k<rowCount(u); ++k)
u(k,0) = v(k,0) / f;
return true;
}
}
// see Lawson & Hanson: Algorithm H1 (p. 57)
template <class T, class C1, class C2, class C3>
bool
qrHouseholderStepImpl(MultiArrayIndex i, MultiArrayView<2, T, C1> & r,
MultiArrayView<2, T, C2> & rhs, MultiArrayView<2, T,
C3> & householderMatrix)
{
typedef typename Matrix<T>::difference_type Shape;
const MultiArrayIndex m = rowCount(r);
const MultiArrayIndex n = columnCount(r);
const MultiArrayIndex rhsCount = columnCount(rhs);
vigra_precondition(i < n && i < m,
"qrHouseholderStepImpl(): Index i out of range.");
Matrix<T> u(m-i,1);
T vnorm;
bool nontrivial = householderVector(columnVector(r, Shape(i,i), m), u,
vnorm);
r(i,i) = vnorm;
columnVector(r, Shape(i+1,i), m).init(NumericTraits<T>::zero());
if(columnCount(householderMatrix) == n)
columnVector(householderMatrix, Shape(i,i), m) = u;
if(nontrivial)
{
for(MultiArrayIndex k=i+1; k<n; ++k)
columnVector(r, Shape(i,k), m) -= dot(columnVector(r, Shape(i,k
), m), u) * u;
for(MultiArrayIndex k=0; k<rhsCount; ++k)
columnVector(rhs, Shape(i,k), m) -= dot(columnVector(rhs, Shape
(i,k), m), u) * u;
}
return r(i,i) != 0.0;
}
template <class T, class C1, class C2>
bool
qrColumnHouseholderStep(MultiArrayIndex i, MultiArrayView<2, T, C1> &r, Mul
tiArrayView<2, T, C2> &rhs)
{
Matrix<T> dontStoreHouseholderVectors; // intentionally empty
return qrHouseholderStepImpl(i, r, rhs, dontStoreHouseholderVectors);
}
template <class T, class C1, class C2>
bool
qrRowHouseholderStep(MultiArrayIndex i, MultiArrayView<2, T, C1> &r, MultiA
rrayView<2, T, C2> & householderMatrix)
{
Matrix<T> dontTransformRHS; // intentionally empty
MultiArrayView<2, T, StridedArrayTag> rt = transpose(r),
ht = transpose(householderMatrix)
;
return qrHouseholderStepImpl(i, rt, dontTransformRHS, ht);
}
// O(n) algorithm due to Bischof: Incremental Condition Estimation, 1990
template <class T, class C1, class C2, class SNType>
void
incrementalMaxSingularValueApproximation(MultiArrayView<2, T, C1> const & n
ewColumn,
MultiArrayView<2, T, C2> & z, SNTy
pe & v)
{
typedef typename Matrix<T>::difference_type Shape;
MultiArrayIndex n = rowCount(newColumn) - 1;
SNType vneu = squaredNorm(newColumn);
T yv = dot(columnVector(newColumn, Shape(0,0),n), columnVector(z, Shape
(0,0),n));
// use atan2 as it is robust against overflow/underflow
double t = 0.5*std::atan2(2.0*yv, sq(v)-vneu),
s = std::sin(t),
c = std::cos(t);
v = std::sqrt(sq(c*v) + sq(s)*vneu + 2.0*s*c*yv);
columnVector(z, Shape(0,0),n) = c*columnVector(z, Shape(0,0),n) + s*col
umnVector(newColumn, Shape(0,0),n);
z(n,0) = s*newColumn(n,0);
}
// O(n) algorithm due to Bischof: Incremental Condition Estimation, 1990
template <class T, class C1, class C2, class SNType>
void
incrementalMinSingularValueApproximation(MultiArrayView<2, T, C1> const & n
ewColumn,
MultiArrayView<2, T, C2> & z, SNTy
pe & v, double tolerance)
{
typedef typename Matrix<T>::difference_type Shape;
if(v <= tolerance)
{
v = 0.0;
return;
}
MultiArrayIndex n = rowCount(newColumn) - 1;
T gamma = newColumn(n,0);
if(gamma == 0.0)
{
v = 0.0;
return;
}
T yv = dot(columnVector(newColumn, Shape(0,0),n), columnVector(z, Shape
(0,0),n));
// use atan2 as it is robust against overflow/underflow
double t = 0.5*std::atan2(-2.0*yv, squaredNorm(gamma / v) + squaredNorm
(yv) - 1.0),
s = std::sin(t),
c = std::cos(t);
columnVector(z, Shape(0,0),n) *= c;
z(n,0) = (s - c*yv) / gamma;
v *= norm(gamma) / hypot(c*gamma, v*(s - c*yv));
}
// QR algorithm with optional column pivoting
template <class T, class C1, class C2, class C3>
unsigned int
qrTransformToTriangularImpl(MultiArrayView<2, T, C1> & r, MultiArrayView<2,
T, C2> & rhs, MultiArrayView<2, T, C3> & householder,
ArrayVector<MultiArrayIndex> & permutation, dou
ble epsilon)
{
typedef typename Matrix<T>::difference_type Shape;
typedef typename NormTraits<MultiArrayView<2, T, C1> >::NormType NormTy
pe;
typedef typename NormTraits<MultiArrayView<2, T, C1> >::SquaredNormType
SNType;
const MultiArrayIndex m = rowCount(r);
const MultiArrayIndex n = columnCount(r);
const MultiArrayIndex maxRank = std::min(m, n);
vigra_precondition(m >= n,
"qrTransformToTriangularImpl(): Coefficient matrix with at least as
many rows as columns required.");
const MultiArrayIndex rhsCount = columnCount(rhs);
bool transformRHS = rhsCount > 0;
vigra_precondition(!transformRHS || m == rowCount(rhs),
"qrTransformToTriangularImpl(): RHS matrix shape mis
match.");
bool storeHouseholderSteps = columnCount(householder) > 0;
vigra_precondition(!storeHouseholderSteps || r.shape() == householder.s
hape(),
"qrTransformToTriangularImpl(): Householder matrix s
hape mismatch.");
bool pivoting = permutation.size() > 0;
vigra_precondition(!pivoting || n == (MultiArrayIndex)permutation.size(
),
"qrTransformToTriangularImpl(): Permutation array si
ze mismatch.");
if(n == 0)
return 0; // trivial solution
Matrix<SNType> columnSquaredNorms;
if(pivoting)
{
columnSquaredNorms.reshape(Shape(1,n));
for(MultiArrayIndex k=0; k<n; ++k)
columnSquaredNorms[k] = squaredNorm(columnVector(r, k));
int pivot = argMax(columnSquaredNorms);
if(pivot != 0)
{
columnVector(r, 0).swapData(columnVector(r, pivot));
std::swap(columnSquaredNorms[0], columnSquaredNorms[pivot]);
std::swap(permutation[0], permutation[pivot]);
}
}
qrHouseholderStepImpl(0, r, rhs, householder);
MultiArrayIndex rank = 1;
NormType maxApproxSingularValue = norm(r(0,0)),
minApproxSingularValue = maxApproxSingularValue;
double tolerance = (epsilon == 0.0)
? m*maxApproxSingularValue*NumericTraits<T>::epsi
lon()
: epsilon;
bool simpleSingularValueApproximation = (n < 4);
Matrix<T> zmax, zmin;
if(minApproxSingularValue <= tolerance)
{
rank = 0;
pivoting = false;
simpleSingularValueApproximation = true;
}
if(!simpleSingularValueApproximation)
{
zmax.reshape(Shape(m,1));
zmin.reshape(Shape(m,1));
zmax(0,0) = r(0,0);
zmin(0,0) = 1.0 / r(0,0);
}
for(MultiArrayIndex k=1; k<maxRank; ++k)
{
if(pivoting)
{
for(MultiArrayIndex l=k; l<n; ++l)
columnSquaredNorms[l] -= squaredNorm(r(k, l));
int pivot = k + argMax(rowVector(columnSquaredNorms, Shape(0,k)
, n));
if(pivot != (int)k)
{
columnVector(r, k).swapData(columnVector(r, pivot));
std::swap(columnSquaredNorms[k], columnSquaredNorms[pivot])
;
std::swap(permutation[k], permutation[pivot]);
}
}
qrHouseholderStepImpl(k, r, rhs, householder);
if(simpleSingularValueApproximation)
{
NormType nv = norm(r(k,k));
maxApproxSingularValue = std::max(nv, maxApproxSingularValue);
minApproxSingularValue = std::min(nv, minApproxSingularValue);
}
else
{
incrementalMaxSingularValueApproximation(columnVector(r, Shape(
0,k),k+1), zmax, maxApproxSingularValue);
incrementalMinSingularValueApproximation(columnVector(r, Shape(
0,k),k+1), zmin, minApproxSingularValue, tolerance);
}
#if 0
Matrix<T> u(k+1,k+1), s(k+1, 1), v(k+1,k+1);
singularValueDecomposition(r.subarray(Shape(0,0), Shape(k+1,k+1)),
u, s, v);
std::cerr << "estimate, svd " << k << ": " << minApproxSingularValu
e << " " << s(k,0) << "\n";
#endif
if(epsilon == 0.0)
tolerance = m*maxApproxSingularValue*NumericTraits<T>::epsilon(
);
if(minApproxSingularValue > tolerance)
++rank;
else
pivoting = false; // matrix doesn't have full rank, triangulize
the rest without pivoting
}
return (unsigned int)rank;
}
template <class T, class C1, class C2>
unsigned int
qrTransformToUpperTriangular(MultiArrayView<2, T, C1> & r, MultiArrayView<2
, T, C2> & rhs,
ArrayVector<MultiArrayIndex> & permutation, do
uble epsilon = 0.0)
{
Matrix<T> dontStoreHouseholderVectors; // intentionally empty
return qrTransformToTriangularImpl(r, rhs, dontStoreHouseholderVectors,
permutation, epsilon);
}
// QR algorithm with optional row pivoting
template <class T, class C1, class C2, class C3>
unsigned int
qrTransformToLowerTriangular(MultiArrayView<2, T, C1> & r, MultiArrayView<2
, T, C2> & rhs, MultiArrayView<2, T, C3> & householderMatrix,
double epsilon = 0.0)
{
ArrayVector<MultiArrayIndex> permutation((unsigned int)rowCount(rhs));
for(MultiArrayIndex k=0; k<(MultiArrayIndex)permutation.size(); ++k)
permutation[k] = k;
Matrix<T> dontTransformRHS; // intentionally empty
MultiArrayView<2, T, StridedArrayTag> rt = transpose(r),
ht = transpose(householderMatrix)
;
unsigned int rank = qrTransformToTriangularImpl(rt, dontTransformRHS, h
t, permutation, epsilon);
// apply row permutation to RHS
Matrix<T> tempRHS(rhs);
for(MultiArrayIndex k=0; k<(MultiArrayIndex)permutation.size(); ++k)
rowVector(rhs, k) = rowVector(tempRHS, permutation[k]);
return rank;
}
// QR algorithm without column pivoting
template <class T, class C1, class C2>
inline bool
qrTransformToUpperTriangular(MultiArrayView<2, T, C1> & r, MultiArrayView<2
, T, C2> & rhs,
double epsilon = 0.0)
{
ArrayVector<MultiArrayIndex> noPivoting; // intentionally empty
return (qrTransformToUpperTriangular(r, rhs, noPivoting, epsilon) ==
(unsigned int)columnCount(r));
}
// QR algorithm without row pivoting
template <class T, class C1, class C2>
inline bool
qrTransformToLowerTriangular(MultiArrayView<2, T, C1> & r, MultiArrayView<2
, T, C2> & householder,
double epsilon = 0.0)
{
Matrix<T> noPivoting; // intentionally empty
return (qrTransformToLowerTriangular(r, noPivoting, householder, epsilo
n) ==
(unsigned int)rowCount(r));
}
// restore ordering of result vector elements after QR solution with column
pivoting
template <class T, class C1, class C2, class Permutation>
void inverseRowPermutation(MultiArrayView<2, T, C1> &permuted, MultiArrayVi
ew<2, T, C2> &res,
Permutation const & permutation)
{
for(MultiArrayIndex k=0; k<columnCount(permuted); ++k)
for(MultiArrayIndex l=0; l<rowCount(permuted); ++l)
res(permutation[l], k) = permuted(l,k);
}
template <class T, class C1, class C2>
void applyHouseholderColumnReflections(MultiArrayView<2, T, C1> const &hous
eholder, MultiArrayView<2, T, C2> &res)
{
typedef typename Matrix<T>::difference_type Shape;
MultiArrayIndex n = rowCount(householder);
MultiArrayIndex m = columnCount(householder);
MultiArrayIndex rhsCount = columnCount(res);
for(int k = m-1; k >= 0; --k)
{
MultiArrayView<2, T, C1> u = columnVector(householder, Shape(k,k),
n);
for(MultiArrayIndex l=0; l<rhsCount; ++l)
columnVector(res, Shape(k,l), n) -= dot(columnVector(res, Shape
(k,l), n), u) * u;
}
}
} // namespace detail
template <class T, class C1, class C2, class C3>
unsigned int
linearSolveQRReplace(MultiArrayView<2, T, C1> &A, MultiArrayView<2, T, C2>
&b,
MultiArrayView<2, T, C3> & res,
double epsilon = 0.0)
{
typedef typename Matrix<T>::difference_type Shape;
MultiArrayIndex n = columnCount(A);
MultiArrayIndex m = rowCount(A);
MultiArrayIndex rhsCount = columnCount(res);
MultiArrayIndex rank = std::min(m,n);
vigra_precondition(rhsCount == columnCount(b),
"linearSolveQR(): RHS and solution must have the same number of
columns.");
vigra_precondition(m == rowCount(b),
"linearSolveQR(): Coefficient matrix and RHS must have the same
number of rows.");
vigra_precondition(n == rowCount(res),
"linearSolveQR(): Mismatch between column count of coefficient m
atrix and row count of solution.");
vigra_precondition(epsilon >= 0.0,
"linearSolveQR(): 'epsilon' must be non-negative.");
if(m < n)
{
// minimum norm solution of underdetermined system
Matrix<T> householderMatrix(n, m);
MultiArrayView<2, T, StridedArrayTag> ht = transpose(householderMat
rix);
rank = (MultiArrayIndex)detail::qrTransformToLowerTriangular(A, b,
ht, epsilon);
res.subarray(Shape(rank,0), Shape(n, rhsCount)).init(NumericTraits<
T>::zero());
if(rank < m)
{
// system is also rank-deficient => compute minimum norm least
squares solution
MultiArrayView<2, T, C1> Asub = A.subarray(Shape(0,0), Shape(m,
rank));
detail::qrTransformToUpperTriangular(Asub, b, epsilon);
linearSolveUpperTriangular(A.subarray(Shape(0,0), Shape(rank,ra
nk)),
b.subarray(Shape(0,0), Shape(rank,rh
sCount)),
res.subarray(Shape(0,0), Shape(rank,
rhsCount)));
}
else
{
// system has full rank => compute minimum norm solution
linearSolveLowerTriangular(A.subarray(Shape(0,0), Shape(rank,ra
nk)),
b.subarray(Shape(0,0), Shape(rank, r
hsCount)),
res.subarray(Shape(0,0), Shape(rank,
rhsCount)));
}
detail::applyHouseholderColumnReflections(householderMatrix.subarra
y(Shape(0,0), Shape(n, rank)), res);
}
else
{
// solution of well-determined or overdetermined system
ArrayVector<MultiArrayIndex> permutation((unsigned int)n);
for(MultiArrayIndex k=0; k<n; ++k)
permutation[k] = k;
rank = (MultiArrayIndex)detail::qrTransformToUpperTriangular(A, b,
permutation, epsilon);
Matrix<T> permutedSolution(n, rhsCount);
if(rank < n)
{
// system is rank-deficient => compute minimum norm solution
Matrix<T> householderMatrix(n, rank);
MultiArrayView<2, T, StridedArrayTag> ht = transpose(householde
rMatrix);
MultiArrayView<2, T, C1> Asub = A.subarray(Shape(0,0), Shape(ra
nk,n));
detail::qrTransformToLowerTriangular(Asub, ht, epsilon);
linearSolveLowerTriangular(A.subarray(Shape(0,0), Shape(rank,ra
nk)),
b.subarray(Shape(0,0), Shape(rank, r
hsCount)),
permutedSolution.subarray(Shape(0,0)
, Shape(rank, rhsCount)));
detail::applyHouseholderColumnReflections(householderMatrix, pe
rmutedSolution);
}
else
{
// system has full rank => compute exact or least squares solut
ion
linearSolveUpperTriangular(A.subarray(Shape(0,0), Shape(rank,ra
nk)),
b.subarray(Shape(0,0), Shape(rank,rh
sCount)),
permutedSolution);
}
detail::inverseRowPermutation(permutedSolution, res, permutation);
}
return (unsigned int)rank;
}
template <class T, class C1, class C2, class C3>
unsigned int linearSolveQR(MultiArrayView<2, T, C1> const & A, MultiArrayVi
ew<2, T, C2> const & b,
MultiArrayView<2, T, C3> & res)
{
Matrix<T> r(A), rhs(b);
return linearSolveQRReplace(r, rhs, res);
}
/** \defgroup MatrixAlgebra Advanced Matrix Algebra
\brief Solution of linear systems, eigen systems, linear least squares
etc.
\ingroup LinearAlgebraModule
*/ */
//@{ //@{
/** invert square matrix \a v. /** Create the inverse or pseudo-inverse of matrix \a v.
The result is written into \a r which must have the same shape.
The inverse is calculated by means of QR decomposition. If \a v
is not invertible, <tt>vigra::PreconditionViolation</tt> exception
is thrown.
<b>\#include</b> "<a href="linear__solve_8hxx-source.html">vigra/linear If the matrix \a v is square, \a res must have the same shape and w
_solve.hxx</a>" or<br> ill contain the
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line inverse of \a v. If \a v is rectangular, it must have more rows tha
ar_algebra.hxx</a>"<br> n columns, and \a res
must have the transposed shape of \a v. The inverse is then compute
d in the least-squares
sense, i.e. \a res will be the pseudo-inverse (Moore-Penrose invers
e).
The function returns <tt>true</tt> upon success, and <tt>false</tt>
if \a v
is not invertible (has not full rank). The inverse is computed by m
eans of QR
decomposition. This function can be applied in-place.
<b>\#include</b> \<<a href="linear__solve_8hxx-source.html">vigra/linea
r_solve.hxx</a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1, class C2> template <class T, class C1, class C2>
void inverse(const MultiArrayView<2, T, C1> &v, MultiArrayView<2, T, C2> &r ) bool inverse(const MultiArrayView<2, T, C1> &v, MultiArrayView<2, T, C2> &r es)
{ {
const unsigned int n = rowCount(r); const MultiArrayIndex n = columnCount(v);
vigra_precondition(n == columnCount(v) && n == rowCount(v) && n == colu vigra_precondition(n <= rowCount(v),
mnCount(r), "inverse(): input matrix must have at least as many rows as columns.
"inverse(): matrices must be square."); ");
vigra_precondition(linearSolve(v, identityMatrix<T>(n), r), vigra_precondition(n == rowCount(res) && rowCount(v) == columnCount(res
"inverse(): matrix is not invertible."); ),
"inverse(): shape of output matrix must be the transpose of the inpu
t matrix' shape.");
Matrix<T> q(v.shape()), r(n, n);
if(!qrDecomposition(v, q, r))
return false; // a didn't have full rank
linearSolveUpperTriangular(r, transpose(q), res);
return true;
} }
/** create the inverse of square matrix \a v. /** Create the inverse or pseudo-inverse of matrix \a v.
The result is returned as a temporary matrix.
The inverse is calculated by means of QR decomposition. If \a v The result is returned as a temporary matrix. If the matrix \a v is
square,
the result will have the same shape and contains the inverse of \a
v.
If \a v is rectangular, it must have more rows than columns, and th
e result will
have the transposed shape of \a v. The inverse is then computed in
the least-squares
sense, i.e. \a res will be the pseudo-inverse (Moore-Penrose invers
e).
The inverse is computed by means of QR decomposition. If \a v
is not invertible, <tt>vigra::PreconditionViolation</tt> exception is thrown. is not invertible, <tt>vigra::PreconditionViolation</tt> exception is thrown.
Usage: Usage:
\code \code
vigra::Matrix<double> v(n, n); vigra::Matrix<double> v(n, n);
v = ...; v = ...;
vigra::Matrix<double> m = inverse(v); vigra::Matrix<double> m = inverse(v);
\endcode \endcode
<b>\#include</b> "<a href="linear__solve_8hxx-source.html">vigra/linear <b>\#include</b> \<<a href="linear__solve_8hxx-source.html">vigra/linea
_solve.hxx</a>" or<br> r_solve.hxx</a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C> template <class T, class C>
TemporaryMatrix<T> inverse(const MultiArrayView<2, T, C> &v) TemporaryMatrix<T> inverse(const MultiArrayView<2, T, C> &v)
{ {
const unsigned int n = rowCount(v); TemporaryMatrix<T> ret(columnCount(v), rowCount(v)); // transpose shap
vigra_precondition(n == columnCount(v), e
"inverse(): matrix must be square."); vigra_precondition(inverse(v, ret),
TemporaryMatrix<T> ret = identityMatrix<T>(n);
vigra_precondition(linearSolve(v, ret, ret),
"inverse(): matrix is not invertible."); "inverse(): matrix is not invertible.");
return ret; return ret;
} }
template <class T> template <class T>
TemporaryMatrix<T> inverse(const TemporaryMatrix<T> &v) TemporaryMatrix<T> inverse(const TemporaryMatrix<T> &v)
{ {
const unsigned int n = v.rowCount(); if(columnCount(v) == rowCount(v))
vigra_precondition(n == v.columnCount(), {
"inverse(): matrix must be square."); vigra_precondition(inverse(v, const_cast<TemporaryMatrix<T> &>(v)),
vigra_precondition(linearSolve(v, identityMatrix<T>(n), v), "inverse(): matrix is not invertible.");
"inverse(): matrix is not invertible."); return v;
return v; }
else
{
TemporaryMatrix<T> ret(columnCount(v), rowCount(v)); // transpose
shape
vigra_precondition(inverse(v, ret),
"inverse(): matrix is not invertible.");
return ret;
}
} }
/** QR decomposition. /** Compute the determinant of a square matrix.
\a a contains the original matrix, results are returned in \a q and \a method must be one of the following:
\a r, where <DL>
\a q is a orthogonal matrix, and \a r is an upper triangular matrix <DT>"Cholesky"<DD> Compute the solution by means of Cholesky decomp
, and osition. This
the following relation holds: method is faster than "LU", but requires the mat
rix \a a
to be symmetric positive definite. If this is
not the case, a <tt>ContractViolation</tt> excep
tion is thrown.
<DT>"LU"<DD> (default) Compute the solution by means of LU decompos
ition.
</DL>
<b>\#include</b> \<<a href="linear__solve_8hxx-source.html">vigra/linea
r_solve.hxx</a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg
*/
template <class T, class C1>
T determinant(MultiArrayView<2, T, C1> const & a, std::string method = "LU"
)
{
MultiArrayIndex n = columnCount(a);
vigra_precondition(rowCount(a) == n,
"determinant(): Square matrix required.");
for(unsigned int k=0; k<method.size(); ++k)
method[k] = tolower(method[k]);
if(n == 1)
return a(0,0);
if(n == 2)
return a(0,0)*a(1,1) - a(0,1)*a(1,0);
if(method == "lu")
{
return detail::determinantByLUDecomposition(a);
}
else if(method == "cholesky")
{
Matrix<T> L(a.shape());
vigra_precondition(choleskyDecomposition(a, L),
"determinant(): Cholesky method requires symmetric positive defi
nite matrix.");
T det = L(0,0);
for(MultiArrayIndex k=1; k<n; ++k)
det *= L(k,k);
return sq(det);
}
else
{
vigra_precondition(false, "determinant(): Unknown solution method."
);
}
return T();
}
/** Compute the logarithm of the determinant of a symmetric positive de
finite matrix.
This is useful to avoid multiplication of very large numbers in big
matrices.
It is implemented by means of Cholesky decomposition.
<b>\#include</b> \<<a href="linear__solve_8hxx-source.html">vigra/linea
r_solve.hxx</a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg
*/
template <class T, class C1>
T logDeterminant(MultiArrayView<2, T, C1> const & a)
{
MultiArrayIndex n = columnCount(a);
vigra_precondition(rowCount(a) == n,
"logDeterminant(): Square matrix required.");
if(n == 1)
{
vigra_precondition(a(0,0) > 0.0,
"logDeterminant(): Matrix not positive definite.");
return std::log(a(0,0));
}
if(n == 2)
{
T det = a(0,0)*a(1,1) - a(0,1)*a(1,0);
vigra_precondition(det > 0.0,
"logDeterminant(): Matrix not positive definite.");
return std::log(det);
}
else
{
Matrix<T> L(a.shape());
vigra_precondition(choleskyDecomposition(a, L),
"logDeterminant(): Matrix not positive definite.");
T logdet = std::log(L(0,0));
for(MultiArrayIndex k=1; k<n; ++k)
logdet += std::log(L(k,k)); // L(k,k) is guaranteed to be posi
tive
return 2.0*logdet;
}
}
/** Cholesky decomposition.
\a A must be a symmetric positive definite matrix, and \a L will be
a lower
triangular matrix, such that (up to round-off errors):
\code \code
assert(a == q * r); A == L * transpose(L);
\endcode \endcode
This implementation uses householder transformations. It can be app This implementation cannot be applied in-place, i.e. <tt>&L == &A</
lied in-place, tt> is an error.
i.e. <tt>&a == &r</tt> is allowed. If \a A is not symmetric, a <tt>ContractViolation</tt> exception is
thrown. If it
is not positive definite, the function returns <tt>false</tt>.
<b>\#include</b> "<a href="linear__solve_8hxx-source.html">vigra/linear <b>\#include</b> \<<a href="linear__solve_8hxx-source.html">vigra/linea
_solve.hxx</a>" or<br> r_solve.hxx</a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1, class C2, class C3> template <class T, class C1, class C2>
void qrDecomposition(MultiArrayView<2, T, C1> const & a, bool choleskyDecomposition(MultiArrayView<2, T, C1> const & A,
MultiArrayView<2, T, C2> &q, MultiArrayView<2, T, C3> MultiArrayView<2, T, C2> &L)
&r)
{ {
typedef typename MultiArrayView<2, T, C2>::difference_type MatrixShape; typedef T Real;
typedef typename MultiArray<1, T>::difference_type VectorShape;
// the orthogonal matrix q will have as many rows and columns as MultiArrayIndex n = columnCount(A);
// the original matrix has columns.
const unsigned int rows = rowCount(a);
const unsigned int cols = columnCount(a);
vigra_precondition(cols == columnCount(r) && cols == rowCount(r) &&
cols == columnCount(q) && cols == rowCount(q),
"qrDecomposition(): Matrix shape mismatch.");
identityMatrix(q); vigra_precondition(rowCount(A) == n,
r.copy(a); // does nothing if &r == &a "choleskyDecomposition(): Input matrix must be squar
e.");
vigra_precondition(n == columnCount(L) && n == rowCount(L),
"choleskyDecomposition(): Output matrix must have sa
me shape as input matrix.");
for(unsigned int k = 0; (k < cols) && (k < rows - 1); ++k) { for (MultiArrayIndex j = 0; j < n; ++j)
{
Real d(0.0);
for (MultiArrayIndex k = 0; k < j; ++k)
{
Real s(0.0);
for (MultiArrayIndex i = 0; i < k; ++i)
{
s += L(k, i)*L(j, i);
}
L(j, k) = s = (A(j, k) - s)/L(k, k);
d = d + s*s;
vigra_precondition(A(k, j) == A(j, k),
"choleskyDecomposition(): Input matrix must be symme
tric.");
}
d = A(j, j) - d;
if(d <= 0.0)
return false; // A is not positive definite
L(j, j) = std::sqrt(d);
for (MultiArrayIndex k = j+1; k < n; ++k)
{
L(j, k) = 0.0;
}
}
return true;
}
const unsigned int rows_left = rows - k; /** QR decomposition.
const unsigned int cols_left = cols - k;
// create a view on the remaining part of r \a a contains the original matrix, results are returned in \a q and
MatrixShape rul(k, k); \a r, where
MultiArrayView<2, T, C2> rsub = r.subarray(rul, r.shape()); \a q is a orthogonal matrix, and \a r is an upper triangular matrix
, such that
(up to round-off errors):
// decompose the first row \code
MultiArrayView <1, T, C2 > vec = rsub.bindOuter(0); a == q * r;
\endcode
// defining householder vector If \a a dosn't have full rank, the function returns <tt>false</tt>.
VectorShape ushape(rows_left); The decomposition is computed by householder transformations. It ca
MultiArray<1, T> u(ushape); n be applied in-place,
for(unsigned int i = 0; i < rows_left; ++i) i.e. <tt>&a == &q</tt> or <tt>&a == &r</tt> are allowed.
u(i) = vec(i);
u(0) += norm(vec);
const T divisor = squaredNorm(u); <b>\#include</b> \<<a href="linear__solve_8hxx-source.html">vigra/linea
const T scal = (divisor == 0) ? 0.0 : 2.0 / divisor; r_solve.hxx</a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg
*/
template <class T, class C1, class C2, class C3>
bool qrDecomposition(MultiArrayView<2, T, C1> const & a,
MultiArrayView<2, T, C2> &q, MultiArrayView<2, T, C3>
&r,
double epsilon = 0.0)
{
const MultiArrayIndex m = rowCount(a);
const MultiArrayIndex n = columnCount(a);
vigra_precondition(n == columnCount(r) && m == rowCount(r) &&
m == columnCount(q) && m == rowCount(q),
"qrDecomposition(): Matrix shape mismatch.");
// apply householder elimination on rsub q = identityMatrix<T>(m);
for(unsigned int i = 0; i < cols_left; ++i) { MultiArrayView<2,T, StridedArrayTag> tq = transpose(q);
r = a;
ArrayVector<MultiArrayIndex> noPivoting; // intentionally empty
return (detail::qrTransformToUpperTriangular(r, tq, noPivoting, epsilon
) == std::min(m,n));
}
// compute the inner product of the i'th column of rsub with u /** Deprecated, use \ref linearSolveUpperTriangular().
T sum = dot(u, rsub.bindOuter(i)); */
template <class T, class C1, class C2, class C3>
inline
bool reverseElimination(const MultiArrayView<2, T, C1> &r, const MultiArray
View<2, T, C2> &b,
MultiArrayView<2, T, C3> x)
{
return linearSolveUpperTriangular(r, b, x);
}
// add rsub*(uu')/(u'u) /** Solve a linear system with upper-triangular coefficient matrix.
sum *= scal;
for(unsigned int j = 0; j < rows_left; ++j)
rsub(j, i) -= sum * u(j);
}
MatrixShape qul(0, k); The square matrix \a r must be an upper-triangular coefficient matr
MultiArrayView <2, T, C3 > qsub = q.subarray(qul, q.shape()); ix as can,
for example, be obtained by means of QR decomposition. If \a r does
n't have full rank
the function fails and returns <tt>false</tt>, otherwise it returns
<tt>true</tt>. The
lower triangular part of matrix \a r will not be touched, so it doe
sn't need to contain zeros.
// apply the (self-inverse) householder matrix on q The column vectors of matrix \a b are the right-hand sides of the e
for(unsigned int i = 0; i < cols; ++i) { quation (several equations
with the same coefficients can thus be solved in one go). The resul
t is returned
int \a x, whose columns contain the solutions for the corresponding
columns of \a b. This implementation can be applied in-place, i.e.
<tt>&b == &x</tt> is allowed.
The following size requirements apply:
// compute the inner product of the i'th row of q with u \code
T sum = dot(qsub.bindInner(i), u); rowCount(r) == columnCount(r);
rowCount(r) == rowCount(b);
columnCount(r) == rowCount(x);
columnCount(b) == columnCount(x);
\endcode
// add q*(uu')/(u'u) <b>\#include</b> \<<a href="linear__solve_8hxx-source.html">vigra/linea
sum *= scal; r_solve.hxx</a>\> or<br>
for(unsigned int j = 0; j < rows_left; ++j) <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
qsub(i, j) -= sum * u(j); ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg
*/
template <class T, class C1, class C2, class C3>
bool linearSolveUpperTriangular(const MultiArrayView<2, T, C1> &r, const Mu
ltiArrayView<2, T, C2> &b,
MultiArrayView<2, T, C3> x)
{
typedef MultiArrayShape<2>::type Shape;
MultiArrayIndex m = rowCount(r);
MultiArrayIndex rhsCount = columnCount(b);
vigra_precondition(m == columnCount(r),
"linearSolveUpperTriangular(): square coefficient matrix required."
);
vigra_precondition(m == rowCount(b) && m == rowCount(x) && rhsCount ==
columnCount(x),
"linearSolveUpperTriangular(): matrix shape mismatch.");
for(MultiArrayIndex k = 0; k < rhsCount; ++k)
{
for(int i=m-1; i>=0; --i)
{
if(r(i,i) == NumericTraits<T>::zero())
return false; // r doesn't have full rank
T sum = b(i, k);
for(MultiArrayIndex j=i+1; j<m; ++j)
sum -= r(i, j) * x(j, k);
x(i, k) = sum / r(i, i);
} }
} }
return true;
} }
/** Solve a linear system with right-triangular defining matrix. /** Solve a linear system with lower-triangular coefficient matrix.
The square matrix \a a must be a right-triangular coefficient matri The square matrix \a l must be a lower-triangular coefficient matri
x as can, x. If \a l
for example, be obtained by means of QR decomposition. The column v doesn't have full rank the function fails and returns <tt>false</tt
ectors >,
in \a b are the right-hand sides of the equation (so, several equat otherwise it returns <tt>true</tt>. The upper triangular part of ma
ions trix \a l will not be touched,
with the same coefficients can be solved in one go). The result is so it doesn't need to contain zeros.
returned
int \a x, whose columns contain the solutions for the correspoindin
g
columns of \a b. The number of columns of \a a must equal the numbe
r of rows of
both \a b and \a x, and the number of columns of \a b and \a x must
be
equal. This implementation can be applied in-place, i.e. <tt>&b ==
&x</tt> is allowed.
<b>\#include</b> "<a href="linear__solve_8hxx-source.html">vigra/linear The column vectors of matrix \a b are the right-hand sides of the e
_solve.hxx</a>" or<br> quation (several equations
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line with the same coefficients can thus be solved in one go). The resul
ar_algebra.hxx</a>"<br> t is returned
in \a x, whose columns contain the solutions for the correspoinding
columns of \a b. This implementation can be applied in-place, i.e.
<tt>&b == &x</tt> is allowed.
The following size requirements apply:
\code
rowCount(l) == columnCount(l);
rowCount(l) == rowCount(b);
columnCount(l) == rowCount(x);
columnCount(b) == columnCount(x);
\endcode
<b>\#include</b> \<<a href="linear__solve_8hxx-source.html">vigra/linea
r_solve.hxx</a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1, class C2, class C3> template <class T, class C1, class C2, class C3>
void reverseElimination(const MultiArrayView<2, T, C1> &r, const MultiArray bool linearSolveLowerTriangular(const MultiArrayView<2, T, C1> &l, const Mu
View<2, T, C2> &b, ltiArrayView<2, T, C2> &b,
MultiArrayView<2, T, C3> & x) MultiArrayView<2, T, C3> x)
{ {
unsigned int m = columnCount(r); MultiArrayIndex m = columnCount(l);
unsigned int n = columnCount(b); MultiArrayIndex n = columnCount(b);
vigra_precondition(m == rowCount(r), vigra_precondition(m == rowCount(l),
"reverseElimination(): square coefficient matrix required."); "linearSolveLowerTriangular(): square coefficient matrix required."
);
vigra_precondition(m == rowCount(b) && m == rowCount(x) && n == columnC ount(x), vigra_precondition(m == rowCount(b) && m == rowCount(x) && n == columnC ount(x),
"reverseElimination(): matrix shape mismatch."); "linearSolveLowerTriangular(): matrix shape mismatch.");
for(unsigned int k = 0; k < n; ++k) for(MultiArrayIndex k = 0; k < n; ++k)
{ {
x(m-1, k) = b(m-1, k) / r(m-1, m-1); for(MultiArrayIndex i=0; i<m; ++i)
if(m >= 2)
{ {
for(int i = m-2; i >= 0; --i) if(l(i,i) == NumericTraits<T>::zero())
{ return false; // l doesn't have full rank
// compute the i'th inner product, excluding the diagonal e T sum = b(i, k);
ntry. for(MultiArrayIndex j=0; j<i; ++j)
T sum = NumericTraits<T>::zero(); sum -= l(i, j) * x(j, k);
for(unsigned int j = i+1; j < m; ++j) x(i, k) = sum / l(i, i);
sum += r(i, j) * x(j, k);
if(r(i, i) != NumericTraits<T>::zero())
x(i, k) = (b(i, k) - sum) / r(i, i);
else
x(i, k) = NumericTraits<T>::zero();
}
} }
} }
return true;
} }
/** Solve a linear system. /** Solve a linear system.
The square matrix \a a is the coefficient matrix, and the column ve ctors \a A is the coefficient matrix, and the column vectors
in \a b are the right-hand sides of the equation (so, several equat ions in \a b are the right-hand sides of the equation (so, several equat ions
with the same coefficients can be solved in one go). The result is returned with the same coefficients can be solved in one go). The result is returned
int \a res, whose columns contain the solutions for the correspoind in \a res, whose columns contain the solutions for the correspondin
ing g
columns of \a b. The number of columns of \a a must equal the numbe columns of \a b. The number of columns of \a A must equal the numbe
r of rows of r of rows of
both \a b and \a res, and the number of columns of \a b and \a res both \a b and \a res, and the number of columns of \a b and \a res
must be must match.
equal. The algorithm uses QR decomposition of \a a. The algorithm r
eturns
<tt>false</tt> if \a a doesn't have full rank. This implementation
can be
applied in-place, i.e. <tt>&b == &res</tt> or <tt>&a == &res</tt> a
re allowed.
<b>\#include</b> "<a href="linear__solve_8hxx-source.html">vigra/linear \a method must be one of the following:
_solve.hxx</a>" or<br> <DL>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <DT>"Cholesky"<DD> Compute the solution by means of Cholesky decomp
ar_algebra.hxx</a>"<br> osition. The
coefficient matrix \a A must by symmetric positi
ve definite. If
this is not the case, the function returns <tt>f
alse</tt>.
<DT>"QR"<DD> (default) Compute the solution by means of QR decompos
ition. The
coefficient matrix \a A can be square or rectang
ular. In the latter case,
it must have more rows than columns, and the sol
ution will be computed in the
least squares sense. If \a A doesn't have full r
ank, the function
returns <tt>false</tt>.
<DT>"SVD"<DD> Compute the solution by means of singular value decom
position. The
coefficient matrix \a A can be square or rectang
ular. In the latter case,
it must have more rows than columns, and the sol
ution will be computed in the
least squares sense. If \a A doesn't have full r
ank, the function
returns <tt>false</tt>.
<DT>"NE"<DD> Compute the solution by means of the normal equations,
i.e. by applying Cholesky
decomposition to the equivalent problem <tt>A'*A
*x = A'*b</tt>. This only makes sense
when the equation is to be solved in the least s
quares sense, i.e. when \a A is a
rectangular matrix with more rows than columns.
If \a A doesn't have full column rank,
the function returns <tt>false</tt>.
</DL>
This function can be applied in-place, i.e. <tt>&b == &res</tt> or
<tt>&A == &res</tt> are allowed
(provided they have the required shapes).
The following size requirements apply:
\code
rowCount(r) == rowCount(b);
columnCount(r) == rowCount(x);
columnCount(b) == columnCount(x);
\endcode
<b>\#include</b> \<<a href="linear__solve_8hxx-source.html">vigra/linea
r_solve.hxx</a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1, class C2, class C3> template <class T, class C1, class C2, class C3>
bool linearSolve(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, bool linearSolve(const MultiArrayView<2, T, C1> &A, const MultiArrayView<2,
T, C2> &b, T, C2> &b,
MultiArrayView<2, T, C3> & res) MultiArrayView<2, T, C3> & res, std::string method = "QR")
{ {
unsigned int acols = columnCount(a); typedef typename Matrix<T>::difference_type Shape;
unsigned int bcols = columnCount(b); typedef typename Matrix<T>::view_type SubMatrix;
vigra_precondition(acols == rowCount(a),
"linearSolve(): square coefficient matrix required."); const MultiArrayIndex n = columnCount(A);
vigra_precondition(acols == rowCount(b) && acols == rowCount(res) && bc const MultiArrayIndex m = rowCount(A);
ols == columnCount(res),
vigra_precondition(n <= m,
"linearSolve(): Coefficient matrix A must have at least as many row
s as columns.");
vigra_precondition(n == rowCount(res) &&
m == rowCount(b) && columnCount(b) == columnCount(re
s),
"linearSolve(): matrix shape mismatch."); "linearSolve(): matrix shape mismatch.");
Matrix<T> q(acols, acols), r(a); for(unsigned int k=0; k<method.size(); ++k)
qrDecomposition(r, q, r); method[k] = (std::string::value_type)tolower(method[k]);
for(unsigned int k=0; k<acols; ++k)
if(r(k,k) == NumericTraits<T>::zero()) if(method == "cholesky")
return false; // a didn't have full rank. {
q.transpose(); vigra_precondition(columnCount(A) == rowCount(A),
reverseElimination(r, q * b, res); "linearSolve(): Cholesky method requires square coefficient mat
rix.");
Matrix<T> L(A.shape());
if(!choleskyDecomposition(A, L))
return false; // false if A wasn't symmetric positive definite
linearSolveLowerTriangular(L, b, res);
linearSolveUpperTriangular(transpose(L), res, res);
}
else if(method == "qr")
{
return (MultiArrayIndex)linearSolveQR(A, b, res) == n;
}
else if(method == "ne")
{
return linearSolve(transpose(A)*A, transpose(A)*b, res, "Cholesky")
;
}
else if(method == "svd")
{
MultiArrayIndex rhsCount = columnCount(b);
Matrix<T> u(A.shape()), s(n, 1), v(n, n);
MultiArrayIndex rank = (MultiArrayIndex)singularValueDecomposition(
A, u, s, v);
Matrix<T> t = transpose(u)*b;
for(MultiArrayIndex l=0; l<rhsCount; ++l)
{
for(MultiArrayIndex k=0; k<rank; ++k)
t(k,l) /= s(k,0);
for(MultiArrayIndex k=rank; k<n; ++k)
t(k,l) = NumericTraits<T>::zero();
}
res = v*t;
return (rank == n);
}
else
{
vigra_precondition(false, "linearSolve(): Unknown solution method."
);
}
return true; return true;
} }
//@} //@}
} // namespace linalg } // namespace linalg
using linalg::inverse; using linalg::inverse;
using linalg::determinant;
using linalg::logDeterminant;
using linalg::linearSolve; using linalg::linearSolve;
using linalg::choleskyDecomposition;
using linalg::qrDecomposition; using linalg::qrDecomposition;
using linalg::reverseElimination; using linalg::linearSolveUpperTriangular;
using linalg::linearSolveLowerTriangular;
} // namespace vigra } // namespace vigra
#endif // VIGRA_LINEAR_SOLVE_HXX #endif // VIGRA_LINEAR_SOLVE_HXX
 End of changes. 56 change blocks. 
181 lines changed or deleted 1256 lines changed or added


 localminmax.hxx   localminmax.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 136 skipping to change at line 136
class DestValue = DestAccessor::value_type, class DestValue = DestAccessor::value_type,
class Neighborhood = EightNeighborCode> class Neighborhood = EightNeighborCode>
void void
localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
DestValue marker = NumericTraits<DestValue>::one(), DestValue marker = NumericTraits<DestValue>::one(),
Neighborhood neighborhood = EightNeighborCode()) Neighborhood neighborhood = EightNeighborCode())
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class DestValue = DestAccessor::value_type, class DestValue = DestAccessor::value_type,
class Neighborhood = EightNeighborCode> class Neighborhood = EightNeighborCode>
void void
localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src, localMinima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
DestValue marker = NumericTraits<DestValue>::one(), DestValue marker = NumericTraits<DestValue>::one(),
Neighborhood neighborhood = EightNeighborCode()) Neighborhood neighborhood = EightNeighborCode())
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="localminmax_8hxx-source.html">vigra/loca lminmax.hxx</a>"<br> <b>\#include</b> \<<a href="localminmax_8hxx-source.html">vigra/loc alminmax.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), minima(w,h); vigra::BImage src(w,h), minima(w,h);
// init destiniation image // init destiniation image
minima = 0; minima = 0;
vigra::localMinima(srcImageRange(src), destImage(minima)); vigra::localMinima(srcImageRange(src), destImage(minima));
\endcode \endcode
skipping to change at line 183 skipping to change at line 183
SrcAccessor::value_type u = src_accessor(src_upperleft); SrcAccessor::value_type u = src_accessor(src_upperleft);
u < u u < u
DestValue marker; DestValue marker;
dest_accessor.set(marker, dest_upperleft); dest_accessor.set(marker, dest_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void localMinima)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class DestValue, class Neighborhood> class DestValue, class Neighborhood>
inline void inline void
localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, localMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
DestValue marker, Neighborhood neighborhood) DestValue marker, Neighborhood neighborhood)
{ {
detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood, detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood,
std::less<typename SrcAccessor::value_type>()); std::less<typename SrcAccessor::value_type>());
skipping to change at line 284 skipping to change at line 286
class DestValue = DestAccessor::value_type, class DestValue = DestAccessor::value_type,
class Neighborhood = EightNeighborCode> class Neighborhood = EightNeighborCode>
void void
localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
DestValue marker = NumericTraits<DestValue>::one(), DestValue marker = NumericTraits<DestValue>::one(),
Neighborhood neighborhood = EightNeighborCode()) Neighborhood neighborhood = EightNeighborCode())
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class DestValue = DestAccessor::value_type, class DestValue = DestAccessor::value_type,
class Neighborhood = EightNeighborCode> class Neighborhood = EightNeighborCode>
void void
localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src, localMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
DestValue marker = NumericTraits<DestValue>::one(), DestValue marker = NumericTraits<DestValue>::one(),
Neighborhood neighborhood = EightNeighborCode()) Neighborhood neighborhood = EightNeighborCode())
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="localminmax_8hxx-source.html">vigra/loca lminmax.hxx</a>"<br> <b>\#include</b> \<<a href="localminmax_8hxx-source.html">vigra/loc alminmax.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), maxima(w,h); vigra::BImage src(w,h), maxima(w,h);
// init destiniation image // init destiniation image
maxima = 0; maxima = 0;
vigra::localMaxima(srcImageRange(src), destImage(maxima)); vigra::localMaxima(srcImageRange(src), destImage(maxima));
\endcode \endcode
skipping to change at line 331 skipping to change at line 333
SrcAccessor::value_type u = src_accessor(src_upperleft); SrcAccessor::value_type u = src_accessor(src_upperleft);
u < u u < u
DestValue marker; DestValue marker;
dest_accessor.set(marker, dest_upperleft); dest_accessor.set(marker, dest_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void localMaxima)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class DestValue, class Neighborhood> class DestValue, class Neighborhood>
inline void inline void
localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, localMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
DestValue marker, Neighborhood neighborhood) DestValue marker, Neighborhood neighborhood)
{ {
detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood, detail::localMinMax(sul, slr, sa, dul, da, marker, neighborhood,
std::greater<typename SrcAccessor::value_type>()); std::greater<typename SrcAccessor::value_type>());
skipping to change at line 515 skipping to change at line 519
class EqualityFunctor = std::equal_to<typename SrcAssesso r::value_type> > class EqualityFunctor = std::equal_to<typename SrcAssesso r::value_type> >
void void
extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor s a, extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor s a,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
DestValue marker = NumericTraits<DestValue>::on e(), DestValue marker = NumericTraits<DestValue>::on e(),
Neighborhood neighborhood = EightNeighborCode() , Neighborhood neighborhood = EightNeighborCode() ,
EqualityFunctor equal = EqualityFunctor()) EqualityFunctor equal = EqualityFunctor())
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class DestValue = DestAccessor::value_type, class DestValue = DestAccessor::value_type,
class Neighborhood = EightNeighborCode, class Neighborhood = EightNeighborCode,
class EqualityFunctor = std::equal_to<typename SrcAssesso r::value_type> > class EqualityFunctor = std::equal_to<typename SrcAssesso r::value_type> >
void void
extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> s rc, extendedLocalMinima(triple<SrcIterator, SrcIterator, SrcAccessor> s rc,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
DestValue marker = NumericTraits<DestValue>::on e(), DestValue marker = NumericTraits<DestValue>::on e(),
Neighborhood neighborhood = EightNeighborCode() , Neighborhood neighborhood = EightNeighborCode() ,
EqualityFunctor equal = EqualityFunctor()) EqualityFunctor equal = EqualityFunctor())
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="localminmax_8hxx-source.html">vigra/loca lminmax.hxx</a>"<br> <b>\#include</b> \<<a href="localminmax_8hxx-source.html">vigra/loc alminmax.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
// optional: define an equality functor // optional: define an equality functor
template <class T> template <class T>
struct EqualWithToleranceFunctor struct EqualWithToleranceFunctor
{ {
EqualWithToleranceFunctor(T tolerance) EqualWithToleranceFunctor(T tolerance)
: t(tolerance) : t(tolerance)
skipping to change at line 589 skipping to change at line 593
EqualityFunctor equal; EqualityFunctor equal;
u == u u == u
equal(u, u); equal(u, u);
u < u u < u
DestValue marker; DestValue marker;
dest_accessor.set(marker, dest_upperleft); dest_accessor.set(marker, dest_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void extendedLocalMinima)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestValue, class DestIterator, class DestAccessor, class DestValue,
class Neighborhood, class EqualityFunctor> class Neighborhood, class EqualityFunctor>
inline void inline void
extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, extendedLocalMinima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestValue marker, DestIterator dul, DestAccessor da, DestValue marker,
Neighborhood neighborhood, EqualityFunctor equal) Neighborhood neighborhood, EqualityFunctor equal)
{ {
typedef typename SrcAccessor::value_type SrcType; typedef typename SrcAccessor::value_type SrcType;
skipping to change at line 731 skipping to change at line 737
class EqualityFunctor = std::equal_to<typename SrcAssesso r::value_type> > class EqualityFunctor = std::equal_to<typename SrcAssesso r::value_type> >
void void
extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor s a, extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor s a,
DestIterator dul, DestAccessor da, DestIterator dul, DestAccessor da,
DestValue marker = NumericTraits<DestValue>::on e(), DestValue marker = NumericTraits<DestValue>::on e(),
Neighborhood neighborhood = EightNeighborCode() , Neighborhood neighborhood = EightNeighborCode() ,
EqualityFunctor equal = EqualityFunctor()) EqualityFunctor equal = EqualityFunctor())
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class DestValue = DestAccessor::value_type, class DestValue = DestAccessor::value_type,
class Neighborhood = EightNeighborCode, class Neighborhood = EightNeighborCode,
class EqualityFunctor = std::equal_to<typename SrcAssesso r::value_type> > class EqualityFunctor = std::equal_to<typename SrcAssesso r::value_type> >
void void
extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> s rc, extendedLocalMaxima(triple<SrcIterator, SrcIterator, SrcAccessor> s rc,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
DestValue marker = NumericTraits<DestValue>::on e(), DestValue marker = NumericTraits<DestValue>::on e(),
Neighborhood neighborhood = EightNeighborCode() , Neighborhood neighborhood = EightNeighborCode() ,
EqualityFunctor equal = EqualityFunctor()) EqualityFunctor equal = EqualityFunctor())
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="localminmax_8hxx-source.html">vigra/loca lminmax.hxx</a>"<br> <b>\#include</b> \<<a href="localminmax_8hxx-source.html">vigra/loc alminmax.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
// optional: define an equality functor // optional: define an equality functor
template <class T> template <class T>
struct EqualWithToleranceFunctor struct EqualWithToleranceFunctor
{ {
EqualWithToleranceFunctor(T tolerance) EqualWithToleranceFunctor(T tolerance)
: t(tolerance) : t(tolerance)
skipping to change at line 805 skipping to change at line 811
EqualityFunctor equal; EqualityFunctor equal;
u == u u == u
equal(u, u); equal(u, u);
u < u u < u
DestValue marker; DestValue marker;
dest_accessor.set(marker, dest_upperleft); dest_accessor.set(marker, dest_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void extendedLocalMaxima)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestValue, class DestIterator, class DestAccessor, class DestValue,
class Neighborhood, class EqualityFunctor> class Neighborhood, class EqualityFunctor>
inline void inline void
extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa, extendedLocalMaxima(SrcIterator sul, SrcIterator slr, SrcAccessor sa,
DestIterator dul, DestAccessor da, DestValue marker, DestIterator dul, DestAccessor da, DestValue marker,
Neighborhood neighborhood, EqualityFunctor equal) Neighborhood neighborhood, EqualityFunctor equal)
{ {
typedef typename SrcAccessor::value_type SrcType; typedef typename SrcAccessor::value_type SrcType;
 End of changes. 14 change blocks. 
11 lines changed or deleted 19 lines changed or added


 mathutil.hxx   mathutil.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2005 by Ullrich Koethe */ /* Copyright 1998-2005 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 53 skipping to change at line 53
#include "config.hxx" #include "config.hxx"
#include "error.hxx" #include "error.hxx"
#include "tuple.hxx" #include "tuple.hxx"
#include "sized_int.hxx" #include "sized_int.hxx"
#include "numerictraits.hxx" #include "numerictraits.hxx"
/*! \page MathConstants Mathematical Constants /*! \page MathConstants Mathematical Constants
<TT>M_PI, M_SQRT2</TT> <TT>M_PI, M_SQRT2</TT>
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathutil.hx x</a>" <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathutil.h xx</a>\>
Since <TT>M_PI</TT> and <TT>M_SQRT2</TT> are not officially standardize d, Since <TT>M_PI</TT> and <TT>M_SQRT2</TT> are not officially standardize d,
we provide definitions here for those compilers that don't support them . we provide definitions here for those compilers that don't support them .
\code \code
#ifndef M_PI #ifndef M_PI
# define M_PI 3.14159265358979323846 # define M_PI 3.14159265358979323846
#endif #endif
#ifndef M_SQRT2 #ifndef M_SQRT2
skipping to change at line 120 skipping to change at line 120
VIGRA_DEFINE_MISSING_ABS(signed char) VIGRA_DEFINE_MISSING_ABS(signed char)
VIGRA_DEFINE_MISSING_ABS(signed short) VIGRA_DEFINE_MISSING_ABS(signed short)
#undef VIGRA_DEFINE_MISSING_ABS #undef VIGRA_DEFINE_MISSING_ABS
/*! The rounding function. /*! The rounding function.
Defined for all floating point types. Rounds towards the nearest in teger Defined for all floating point types. Rounds towards the nearest in teger
such that <tt>abs(round(t)) == round(abs(t))</tt> for all <tt>t</tt >. such that <tt>abs(round(t)) == round(abs(t))</tt> for all <tt>t</tt >.
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
inline float round(float t) inline float round(float t)
{ {
return t >= 0.0 return t >= 0.0
? floor(t + 0.5) ? floor(t + 0.5)
: ceil(t - 0.5); : ceil(t - 0.5);
} }
inline double round(double t) inline double round(double t)
skipping to change at line 144 skipping to change at line 144
: ceil(t - 0.5); : ceil(t - 0.5);
} }
inline long double round(long double t) inline long double round(long double t)
{ {
return t >= 0.0 return t >= 0.0
? floor(t + 0.5) ? floor(t + 0.5)
: ceil(t - 0.5); : ceil(t - 0.5);
} }
/*! Round up to the nearest power of 2.
Efficient algorithm for finding the smallest power of 2 which is no
t smaller than \a x
(function clp2() from Henry Warren: "Hacker's Delight", Addison-Wes
ley, 2003,
see http://www.hackersdelight.org/).
If \a x > 2^31, the function will return 0 because integer arithmet
ic is defined modulo 2^32.
<b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut
il.hxx</a>\><br>
Namespace: vigra
*/
inline UInt32 ceilPower2(UInt32 x)
{
if(x == 0) return 0;
x = x - 1;
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >>16);
return x + 1;
}
/*! Round down to the nearest power of 2.
Efficient algorithm for finding the largest power of 2 which is not
greater than \a x
(function flp2() from Henry Warren: "Hacker's Delight", Addison-Wes
ley, 2003,
see http://www.hackersdelight.org/).
<b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut
il.hxx</a>\><br>
Namespace: vigra
*/
inline UInt32 floorPower2(UInt32 x)
{
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >>16);
return x - (x >> 1);
}
namespace detail {
template <class T>
class IntLog2
{
public:
static Int32 table[64];
};
template <class T>
Int32 IntLog2<T>::table[64] = {
-1, 0, -1, 15, -1, 1, 28, -1, 16, -1, -1, -1, 2, 21,
29, -1, -1, -1, 19, 17, 10, -1, 12, -1, -1, 3, -1, 6,
-1, 22, 30, -1, 14, -1, 27, -1, -1, -1, 20, -1, 18, 9
,
11, -1, 5, -1, -1, 13, 26, -1, -1, 8, -1, 4, -1, 25,
-1, 7, 24, -1, 23, -1, 31, -1};
} // namespace detail
/*! Compute the base-2 logarithm of an integer.
Returns the position of the left-most 1-bit in the given number \a
x, or
-1 if \a x == 0. That is,
\code
assert(k >= 0 && k < 32 && log2i(1 << k) == k);
\endcode
The function uses Robert Harley's algorithm to determine the number
of leading zeros
in \a x (algorithm nlz10() at http://www.hackersdelight.org/). But
note that the functions
\ref floorPower2() or \ref ceilPower2() are more efficient and shou
ld be preferred when possible.
<b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut
il.hxx</a>\><br>
Namespace: vigra
*/
inline Int32 log2i(UInt32 x)
{
// Propagate leftmost 1-bit to the right.
x = x | (x >> 1);
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >>16);
x = x*0x06EB14F9; // Multiplier is 7*255**3.
return detail::IntLog2<Int32>::table[x >> 26];
}
/*! The square function. /*! The square function.
sq(x) is needed so often that it makes sense to define it as a func tion. <tt>sq(x) = x*x</tt> is needed so often that it makes sense to defi ne it as a function.
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class T> template <class T>
inline inline
typename NumericTraits<T>::Promote sq(T t) typename NumericTraits<T>::Promote sq(T t)
{ {
return t*t; return t*t;
} }
namespace detail { namespace detail {
template <class T> template <class T>
class IntSquareRoot class IntSquareRoot
{ {
public: public:
static int sqq_table[]; static UInt32 sqq_table[];
static UInt32 exec(UInt32 v); static UInt32 exec(UInt32 v);
}; };
template <class T> template <class T>
int IntSquareRoot<T>::sqq_table[] = { UInt32 IntSquareRoot<T>::sqq_table[] = {
0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53, 55 , 57, 0, 16, 22, 27, 32, 35, 39, 42, 45, 48, 50, 53, 55 , 57,
59, 61, 64, 65, 67, 69, 71, 73, 75, 76, 78, 80, 81 , 83, 59, 61, 64, 65, 67, 69, 71, 73, 75, 76, 78, 80, 81 , 83,
84, 86, 87, 89, 90, 91, 93, 94, 96, 97, 98, 99, 101 , 102, 84, 86, 87, 89, 90, 91, 93, 94, 96, 97, 98, 99, 101 , 102,
103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117 , 118, 103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117 , 118,
119, 120, 121, 122, 123, 124, 125, 126, 128, 128, 129, 130, 131 , 132, 119, 120, 121, 122, 123, 124, 125, 126, 128, 128, 129, 130, 131 , 132,
133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144 , 145, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144 , 145,
146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155, 156 , 157, 146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155, 156 , 157,
158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167 , 168, 158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167 , 168,
169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178 , 178, 169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178 , 178,
179, 180, 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187 , 188, 179, 180, 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187 , 188,
skipping to change at line 261 skipping to change at line 350
} }
} // namespace detail } // namespace detail
using VIGRA_CSTD::sqrt; using VIGRA_CSTD::sqrt;
/*! Signed integer square root. /*! Signed integer square root.
Useful for fast fixed-point computations. Useful for fast fixed-point computations.
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
inline Int32 sqrti(Int32 v) inline Int32 sqrti(Int32 v)
{ {
if(v < 0) if(v < 0)
throw std::domain_error("sqrti(Int32): negative argument."); throw std::domain_error("sqrti(Int32): negative argument.");
return (Int32)detail::IntSquareRoot<UInt32>::exec((UInt32)v); return (Int32)detail::IntSquareRoot<UInt32>::exec((UInt32)v);
} }
/*! Unsigned integer square root. /*! Unsigned integer square root.
Useful for fast fixed-point computations. Useful for fast fixed-point computations.
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
inline UInt32 sqrti(UInt32 v) inline UInt32 sqrti(UInt32 v)
{ {
return detail::IntSquareRoot<UInt32>::exec(v); return detail::IntSquareRoot<UInt32>::exec(v);
} }
#ifndef VIGRA_HAS_HYPOT #ifndef VIGRA_HAS_HYPOT
/*! Compute the Euclidean distance (length of the hypothenuse of a righ t-angled triangle). /*! Compute the Euclidean distance (length of the hypothenuse of a righ t-angled triangle).
The hypot() function returns the sqrt(a*a + b*b). The hypot() function returns the sqrt(a*a + b*b).
It is implemented in a way that minimizes round-off error. It is implemented in a way that minimizes round-off error.
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
inline double hypot(double a, double b) inline double hypot(double a, double b)
{ {
double absa = VIGRA_CSTD::fabs(a), absb = VIGRA_CSTD::fabs(b); double absa = VIGRA_CSTD::fabs(a), absb = VIGRA_CSTD::fabs(b);
if (absa > absb) if (absa > absb)
return absa * VIGRA_CSTD::sqrt(1.0 + sq(absb/absa)); return absa * VIGRA_CSTD::sqrt(1.0 + sq(absb/absa));
else else
return absb == 0.0 return absb == 0.0
? 0.0 ? 0.0
skipping to change at line 313 skipping to change at line 402
#else #else
using ::hypot; using ::hypot;
#endif #endif
/*! The sign function. /*! The sign function.
Returns 1, 0, or -1 depending on the sign of \a t. Returns 1, 0, or -1 depending on the sign of \a t.
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class T> template <class T>
T sign(T t) inline T sign(T t)
{ {
return t > NumericTraits<T>::zero() return t > NumericTraits<T>::zero()
? NumericTraits<T>::one() ? NumericTraits<T>::one()
: t < NumericTraits<T>::zero() : t < NumericTraits<T>::zero()
? -NumericTraits<T>::one() ? -NumericTraits<T>::one()
: NumericTraits<T>::zero(); : NumericTraits<T>::zero();
} }
/*! The binary sign function. /*! The binary sign function.
Transfers the sign of \a t2 to \a t1. Transfers the sign of \a t2 to \a t1.
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class T1, class T2> template <class T1, class T2>
T1 sign(T1 t1, T2 t2) inline T1 sign(T1 t1, T2 t2)
{ {
return t2 >= NumericTraits<T2>::zero() return t2 >= NumericTraits<T2>::zero()
? abs(t1) ? abs(t1)
: -abs(t1); : -abs(t1);
} }
#define VIGRA_DEFINE_NORM(T) \ #define VIGRA_DEFINE_NORM(T) \
inline NormTraits<T>::SquaredNormType squaredNorm(T t) { return sq(t); } \ inline NormTraits<T>::SquaredNormType squaredNorm(T t) { return sq(t); } \
inline NormTraits<T>::NormType norm(T t) { return abs(t); } inline NormTraits<T>::NormType norm(T t) { return abs(t); }
skipping to change at line 384 skipping to change at line 473
*/ */
NormTraits<T>::SquaredNormType squaredNorm(T const & t); NormTraits<T>::SquaredNormType squaredNorm(T const & t);
#endif #endif
/*! The norm of a numerical object. /*! The norm of a numerical object.
For scalar types: implemented as <tt>abs(t)</tt><br> For scalar types: implemented as <tt>abs(t)</tt><br>
otherwise: implemented as <tt>sqrt(squaredNorm(t))</tt>. otherwise: implemented as <tt>sqrt(squaredNorm(t))</tt>.
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class T> template <class T>
inline typename NormTraits<T>::NormType inline typename NormTraits<T>::NormType
norm(T const & t) norm(T const & t)
{ {
typedef typename NormTraits<T>::SquaredNormType SNT; typedef typename NormTraits<T>::SquaredNormType SNT;
return sqrt(static_cast<typename SquareRootTraits<SNT>::SquareRootArgum ent>(squaredNorm(t))); return sqrt(static_cast<typename SquareRootTraits<SNT>::SquareRootArgum ent>(squaredNorm(t)));
} }
/*! Find the minimum element in a sequence.
The function returns the iterator refering to the minimum element.
<b>Required Interface:</b>
\code
Iterator is a standard forward iterator.
bool f = *first < NumericTraits<typename std::iterator_traits<Itera
tor>::value_type>::max();
\endcode
<b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut
il.hxx</a>\><br>
Namespace: vigra
*/
template <class Iterator>
Iterator argMin(Iterator first, Iterator last)
{
typedef typename std::iterator_traits<Iterator>::value_type Value;
Value vopt = NumericTraits<Value>::max();
Iterator best = last;
for(; first != last; ++first)
{
if(*first < vopt)
{
vopt = *first;
best = first;
}
}
return best;
}
/*! Find the maximum element in a sequence.
The function returns the iterator refering to the maximum element.
<b>Required Interface:</b>
\code
Iterator is a standard forward iterator.
bool f = NumericTraits<typename std::iterator_traits<Iterator>::val
ue_type>::min() < *first;
\endcode
<b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut
il.hxx</a>\><br>
Namespace: vigra
*/
template <class Iterator>
Iterator argMax(Iterator first, Iterator last)
{
typedef typename std::iterator_traits<Iterator>::value_type Value;
Value vopt = NumericTraits<Value>::min();
Iterator best = last;
for(; first != last; ++first)
{
if(vopt < *first)
{
vopt = *first;
best = first;
}
}
return best;
}
/*! Find the minimum element in a sequence conforming to a condition.
The function returns the iterator refering to the minimum element,
where only elements conforming to the condition (i.e. where
<tt>condition(*iterator)</tt> evaluates to <tt>true</tt>) are consi
dered.
If no element conforms to the condition, or the sequence is empty,
the end iterator \a last is returned.
<b>Required Interface:</b>
\code
Iterator is a standard forward iterator.
bool c = condition(*first);
bool f = *first < NumericTraits<typename std::iterator_traits<Itera
tor>::value_type>::max();
\endcode
<b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut
il.hxx</a>\><br>
Namespace: vigra
*/
template <class Iterator, class UnaryFunctor>
Iterator argMinIf(Iterator first, Iterator last, UnaryFunctor condition)
{
typedef typename std::iterator_traits<Iterator>::value_type Value;
Value vopt = NumericTraits<Value>::max();
Iterator best = last;
for(; first != last; ++first)
{
if(condition(*first) && *first < vopt)
{
vopt = *first;
best = first;
}
}
return best;
}
/*! Find the maximum element in a sequence conforming to a condition.
The function returns the iterator refering to the maximum element,
where only elements conforming to the condition (i.e. where
<tt>condition(*iterator)</tt> evaluates to <tt>true</tt>) are consi
dered.
If no element conforms to the condition, or the sequence is empty,
the end iterator \a last is returned.
<b>Required Interface:</b>
\code
Iterator is a standard forward iterator.
bool c = condition(*first);
bool f = NumericTraits<typename std::iterator_traits<Iterator>::val
ue_type>::min() < *first;
\endcode
<b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut
il.hxx</a>\><br>
Namespace: vigra
*/
template <class Iterator, class UnaryFunctor>
Iterator argMaxIf(Iterator first, Iterator last, UnaryFunctor condition)
{
typedef typename std::iterator_traits<Iterator>::value_type Value;
Value vopt = NumericTraits<Value>::min();
Iterator best = last;
for(; first != last; ++first)
{
if(condition(*first) && vopt < *first)
{
vopt = *first;
best = first;
}
}
return best;
}
namespace detail { namespace detail {
template <class T> template <class T>
T ellipticRD(T x, T y, T z) T ellipticRD(T x, T y, T z)
{ {
double f = 1.0, s = 0.0, X, Y, Z, m; double f = 1.0, s = 0.0, X, Y, Z, m;
while(true) for(;;)
{ {
m = (x + y + 3.0*z) / 5.0; m = (x + y + 3.0*z) / 5.0;
X = 1.0 - x/m; X = 1.0 - x/m;
Y = 1.0 - y/m; Y = 1.0 - y/m;
Z = 1.0 - z/m; Z = 1.0 - z/m;
if(std::max(std::max(VIGRA_CSTD::fabs(X), VIGRA_CSTD::fabs(Y)), VIG RA_CSTD::fabs(Z)) < 0.01) if(std::max(std::max(VIGRA_CSTD::fabs(X), VIGRA_CSTD::fabs(Y)), VIG RA_CSTD::fabs(Z)) < 0.01)
break; break;
double l = VIGRA_CSTD::sqrt(x*y) + VIGRA_CSTD::sqrt(x*z) + VIGRA_CS TD::sqrt(y*z); double l = VIGRA_CSTD::sqrt(x*y) + VIGRA_CSTD::sqrt(x*z) + VIGRA_CS TD::sqrt(y*z);
s += f / (VIGRA_CSTD::sqrt(z)*(z + l)); s += f / (VIGRA_CSTD::sqrt(z)*(z + l));
f /= 4.0; f /= 4.0;
skipping to change at line 429 skipping to change at line 658
double d = a - 6.0*b; double d = a - 6.0*b;
double e = d + 2.0*c; double e = d + 2.0*c;
return 3.0*s + f*(1.0+d*(-3.0/14.0+d*9.0/88.0-Z*e*4.5/26.0) return 3.0*s + f*(1.0+d*(-3.0/14.0+d*9.0/88.0-Z*e*4.5/26.0)
+Z*(e/6.0+Z*(-c*9.0/22.0+a*Z*3.0/26.0))) / VIGRA_CSTD ::pow(m,1.5); +Z*(e/6.0+Z*(-c*9.0/22.0+a*Z*3.0/26.0))) / VIGRA_CSTD ::pow(m,1.5);
} }
template <class T> template <class T>
T ellipticRF(T x, T y, T z) T ellipticRF(T x, T y, T z)
{ {
double X, Y, Z, m; double X, Y, Z, m;
while(true) for(;;)
{ {
m = (x + y + z) / 3.0; m = (x + y + z) / 3.0;
X = 1.0 - x/m; X = 1.0 - x/m;
Y = 1.0 - y/m; Y = 1.0 - y/m;
Z = 1.0 - z/m; Z = 1.0 - z/m;
if(std::max(std::max(VIGRA_CSTD::fabs(X), VIGRA_CSTD::fabs(Y)), VIG RA_CSTD::fabs(Z)) < 0.01) if(std::max(std::max(VIGRA_CSTD::fabs(X), VIGRA_CSTD::fabs(Y)), VIG RA_CSTD::fabs(Z)) < 0.01)
break; break;
double l = VIGRA_CSTD::sqrt(x*y) + VIGRA_CSTD::sqrt(x*z) + VIGRA_CS TD::sqrt(y*z); double l = VIGRA_CSTD::sqrt(x*y) + VIGRA_CSTD::sqrt(x*z) + VIGRA_CS TD::sqrt(y*z);
x = (x + l)/4.0; x = (x + l)/4.0;
y = (y + l)/4.0; y = (y + l)/4.0;
skipping to change at line 462 skipping to change at line 691
\f[ \f[
\mbox{F}(x, k) = \int_0^x \frac{1}{\sqrt{1 - k^2 \sin(t)^2}} dt \mbox{F}(x, k) = \int_0^x \frac{1}{\sqrt{1 - k^2 \sin(t)^2}} dt
\f] \f]
according to the algorithm given in Press et al. "Numerical Recipes ". according to the algorithm given in Press et al. "Numerical Recipes ".
Note: In some libraries (e.g. Mathematica), the second parameter of the elliptic integral Note: In some libraries (e.g. Mathematica), the second parameter of the elliptic integral
functions must be k^2 rather than k. Check the documentation when r esults disagree! functions must be k^2 rather than k. Check the documentation when r esults disagree!
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
inline double ellipticIntegralF(double x, double k) inline double ellipticIntegralF(double x, double k)
{ {
double c2 = sq(VIGRA_CSTD::cos(x)); double c2 = sq(VIGRA_CSTD::cos(x));
double s = VIGRA_CSTD::sin(x); double s = VIGRA_CSTD::sin(x);
return s*detail::ellipticRF(c2, 1.0 - sq(k*s), 1.0); return s*detail::ellipticRF(c2, 1.0 - sq(k*s), 1.0);
} }
/*! The incomplete elliptic integral of the second kind. /*! The incomplete elliptic integral of the second kind.
skipping to change at line 486 skipping to change at line 715
\f[ \f[
\mbox{E}(x, k) = \int_0^x \sqrt{1 - k^2 \sin(t)^2} dt \mbox{E}(x, k) = \int_0^x \sqrt{1 - k^2 \sin(t)^2} dt
\f] \f]
according to the algorithm given in Press et al. "Numerical Recipes ". The according to the algorithm given in Press et al. "Numerical Recipes ". The
complete elliptic integral of the second kind is simply <tt>ellipti cIntegralE(M_PI/2, k)</TT>. complete elliptic integral of the second kind is simply <tt>ellipti cIntegralE(M_PI/2, k)</TT>.
Note: In some libraries (e.g. Mathematica), the second parameter of the elliptic integral Note: In some libraries (e.g. Mathematica), the second parameter of the elliptic integral
functions must be k^2 rather than k. Check the documentation when r esults disagree! functions must be k^2 rather than k. Check the documentation when r esults disagree!
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
inline double ellipticIntegralE(double x, double k) inline double ellipticIntegralE(double x, double k)
{ {
double c2 = sq(VIGRA_CSTD::cos(x)); double c2 = sq(VIGRA_CSTD::cos(x));
double s = VIGRA_CSTD::sin(x); double s = VIGRA_CSTD::sin(x);
k = sq(k*s); k = sq(k*s);
return s*(detail::ellipticRF(c2, 1.0-k, 1.0) - k/3.0*detail::ellipticRD (c2, 1.0-k, 1.0)); return s*(detail::ellipticRF(c2, 1.0-k, 1.0) - k/3.0*detail::ellipticRD (c2, 1.0-k, 1.0));
} }
skipping to change at line 529 skipping to change at line 758
If <tt>erf()</tt> is not provided in the C standard math library (a s it should according to the If <tt>erf()</tt> is not provided in the C standard math library (a s it should according to the
new C99 standard ?), VIGRA implements <tt>erf()</tt> as an approxim ation of the error new C99 standard ?), VIGRA implements <tt>erf()</tt> as an approxim ation of the error
function function
\f[ \f[
\mbox{erf}(x) = \int_0^x e^{-t^2} dt \mbox{erf}(x) = \int_0^x e^{-t^2} dt
\f] \f]
according to the formula given in Press et al. "Numerical Recipes". according to the formula given in Press et al. "Numerical Recipes".
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
inline double erf(double x) inline double erf(double x)
{ {
return detail::erfImpl(x); return detail::erfImpl(x);
} }
#else #else
using VIGRA_CSTD::erf; using VIGRA_CSTD::erf;
skipping to change at line 649 skipping to change at line 878
} }
} // namespace detail } // namespace detail
/*! Chi square distribution. /*! Chi square distribution.
Computes the density of a chi square distribution with \a degreesOf Freedom Computes the density of a chi square distribution with \a degreesOf Freedom
and tolerance \a accuracy at the given argument \a arg and tolerance \a accuracy at the given argument \a arg
by calling <tt>noncentralChi2(degreesOfFreedom, 0.0, arg, accuracy) </tt>. by calling <tt>noncentralChi2(degreesOfFreedom, 0.0, arg, accuracy) </tt>.
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
inline double chi2(unsigned int degreesOfFreedom, double arg, double accura cy = 1e-7) inline double chi2(unsigned int degreesOfFreedom, double arg, double accura cy = 1e-7)
{ {
return detail::noncentralChi2CDF(degreesOfFreedom, 0.0, arg, accuracy). first; return detail::noncentralChi2CDF(degreesOfFreedom, 0.0, arg, accuracy). first;
} }
/*! Cumulative chi square distribution. /*! Cumulative chi square distribution.
Computes the cumulative density of a chi square distribution with \ a degreesOfFreedom Computes the cumulative density of a chi square distribution with \ a degreesOfFreedom
and tolerance \a accuracy at the given argument \a arg, i.e. the pr obability that and tolerance \a accuracy at the given argument \a arg, i.e. the pr obability that
a random number drawn from the distribution is below \a arg a random number drawn from the distribution is below \a arg
by calling <tt>noncentralChi2CDF(degreesOfFreedom, 0.0, arg, accura cy)</tt>. by calling <tt>noncentralChi2CDF(degreesOfFreedom, 0.0, arg, accura cy)</tt>.
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
inline double chi2CDF(unsigned int degreesOfFreedom, double arg, double acc uracy = 1e-7) inline double chi2CDF(unsigned int degreesOfFreedom, double arg, double acc uracy = 1e-7)
{ {
return detail::noncentralChi2CDF(degreesOfFreedom, 0.0, arg, accuracy). second; return detail::noncentralChi2CDF(degreesOfFreedom, 0.0, arg, accuracy). second;
} }
/*! Non-central chi square distribution. /*! Non-central chi square distribution.
Computes the density of a non-central chi square distribution with \a degreesOfFreedom, Computes the density of a non-central chi square distribution with \a degreesOfFreedom,
noncentrality parameter \a noncentrality and tolerance \a accuracy at the given argument noncentrality parameter \a noncentrality and tolerance \a accuracy at the given argument
\a arg. It uses Algorithm AS 231 from Appl. Statist. (1987) Vol.36, No.3 (code ported from \a arg. It uses Algorithm AS 231 from Appl. Statist. (1987) Vol.36, No.3 (code ported from
http://lib.stat.cmu.edu/apstat/231). The algorithm has linear compl exity in the number of http://lib.stat.cmu.edu/apstat/231). The algorithm has linear compl exity in the number of
degrees of freedom. degrees of freedom.
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
inline double noncentralChi2(unsigned int degreesOfFreedom, inline double noncentralChi2(unsigned int degreesOfFreedom,
double noncentrality, double arg, double accuracy = 1e-7) double noncentrality, double arg, double accuracy = 1e-7)
{ {
return detail::noncentralChi2CDF(degreesOfFreedom, noncentrality, arg, accuracy).first; return detail::noncentralChi2CDF(degreesOfFreedom, noncentrality, arg, accuracy).first;
} }
/*! Cumulative non-central chi square distribution. /*! Cumulative non-central chi square distribution.
Computes the cumulative density of a chi square distribution with \ a degreesOfFreedom, Computes the cumulative density of a chi square distribution with \ a degreesOfFreedom,
noncentrality parameter \a noncentrality and tolerance \a accuracy at the given argument noncentrality parameter \a noncentrality and tolerance \a accuracy at the given argument
\a arg, i.e. the probability that a random number drawn from the di stribution is below \a arg \a arg, i.e. the probability that a random number drawn from the di stribution is below \a arg
It uses Algorithm AS 231 from Appl. Statist. (1987) Vol.36, No.3 (c ode ported from It uses Algorithm AS 231 from Appl. Statist. (1987) Vol.36, No.3 (c ode ported from
http://lib.stat.cmu.edu/apstat/231). The algorithm has linear compl exity in the number of http://lib.stat.cmu.edu/apstat/231). The algorithm has linear compl exity in the number of
degrees of freedom (see noncentralChi2CDFApprox() for a constant-ti me algorithm). degrees of freedom (see noncentralChi2CDFApprox() for a constant-ti me algorithm).
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
inline double noncentralChi2CDF(unsigned int degreesOfFreedom, inline double noncentralChi2CDF(unsigned int degreesOfFreedom,
double noncentrality, double arg, double accuracy = 1e-7) double noncentrality, double arg, double accuracy = 1e-7)
{ {
return detail::noncentralChi2CDF(degreesOfFreedom, noncentrality, arg, accuracy).second; return detail::noncentralChi2CDF(degreesOfFreedom, noncentrality, arg, accuracy).second;
} }
/*! Cumulative non-central chi square distribution (approximate). /*! Cumulative non-central chi square distribution (approximate).
Computes approximate values of the cumulative density of a chi squa re distribution with \a degreesOfFreedom, Computes approximate values of the cumulative density of a chi squa re distribution with \a degreesOfFreedom,
and noncentrality parameter \a noncentrality at the given argument and noncentrality parameter \a noncentrality at the given argument
\a arg, i.e. the probability that a random number drawn from the di stribution is below \a arg \a arg, i.e. the probability that a random number drawn from the di stribution is below \a arg
It uses the approximate transform into a normal distribution due to Wilson and Hilferty It uses the approximate transform into a normal distribution due to Wilson and Hilferty
(see Abramovitz, Stegun: "Handbook of Mathematical Functions", form ula 26.3.32). (see Abramovitz, Stegun: "Handbook of Mathematical Functions", form ula 26.3.32).
The algorithm's running time is independent of the inputs, i.e. is should be used The algorithm's running time is independent of the inputs, i.e. is should be used
when noncentralChi2CDF() is too slow, and approximate values are su fficient. The accuracy is only when noncentralChi2CDF() is too slow, and approximate values are su fficient. The accuracy is only
about 0.1 for few degrees of freedom, but reaches about 0.001 above dof = 5. about 0.1 for few degrees of freedom, but reaches about 0.001 above dof = 5.
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
inline double noncentralChi2CDFApprox(unsigned int degreesOfFreedom, double noncentrality, double arg) inline double noncentralChi2CDFApprox(unsigned int degreesOfFreedom, double noncentrality, double arg)
{ {
return detail::noncentralChi2CDFApprox(degreesOfFreedom, noncentrality, arg); return detail::noncentralChi2CDFApprox(degreesOfFreedom, noncentrality, arg);
} }
namespace detail { namespace detail {
// both f1 and f2 are unsigned here // both f1 and f2 are unsigned here
skipping to change at line 750 skipping to change at line 979
} // namespace detail } // namespace detail
/*! Tolerance based floating-point comparison. /*! Tolerance based floating-point comparison.
Check whether two floating point numbers are equal within the given tolerance. Check whether two floating point numbers are equal within the given tolerance.
This is useful because floating point numbers that should be equal in theory are This is useful because floating point numbers that should be equal in theory are
rarely exactly equal in practice. If the tolerance \a epsilon is no t given, rarely exactly equal in practice. If the tolerance \a epsilon is no t given,
twice the machine epsilon is used. twice the machine epsilon is used.
<b>\#include</b> "<a href="mathutil_8hxx-source.html">vigra/mathuti l.hxx</a>"<br> <b>\#include</b> \<<a href="mathutil_8hxx-source.html">vigra/mathut il.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class T1, class T2> template <class T1, class T2>
bool closeAtTolerance(T1 l, T2 r, typename PromoteTraits<T1, T2>::Promote e bool
psilon) closeAtTolerance(T1 l, T2 r, typename PromoteTraits<T1, T2>::Promote epsilo
n)
{ {
typedef typename PromoteTraits<T1, T2>::Promote T; typedef typename PromoteTraits<T1, T2>::Promote T;
if(l == 0.0) if(l == 0.0)
return VIGRA_CSTD::fabs(r) <= epsilon; return VIGRA_CSTD::fabs(r) <= epsilon;
if(r == 0.0) if(r == 0.0)
return VIGRA_CSTD::fabs(l) <= epsilon; return VIGRA_CSTD::fabs(l) <= epsilon;
T diff = VIGRA_CSTD::fabs( l - r ); T diff = VIGRA_CSTD::fabs( l - r );
T d1 = detail::safeFloatDivision<T>( diff, VIGRA_CSTD::fabs( r ) ); T d1 = detail::safeFloatDivision<T>( diff, VIGRA_CSTD::fabs( r ) );
T d2 = detail::safeFloatDivision<T>( diff, VIGRA_CSTD::fabs( l ) ); T d2 = detail::safeFloatDivision<T>( diff, VIGRA_CSTD::fabs( l ) );
return (d1 <= epsilon && d2 <= epsilon); return (d1 <= epsilon && d2 <= epsilon);
} }
template <class T1, class T2> template <class T1, class T2>
bool closeAtTolerance(T1 l, T2 r) inline bool closeAtTolerance(T1 l, T2 r)
{ {
typedef typename PromoteTraits<T1, T2>::Promote T; typedef typename PromoteTraits<T1, T2>::Promote T;
return closeAtTolerance(l, r, 2.0 * NumericTraits<T>::epsilon()); return closeAtTolerance(l, r, 2.0 * NumericTraits<T>::epsilon());
} }
//@} //@}
} // namespace vigra } // namespace vigra
#endif /* VIGRA_MATHUTIL_HXX */ #endif /* VIGRA_MATHUTIL_HXX */
 End of changes. 31 change blocks. 
31 lines changed or deleted 284 lines changed or added


 matrix.hxx   matrix.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2004 by Gunnar Kedenburg and Ullrich Koethe */ /* Copyright 2003-2008 by Gunnar Kedenburg and Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 51 skipping to change at line 50
#include <cmath> #include <cmath>
#include <iosfwd> #include <iosfwd>
#include <iomanip> #include <iomanip>
#include "multi_array.hxx" #include "multi_array.hxx"
#include "mathutil.hxx" #include "mathutil.hxx"
#include "numerictraits.hxx" #include "numerictraits.hxx"
namespace vigra namespace vigra
{ {
/** \defgroup LinearAlgebraModule Linear Algebra
\brief Classes and functions for matrix algebra, linear equations syste
ms, eigen systems, least squares etc.
*/
/** \ingroup LinearAlgebraModule
Namespace <tt>vigra/linalg</tt> hold VIGRA's linear algebra functionali
ty. But most of its contents
is exported into namespace <tt>vigra</tt> via <tt>using</tt> directives
.
*/
namespace linalg namespace linalg
{ {
template <class T, class C> template <class T, class C>
inline std::size_t rowCount(const MultiArrayView<2, T, C> &x); inline MultiArrayIndex
rowCount(const MultiArrayView<2, T, C> &x);
template <class T, class C> template <class T, class C>
inline std::size_t columnCount(const MultiArrayView<2, T, C> &x); inline MultiArrayIndex
columnCount(const MultiArrayView<2, T, C> &x);
template <class T, class C> template <class T, class C>
MultiArrayView <2, T, C> inline MultiArrayView <2, T, C>
rowVector(MultiArrayView <2, T, C> const & m, int d); rowVector(MultiArrayView <2, T, C> const & m, MultiArrayIndex d);
template <class T, class C> template <class T, class C>
MultiArrayView <2, T, C> inline MultiArrayView <2, T, C>
columnVector(MultiArrayView<2, T, C> const & m, int d); columnVector(MultiArrayView<2, T, C> const & m, MultiArrayIndex d);
template <class T, class ALLOC> template <class T, class ALLOC>
class TemporaryMatrix; class TemporaryMatrix;
template <class T, class C1, class C2> template <class T, class C1, class C2>
void transpose(const MultiArrayView<2, T, C1> &v, MultiArrayView<2, T, C2> &r); void transpose(const MultiArrayView<2, T, C1> &v, MultiArrayView<2, T, C2> &r);
template <class T, class C> template <class T, class C>
bool isSymmetric(const MultiArrayView<2, T, C> &v); bool isSymmetric(const MultiArrayView<2, T, C> &v);
enum RawArrayMemoryLayout { RowMajor, ColumnMajor }; enum RawArrayMemoryLayout { RowMajor, ColumnMajor };
/********************************************************/ /********************************************************/
/* */ /* */
/* Matrix */ /* Matrix */
/* */ /* */
/********************************************************/ /********************************************************/
/** Matrix class. /** Matrix class.
\ingroup LinearAlgebraModule
This is the basic class for all linear algebra computations. Matrices a re This is the basic class for all linear algebra computations. Matrices a re
strored in a <i>column-major</i> format, i.e. the row index is varying fastest. strored in a <i>column-major</i> format, i.e. the row index is varying fastest.
This is the same format as in the lapack and gmm++ libraries, so it wil l This is the same format as in the lapack and gmm++ libraries, so it wil l
be easy to interface these libraries. In fact, if you need optimized be easy to interface these libraries. In fact, if you need optimized
high performance code, you should use them. The VIGRA linear algebra high performance code, you should use them. The VIGRA linear algebra
functionality is provided for smaller problems and rapid prototyping functionality is provided for smaller problems and rapid prototyping
(no one wants to spend half the day installing a new library just to (no one wants to spend half the day installing a new library just to
discover that the new algorithm idea didn't work anyway). discover that the new algorithm idea didn't work anyway).
<b>See also:</b> <b>See also:</b>
<ul> <ul>
<li> \ref LinearAlgebraFunctions <li> \ref LinearAlgebraFunctions
</ul> </ul>
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class ALLOC = std::allocator<T> > template <class T, class ALLOC = std::allocator<T> >
class Matrix class Matrix
: public MultiArray<2, T, ALLOC> : public MultiArray<2, T, ALLOC>
{ {
typedef MultiArray<2, T, ALLOC> BaseType; typedef MultiArray<2, T, ALLOC> BaseType;
public: public:
typedef Matrix<T, ALLOC> matrix_type; typedef Matrix<T, ALLOC> matrix_type;
typedef TemporaryMatrix<T, ALLOC> temp_type; typedef TemporaryMatrix<T, ALLOC> temp_type;
typedef MultiArrayView<2, T, UnstridedArrayTag> view_type; typedef MultiArrayView<2, T, UnstridedArrayTag> view_type;
typedef typename BaseType::value_type value_type; typedef typename BaseType::value_type value_type;
typedef typename BaseType::pointer pointer; typedef typename BaseType::pointer pointer;
typedef typename BaseType::const_pointer const_pointer; typedef typename BaseType::const_pointer const_pointer;
typedef typename BaseType::reference reference; typedef typename BaseType::reference reference;
typedef typename BaseType::const_reference const_reference; typedef typename BaseType::const_reference const_reference;
typedef typename BaseType::difference_type difference_type; typedef typename BaseType::difference_type difference_type;
typedef typename BaseType::difference_type_1 difference_type_1;
typedef ALLOC allocator_type; typedef ALLOC allocator_type;
typedef typename BaseType::SquaredNormType SquaredNormType;
typedef typename BaseType::NormType NormType;
/** default constructor /** default constructor
*/ */
Matrix() Matrix()
{} {}
/** construct with given allocator /** construct with given allocator
*/ */
explicit Matrix(ALLOC const & alloc) explicit Matrix(ALLOC const & alloc)
: BaseType(alloc) : BaseType(alloc)
skipping to change at line 151 skipping to change at line 163
explicit Matrix(const difference_type &shape, explicit Matrix(const difference_type &shape,
ALLOC const & alloc = allocator_type()) ALLOC const & alloc = allocator_type())
: BaseType(shape, alloc) : BaseType(shape, alloc)
{} {}
/** construct with given shape and init all /** construct with given shape and init all
elements with zero. Note that the order of the axes is elements with zero. Note that the order of the axes is
<tt>(rows, columns)</tt> which <tt>(rows, columns)</tt> which
is the opposite of the usual VIGRA convention. is the opposite of the usual VIGRA convention.
*/ */
Matrix(std::size_t rows, std::size_t columns, Matrix(difference_type_1 rows, difference_type_1 columns,
ALLOC const & alloc = allocator_type()) ALLOC const & alloc = allocator_type())
: BaseType(difference_type(rows, columns), alloc) : BaseType(difference_type(rows, columns), alloc)
{} {}
/** construct with given shape and init all /** construct with given shape and init all
elements with the constant \a init. Note that the order of the axes is elements with the constant \a init. Note that the order of the axes is
<tt>difference_type(rows, columns)</tt> which <tt>difference_type(rows, columns)</tt> which
is the opposite of the usual VIGRA convention. is the opposite of the usual VIGRA convention.
*/ */
Matrix(const difference_type &shape, const_reference init, Matrix(const difference_type &shape, const_reference init,
allocator_type const & alloc = allocator_type()) allocator_type const & alloc = allocator_type())
: BaseType(shape, init, alloc) : BaseType(shape, init, alloc)
{} {}
/** construct with given shape and init all /** construct with given shape and init all
elements with the constant \a init. Note that the order of the axes is elements with the constant \a init. Note that the order of the axes is
<tt>(rows, columns)</tt> which <tt>(rows, columns)</tt> which
is the opposite of the usual VIGRA convention. is the opposite of the usual VIGRA convention.
*/ */
Matrix(std::size_t rows, std::size_t columns, const_reference init, Matrix(difference_type_1 rows, difference_type_1 columns, const_referen ce init,
allocator_type const & alloc = allocator_type()) allocator_type const & alloc = allocator_type())
: BaseType(difference_type(rows, columns), init, alloc) : BaseType(difference_type(rows, columns), init, alloc)
{} {}
/** construct with given shape and copy data from C-style array \a init. /** construct with given shape and copy data from C-style array \a init.
Unless \a layout is <tt>ColumnMajor</tt>, the elements in this array Unless \a layout is <tt>ColumnMajor</tt>, the elements in this array
are assumed to be given in row-major order (the C standard orde r) and are assumed to be given in row-major order (the C standard orde r) and
will automatically be converted to the required column-major fo rmat. will automatically be converted to the required column-major fo rmat.
Note that the order of the axes is <tt>difference_type(rows, co lumns)</tt> which Note that the order of the axes is <tt>difference_type(rows, co lumns)</tt> which
is the opposite of the usual VIGRA convention. is the opposite of the usual VIGRA convention.
skipping to change at line 205 skipping to change at line 217
} }
} }
/** construct with given shape and copy data from C-style array \a init. /** construct with given shape and copy data from C-style array \a init.
Unless \a layout is <tt>ColumnMajor</tt>, the elements in this array Unless \a layout is <tt>ColumnMajor</tt>, the elements in this array
are assumed to be given in row-major order (the C standard orde r) and are assumed to be given in row-major order (the C standard orde r) and
will automatically be converted to the required column-major fo rmat. will automatically be converted to the required column-major fo rmat.
Note that the order of the axes is <tt>(rows, columns)</tt> whi ch Note that the order of the axes is <tt>(rows, columns)</tt> whi ch
is the opposite of the usual VIGRA convention. is the opposite of the usual VIGRA convention.
*/ */
Matrix(std::size_t rows, std::size_t columns, const_pointer init, RawAr rayMemoryLayout layout = RowMajor, Matrix(difference_type_1 rows, difference_type_1 columns, const_pointer init, RawArrayMemoryLayout layout = RowMajor,
allocator_type const & alloc = allocator_type()) allocator_type const & alloc = allocator_type())
: BaseType(difference_type(rows, columns), alloc) // FIXME: this functi on initializes the memory twice : BaseType(difference_type(rows, columns), alloc) // FIXME: this functi on initializes the memory twice
{ {
if(layout == RowMajor) if(layout == RowMajor)
{ {
difference_type trans(columns, rows); difference_type trans(columns, rows);
linalg::transpose(MultiArrayView<2, T>(trans, const_cast<pointe r>(init)), *this); linalg::transpose(MultiArrayView<2, T>(trans, const_cast<pointe r>(init)), *this);
} }
else else
{ {
skipping to change at line 262 skipping to change at line 274
If the size of \a rhs is the same as the matrix's old size, onl y the data If the size of \a rhs is the same as the matrix's old size, onl y the data
are copied. Otherwise, new storage is allocated, which invalida tes are copied. Otherwise, new storage is allocated, which invalida tes
all objects (array views, iterators) depending on the matrix. all objects (array views, iterators) depending on the matrix.
*/ */
Matrix & operator=(const Matrix &rhs) Matrix & operator=(const Matrix &rhs)
{ {
BaseType::operator=(rhs); // has the correct semantics already BaseType::operator=(rhs); // has the correct semantics already
return *this; return *this;
} }
/** assign a temporary matrix. This is implemented by swapping the /** assign a temporary matrix. If the shapes of the two matrices ma
data tch,
only the data are copied (in order to not invalidate views and
iterators
depending on this matrix). Otherwise, the memory is swapped
between the two matrices, so that all depending objects between the two matrices, so that all depending objects
(array views, iterators) ar invalidated. (array views, iterators) ar invalidated.
*/ */
Matrix & operator=(const TemporaryMatrix<T, ALLOC> &rhs) Matrix & operator=(const TemporaryMatrix<T, ALLOC> &rhs)
{ {
this->swap(const_cast<TemporaryMatrix<T, ALLOC> &>(rhs)); if(this->shape() == rhs.shape())
this->copy(rhs);
else
this->swap(const_cast<TemporaryMatrix<T, ALLOC> &>(rhs));
return *this; return *this;
} }
/** assignment from arbitrary 2-dimensional MultiArrayView.<br> /** assignment from arbitrary 2-dimensional MultiArrayView.<br>
If the size of \a rhs is the same as the matrix's old size, onl y the data If the size of \a rhs is the same as the matrix's old size, onl y the data
are copied. Otherwise, new storage is allocated, which invalida tes are copied. Otherwise, new storage is allocated, which invalida tes
all objects (array views, iterators) depending on the matrix. all objects (array views, iterators) depending on the matrix.
\a rhs is assumed to be in column-major order already. \a rhs is assumed to be in column-major order already.
*/ */
template <class U, class C> template <class U, class C>
Matrix & operator=(const MultiArrayView<2, U, C> &rhs) Matrix & operator=(const MultiArrayView<2, U, C> &rhs)
{ {
BaseType::operator=(rhs); // has the correct semantics already BaseType::operator=(rhs); // has the correct semantics already
return *this; return *this;
} }
/** init elements with a constant
*/
template <class U>
Matrix & init(const U & init)
{
BaseType::init(init);
return *this;
}
/** reshape to the given shape and initialize with zero.
*/
void reshape(difference_type_1 rows, difference_type_1 columns)
{
BaseType::reshape(difference_type(rows, columns));
}
/** reshape to the given shape and initialize with \a init.
*/
void reshape(difference_type_1 rows, difference_type_1 columns, const_r
eference init)
{
BaseType::reshape(difference_type(rows, columns), init);
}
/** reshape to the given shape and initialize with zero.
*/
void reshape(difference_type const & shape)
{
BaseType::reshape(shape);
}
/** reshape to the given shape and initialize with \a init.
*/
void reshape(difference_type const & shape, const_reference init)
{
BaseType::reshape(shape, init);
}
/** Create a matrix view that represents the row vector of row \a d . /** Create a matrix view that represents the row vector of row \a d .
*/ */
view_type rowVector(std::size_t d) const view_type rowVector(difference_type_1 d) const
{ {
return vigra::linalg::rowVector(*this, d); return vigra::linalg::rowVector(*this, d);
} }
/** Create a matrix view that represents the column vector of colum n \a d. /** Create a matrix view that represents the column vector of colum n \a d.
*/ */
view_type columnVector(std::size_t d) const view_type columnVector(difference_type_1 d) const
{ {
return vigra::linalg::columnVector(*this, d); return vigra::linalg::columnVector(*this, d);
} }
/** number of rows (height) of the matrix. /** number of rows (height) of the matrix.
*/ */
std::size_t rowCount() const difference_type_1 rowCount() const
{ {
return this->m_shape[0]; return this->m_shape[0];
} }
/** number of columns (width) of the matrix. /** number of columns (width) of the matrix.
*/ */
std::size_t columnCount() const difference_type_1 columnCount() const
{ {
return this->m_shape[1]; return this->m_shape[1];
} }
/** number of elements (width*height) of the matrix. /** number of elements (width*height) of the matrix.
*/ */
std::size_t elementCount() const difference_type_1 elementCount() const
{ {
return rowCount()*columnCount(); return rowCount()*columnCount();
} }
/** check whether the matrix is symmetric. /** check whether the matrix is symmetric.
*/ */
bool isSymmetric() const bool isSymmetric() const
{ {
return vigra::linalg::isSymmetric(*this); return vigra::linalg::isSymmetric(*this);
} }
#ifdef DOXYGEN #ifdef DOXYGEN
// repeat the index functions for documentation. In real code, they are inh erited. // repeat the following functions for documentation. In real code, they are inherited.
/** read/write access to matrix element <tt>(row, column)</tt>. /** read/write access to matrix element <tt>(row, column)</tt>.
Note that the order of the argument is the opposite of the usua l Note that the order of the argument is the opposite of the usua l
VIGRA convention due to column-major matrix order. VIGRA convention due to column-major matrix order.
*/ */
value_type & operator()(std::size_t row, std::size_t column); value_type & operator()(difference_type_1 row, difference_type_1 column );
/** read access to matrix element <tt>(row, column)</tt>. /** read access to matrix element <tt>(row, column)</tt>.
Note that the order of the argument is the opposite of the usua l Note that the order of the argument is the opposite of the usua l
VIGRA convention due to column-major matrix order. VIGRA convention due to column-major matrix order.
*/ */
value_type operator()(std::size_t row, std::size_t column) const; value_type operator()(difference_type_1 row, difference_type_1 column)
#endif const;
/** squared Frobenius norm. Sum of squares of the matrix elements. /** squared Frobenius norm. Sum of squares of the matrix elements.
*/ */
SquaredNormType squaredNorm() const typename NormTraits<Matrix>::SquaredNormType squaredNorm() const;
{
return BaseType::squaredNorm();
}
/** Frobenius norm. Root of sum of squares of the matrix elements. /** Frobenius norm. Root of sum of squares of the matrix elements.
*/ */
NormType norm() const typename NormTraits<Matrix>::NormType norm() const;
{
return BaseType::norm();
}
/** transpose matrix in-place (precondition: matrix must be square) /** create a transposed view of this matrix.
No data are copied. If you want to transpose this matrix perman
ently,
you have to assign the transposed view:
\code
a = a.transpose();
\endcode
*/ */
Matrix & transpose(); MultiArrayView<2, vluae_type, StridedArrayTag> transpose() const;
#endif
/** add \a other to this (sizes must match). /** add \a other to this (sizes must match).
*/ */
template <class U, class C> template <class U, class C>
Matrix & operator+=(MultiArrayView<2, U, C> const & other); Matrix & operator+=(MultiArrayView<2, U, C> const & other)
{
BaseType::operator+=(other);
return *this;
}
/** subtract \a other from this (sizes must match). /** subtract \a other from this (sizes must match).
*/ */
template <class U, class C> template <class U, class C>
Matrix & operator-=(MultiArrayView<2, U, C> const & other); Matrix & operator-=(MultiArrayView<2, U, C> const & other)
{
BaseType::operator-=(other);
return *this;
}
/** scalar multiply this with \a other /** multiply \a other element-wise with this matrix (sizes must mat ch).
*/ */
Matrix & operator*=(T other); template <class U, class C>
Matrix & operator*=(MultiArrayView<2, U, C> const & other)
{
BaseType::operator*=(other);
return *this;
}
/** scalar devide this by \a other /** divide this matrix element-wise by \a other (sizes must match).
*/ */
Matrix & operator/=(T other); template <class U, class C>
}; Matrix & operator/=(MultiArrayView<2, U, C> const & other)
{
template <class T, class ALLOC> BaseType::operator/=(other);
Matrix<T, ALLOC> & Matrix<T, ALLOC>::transpose() return *this;
{ }
const std::size_t cols = columnCount();
vigra_precondition(cols == rowCount(),
"Matrix::transpose(): in-place transposition requires square matrix
.");
for(std::size_t i = 0; i < cols; ++i)
for(std::size_t j = i+1; j < cols; ++j)
std::swap((*this)(j, i), (*this)(i, j));
return *this;
}
template <class T, class ALLOC>
template <class U, class C>
Matrix<T, ALLOC> & Matrix<T, ALLOC>::operator+=(MultiArrayView<2, U, C> con
st & other)
{
const std::size_t rows = rowCount();
const std::size_t cols = columnCount();
vigra_precondition(rows == vigra::linalg::rowCount(other) && cols == vi
gra::linalg::columnCount(other),
"Matrix::operator+=(): Shape mismatch.");
for(std::size_t i = 0; i < cols; ++i)
for(std::size_t j = 0; j < rows; ++j)
(*this)(j, i) += other(j, i);
return *this;
}
template <class T, class ALLOC>
template <class U, class C>
Matrix<T, ALLOC> & Matrix<T, ALLOC>::operator-=(MultiArrayView<2, U, C> con
st & other)
{
const std::size_t rows = rowCount();
const std::size_t cols = columnCount();
vigra_precondition(rows == vigra::linalg::rowCount(other) && cols == vi
gra::linalg::columnCount(other),
"Matrix::operator-=(): Shape mismatch.");
for(std::size_t i = 0; i < cols; ++i)
for(std::size_t j = 0; j < rows; ++j)
(*this)(j, i) -= other(j, i);
return *this;
}
template <class T, class ALLOC> /** add \a other to each element of this matrix
Matrix<T, ALLOC> & Matrix<T, ALLOC>::operator*=(T other) */
{ Matrix & operator+=(T other)
const std::size_t rows = rowCount(); {
const std::size_t cols = columnCount(); BaseType::operator+=(other);
return *this;
}
for(std::size_t i = 0; i < cols; ++i) /** subtraxt \a other from each element of this matrix
for(std::size_t j = 0; j < rows; ++j) */
(*this)(j, i) *= other; Matrix & operator-=(T other)
return *this; {
} BaseType::operator-=(other);
return *this;
}
template <class T, class ALLOC> /** scalar multiply this with \a other
Matrix<T, ALLOC> & Matrix<T, ALLOC>::operator/=(T other) */
{ Matrix & operator*=(T other)
const std::size_t rows = rowCount(); {
const std::size_t cols = columnCount(); BaseType::operator*=(other);
return *this;
}
for(std::size_t i = 0; i < cols; ++i) /** scalar devide this by \a other
for(std::size_t j = 0; j < rows; ++j) */
(*this)(j, i) /= other; Matrix & operator/=(T other)
return *this; {
} BaseType::operator/=(other);
return *this;
}
};
// TemporaryMatrix is provided as an optimization: Functions returning a ma trix can // TemporaryMatrix is provided as an optimization: Functions returning a ma trix can
// use TemporaryMatrix to make explicit that it was allocated as a temporar y data structure. // use TemporaryMatrix to make explicit that it was allocated as a temporar y data structure.
// Functions receiving a TemporaryMatrix can thus often avoid to allocate n ew temporary // Functions receiving a TemporaryMatrix can thus often avoid to allocate n ew temporary
// memory. // memory.
template <class T, class ALLOC = std::allocator<T> > template <class T, class ALLOC = std::allocator<T> >
class TemporaryMatrix class TemporaryMatrix
: public Matrix<T, ALLOC> : public Matrix<T, ALLOC>
{ {
typedef Matrix<T, ALLOC> BaseType; typedef Matrix<T, ALLOC> BaseType;
public: public:
typedef Matrix<T, ALLOC> matrix_type; typedef Matrix<T, ALLOC> matrix_type;
typedef TemporaryMatrix<T, ALLOC> temp_type; typedef TemporaryMatrix<T, ALLOC> temp_type;
typedef MultiArrayView<2, T, UnstridedArrayTag> view_type; typedef MultiArrayView<2, T, UnstridedArrayTag> view_type;
typedef typename BaseType::value_type value_type; typedef typename BaseType::value_type value_type;
typedef typename BaseType::pointer pointer; typedef typename BaseType::pointer pointer;
typedef typename BaseType::const_pointer const_pointer; typedef typename BaseType::const_pointer const_pointer;
typedef typename BaseType::reference reference; typedef typename BaseType::reference reference;
typedef typename BaseType::const_reference const_reference; typedef typename BaseType::const_reference const_reference;
typedef typename BaseType::difference_type difference_type; typedef typename BaseType::difference_type difference_type;
typedef typename BaseType::difference_type_1 difference_type_1;
typedef ALLOC allocator_type; typedef ALLOC allocator_type;
TemporaryMatrix(std::size_t rows, std::size_t columns) TemporaryMatrix(difference_type const & shape)
: BaseType(shape, ALLOC())
{}
TemporaryMatrix(difference_type const & shape, const_reference init)
: BaseType(shape, init, ALLOC())
{}
TemporaryMatrix(difference_type_1 rows, difference_type_1 columns)
: BaseType(rows, columns, ALLOC()) : BaseType(rows, columns, ALLOC())
{} {}
TemporaryMatrix(std::size_t rows, std::size_t columns, const_reference init) TemporaryMatrix(difference_type_1 rows, difference_type_1 columns, cons t_reference init)
: BaseType(rows, columns, init, ALLOC()) : BaseType(rows, columns, init, ALLOC())
{} {}
template<class U, class C> template<class U, class C>
TemporaryMatrix(const MultiArrayView<2, U, C> &rhs) TemporaryMatrix(const MultiArrayView<2, U, C> &rhs)
: BaseType(rhs) : BaseType(rhs)
{} {}
TemporaryMatrix(const TemporaryMatrix &rhs) TemporaryMatrix(const TemporaryMatrix &rhs)
: BaseType() : BaseType()
{ {
this->swap(const_cast<TemporaryMatrix &>(rhs)); this->swap(const_cast<TemporaryMatrix &>(rhs));
} }
TemporaryMatrix & transpose() template <class U>
TemporaryMatrix & init(const U & init)
{ {
BaseType::transpose(); BaseType::init(init);
return *this; return *this;
} }
template <class U, class C> template <class U, class C>
TemporaryMatrix & operator+=(MultiArrayView<2, U, C> const & other) TemporaryMatrix & operator+=(MultiArrayView<2, U, C> const & other)
{ {
BaseType::operator+=(other); BaseType::operator+=(other);
return *this; return *this;
} }
template <class U, class C> template <class U, class C>
TemporaryMatrix & operator-=(MultiArrayView<2, U, C> const & other) TemporaryMatrix & operator-=(MultiArrayView<2, U, C> const & other)
{ {
BaseType::operator-=(other); BaseType::operator-=(other);
return *this; return *this;
} }
template <class U, class C>
TemporaryMatrix & operator*=(MultiArrayView<2, U, C> const & other)
{
BaseType::operator*=(other);
return *this;
}
template <class U, class C>
TemporaryMatrix & operator/=(MultiArrayView<2, U, C> const & other)
{
BaseType::operator/=(other);
return *this;
}
TemporaryMatrix & operator+=(T other)
{
BaseType::operator+=(other);
return *this;
}
TemporaryMatrix & operator-=(T other)
{
BaseType::operator-=(other);
return *this;
}
TemporaryMatrix & operator*=(T other) TemporaryMatrix & operator*=(T other)
{ {
BaseType::operator*=(other); BaseType::operator*=(other);
return *this; return *this;
} }
TemporaryMatrix & operator/=(T other) TemporaryMatrix & operator/=(T other)
{ {
BaseType::operator/=(other); BaseType::operator/=(other);
return *this; return *this;
} }
private: private:
TemporaryMatrix &operator=(const TemporaryMatrix &rhs); // not implemen ted TemporaryMatrix &operator=(const TemporaryMatrix &rhs); // intentionall y not implemented
}; };
/** \addtogroup LinearAlgebraFunctions Matrix functions /** \defgroup LinearAlgebraFunctions Matrix Functions
\brief Basic matrix algebra, element-wise mathematical functions, row a
nd columns statistics, data normalization etc.
\ingroup LinearAlgebraModule
*/ */
//@{ //@{
/** Number of rows of a matrix represented as a <tt>MultiArrayView<2 ,...&gt;</tt> /** Number of rows of a matrix represented as a <tt>MultiArrayView<2, . ..&gt;</tt>
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C> template <class T, class C>
inline std::size_t rowCount(const MultiArrayView<2, T, C> &x) inline MultiArrayIndex
rowCount(const MultiArrayView<2, T, C> &x)
{ {
return x.shape(0); return x.shape(0);
} }
/** Number of columns of a matrix represented as a <tt>MultiArrayView&l t;2,...&gt;</tt> /** Number of columns of a matrix represented as a <tt>MultiArrayView<2 , ...&gt;</tt>
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C> template <class T, class C>
inline std::size_t columnCount(const MultiArrayView<2, T, C> &x) inline MultiArrayIndex
columnCount(const MultiArrayView<2, T, C> &x)
{ {
return x.shape(1); return x.shape(1);
} }
/** Create a row vector view for row \a d of the matrix \a m /** Create a row vector view for row \a d of the matrix \a m
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C> template <class T, class C>
MultiArrayView <2, T, C> inline MultiArrayView <2, T, C>
rowVector(MultiArrayView <2, T, C> const & m, int d) rowVector(MultiArrayView <2, T, C> const & m, MultiArrayIndex d)
{ {
typedef typename MultiArrayView <2, T, C>::difference_type Shape; typedef typename MultiArrayView <2, T, C>::difference_type Shape;
return m.subarray(Shape(d, 0), Shape(d+1, columnCount(m))); return m.subarray(Shape(d, 0), Shape(d+1, columnCount(m)));
} }
/** Create a row vector view of the matrix \a m starting at element \a
first and ranging
to column \a end (non-inclusive).
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg
*/
template <class T, class C>
inline MultiArrayView <2, T, C>
rowVector(MultiArrayView <2, T, C> const & m, MultiArrayShape<2>::type firs
t, MultiArrayIndex end)
{
typedef typename MultiArrayView <2, T, C>::difference_type Shape;
return m.subarray(first, Shape(first[0]+1, end));
}
/** Create a column vector view for column \a d of the matrix \a m /** Create a column vector view for column \a d of the matrix \a m
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C> template <class T, class C>
MultiArrayView <2, T, C> inline MultiArrayView <2, T, C>
columnVector(MultiArrayView<2, T, C> const & m, int d) columnVector(MultiArrayView<2, T, C> const & m, MultiArrayIndex d)
{ {
typedef typename MultiArrayView <2, T, C>::difference_type Shape; typedef typename MultiArrayView <2, T, C>::difference_type Shape;
return m.subarray(Shape(0, d), Shape(rowCount(m), d+1)); return m.subarray(Shape(0, d), Shape(rowCount(m), d+1));
} }
/** Create a column vector view of the matrix \a m starting at element
\a first and
ranging to row \a end (non-inclusive).
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg
**/
template <class T, class C>
inline MultiArrayView <2, T, C>
columnVector(MultiArrayView<2, T, C> const & m, MultiArrayShape<2>::type fi
rst, int end)
{
typedef typename MultiArrayView <2, T, C>::difference_type Shape;
return m.subarray(first, Shape(end, first[1]+1));
}
/** Check whether matrix \a m is symmetric. /** Check whether matrix \a m is symmetric.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C> template <class T, class C>
bool bool
isSymmetric(MultiArrayView<2, T, C> const & m) isSymmetric(MultiArrayView<2, T, C> const & m)
{ {
const std::size_t size = rowCount(m); const MultiArrayIndex size = rowCount(m);
if(size != columnCount(m)) if(size != columnCount(m))
return false; return false;
for(std::size_t i = 0; i < size; ++i) for(MultiArrayIndex i = 0; i < size; ++i)
for(std::size_t j = i+1; j < size; ++j) for(MultiArrayIndex j = i+1; j < size; ++j)
if(m(j, i) != m(i, j)) if(m(j, i) != m(i, j))
return false; return false;
return true; return true;
} }
#ifdef DOXYGEN // documentation only -- function is already defined in vigr a/multi_array.hxx #ifdef DOXYGEN // documentation only -- function is already defined in vigr a/multi_array.hxx
/** calculate the squared Frobenius norm of a matrix. /** calculate the squared Frobenius norm of a matrix.
Equal to the sum of squares of the matrix elements. Equal to the sum of squares of the matrix elements.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a >" <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</ a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class T, class ALLOC> template <class T, class ALLOC>
typename Matrix<T, ALLLOC>::SquaredNormType typename Matrix<T, ALLLOC>::SquaredNormType
squaredNorm(const Matrix<T, ALLLOC> &a); squaredNorm(const Matrix<T, ALLLOC> &a);
/** calculate the Frobenius norm of a matrix. /** calculate the Frobenius norm of a matrix.
Equal to the root of the sum of squares of the matrix elements. Equal to the root of the sum of squares of the matrix elements.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a >" <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</ a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class T, class ALLOC> template <class T, class ALLOC>
typename Matrix<T, ALLLOC>::NormType typename Matrix<T, ALLLOC>::NormType
norm(const Matrix<T, ALLLOC> &a); norm(const Matrix<T, ALLLOC> &a);
#endif // DOXYGEN #endif // DOXYGEN
/** initialize the given square matrix as an identity matrix. /** initialize the given square matrix as an identity matrix.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C> template <class T, class C>
void identityMatrix(MultiArrayView<2, T, C> &r) void identityMatrix(MultiArrayView<2, T, C> &r)
{ {
const std::size_t rows = rowCount(r); const MultiArrayIndex rows = rowCount(r);
vigra_precondition(rows == columnCount(r), vigra_precondition(rows == columnCount(r),
"identityMatrix(): Matrix must be square."); "identityMatrix(): Matrix must be square.");
for(std::size_t i = 0; i < rows; ++i) { for(MultiArrayIndex i = 0; i < rows; ++i) {
for(std::size_t j = 0; j < rows; ++j) for(MultiArrayIndex j = 0; j < rows; ++j)
r(j, i) = NumericTraits<T>::zero(); r(j, i) = NumericTraits<T>::zero();
r(i, i) = NumericTraits<T>::one(); r(i, i) = NumericTraits<T>::one();
} }
} }
/** create n identity matrix of the given size. /** create n identity matrix of the given size.
Usage: Usage:
\code \code
vigra::Matrix<double> m = vigra::identityMatrix<double>(size); vigra::Matrix<double> m = vigra::identityMatrix<double>(size);
\endcode \endcode
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T> template <class T>
TemporaryMatrix<T> identityMatrix(std::size_t size) TemporaryMatrix<T> identityMatrix(MultiArrayIndex size)
{ {
TemporaryMatrix<T> ret(size, size, NumericTraits<T>::zero()); TemporaryMatrix<T> ret(size, size, NumericTraits<T>::zero());
for(std::size_t i = 0; i < size; ++i) for(MultiArrayIndex i = 0; i < size; ++i)
ret(i, i) = NumericTraits<T>::one(); ret(i, i) = NumericTraits<T>::one();
return ret; return ret;
} }
template <class T, class C1, class C2> template <class T, class C1, class C2>
void diagonalMatrixImpl(MultiArrayView<1, T, C1> const & v, MultiArrayView< 2, T, C2> &r) void diagonalMatrixImpl(MultiArrayView<1, T, C1> const & v, MultiArrayView< 2, T, C2> &r)
{ {
const std::size_t size = v.elementCount(); const MultiArrayIndex size = v.elementCount();
vigra_precondition(rowCount(r) == size && columnCount(r) == size, vigra_precondition(rowCount(r) == size && columnCount(r) == size,
"diagonalMatrix(): result must be a square matrix."); "diagonalMatrix(): result must be a square matrix.");
for(std::size_t i = 0; i < size; ++i) for(MultiArrayIndex i = 0; i < size; ++i)
r(i, i) = v(i); r(i, i) = v(i);
} }
/** make a diagonal matrix from a vector. /** make a diagonal matrix from a vector.
The vector is given as matrix \a v, which must either have a single The vector is given as matrix \a v, which must either have a single
row or column. The result is witten into the square matrix \a r. row or column. The result is witten into the square matrix \a r.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1, class C2> template <class T, class C1, class C2>
void diagonalMatrix(MultiArrayView<2, T, C1> const & v, MultiArrayView<2, T , C2> &r) void diagonalMatrix(MultiArrayView<2, T, C1> const & v, MultiArrayView<2, T , C2> &r)
{ {
vigra_precondition(rowCount(v) == 1 || columnCount(v) == 1, vigra_precondition(rowCount(v) == 1 || columnCount(v) == 1,
"diagonalMatrix(): input must be a vector."); "diagonalMatrix(): input must be a vector.");
r.init(NumericTraits<T>::zero()); r.init(NumericTraits<T>::zero());
if(rowCount(v) == 1) if(rowCount(v) == 1)
diagonalMatrixImpl(v.bindInner(0), r); diagonalMatrixImpl(v.bindInner(0), r);
skipping to change at line 704 skipping to change at line 814
row or column. The result is returned as a temporary matrix. row or column. The result is returned as a temporary matrix.
Usage: Usage:
\code \code
vigra::Matrix<double> v(1, len); vigra::Matrix<double> v(1, len);
v = ...; v = ...;
vigra::Matrix<double> m = diagonalMatrix(v); vigra::Matrix<double> m = diagonalMatrix(v);
\endcode \endcode
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C> template <class T, class C>
TemporaryMatrix<T> diagonalMatrix(MultiArrayView<2, T, C> const & v) TemporaryMatrix<T> diagonalMatrix(MultiArrayView<2, T, C> const & v)
{ {
vigra_precondition(rowCount(v) == 1 || columnCount(v) == 1, vigra_precondition(rowCount(v) == 1 || columnCount(v) == 1,
"diagonalMatrix(): input must be a vector."); "diagonalMatrix(): input must be a vector.");
std::size_t size = v.elementCount(); MultiArrayIndex size = v.elementCount();
TemporaryMatrix<T> ret(size, size, NumericTraits<T>::zero()); TemporaryMatrix<T> ret(size, size, NumericTraits<T>::zero());
if(rowCount(v) == 1) if(rowCount(v) == 1)
diagonalMatrixImpl(v.bindInner(0), ret); diagonalMatrixImpl(v.bindInner(0), ret);
else else
diagonalMatrixImpl(v.bindOuter(0), ret); diagonalMatrixImpl(v.bindOuter(0), ret);
return ret; return ret;
} }
/** transpose matrix \a v. /** transpose matrix \a v.
The result is written into \a r which must have the correct (i.e. The result is written into \a r which must have the correct (i.e.
transposed) shape. transposed) shape.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1, class C2> template <class T, class C1, class C2>
void transpose(const MultiArrayView<2, T, C1> &v, MultiArrayView<2, T, C2> &r) void transpose(const MultiArrayView<2, T, C1> &v, MultiArrayView<2, T, C2> &r)
{ {
const std::size_t rows = rowCount(r); const MultiArrayIndex rows = rowCount(r);
const std::size_t cols = columnCount(r); const MultiArrayIndex cols = columnCount(r);
vigra_precondition(rows == columnCount(v) && cols == rowCount(v), vigra_precondition(rows == columnCount(v) && cols == rowCount(v),
"transpose(): arrays must have transposed shapes."); "transpose(): arrays must have transposed shapes.");
for(std::size_t i = 0; i < cols; ++i) for(MultiArrayIndex i = 0; i < cols; ++i)
for(std::size_t j = 0; j < rows; ++j) for(MultiArrayIndex j = 0; j < rows; ++j)
r(j, i) = v(i, j); r(j, i) = v(i, j);
} }
/** create the transpose of a matrix \a v. /** create the transpose of matrix \a v.
The result is returned as a temporary matrix. This does not copy any data, but only creates a transposed view
to the original matrix. A copy is only made when the transposed vie
w
is assigned to another matrix.
Usage: Usage:
\code \code
vigra::Matrix<double> v(rows, cols); vigra::Matrix<double> v(rows, cols);
v = ...; v = ...;
vigra::Matrix<double> m = transpose(v); vigra::Matrix<double> m = transpose(v);
\endcode \endcode
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C> template <class T, class C>
TemporaryMatrix<T> transpose(MultiArrayView<2, T, C> const & v) inline MultiArrayView<2, T, StridedArrayTag>
transpose(MultiArrayView<2, T, C> const & v)
{ {
TemporaryMatrix<T> ret(columnCount(v), rowCount(v)); return v.transpose();
transpose(v, ret);
return ret;
} }
template <class T> /** Create new matrix by concatenating two matrices \a a and \a b verti
TemporaryMatrix<T> transpose(TemporaryMatrix<T> const & v) cally, i.e. on top of each other.
The two matrices must have the same number of columns.
The result is returned as a temporary matrix.
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg
*/
template <class T, class C1, class C2>
inline TemporaryMatrix<T>
joinVertically(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T
, C2> &b)
{ {
const std::size_t rows = v.rowCount(); typedef typename TemporaryMatrix<T>::difference_type Shape;
const std::size_t cols = v.columnCount();
if(rows == cols) MultiArrayIndex n = columnCount(a);
{ vigra_precondition(n == columnCount(b),
return const_cast<TemporaryMatrix<T> &>(v).transpose(); "joinVertically(): shape mismatch.");
}
else MultiArrayIndex ma = rowCount(a);
MultiArrayIndex mb = rowCount(b);
TemporaryMatrix<T> t(ma + mb, n, T());
t.subarray(Shape(0,0), Shape(ma, n)) = a;
t.subarray(Shape(ma,0), Shape(ma+mb, n)) = b;
return t;
}
/** Create new matrix by concatenating two matrices \a a and \a b horiz
ontally, i.e. side by side.
The two matrices must have the same number of rows.
The result is returned as a temporary matrix.
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg
*/
template <class T, class C1, class C2>
inline TemporaryMatrix<T>
joinHorizontally(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2,
T, C2> &b)
{
typedef typename TemporaryMatrix<T>::difference_type Shape;
MultiArrayIndex m = rowCount(a);
vigra_precondition(m == rowCount(b),
"joinHorizontally(): shape mismatch.");
MultiArrayIndex na = columnCount(a);
MultiArrayIndex nb = columnCount(b);
TemporaryMatrix<T> t(m, na + nb, T());
t.subarray(Shape(0,0), Shape(m, na)) = a;
t.subarray(Shape(0, na), Shape(m, na + nb)) = b;
return t;
}
/** Initialize a matrix with repeated copies of a given matrix.
Matrix \a r will consist of \a verticalCount downward repetitions o
f \a v,
and \a horizontalCount side-by-side repetitions. When \a v has size
<tt>m</tt> by <tt>n</tt>,
\a r must have size <tt>(m*verticalCount)</tt> by <tt>(n*horizontal
Count)</tt>.
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg
*/
template <class T, class C1, class C2>
void repeatMatrix(MultiArrayView<2, T, C1> const & v, MultiArrayView<2, T,
C2> &r,
unsigned int verticalCount, unsigned int horizontalCount)
{
typedef typename Matrix<T>::difference_type Shape;
MultiArrayIndex m = rowCount(v), n = columnCount(v);
vigra_precondition(m*verticalCount == rowCount(r) && n*horizontalCount
== columnCount(r),
"repeatMatrix(): Shape mismatch.");
for(MultiArrayIndex l=0; l<(MultiArrayIndex)horizontalCount; ++l)
{ {
TemporaryMatrix<T> ret(cols, rows); for(MultiArrayIndex k=0; k<(MultiArrayIndex)verticalCount; ++k)
transpose(v, ret); {
return ret; r.subarray(Shape(k*m, l*n), Shape((k+1)*m, (l+1)*n)) = v;
}
} }
} }
/** Create a new matrix by repeating a given matrix.
The resulting matrix \a r will consist of \a verticalCount downward
repetitions of \a v,
and \a horizontalCount side-by-side repetitions, i.e. it will be of
size
<tt>(m*verticalCount)</tt> by <tt>(n*horizontalCount)</tt> when \a
v has size <tt>m</tt> by <tt>n</tt>.
The result is returned as a temporary matrix.
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg
*/
template <class T, class C>
TemporaryMatrix<T>
repeatMatrix(MultiArrayView<2, T, C> const & v, unsigned int verticalCount,
unsigned int horizontalCount)
{
MultiArrayIndex m = rowCount(v), n = columnCount(v);
TemporaryMatrix<T> ret(verticalCount*m, horizontalCount*n);
repeatMatrix(v, ret, verticalCount, horizontalCount);
return ret;
}
/** add matrices \a a and \a b. /** add matrices \a a and \a b.
The result is written into \a r. All three matrices must have the s ame shape. The result is written into \a r. All three matrices must have the s ame shape.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C1, class C2, class C3> template <class T, class C1, class C2, class C3>
void add(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b, void add(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b,
MultiArrayView<2, T, C3> &r) MultiArrayView<2, T, C3> &r)
{ {
const std::size_t rrows = rowCount(r); const MultiArrayIndex rrows = rowCount(r);
const std::size_t rcols = columnCount(r); const MultiArrayIndex rcols = columnCount(r);
vigra_precondition(rrows == rowCount(a) && rcols == columnCount(a) && vigra_precondition(rrows == rowCount(a) && rcols == columnCount(a) &&
rrows == rowCount(b) && rcols == columnCount(b), rrows == rowCount(b) && rcols == columnCount(b),
"add(): Matrix shapes must agree."); "add(): Matrix shapes must agree.");
for(std::size_t i = 0; i < rcols; ++i) { for(MultiArrayIndex i = 0; i < rcols; ++i) {
for(std::size_t j = 0; j < rrows; ++j) { for(MultiArrayIndex j = 0; j < rrows; ++j) {
r(j, i) = a(j, i) + b(j, i); r(j, i) = a(j, i) + b(j, i);
} }
} }
} }
/** add matrices \a a and \a b. /** add matrices \a a and \a b.
The two matrices must have the same shape. The two matrices must have the same shape.
The result is returned as a temporary matrix. The result is returned as a temporary matrix.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C1, class C2> template <class T, class C1, class C2>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
operator+(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b) operator+(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b)
{ {
return TemporaryMatrix<T>(a) += b; return TemporaryMatrix<T>(a) += b;
} }
template <class T, class C> template <class T, class C>
skipping to change at line 842 skipping to change at line 1038
return const_cast<TemporaryMatrix<T> &>(b) += a; return const_cast<TemporaryMatrix<T> &>(b) += a;
} }
template <class T> template <class T>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
operator+(const TemporaryMatrix<T> &a, const TemporaryMatrix<T> &b) operator+(const TemporaryMatrix<T> &a, const TemporaryMatrix<T> &b)
{ {
return const_cast<TemporaryMatrix<T> &>(a) += b; return const_cast<TemporaryMatrix<T> &>(a) += b;
} }
/** add scalar \a b to every element of the matrix \a a.
The result is returned as a temporary matrix.
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg
*/
template <class T, class C>
inline TemporaryMatrix<T>
operator+(const MultiArrayView<2, T, C> &a, T b)
{
return TemporaryMatrix<T>(a) += b;
}
template <class T>
inline TemporaryMatrix<T>
operator+(const TemporaryMatrix<T> &a, T b)
{
return const_cast<TemporaryMatrix<T> &>(a) += b;
}
/** add scalar \a a to every element of the matrix \a b.
The result is returned as a temporary matrix.
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg
*/
template <class T, class C>
inline TemporaryMatrix<T>
operator+(T a, const MultiArrayView<2, T, C> &b)
{
return TemporaryMatrix<T>(b) += a;
}
template <class T>
inline TemporaryMatrix<T>
operator+(T a, const TemporaryMatrix<T> &b)
{
return const_cast<TemporaryMatrix<T> &>(b) += a;
}
/** subtract matrix \a b from \a a. /** subtract matrix \a b from \a a.
The result is written into \a r. All three matrices must have the s ame shape. The result is written into \a r. All three matrices must have the s ame shape.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C1, class C2, class C3> template <class T, class C1, class C2, class C3>
void sub(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b, void sub(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b,
MultiArrayView<2, T, C3> &r) MultiArrayView<2, T, C3> &r)
{ {
const std::size_t rrows = rowCount(r); const MultiArrayIndex rrows = rowCount(r);
const std::size_t rcols = columnCount(r); const MultiArrayIndex rcols = columnCount(r);
vigra_precondition(rrows == rowCount(a) && rcols == columnCount(a) && vigra_precondition(rrows == rowCount(a) && rcols == columnCount(a) &&
rrows == rowCount(b) && rcols == columnCount(b), rrows == rowCount(b) && rcols == columnCount(b),
"subtract(): Matrix shapes must agree."); "subtract(): Matrix shapes must agree.");
for(std::size_t i = 0; i < rcols; ++i) { for(MultiArrayIndex i = 0; i < rcols; ++i) {
for(std::size_t j = 0; j < rrows; ++j) { for(MultiArrayIndex j = 0; j < rrows; ++j) {
r(j, i) = a(j, i) - b(j, i); r(j, i) = a(j, i) - b(j, i);
} }
} }
} }
/** subtract matrix \a b from \a a. /** subtract matrix \a b from \a a.
The two matrices must have the same shape. The two matrices must have the same shape.
The result is returned as a temporary matrix. The result is returned as a temporary matrix.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C1, class C2> template <class T, class C1, class C2>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
operator-(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b) operator-(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b)
{ {
return TemporaryMatrix<T>(a) -= b; return TemporaryMatrix<T>(a) -= b;
} }
template <class T, class C> template <class T, class C>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
operator-(const TemporaryMatrix<T> &a, const MultiArrayView<2, T, C> &b) operator-(const TemporaryMatrix<T> &a, const MultiArrayView<2, T, C> &b)
{ {
return const_cast<TemporaryMatrix<T> &>(a) -= b; return const_cast<TemporaryMatrix<T> &>(a) -= b;
} }
template <class T, class C> template <class T, class C>
TemporaryMatrix<T> TemporaryMatrix<T>
operator-(const MultiArrayView<2, T, C> &a, const TemporaryMatrix<T> &b) operator-(const MultiArrayView<2, T, C> &a, const TemporaryMatrix<T> &b)
{ {
const std::size_t rows = rowCount(a); const MultiArrayIndex rows = rowCount(a);
const std::size_t cols = columnCount(a); const MultiArrayIndex cols = columnCount(a);
vigra_precondition(rows == b.rowCount() && cols == b.columnCount(), vigra_precondition(rows == b.rowCount() && cols == b.columnCount(),
"Matrix::operator-(): Shape mismatch."); "Matrix::operator-(): Shape mismatch.");
for(std::size_t i = 0; i < cols; ++i) for(MultiArrayIndex i = 0; i < cols; ++i)
for(std::size_t j = 0; j < rows; ++j) for(MultiArrayIndex j = 0; j < rows; ++j)
const_cast<TemporaryMatrix<T> &>(b)(j, i) = a(j, i) - b(j, i); const_cast<TemporaryMatrix<T> &>(b)(j, i) = a(j, i) - b(j, i);
return b; return b;
} }
template <class T> template <class T>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
operator-(const TemporaryMatrix<T> &a, const TemporaryMatrix<T> &b) operator-(const TemporaryMatrix<T> &a, const TemporaryMatrix<T> &b)
{ {
return const_cast<TemporaryMatrix<T> &>(a) -= b; return const_cast<TemporaryMatrix<T> &>(a) -= b;
} }
/** negate matrix \a a. /** negate matrix \a a.
The result is returned as a temporary matrix. The result is returned as a temporary matrix.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C> template <class T, class C>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
operator-(const MultiArrayView<2, T, C> &a) operator-(const MultiArrayView<2, T, C> &a)
{ {
return TemporaryMatrix<T>(a) *= -NumericTraits<T>::one(); return TemporaryMatrix<T>(a) *= -NumericTraits<T>::one();
} }
template <class T> template <class T>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
operator-(const TemporaryMatrix<T> &a) operator-(const TemporaryMatrix<T> &a)
{ {
return const_cast<TemporaryMatrix<T> &>(a) *= -NumericTraits<T>::one(); return const_cast<TemporaryMatrix<T> &>(a) *= -NumericTraits<T>::one();
} }
/** subtract scalar \a b from every element of the matrix \a a.
The result is returned as a temporary matrix.
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg
*/
template <class T, class C>
inline TemporaryMatrix<T>
operator-(const MultiArrayView<2, T, C> &a, T b)
{
return TemporaryMatrix<T>(a) -= b;
}
template <class T>
inline TemporaryMatrix<T>
operator-(const TemporaryMatrix<T> &a, T b)
{
return const_cast<TemporaryMatrix<T> &>(a) -= b;
}
/** subtract every element of the matrix \a b from scalar \a a.
The result is returned as a temporary matrix.
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg
*/
template <class T, class C>
inline TemporaryMatrix<T>
operator-(T a, const MultiArrayView<2, T, C> &b)
{
return TemporaryMatrix<T>(b.shape(), a) -= b;
}
/** calculate the inner product of two matrices representing vectors. /** calculate the inner product of two matrices representing vectors.
That is, matrix \a x must have a single row, and matrix \a y must Typically, matrix \a x has a single row, and matrix \a y has
have a single column, and the other dimensions must match. a single column, and the other dimensions match. In addition, this
function handles the cases when either or both of the two inputs ar
e
transposed (e.g. it can compute the dot product of two column vecto
rs).
A <tt>PreconditionViolation</tt> exception is thrown when
the shape conditions are violated.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1, class C2> template <class T, class C1, class C2>
T dot(const MultiArrayView<2, T, C1> &x, const MultiArrayView<2, T, C2> &y) typename NormTraits<T>::SquaredNormType
dot(const MultiArrayView<2, T, C1> &x, const MultiArrayView<2, T, C2> &y)
{ {
const std::size_t n = columnCount(x); typename NormTraits<T>::SquaredNormType ret =
vigra_precondition(n == rowCount(y) && 1 == rowCount(x) && 1 == columnC NumericTraits<typename NormTraits<T>::SquaredNormType>::zero();
ount(y), if(y.shape(1) == 1)
"dot(): shape mismatch."); {
T ret = NumericTraits<T>::zero(); std::ptrdiff_t size = y.shape(0);
for(std::size_t i = 0; i < n; ++i) if(x.shape(0) == 1 && x.shape(1) == size) // proper scalar product
ret += x(0, i) * y(i, 0); for(std::ptrdiff_t i = 0; i < size; ++i)
ret += x(0, i) * y(i, 0);
else if(x.shape(1) == 1u && x.shape(0) == size) // two column vecto
rs
for(std::ptrdiff_t i = 0; i < size; ++i)
ret += x(i, 0) * y(i, 0);
else
vigra_precondition(false, "dot(): wrong matrix shapes.");
}
else if(y.shape(0) == 1)
{
std::ptrdiff_t size = y.shape(1);
if(x.shape(0) == 1u && x.shape(1) == size) // two row vectors
for(std::ptrdiff_t i = 0; i < size; ++i)
ret += x(0, i) * y(0, i);
else if(x.shape(1) == 1u && x.shape(0) == size) // column dot row
for(std::ptrdiff_t i = 0; i < size; ++i)
ret += x(i, 0) * y(0, i);
else
vigra_precondition(false, "dot(): wrong matrix shapes.");
}
else
vigra_precondition(false, "dot(): wrong matrix shapes.");
return ret; return ret;
} }
/** calculate the inner product of two vectors. The vector /** calculate the inner product of two vectors. The vector
lengths must match. lengths must match.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1, class C2> template <class T, class C1, class C2>
T dot(const MultiArrayView<1, T, C1> &x, const MultiArrayView<1, T, C2> &y) typename NormTraits<T>::SquaredNormType
dot(const MultiArrayView<1, T, C1> &x, const MultiArrayView<1, T, C2> &y)
{ {
const std::size_t n = x.elementCount(); const MultiArrayIndex n = x.elementCount();
vigra_precondition(n == y.elementCount(), vigra_precondition(n == y.elementCount(),
"dot(): shape mismatch."); "dot(): shape mismatch.");
T ret = NumericTraits<T>::zero(); typename NormTraits<T>::SquaredNormType ret =
for(std::size_t i = 0; i < n; ++i) NumericTraits<typename NormTraits<T>::SquaredNormType>::zer
o();
for(MultiArrayIndex i = 0; i < n; ++i)
ret += x(i) * y(i); ret += x(i) * y(i);
return ret; return ret;
} }
/** calculate the cross product of two vectors of length 3. /** calculate the cross product of two vectors of length 3.
The result is written into \a r. The result is written into \a r.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1, class C2, class C3> template <class T, class C1, class C2, class C3>
void cross(const MultiArrayView<1, T, C1> &x, const MultiArrayView<1, T, C2 > &y, void cross(const MultiArrayView<1, T, C1> &x, const MultiArrayView<1, T, C2 > &y,
MultiArrayView<1, T, C3> &r) MultiArrayView<1, T, C3> &r)
{ {
vigra_precondition(3 == x.elementCount() && 3 == y.elementCount() && 3 == r.elementCount(), vigra_precondition(3 == x.elementCount() && 3 == y.elementCount() && 3 == r.elementCount(),
"cross(): vectors must have length 3."); "cross(): vectors must have length 3.");
r(0) = x(1)*y(2) - x(2)*y(1); r(0) = x(1)*y(2) - x(2)*y(1);
r(1) = x(2)*y(0) - x(0)*y(2); r(1) = x(2)*y(0) - x(0)*y(2);
r(2) = x(0)*y(1) - x(1)*y(0); r(2) = x(0)*y(1) - x(1)*y(0);
} }
/** calculate the cross product of two matrices representing vectors. /** calculate the cross product of two matrices representing vectors.
That is, \a x, \a y, and \a r must have a single column of length 3 . The result That is, \a x, \a y, and \a r must have a single column of length 3 . The result
is written into \a r. is written into \a r.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1, class C2, class C3> template <class T, class C1, class C2, class C3>
void cross(const MultiArrayView<2, T, C1> &x, const MultiArrayView<2, T, C2 > &y, void cross(const MultiArrayView<2, T, C1> &x, const MultiArrayView<2, T, C2 > &y,
MultiArrayView<2, T, C3> &r) MultiArrayView<2, T, C3> &r)
{ {
vigra_precondition(3 == rowCount(x) && 3 == rowCount(y) && 3 == rowCoun t(r) , vigra_precondition(3 == rowCount(x) && 3 == rowCount(y) && 3 == rowCoun t(r) ,
"cross(): vectors must have length 3."); "cross(): vectors must have length 3.");
r(0,0) = x(1,0)*y(2,0) - x(2,0)*y(1,0); r(0,0) = x(1,0)*y(2,0) - x(2,0)*y(1,0);
r(1,0) = x(2,0)*y(0,0) - x(0,0)*y(2,0); r(1,0) = x(2,0)*y(0,0) - x(0,0)*y(2,0);
r(2,0) = x(0,0)*y(1,0) - x(1,0)*y(0,0); r(2,0) = x(0,0)*y(1,0) - x(1,0)*y(0,0);
} }
/** calculate the cross product of two matrices representing vectors. /** calculate the cross product of two matrices representing vectors.
That is, \a x, and \a y must have a single column of length 3. The result That is, \a x, and \a y must have a single column of length 3. The result
is returned as a temporary matrix. is returned as a temporary matrix.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1, class C2> template <class T, class C1, class C2>
TemporaryMatrix<T> TemporaryMatrix<T>
cross(const MultiArrayView<2, T, C1> &x, const MultiArrayView<2, T, C2> &y) cross(const MultiArrayView<2, T, C1> &x, const MultiArrayView<2, T, C2> &y)
{ {
TemporaryMatrix<T> ret(3, 1); TemporaryMatrix<T> ret(3, 1);
cross(x, y, ret); cross(x, y, ret);
return ret; return ret;
} }
/** calculate the outer product of two matrices representing vectors. /** calculate the outer product of two matrices representing vectors.
That is, matrix \a x must have a single column, and matrix \a y mus t That is, matrix \a x must have a single column, and matrix \a y mus t
have a single row, and the other dimensions must match. The result have a single row, and the other dimensions must match. The result
is written into \a r. is written into \a r.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1, class C2, class C3> template <class T, class C1, class C2, class C3>
void outer(const MultiArrayView<2, T, C1> &x, const MultiArrayView<2, T, C2 > &y, void outer(const MultiArrayView<2, T, C1> &x, const MultiArrayView<2, T, C2 > &y,
MultiArrayView<2, T, C3> &r) MultiArrayView<2, T, C3> &r)
{ {
const std::size_t rows = rowCount(r); const MultiArrayIndex rows = rowCount(r);
const std::size_t cols = columnCount(r); const MultiArrayIndex cols = columnCount(r);
vigra_precondition(rows == rowCount(x) && cols == columnCount(y) && vigra_precondition(rows == rowCount(x) && cols == columnCount(y) &&
1 == columnCount(x) && 1 == rowCount(y), 1 == columnCount(x) && 1 == rowCount(y),
"outer(): shape mismatch."); "outer(): shape mismatch.");
for(std::size_t i = 0; i < cols; ++i) for(MultiArrayIndex i = 0; i < cols; ++i)
for(std::size_t j = 0; j < rows; ++j) for(MultiArrayIndex j = 0; j < rows; ++j)
r(j, i) = x(j, 0) * y(0, i); r(j, i) = x(j, 0) * y(0, i);
} }
/** calculate the outer product of two matrices representing vectors. /** calculate the outer product of two matrices representing vectors.
That is, matrix \a x must have a single column, and matrix \a y mus t That is, matrix \a x must have a single column, and matrix \a y mus t
have a single row, and the other dimensions must match. The result have a single row, and the other dimensions must match. The result
is returned as a temporary matrix. is returned as a temporary matrix.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1, class C2> template <class T, class C1, class C2>
TemporaryMatrix<T> TemporaryMatrix<T>
outer(const MultiArrayView<2, T, C1> &x, const MultiArrayView<2, T, C2> &y) outer(const MultiArrayView<2, T, C1> &x, const MultiArrayView<2, T, C2> &y)
{ {
const std::size_t rows = rowCount(x); const MultiArrayIndex rows = rowCount(x);
const std::size_t cols = columnCount(y); const MultiArrayIndex cols = columnCount(y);
vigra_precondition(1 == columnCount(x) && 1 == rowCount(y), vigra_precondition(1 == columnCount(x) && 1 == rowCount(y),
"outer(): shape mismatch."); "outer(): shape mismatch.");
TemporaryMatrix<T> ret(rows, cols); TemporaryMatrix<T> ret(rows, cols);
outer(x, y, ret); outer(x, y, ret);
return ret; return ret;
} }
/** calculate the outer product of a matrix (representing a vector) wit h itself. /** calculate the outer product of a matrix (representing a vector) wit h itself.
The result is returned as a temporary matrix. The result is returned as a temporary matrix.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg Namespaces: vigra and vigra::linalg
*/ */
template <class T, class C1> template <class T, class C>
TemporaryMatrix<T> TemporaryMatrix<T>
outer(const MultiArrayView<2, T, C1> &x) outer(const MultiArrayView<2, T, C> &x)
{ {
const std::size_t rows = rowCount(x); const MultiArrayIndex rows = rowCount(x);
const std::size_t cols = columnCount(x); const MultiArrayIndex cols = columnCount(x);
vigra_precondition(rows == 1 || cols == 1, vigra_precondition(rows == 1 || cols == 1,
"outer(): matrix does not represent a vector."); "outer(): matrix does not represent a vector.");
const std::size_t size = std::max(rows, cols); const MultiArrayIndex size = std::max(rows, cols);
TemporaryMatrix<T> ret(size, size); TemporaryMatrix<T> ret(size, size);
if(rows == 1) if(rows == 1)
{ {
for(std::size_t i = 0; i < size; ++i) for(MultiArrayIndex i = 0; i < size; ++i)
for(std::size_t j = 0; j < size; ++j) for(MultiArrayIndex j = 0; j < size; ++j)
ret(j, i) = x(0, j) * x(0, i); ret(j, i) = x(0, j) * x(0, i);
} }
else else
{ {
for(std::size_t i = 0; i < size; ++i) for(MultiArrayIndex i = 0; i < size; ++i)
for(std::size_t j = 0; j < size; ++j) for(MultiArrayIndex j = 0; j < size; ++j)
ret(j, i) = x(j, 0) * x(i, 0); ret(j, i) = x(j, 0) * x(i, 0);
} }
return ret; return ret;
} }
/** multiply matrix \a a with scalar \a b. template <class T>
class PointWise
{
public:
T const & t;
PointWise(T const & it)
: t(it)
{}
};
template <class T>
PointWise<T> pointWise(T const & t)
{
return PointWise<T>(t);
}
/** multiply matrix \a a with scalar \a b.
The result is written into \a r. \a a and \a r must have the same s hape. The result is written into \a r. \a a and \a r must have the same s hape.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C1, class C2> template <class T, class C1, class C2>
void smul(const MultiArrayView<2, T, C1> &a, T b, MultiArrayView<2, T, C2> &r) void smul(const MultiArrayView<2, T, C1> &a, T b, MultiArrayView<2, T, C2> &r)
{ {
const std::size_t rows = rowCount(a); const MultiArrayIndex rows = rowCount(a);
const std::size_t cols = columnCount(a); const MultiArrayIndex cols = columnCount(a);
vigra_precondition(rows == rowCount(r) && cols == columnCount(r), vigra_precondition(rows == rowCount(r) && cols == columnCount(r),
"smul(): Matrix sizes must agree."); "smul(): Matrix sizes must agree.");
for(std::size_t i = 0; i < cols; ++i) for(MultiArrayIndex i = 0; i < cols; ++i)
for(std::size_t j = 0; j < rows; ++j) for(MultiArrayIndex j = 0; j < rows; ++j)
r(j, i) = a(j, i) * b; r(j, i) = a(j, i) * b;
} }
/** multiply scalar \a a with matrix \a b. /** multiply scalar \a a with matrix \a b.
The result is written into \a r. \a b and \a r must have the same s hape. The result is written into \a r. \a b and \a r must have the same s hape.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C2, class C3> template <class T, class C2, class C3>
void smul(T a, const MultiArrayView<2, T, C2> &b, MultiArrayView<2, T, C3> &r) void smul(T a, const MultiArrayView<2, T, C2> &b, MultiArrayView<2, T, C3> &r)
{ {
smul(b, a, r); smul(b, a, r);
} }
/** perform matrix multiplication of matrices \a a and \a b. /** perform matrix multiplication of matrices \a a and \a b.
The result is written into \a r. The three matrices must have match ing shapes. The result is written into \a r. The three matrices must have match ing shapes.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C1, class C2, class C3> template <class T, class C1, class C2, class C3>
void mmul(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b, void mmul(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b,
MultiArrayView<2, T, C3> &r) MultiArrayView<2, T, C3> &r)
{ {
const std::size_t rrows = rowCount(r); const MultiArrayIndex rrows = rowCount(r);
const std::size_t rcols = columnCount(r); const MultiArrayIndex rcols = columnCount(r);
const std::size_t acols = columnCount(a); const MultiArrayIndex acols = columnCount(a);
vigra_precondition(rrows == rowCount(a) && rcols == columnCount(b) && a cols == rowCount(b), vigra_precondition(rrows == rowCount(a) && rcols == columnCount(b) && a cols == rowCount(b),
"mmul(): Matrix shapes must agree."); "mmul(): Matrix shapes must agree.");
for(std::size_t i = 0; i < rcols; ++i) { // order of loops ensures that inner loop goes down columns
for(std::size_t j = 0; j < rrows; ++j) { for(MultiArrayIndex i = 0; i < rcols; ++i)
r(j, i) = 0.0; {
for(std::size_t k = 0; k < acols; ++k) { for(MultiArrayIndex j = 0; j < rrows; ++j)
r(j, i) = a(j, 0) * b(0, i);
for(MultiArrayIndex k = 1; k < acols; ++k)
for(MultiArrayIndex j = 0; j < rrows; ++j)
r(j, i) += a(j, k) * b(k, i); r(j, i) += a(j, k) * b(k, i);
}
}
} }
} }
/** perform matrix multiplication of matrices \a a and \a b. /** perform matrix multiplication of matrices \a a and \a b.
\a a and \a b must have matching shapes. \a a and \a b must have matching shapes.
The result is returned as a temporary matrix. The result is returned as a temporary matrix.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C1, class C2> template <class T, class C1, class C2>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
mmul(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b) mmul(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b)
{ {
TemporaryMatrix<T> ret(rowCount(a), columnCount(b)); TemporaryMatrix<T> ret(rowCount(a), columnCount(b));
mmul(a, b, ret); mmul(a, b, ret);
return ret; return ret;
} }
/** multiply two matrices \a a and \a b pointwise. /** multiply two matrices \a a and \a b pointwise.
The result is written into \a r. All three matrices must have the s ame shape. The result is written into \a r. All three matrices must have the s ame shape.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C1, class C2, class C3> template <class T, class C1, class C2, class C3>
void pmul(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b, void pmul(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b,
MultiArrayView<2, T, C3> &r) MultiArrayView<2, T, C3> &r)
{ {
const std::size_t rrows = rowCount(r); const MultiArrayIndex rrows = rowCount(r);
const std::size_t rcols = columnCount(r); const MultiArrayIndex rcols = columnCount(r);
vigra_precondition(rrows == rowCount(a) && rcols == columnCount(a) && vigra_precondition(rrows == rowCount(a) && rcols == columnCount(a) &&
rrows == rowCount(b) && rcols == columnCount(b), rrows == rowCount(b) && rcols == columnCount(b),
"pmul(): Matrix shapes must agree."); "pmul(): Matrix shapes must agree.");
for(std::size_t i = 0; i < rcols; ++i) { for(MultiArrayIndex i = 0; i < rcols; ++i) {
for(std::size_t j = 0; j < rrows; ++j) { for(MultiArrayIndex j = 0; j < rrows; ++j) {
r(j, i) = a(j, i) * b(j, i); r(j, i) = a(j, i) * b(j, i);
} }
} }
} }
/** multiply matrices \a a and \a b pointwise. /** multiply matrices \a a and \a b pointwise.
\a a and \a b must have matching shapes. \a a and \a b must have matching shapes.
The result is returned as a temporary matrix. The result is returned as a temporary matrix.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C1, class C2> template <class T, class C1, class C2>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
pmul(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b) pmul(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b)
{ {
TemporaryMatrix<T> ret(rowCount(a), columnCount(b)); TemporaryMatrix<T> ret(a.shape());
pmul(a, b, ret); pmul(a, b, ret);
return ret; return ret;
} }
/** multiply matrices \a a and \a b pointwise.
\a a and \a b must have matching shapes.
The result is returned as a temporary matrix.
Usage:
\code
Matrix<double> a(m,n), b(m,n);
Matrix<double> c = a * pointWise(b);
// is equivalent to
// Matrix<double> c = pmul(a, b);
\endcode
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg
*/
template <class T, class C, class U>
inline TemporaryMatrix<T>
operator*(const MultiArrayView<2, T, C> &a, PointWise<U> b)
{
return pmul(a, b.t);
}
/** multiply matrix \a a with scalar \a b. /** multiply matrix \a a with scalar \a b.
The result is returned as a temporary matrix. The result is returned as a temporary matrix.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C> template <class T, class C>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
operator*(const MultiArrayView<2, T, C> &a, T b) operator*(const MultiArrayView<2, T, C> &a, T b)
{ {
return TemporaryMatrix<T>(a) *= b; return TemporaryMatrix<T>(a) *= b;
} }
template <class T> template <class T>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
operator*(const TemporaryMatrix<T> &a, T b) operator*(const TemporaryMatrix<T> &a, T b)
{ {
return const_cast<TemporaryMatrix<T> &>(a) *= b; return const_cast<TemporaryMatrix<T> &>(a) *= b;
} }
/** multiply scalar \a a with matrix \a b. /** multiply scalar \a a with matrix \a b.
The result is returned as a temporary matrix. The result is returned as a temporary matrix.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C> template <class T, class C>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
operator*(T a, const MultiArrayView<2, T, C> &b) operator*(T a, const MultiArrayView<2, T, C> &b)
{ {
return TemporaryMatrix<T>(b) *= a; return TemporaryMatrix<T>(b) *= a;
} }
template <class T> template <class T>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
operator*(T a, const TemporaryMatrix<T> &b) operator*(T a, const TemporaryMatrix<T> &b)
{ {
return const_cast<TemporaryMatrix<T> &>(b) *= b; return const_cast<TemporaryMatrix<T> &>(b) *= a;
} }
/** multiply matrix \a a with TinyVector \a b. /** multiply matrix \a a with TinyVector \a b.
\a a must be of size <tt>N x N</tt>. Vector \a b and the result \a a must be of size <tt>N x N</tt>. Vector \a b and the result
vector are interpreted as column vectors. vector are interpreted as column vectors.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class A, int N, class DATA, class DERIVED> template <class T, class A, int N, class DATA, class DERIVED>
TinyVector<T, N> TinyVector<T, N>
operator*(const Matrix<T, A> &a, const TinyVectorBase<T, N, DATA, DERIVED> &b) operator*(const Matrix<T, A> &a, const TinyVectorBase<T, N, DATA, DERIVED> &b)
{ {
vigra_precondition(N == rowCount(a) && N == columnCount(a), vigra_precondition(N == rowCount(a) && N == columnCount(a),
"operator*(Matrix, TinyVector): Shape mismatch."); "operator*(Matrix, TinyVector): Shape mismatch.");
TinyVector<T, N> res = TinyVectorView<T, N>(&a(0,0)) * b[0]; TinyVector<T, N> res = TinyVectorView<T, N>(&a(0,0)) * b[0];
for(std::size_t i = 1; i < N; ++i) for(MultiArrayIndex i = 1; i < N; ++i)
res += TinyVectorView<T, N>(&a(0,i)) * b[i]; res += TinyVectorView<T, N>(&a(0,i)) * b[i];
return res; return res;
} }
/** multiply TinyVector \a a with matrix \a b. /** multiply TinyVector \a a with matrix \a b.
\a b must be of size <tt>N x N</tt>. Vector \a a and the result \a b must be of size <tt>N x N</tt>. Vector \a a and the result
vector are interpreted as row vectors. vector are interpreted as row vectors.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, int N, class DATA, class DERIVED, class A> template <class T, int N, class DATA, class DERIVED, class A>
TinyVector<T, N> TinyVector<T, N>
operator*(const TinyVectorBase<T, N, DATA, DERIVED> &a, const Matrix<T, A> &b) operator*(const TinyVectorBase<T, N, DATA, DERIVED> &a, const Matrix<T, A> &b)
{ {
vigra_precondition(N == rowCount(b) && N == columnCount(b), vigra_precondition(N == rowCount(b) && N == columnCount(b),
"operator*(TinyVector, Matrix): Shape mismatch."); "operator*(TinyVector, Matrix): Shape mismatch.");
TinyVector<T, N> res; TinyVector<T, N> res;
for(std::size_t i = 0; i < N; ++i) for(MultiArrayIndex i = 0; i < N; ++i)
res[i] = dot(a, TinyVectorView<T, N>(&b(0,i))); res[i] = dot(a, TinyVectorView<T, N>(&b(0,i)));
return res; return res;
} }
/** perform matrix multiplication of matrices \a a and \a b. /** perform matrix multiplication of matrices \a a and \a b.
\a a and \a b must have matching shapes. \a a and \a b must have matching shapes.
The result is returned as a temporary matrix. The result is returned as a temporary matrix.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C1, class C2> template <class T, class C1, class C2>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
operator*(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b) operator*(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b)
{ {
TemporaryMatrix<T> ret(rowCount(a), columnCount(b)); TemporaryMatrix<T> ret(rowCount(a), columnCount(b));
mmul(a, b, ret); mmul(a, b, ret);
return ret; return ret;
} }
/** divide matrix \a a by scalar \a b. /** divide matrix \a a by scalar \a b.
The result is written into \a r. \a a and \a r must have the same s hape. The result is written into \a r. \a a and \a r must have the same s hape.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C1, class C2> template <class T, class C1, class C2>
void sdiv(const MultiArrayView<2, T, C1> &a, T b, MultiArrayView<2, T, C2> &r) void sdiv(const MultiArrayView<2, T, C1> &a, T b, MultiArrayView<2, T, C2> &r)
{ {
const std::size_t rows = rowCount(a); const MultiArrayIndex rows = rowCount(a);
const std::size_t cols = columnCount(a); const MultiArrayIndex cols = columnCount(a);
vigra_precondition(rows == rowCount(r) && cols == columnCount(r), vigra_precondition(rows == rowCount(r) && cols == columnCount(r),
"sdiv(): Matrix sizes must agree."); "sdiv(): Matrix sizes must agree.");
for(std::size_t i = 0; i < cols; ++i) for(MultiArrayIndex i = 0; i < cols; ++i)
for(std::size_t j = 0; j < rows; ++j) for(MultiArrayIndex j = 0; j < rows; ++j)
r(j, i) = a(j, i) / b; r(j, i) = a(j, i) / b;
} }
/** divide two matrices \a a and \a b pointwise. /** divide two matrices \a a and \a b pointwise.
The result is written into \a r. All three matrices must have the s ame shape. The result is written into \a r. All three matrices must have the s ame shape.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C1, class C2, class C3> template <class T, class C1, class C2, class C3>
void pdiv(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b, void pdiv(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b,
MultiArrayView<2, T, C3> &r) MultiArrayView<2, T, C3> &r)
{ {
const std::size_t rrows = rowCount(r); const MultiArrayIndex rrows = rowCount(r);
const std::size_t rcols = columnCount(r); const MultiArrayIndex rcols = columnCount(r);
vigra_precondition(rrows == rowCount(a) && rcols == columnCount(a) && vigra_precondition(rrows == rowCount(a) && rcols == columnCount(a) &&
rrows == rowCount(b) && rcols == columnCount(b), rrows == rowCount(b) && rcols == columnCount(b),
"pdiv(): Matrix shapes must agree."); "pdiv(): Matrix shapes must agree.");
for(std::size_t i = 0; i < rcols; ++i) { for(MultiArrayIndex i = 0; i < rcols; ++i) {
for(std::size_t j = 0; j < rrows; ++j) { for(MultiArrayIndex j = 0; j < rrows; ++j) {
r(j, i) = a(j, i) * b(j, i); r(j, i) = a(j, i) / b(j, i);
} }
} }
} }
/** divide matrices \a a and \a b pointwise. /** divide matrices \a a and \a b pointwise.
\a a and \a b must have matching shapes. \a a and \a b must have matching shapes.
The result is returned as a temporary matrix. The result is returned as a temporary matrix.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C1, class C2> template <class T, class C1, class C2>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
pdiv(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b) pdiv(const MultiArrayView<2, T, C1> &a, const MultiArrayView<2, T, C2> &b)
{ {
TemporaryMatrix<T> ret(rowCount(a), columnCount(b)); TemporaryMatrix<T> ret(a.shape());
pdiv(a, b, ret); pdiv(a, b, ret);
return ret; return ret;
} }
/** divide matrices \a a and \a b pointwise.
\a a and \a b must have matching shapes.
The result is returned as a temporary matrix.
Usage:
\code
Matrix<double> a(m,n), b(m,n);
Matrix<double> c = a / pointWise(b);
// is equivalent to
// Matrix<double> c = pdiv(a, b);
\endcode
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg
*/
template <class T, class C, class U>
inline TemporaryMatrix<T>
operator/(const MultiArrayView<2, T, C> &a, PointWise<U> b)
{
return pdiv(a, b.t);
}
/** divide matrix \a a by scalar \a b. /** divide matrix \a a by scalar \a b.
The result is returned as a temporary matrix. The result is returned as a temporary matrix.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg Namespace: vigra::linalg
*/ */
template <class T, class C> template <class T, class C>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
operator/(const MultiArrayView<2, T, C> &a, T b) operator/(const MultiArrayView<2, T, C> &a, T b)
{ {
return TemporaryMatrix<T>(a) /= b; return TemporaryMatrix<T>(a) /= b;
} }
template <class T> template <class T>
inline TemporaryMatrix<T> inline TemporaryMatrix<T>
operator/(const TemporaryMatrix<T> &a, T b) operator/(const TemporaryMatrix<T> &a, T b)
{ {
return const_cast<TemporaryMatrix<T> &>(a) /= b; return const_cast<TemporaryMatrix<T> &>(a) /= b;
} }
/** Create a matrix whose elements are the quotients between scalar \a
a and
matrix \a b. The result is returned as a temporary matrix.
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespace: vigra::linalg
*/
template <class T, class C>
inline TemporaryMatrix<T>
operator/(T a, const MultiArrayView<2, T, C> &b)
{
return TemporaryMatrix<T>(b.shape(), a) / pointWise(b);
}
using vigra::argMin;
using vigra::argMinIf;
using vigra::argMax;
using vigra::argMaxIf;
/*! Find the index of the minimum element in a matrix.
The function returns the index in column-major scan-order sense,
i.e. according to the order used by <tt>MultiArrayView::operator[]<
/tt>.
If the matrix is actually a vector, this is just the row or columns
index.
In case of a truely 2-dimensional matrix, the index can be converte
d to an
index pair by calling <tt>MultiArrayView::scanOrderIndexToCoordinat
e()</tt>
<b>Required Interface:</b>
\code
bool f = a[0] < NumericTraits<T>::max();
\endcode
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.h
xx</a>\><br>
Namespace: vigra
*/
template <class T, class C>
int argMin(MultiArrayView<2, T, C> const & a)
{
T vopt = NumericTraits<T>::max();
int best = -1;
for(int k=0; k < a.size(); ++k)
{
if(a[k] < vopt)
{
vopt = a[k];
best = k;
}
}
return best;
}
/*! Find the index of the maximum element in a matrix.
The function returns the index in column-major scan-order sense,
i.e. according to the order used by <tt>MultiArrayView::operator[]<
/tt>.
If the matrix is actually a vector, this is just the row or columns
index.
In case of a truely 2-dimensional matrix, the index can be converte
d to an
index pair by calling <tt>MultiArrayView::scanOrderIndexToCoordinat
e()</tt>
<b>Required Interface:</b>
\code
bool f = NumericTraits<T>::min() < a[0];
\endcode
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.h
xx</a>\><br>
Namespace: vigra
*/
template <class T, class C>
int argMax(MultiArrayView<2, T, C> const & a)
{
T vopt = NumericTraits<T>::min();
int best = -1;
for(int k=0; k < a.size(); ++k)
{
if(vopt < a[k])
{
vopt = a[k];
best = k;
}
}
return best;
}
/*! Find the index of the minimum element in a matrix subject to a cond
ition.
The function returns <tt>-1</tt> if no element conforms to \a condi
tion.
Otherwise, the index of the maximum element is returned in column-m
ajor scan-order sense,
i.e. according to the order used by <tt>MultiArrayView::operator[]<
/tt>.
If the matrix is actually a vector, this is just the row or columns
index.
In case of a truely 2-dimensional matrix, the index can be converte
d to an
index pair by calling <tt>MultiArrayView::scanOrderIndexToCoordinat
e()</tt>
<b>Required Interface:</b>
\code
bool c = condition(a[0]);
bool f = a[0] < NumericTraits<T>::max();
\endcode
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.h
xx</a>\><br>
Namespace: vigra
*/
template <class T, class C, class UnaryFunctor>
int argMinIf(MultiArrayView<2, T, C> const & a, UnaryFunctor condition)
{
T vopt = NumericTraits<T>::max();
int best = -1;
for(int k=0; k < a.size(); ++k)
{
if(condition(a[k]) && a[k] < vopt)
{
vopt = a[k];
best = k;
}
}
return best;
}
/*! Find the index of the maximum element in a matrix subject to a cond
ition.
The function returns <tt>-1</tt> if no element conforms to \a condi
tion.
Otherwise, the index of the maximum element is returned in column-m
ajor scan-order sense,
i.e. according to the order used by <tt>MultiArrayView::operator[]<
/tt>.
If the matrix is actually a vector, this is just the row or columns
index.
In case of a truely 2-dimensional matrix, the index can be converte
d to an
index pair by calling <tt>MultiArrayView::scanOrderIndexToCoordinat
e()</tt>
<b>Required Interface:</b>
\code
bool c = condition(a[0]);
bool f = NumericTraits<T>::min() < a[0];
\endcode
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.h
xx</a>\><br>
Namespace: vigra
*/
template <class T, class C, class UnaryFunctor>
int argMaxIf(MultiArrayView<2, T, C> const & a, UnaryFunctor condition)
{
T vopt = NumericTraits<T>::min();
int best = -1;
for(int k=0; k < a.size(); ++k)
{
if(condition(a[k]) && vopt < a[k])
{
vopt = a[k];
best = k;
}
}
return best;
}
/** Matrix point-wise power.
*/
template <class T, class C>
linalg::TemporaryMatrix<T> pow(MultiArrayView<2, T, C> const & v, T exponen
t)
{
linalg::TemporaryMatrix<T> t(v.shape());
MultiArrayIndex m = rowCount(v), n = columnCount(v);
for(MultiArrayIndex i = 0; i < n; ++i)
for(MultiArrayIndex j = 0; j < m; ++j)
t(j, i) = vigra::pow(v(j, i), exponent);
return t;
}
template <class T>
linalg::TemporaryMatrix<T> pow(linalg::TemporaryMatrix<T> const & v, T expo
nent)
{
linalg::TemporaryMatrix<T> & t = const_cast<linalg::TemporaryMatrix<T>
&>(v);
MultiArrayIndex m = rowCount(t), n = columnCount(t);
for(MultiArrayIndex i = 0; i < n; ++i)
for(MultiArrayIndex j = 0; j < m; ++j)
t(j, i) = vigra::pow(t(j, i), exponent);
return t;
}
template <class T, class C>
linalg::TemporaryMatrix<T> pow(MultiArrayView<2, T, C> const & v, int expon
ent)
{
linalg::TemporaryMatrix<T> t(v.shape());
MultiArrayIndex m = rowCount(v), n = columnCount(v);
for(MultiArrayIndex i = 0; i < n; ++i)
for(MultiArrayIndex j = 0; j < m; ++j)
t(j, i) = vigra::pow(v(j, i), exponent);
return t;
}
template <class T>
linalg::TemporaryMatrix<T> pow(linalg::TemporaryMatrix<T> const & v, int ex
ponent)
{
linalg::TemporaryMatrix<T> & t = const_cast<linalg::TemporaryMatrix<T>
&>(v);
MultiArrayIndex m = rowCount(t), n = columnCount(t);
for(MultiArrayIndex i = 0; i < n; ++i)
for(MultiArrayIndex j = 0; j < m; ++j)
t(j, i) = vigra::pow(t(j, i), exponent);
return t;
}
template <class C>
linalg::TemporaryMatrix<int> pow(MultiArrayView<2, int, C> const & v, int e
xponent)
{
linalg::TemporaryMatrix<int> t(v.shape());
MultiArrayIndex m = rowCount(v), n = columnCount(v);
for(MultiArrayIndex i = 0; i < n; ++i)
for(MultiArrayIndex j = 0; j < m; ++j)
t(j, i) = (int)vigra::pow((double)v(j, i), exponent);
return t;
}
inline
linalg::TemporaryMatrix<int> pow(linalg::TemporaryMatrix<int> const & v, in
t exponent)
{
linalg::TemporaryMatrix<int> & t = const_cast<linalg::TemporaryMatrix<i
nt> &>(v);
MultiArrayIndex m = rowCount(t), n = columnCount(t);
for(MultiArrayIndex i = 0; i < n; ++i)
for(MultiArrayIndex j = 0; j < m; ++j)
t(j, i) = (int)vigra::pow((double)t(j, i), exponent);
return t;
}
/** Matrix point-wise sqrt. */
template <class T, class C>
linalg::TemporaryMatrix<T> sqrt(MultiArrayView<2, T, C> const & v);
/** Matrix point-wise exp. */
template <class T, class C>
linalg::TemporaryMatrix<T> exp(MultiArrayView<2, T, C> const & v);
/** Matrix point-wise log. */
template <class T, class C>
linalg::TemporaryMatrix<T> log(MultiArrayView<2, T, C> const & v);
/** Matrix point-wise log10. */
template <class T, class C>
linalg::TemporaryMatrix<T> log10(MultiArrayView<2, T, C> const & v);
/** Matrix point-wise sin. */
template <class T, class C>
linalg::TemporaryMatrix<T> sin(MultiArrayView<2, T, C> const & v);
/** Matrix point-wise asin. */
template <class T, class C>
linalg::TemporaryMatrix<T> asin(MultiArrayView<2, T, C> const & v);
/** Matrix point-wise cos. */
template <class T, class C>
linalg::TemporaryMatrix<T> cos(MultiArrayView<2, T, C> const & v);
/** Matrix point-wise acos. */
template <class T, class C>
linalg::TemporaryMatrix<T> acos(MultiArrayView<2, T, C> const & v);
/** Matrix point-wise tan. */
template <class T, class C>
linalg::TemporaryMatrix<T> tan(MultiArrayView<2, T, C> const & v);
/** Matrix point-wise atan. */
template <class T, class C>
linalg::TemporaryMatrix<T> atan(MultiArrayView<2, T, C> const & v);
/** Matrix point-wise round. */
template <class T, class C>
linalg::TemporaryMatrix<T> round(MultiArrayView<2, T, C> const & v);
/** Matrix point-wise floor. */
template <class T, class C>
linalg::TemporaryMatrix<T> floor(MultiArrayView<2, T, C> const & v);
/** Matrix point-wise ceil. */
template <class T, class C>
linalg::TemporaryMatrix<T> ceil(MultiArrayView<2, T, C> const & v);
/** Matrix point-wise abs. */
template <class T, class C>
linalg::TemporaryMatrix<T> abs(MultiArrayView<2, T, C> const & v);
/** Matrix point-wise square. */
template <class T, class C>
linalg::TemporaryMatrix<T> sq(MultiArrayView<2, T, C> const & v);
/** Matrix point-wise sign. */
template <class T, class C>
linalg::TemporaryMatrix<T> sign(MultiArrayView<2, T, C> const & v);
#define VIGRA_MATRIX_UNARY_FUNCTION(FUNCTION, NAMESPACE) \
using NAMESPACE::FUNCTION; \
template <class T, class C> \
linalg::TemporaryMatrix<T> FUNCTION(MultiArrayView<2, T, C> const & v) \
{ \
linalg::TemporaryMatrix<T> t(v.shape()); \
MultiArrayIndex m = rowCount(v), n = columnCount(v); \
\
for(MultiArrayIndex i = 0; i < n; ++i) \
for(MultiArrayIndex j = 0; j < m; ++j) \
t(j, i) = NAMESPACE::FUNCTION(v(j, i)); \
return t; \
} \
\
template <class T> \
linalg::TemporaryMatrix<T> FUNCTION(linalg::Matrix<T> const & v) \
{ \
linalg::TemporaryMatrix<T> t(v.shape()); \
MultiArrayIndex m = rowCount(v), n = columnCount(v); \
\
for(MultiArrayIndex i = 0; i < n; ++i) \
for(MultiArrayIndex j = 0; j < m; ++j) \
t(j, i) = NAMESPACE::FUNCTION(v(j, i)); \
return t; \
} \
\
template <class T> \
linalg::TemporaryMatrix<T> FUNCTION(linalg::TemporaryMatrix<T> const & v) \
{ \
linalg::TemporaryMatrix<T> & t = const_cast<linalg::TemporaryMatrix<T>
&>(v); \
MultiArrayIndex m = rowCount(t), n = columnCount(t); \
\
for(MultiArrayIndex i = 0; i < n; ++i) \
for(MultiArrayIndex j = 0; j < m; ++j) \
t(j, i) = NAMESPACE::FUNCTION(t(j, i)); \
return v; \
}\
}\
using linalg::FUNCTION;\
namespace linalg {
VIGRA_MATRIX_UNARY_FUNCTION(sqrt, std)
VIGRA_MATRIX_UNARY_FUNCTION(exp, std)
VIGRA_MATRIX_UNARY_FUNCTION(log, std)
VIGRA_MATRIX_UNARY_FUNCTION(log10, std)
VIGRA_MATRIX_UNARY_FUNCTION(sin, std)
VIGRA_MATRIX_UNARY_FUNCTION(asin, std)
VIGRA_MATRIX_UNARY_FUNCTION(cos, std)
VIGRA_MATRIX_UNARY_FUNCTION(acos, std)
VIGRA_MATRIX_UNARY_FUNCTION(tan, std)
VIGRA_MATRIX_UNARY_FUNCTION(atan, std)
VIGRA_MATRIX_UNARY_FUNCTION(round, vigra)
VIGRA_MATRIX_UNARY_FUNCTION(floor, vigra)
VIGRA_MATRIX_UNARY_FUNCTION(ceil, vigra)
VIGRA_MATRIX_UNARY_FUNCTION(abs, vigra)
VIGRA_MATRIX_UNARY_FUNCTION(sq, vigra)
VIGRA_MATRIX_UNARY_FUNCTION(sign, vigra)
#undef VIGRA_MATRIX_UNARY_FUNCTION
//@} //@}
} // namespace linalg } // namespace linalg
using linalg::RowMajor; using linalg::RowMajor;
using linalg::ColumnMajor; using linalg::ColumnMajor;
using linalg::Matrix; using linalg::Matrix;
using linalg::identityMatrix; using linalg::identityMatrix;
using linalg::diagonalMatrix; using linalg::diagonalMatrix;
using linalg::transpose; using linalg::transpose;
using linalg::pointWise;
using linalg::dot; using linalg::dot;
using linalg::cross; using linalg::cross;
using linalg::outer; using linalg::outer;
using linalg::rowCount; using linalg::rowCount;
using linalg::columnCount; using linalg::columnCount;
using linalg::rowVector; using linalg::rowVector;
using linalg::columnVector; using linalg::columnVector;
using linalg::isSymmetric; using linalg::isSymmetric;
using linalg::joinHorizontally;
using linalg::joinVertically;
using linalg::argMin;
using linalg::argMinIf;
using linalg::argMax;
using linalg::argMaxIf;
/********************************************************/ /********************************************************/
/* */ /* */
/* NormTraits */ /* NormTraits */
/* */ /* */
/********************************************************/ /********************************************************/
template <class T, class ALLOC> template <class T, class ALLOC>
struct NormTraits<linalg::Matrix<T, ALLOC> > struct NormTraits<Matrix<T, ALLOC> >
: public NormTraits<MultiArray<2, T, ALLOC> >
{ {
typedef linalg::Matrix<T, ALLOC> Type; typedef NormTraits<MultiArray<2, T, ALLOC> > BaseType;
typedef typename Type::SquaredNormType SquaredNormType; typedef Matrix<T, ALLOC> Type;
typedef typename Type::NormType NormType; typedef typename BaseType::SquaredNormType SquaredNormType;
typedef typename BaseType::NormType NormType;
}; };
template <class T, class ALLOC> template <class T, class ALLOC>
struct NormTraits<linalg::TemporaryMatrix<T, ALLOC> > struct NormTraits<linalg::TemporaryMatrix<T, ALLOC> >
: public NormTraits<Matrix<T, ALLOC> >
{ {
typedef linalg::TemporaryMatrix<T, ALLOC> Type; typedef NormTraits<Matrix<T, ALLOC> > BaseType;
typedef typename Type::SquaredNormType SquaredNormType; typedef linalg::TemporaryMatrix<T, ALLOC> Type;
typedef typename Type::NormType NormType; typedef typename BaseType::SquaredNormType SquaredNormType;
typedef typename BaseType::NormType NormType;
}; };
/** \addtogroup LinearAlgebraFunctions Matrix functions /** \addtogroup LinearAlgebraFunctions
*/ */
//@{ //@{
/** print a matrix \a m to the stream \a s. /** print a matrix \a m to the stream \a s.
<b>\#include</b> "<a href="matrix_8hxx-source.html">vigra/matrix.hxx</a <b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
>" or<br> a>\> or<br>
<b>\#include</b> "<a href="linear__algebra_8hxx-source.html">vigra/line <b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ar_algebra.hxx</a>"<br> ear_algebra.hxx</a>\><br>
Namespace: std Namespace: std
*/ */
template <class T, class C> template <class T, class C>
std::ostream & std::ostream &
operator<<(std::ostream & s, const vigra::MultiArrayView<2, T, C> &m) operator<<(std::ostream & s, const vigra::MultiArrayView<2, T, C> &m)
{ {
const std::size_t rows = vigra::linalg::rowCount(m); const MultiArrayIndex rows = vigra::linalg::rowCount(m);
const std::size_t cols = vigra::linalg::columnCount(m); const MultiArrayIndex cols = vigra::linalg::columnCount(m);
std::ios::fmtflags flags = std::ios::fmtflags flags =
s.setf(std::ios::right | std::ios::fixed, std::ios::adjustfield | s td::ios::floatfield); s.setf(std::ios::right | std::ios::fixed, std::ios::adjustfield | s td::ios::floatfield);
for(std::size_t j = 0; j < rows; ++j) for(MultiArrayIndex j = 0; j < rows; ++j)
{ {
for(std::size_t i = 0; i < cols; ++i) for(MultiArrayIndex i = 0; i < cols; ++i)
{ {
s << std::setw(7) << std::setprecision(4) << m(j, i) << " "; s << std::setw(7) << std::setprecision(4) << m(j, i) << " ";
} }
s << std::endl; s << std::endl;
} }
s.setf(flags); s.setf(flags);
return s; return s;
} }
//@} //@}
namespace linalg {
namespace detail {
template <class T1, class C1, class T2, class C2, class T3, class C3>
void
columnStatisticsImpl(MultiArrayView<2, T1, C1> const & A,
MultiArrayView<2, T2, C2> & mean, MultiArrayView<2, T3, C3
> & sumOfSquaredDifferences)
{
MultiArrayIndex m = rowCount(A);
MultiArrayIndex n = columnCount(A);
vigra_precondition(1 == rowCount(mean) && n == columnCount(mean) &&
1 == rowCount(sumOfSquaredDifferences) && n == colum
nCount(sumOfSquaredDifferences),
"columnStatistics(): Shape mismatch between input an
d output.");
// West's algorithm for incremental variance computation
mean.init(NumericTraits<T2>::zero());
sumOfSquaredDifferences.init(NumericTraits<T3>::zero());
for(MultiArrayIndex k=0; k<m; ++k)
{
Matrix<T2> t = rowVector(A, k) - mean;
typename NumericTraits<T2>::RealPromote f = 1.0 / (k + 1.0),
f1 = 1.0 - f;
mean += f*t;
sumOfSquaredDifferences += f1*sq(t);
}
}
template <class T1, class C1, class T2, class C2, class T3, class C3>
void
columnStatistics2PassImpl(MultiArrayView<2, T1, C1> const & A,
MultiArrayView<2, T2, C2> & mean, MultiArrayView<2, T3, C3
> & sumOfSquaredDifferences)
{
MultiArrayIndex m = rowCount(A);
MultiArrayIndex n = columnCount(A);
vigra_precondition(1 == rowCount(mean) && n == columnCount(mean) &&
1 == rowCount(sumOfSquaredDifferences) && n == colum
nCount(sumOfSquaredDifferences),
"columnStatistics(): Shape mismatch between input an
d output.");
// two-pass algorithm for incremental variance computation
mean.init(NumericTraits<T2>::zero());
for(MultiArrayIndex k=0; k<m; ++k)
{
mean += rowVector(A, k);
}
mean /= (double)m;
sumOfSquaredDifferences.init(NumericTraits<T3>::zero());
for(MultiArrayIndex k=0; k<m; ++k)
{
sumOfSquaredDifferences += sq(rowVector(A, k) - mean);
}
}
} // namespace detail
/** \addtogroup LinearAlgebraFunctions
*/
//@{
/** Compute statistics of every column of matrix \a A.
The result matrices must be row vectors with as many columns as \a A.
<b> Declarations:</b>
compute only the mean:
\code
namespace vigra { namespace linalg {
template <class T1, class C1, class T2, class C2>
void
columnStatistics(MultiArrayView<2, T1, C1> const & A,
MultiArrayView<2, T2, C2> & mean);
} }
\endcode
compute mean and standard deviation:
\code
namespace vigra { namespace linalg {
template <class T1, class C1, class T2, class C2, class T3, class C
3>
void
columnStatistics(MultiArrayView<2, T1, C1> const & A,
MultiArrayView<2, T2, C2> & mean,
MultiArrayView<2, T3, C3> & stdDev);
} }
\endcode
compute mean, standard deviation, and norm:
\code
namespace vigra { namespace linalg {
template <class T1, class C1, class T2, class C2, class T3, class C
3, class T4, class C4>
void
columnStatistics(MultiArrayView<2, T1, C1> const & A,
MultiArrayView<2, T2, C2> & mean,
MultiArrayView<2, T3, C3> & stdDev,
MultiArrayView<2, T4, C4> & norm);
} }
\endcode
<b> Usage:</b>
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg
\code
Matrix A(rows, columns);
.. // fill A
Matrix columnMean(1, columns), columnStdDev(1, columns), columnNorm(1,
columns);
columnStatistics(A, columnMean, columnStdDev, columnNorm);
\endcode
*/
doxygen_overloaded_function(template <...> void columnStatistics)
template <class T1, class C1, class T2, class C2>
void
columnStatistics(MultiArrayView<2, T1, C1> const & A,
MultiArrayView<2, T2, C2> & mean)
{
MultiArrayIndex m = rowCount(A);
MultiArrayIndex n = columnCount(A);
vigra_precondition(1 == rowCount(mean) && n == columnCount(mean),
"columnStatistics(): Shape mismatch between input an
d output.");
mean.init(NumericTraits<T2>::zero());
for(MultiArrayIndex k=0; k<m; ++k)
{
mean += rowVector(A, k);
}
mean /= T2(m);
}
template <class T1, class C1, class T2, class C2, class T3, class C3>
void
columnStatistics(MultiArrayView<2, T1, C1> const & A,
MultiArrayView<2, T2, C2> & mean, MultiArrayView<2, T3, C3
> & stdDev)
{
detail::columnStatisticsImpl(A, mean, stdDev);
if(rowCount(A) > 1)
stdDev = sqrt(stdDev / T3(rowCount(A) - 1.0));
}
template <class T1, class C1, class T2, class C2, class T3, class C3, class
T4, class C4>
void
columnStatistics(MultiArrayView<2, T1, C1> const & A,
MultiArrayView<2, T2, C2> & mean, MultiArrayView<2, T3, C3
> & stdDev, MultiArrayView<2, T4, C4> & norm)
{
MultiArrayIndex m = rowCount(A);
MultiArrayIndex n = columnCount(A);
vigra_precondition(1 == rowCount(mean) && n == columnCount(mean) &&
1 == rowCount(stdDev) && n == columnCount(stdDev) &&
1 == rowCount(norm) && n == columnCount(norm),
"columnStatistics(): Shape mismatch between input an
d output.");
detail::columnStatisticsImpl(A, mean, stdDev);
norm = sqrt(stdDev + T2(m) * sq(mean));
stdDev = sqrt(stdDev / T3(m - 1.0));
}
/** Compute statistics of every row of matrix \a A.
The result matrices must be column vectors with as many rows as \a A.
<b> Declarations:</b>
compute only the mean:
\code
namespace vigra { namespace linalg {
template <class T1, class C1, class T2, class C2>
void
rowStatistics(MultiArrayView<2, T1, C1> const & A,
MultiArrayView<2, T2, C2> & mean);
} }
\endcode
compute mean and standard deviation:
\code
namespace vigra { namespace linalg {
template <class T1, class C1, class T2, class C2, class T3, class C
3>
void
rowStatistics(MultiArrayView<2, T1, C1> const & A,
MultiArrayView<2, T2, C2> & mean,
MultiArrayView<2, T3, C3> & stdDev);
} }
\endcode
compute mean, standard deviation, and norm:
\code
namespace vigra { namespace linalg {
template <class T1, class C1, class T2, class C2, class T3, class C
3, class T4, class C4>
void
rowStatistics(MultiArrayView<2, T1, C1> const & A,
MultiArrayView<2, T2, C2> & mean,
MultiArrayView<2, T3, C3> & stdDev,
MultiArrayView<2, T4, C4> & norm);
} }
\endcode
<b> Usage:</b>
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg
\code
Matrix A(rows, columns);
.. // fill A
Matrix rowMean(rows, 1), rowStdDev(rows, 1), rowNorm(rows, 1);
rowStatistics(a, rowMean, rowStdDev, rowNorm);
\endcode
*/
doxygen_overloaded_function(template <...> void rowStatistics)
template <class T1, class C1, class T2, class C2>
void
rowStatistics(MultiArrayView<2, T1, C1> const & A,
MultiArrayView<2, T2, C2> & mean)
{
vigra_precondition(1 == columnCount(mean) && rowCount(A) == rowCount(me
an),
"rowStatistics(): Shape mismatch between input and o
utput.");
MultiArrayView<2, T2, StridedArrayTag> tm = transpose(mean);
columnStatistics(transpose(A), tm);
}
template <class T1, class C1, class T2, class C2, class T3, class C3>
void
rowStatistics(MultiArrayView<2, T1, C1> const & A,
MultiArrayView<2, T2, C2> & mean, MultiArrayView<2, T3, C3
> & stdDev)
{
vigra_precondition(1 == columnCount(mean) && rowCount(A) == rowCount(me
an) &&
1 == columnCount(stdDev) && rowCount(A) == rowCount(
stdDev),
"rowStatistics(): Shape mismatch between input and o
utput.");
MultiArrayView<2, T2, StridedArrayTag> tm = transpose(mean);
MultiArrayView<2, T3, StridedArrayTag> ts = transpose(stdDev);
columnStatistics(transpose(A), tm, ts);
}
template <class T1, class C1, class T2, class C2, class T3, class C3, class
T4, class C4>
void
rowStatistics(MultiArrayView<2, T1, C1> const & A,
MultiArrayView<2, T2, C2> & mean, MultiArrayView<2, T3, C3
> & stdDev, MultiArrayView<2, T4, C4> & norm)
{
vigra_precondition(1 == columnCount(mean) && rowCount(A) == rowCount(me
an) &&
1 == columnCount(stdDev) && rowCount(A) == rowCount(
stdDev) &&
1 == columnCount(norm) && rowCount(A) == rowCount(no
rm),
"rowStatistics(): Shape mismatch between input and o
utput.");
MultiArrayView<2, T2, StridedArrayTag> tm = transpose(mean);
MultiArrayView<2, T3, StridedArrayTag> ts = transpose(stdDev);
MultiArrayView<2, T4, StridedArrayTag> tn = transpose(norm);
columnStatistics(transpose(A), tm, ts, tn);
}
namespace detail {
template <class T1, class C1, class U, class T2, class C2, class T3, class
C3>
void updateCovarianceMatrix(MultiArrayView<2, T1, C1> const & features,
U & count, MultiArrayView<2, T2, C2> & mean, MultiAr
rayView<2, T3, C3> & covariance)
{
MultiArrayIndex n = std::max(rowCount(features), columnCount(features))
;
vigra_precondition(std::min(rowCount(features), columnCount(features))
== 1,
"updateCovarianceMatrix(): Features must be a row or column vecto
r.");
vigra_precondition(mean.shape() == features.shape(),
"updateCovarianceMatrix(): Shape mismatch between feature vector
and mean vector.");
vigra_precondition(n == rowCount(covariance) && n == columnCount(covari
ance),
"updateCovarianceMatrix(): Shape mismatch between feature vector
and covariance matrix.");
// West's algorithm for incremental covariance matrix computation
Matrix<T2> t = features - mean;
++count;
double f = 1.0 / count,
f1 = 1.0 - f;
mean += f*t;
if(rowCount(features) == 1) // update column covariance from current ro
w
{
for(MultiArrayIndex k=0; k<n; ++k)
{
covariance(k, k) += f1*sq(t(0, k));
for(MultiArrayIndex l=k+1; l<n; ++l)
{
covariance(k, l) += f1*t(0, k)*t(0, l);
covariance(l, k) = covariance(k, l);
}
}
}
else // update row covariance from current column
{
for(MultiArrayIndex k=0; k<n; ++k)
{
covariance(k, k) += f1*sq(t(k, 0));
for(MultiArrayIndex l=k+1; l<n; ++l)
{
covariance(k, l) += f1*t(k, 0)*t(l, 0);
covariance(l, k) = covariance(k, l);
}
}
}
}
} // namespace detail
/*! Compute the covariance matrix between the columns of a matrix \a fe
atures.
The result matrix \a covariance must by a square matrix with as man
y rows and
columns as the number of columns in matrix \a features.
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.h
xx</a>\><br>
Namespace: vigra
*/
template <class T1, class C1, class T2, class C2>
void covarianceMatrixOfColumns(MultiArrayView<2, T1, C1> const & features,
MultiArrayView<2, T2, C2> & covariance)
{
MultiArrayIndex m = rowCount(features), n = columnCount(features);
vigra_precondition(n == rowCount(covariance) && n == columnCount(covari
ance),
"covarianceMatrixOfColumns(): Shape mismatch between feature matr
ix and covariance matrix.");
MultiArrayIndex count = 0;
Matrix<T2> means(1, n);
covariance.init(NumericTraits<T2>::zero());
for(MultiArrayIndex k=0; k<m; ++k)
detail::updateCovarianceMatrix(rowVector(features, k), count, means
, covariance);
covariance /= T2(m - 1);
}
/*! Compute the covariance matrix between the columns of a matrix \a fe
atures.
The result is returned as a square temporary matrix with as many ro
ws and
columns as the number of columns in matrix \a features.
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.h
xx</a>\><br>
Namespace: vigra
*/
template <class T, class C>
TemporaryMatrix<T>
covarianceMatrixOfColumns(MultiArrayView<2, T, C> const & features)
{
TemporaryMatrix<T> res(columnCount(features), columnCount(features));
covarianceMatrixOfColumns(features, res);
return res;
}
/*! Compute the covariance matrix between the rows of a matrix \a featu
res.
The result matrix \a covariance must by a square matrix with as man
y rows and
columns as the number of rows in matrix \a features.
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.h
xx</a>\><br>
Namespace: vigra
*/
template <class T1, class C1, class T2, class C2>
void covarianceMatrixOfRows(MultiArrayView<2, T1, C1> const & features,
MultiArrayView<2, T2, C2> & covariance)
{
MultiArrayIndex m = rowCount(features), n = columnCount(features);
vigra_precondition(m == rowCount(covariance) && m == columnCount(covari
ance),
"covarianceMatrixOfRows(): Shape mismatch between feature matrix
and covariance matrix.");
MultiArrayIndex count = 0;
Matrix<T2> means(m, 1);
covariance.init(NumericTraits<T2>::zero());
for(MultiArrayIndex k=0; k<n; ++k)
detail::updateCovarianceMatrix(columnVector(features, k), count, me
ans, covariance);
covariance /= T2(m - 1);
}
/*! Compute the covariance matrix between the rows of a matrix \a featu
res.
The result is returned as a square temporary matrix with as many ro
ws and
columns as the number of rows in matrix \a features.
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.h
xx</a>\><br>
Namespace: vigra
*/
template <class T, class C>
TemporaryMatrix<T>
covarianceMatrixOfRows(MultiArrayView<2, T, C> const & features)
{
TemporaryMatrix<T> res(rowCount(features), rowCount(features));
covarianceMatrixOfRows(features, res);
return res;
}
enum DataPreparationGoals { ZeroMean = 1, UnitVariance = 2, UnitNorm = 4 };
inline DataPreparationGoals operator|(DataPreparationGoals l, DataPreparati
onGoals r)
{
return DataPreparationGoals(int(l) | int(r));
}
namespace detail {
template <class T, class C1, class C2, class C3, class C4>
void
prepareDataImpl(const MultiArrayView<2, T, C1> & A,
MultiArrayView<2, T, C2> & res, MultiArrayView<2, T, C3> & o
ffset, MultiArrayView<2, T, C4> & scaling,
DataPreparationGoals goals)
{
MultiArrayIndex m = rowCount(A);
MultiArrayIndex n = columnCount(A);
vigra_precondition(A.shape() == res.shape() &&
n == columnCount(offset) && 1 == rowCount(offset) &&
n == columnCount(scaling) && 1 == rowCount(scaling),
"prepareDataImpl(): Shape mismatch between input and
output.");
if(!goals)
{
res = A;
offset.init(NumericTraits<T>::zero());
scaling.init(NumericTraits<T>::one());
return;
}
bool zeroMean = (goals & ZeroMean) != 0;
bool unitVariance = (goals & UnitVariance) != 0;
bool unitNorm = (goals & UnitNorm) != 0;
vigra_precondition(!(unitVariance && unitNorm),
"prepareDataImpl(): Unit variance and unit norm cannot be achieved
at the same time.");
Matrix<T> mean(1, n), sumOfSquaredDifferences(1, n);
detail::columnStatisticsImpl(A, mean, sumOfSquaredDifferences);
for(MultiArrayIndex k=0; k<n; ++k)
{
T stdDev = std::sqrt(sumOfSquaredDifferences(0, k) / T(m-1));
if(closeAtTolerance(stdDev / mean(0,k), NumericTraits<T>::zero()))
stdDev = NumericTraits<T>::zero();
if(zeroMean && stdDev > NumericTraits<T>::zero())
{
columnVector(res, k) = columnVector(A, k) - mean(0,k);
offset(0, k) = mean(0, k);
mean(0, k) = NumericTraits<T>::zero();
}
else
{
columnVector(res, k) = columnVector(A, k);
offset(0, k) = NumericTraits<T>::zero();
}
T norm = mean(0,k) == NumericTraits<T>::zero()
? std::sqrt(sumOfSquaredDifferences(0, k))
: std::sqrt(sumOfSquaredDifferences(0, k) + T(m) * sq(mea
n(0,k)));
if(unitNorm && norm > NumericTraits<T>::zero())
{
columnVector(res, k) /= norm;
scaling(0, k) = NumericTraits<T>::one() / norm;
}
else if(unitVariance && stdDev > NumericTraits<T>::zero())
{
columnVector(res, k) /= stdDev;
scaling(0, k) = NumericTraits<T>::one() / stdDev;
}
else
{
scaling(0, k) = NumericTraits<T>::one();
}
}
}
} // namespace detail
/*! Standardize the columns of a matrix according to given <tt>DataPrep
arationGoals</tt>.
For every column of the matrix \a A, this function computes mean,
standard deviation, and norm. It then applies a linear transformation t
o the values of
the column according to these statistics and the given <tt>DataPreparat
ionGoals</tt>.
The result is returned in matrix \a res which must have the same size a
s \a A.
Optionally, the transformation applied can also be returned in the matr
ices \a offset
and \a scaling (see below for an example how these matrices can be used
to standardize
more data according to the same transformation).
The following <tt>DataPreparationGoals</tt> are supported:
<DL>
<DT><tt>ZeroMean</tt><DD> Subtract the column mean form every column if
the values in the column are not constant.
Do nothing in a constant column.
<DT><tt>UnitVariance</tt><DD> Divide by the column standard deviation i
f the values in the column are not constant.
Do nothing in a constant column.
<DT><tt>UnitNorm</tt><DD> Divide by the column norm if it is non-zero.
<DT><tt>ZeroMean | UnitVariance</tt><DD> First subtact the mean and the
n divide by the standard deviation, unless the
column is constant (in which c
ase the column remains unchanged).
<DT><tt>ZeroMean | UnitNorm</tt><DD> If the column is non-constant, sub
tract the mean. Then divide by the norm
of the result if the norm is non-z
ero.
</DL>
<b> Declarations:</b>
Standardize the matrix and return the parameters of the linear transfor
mation.
The matrices \a offset and \a scaling must be row vectors with as many
columns as \a A.
\code
namespace vigra { namespace linalg {
template <class T, class C1, class C2, class C3, class C4>
void
prepareColumns(MultiArrayView<2, T, C1> const & A,
MultiArrayView<2, T, C2> & res,
MultiArrayView<2, T, C3> & offset,
MultiArrayView<2, T, C4> & scaling,
DataPreparationGoals goals = ZeroMean | UnitVariance
);
} }
\endcode
Only standardize the matrix.
\code
namespace vigra { namespace linalg {
template <class T, class C1, class C2>
void
prepareColumns(MultiArrayView<2, T, C1> const & A,
MultiArrayView<2, T, C2> & res,
DataPreparationGoals goals = ZeroMean | UnitVariance
);
} }
\endcode
<b> Usage:</b>
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg
\code
Matrix A(rows, columns);
.. // fill A
Matrix standardizedA(rows, columns), offset(1, columns), scaling(1, col
umns);
prepareColumns(A, standardizedA, offset, scaling, ZeroMean | UnitNorm);
// use offset and scaling to prepare additional data according to the s
ame transformation
Matrix newData(nrows, columns);
Matrix standardizedNewData = (newData - repeatMatrix(offset, nrows, 1))
* pointWise(repeatMatrix(scaling, nrows, 1));
\endcode
*/
doxygen_overloaded_function(template <...> void prepareColumns)
template <class T, class C1, class C2, class C3, class C4>
inline void
prepareColumns(MultiArrayView<2, T, C1> const & A,
MultiArrayView<2, T, C2> & res, MultiArrayView<2, T, C3> & o
ffset, MultiArrayView<2, T, C4> & scaling,
DataPreparationGoals goals = ZeroMean | UnitVariance)
{
detail::prepareDataImpl(A, res, offset, scaling, goals);
}
template <class T, class C1, class C2>
inline void
prepareColumns(MultiArrayView<2, T, C1> const & A, MultiArrayView<2, T, C2>
& res,
DataPreparationGoals goals = ZeroMean | UnitVariance)
{
Matrix<T> offset(1, columnCount(A)), scaling(1, columnCount(A));
detail::prepareDataImpl(A, res, offset, scaling, goals);
}
/*! Standardize the rows of a matrix according to given <tt>DataPrepara
tionGoals</tt>.
This algorithm works in the same way as \ref prepareColumns() (see ther
e for detailed
documentation), but is applied to the rows of the matrix \a A instead.
Accordingly, the
matrices holding the parameters of the linear transformation must be co
lumn vectors
with as many rows as \a A.
<b> Declarations:</b>
Standardize the matrix and return the parameters of the linear transfor
mation.
The matrices \a offset and \a scaling must be column vectors
with as many rows as \a A.
\code
namespace vigra { namespace linalg {
template <class T, class C1, class C2, class C3, class C4>
void
prepareRows(MultiArrayView<2, T, C1> const & A,
MultiArrayView<2, T, C2> & res,
MultiArrayView<2, T, C3> & offset,
MultiArrayView<2, T, C4> & scaling,
DataPreparationGoals goals = ZeroMean | UnitVariance)
} }
\endcode
Only standardize the matrix.
\code
namespace vigra { namespace linalg {
template <class T, class C1, class C2>
void
prepareRows(MultiArrayView<2, T, C1> const & A,
MultiArrayView<2, T, C2> & res,
DataPreparationGoals goals = ZeroMean | UnitVariance);
} }
\endcode
<b> Usage:</b>
<b>\#include</b> \<<a href="matrix_8hxx-source.html">vigra/matrix.hxx</
a>\> or<br>
<b>\#include</b> \<<a href="linear__algebra_8hxx-source.html">vigra/lin
ear_algebra.hxx</a>\><br>
Namespaces: vigra and vigra::linalg
\code
Matrix A(rows, columns);
.. // fill A
Matrix standardizedA(rows, columns), offset(rows, 1), scaling(rows, 1);
prepareRows(A, standardizedA, offset, scaling, ZeroMean | UnitNorm);
// use offset and scaling to prepare additional data according to the s
ame transformation
Matrix newData(rows, ncolumns);
Matrix standardizedNewData = (newData - repeatMatrix(offset, 1, ncolumn
s)) * pointWise(repeatMatrix(scaling, 1, ncolumns));
\endcode
*/
doxygen_overloaded_function(template <...> void prepareRows)
template <class T, class C1, class C2, class C3, class C4>
inline void
prepareRows(MultiArrayView<2, T, C1> const & A,
MultiArrayView<2, T, C2> & res, MultiArrayView<2, T, C3> & offs
et, MultiArrayView<2, T, C4> & scaling,
DataPreparationGoals goals = ZeroMean | UnitVariance)
{
MultiArrayView<2, T, StridedArrayTag> tr = transpose(res), to = transpo
se(offset), ts = transpose(scaling);
detail::prepareDataImpl(transpose(A), tr, to, ts, goals);
}
template <class T, class C1, class C2>
inline void
prepareRows(MultiArrayView<2, T, C1> const & A, MultiArrayView<2, T, C2> &
res,
DataPreparationGoals goals = ZeroMean | UnitVariance)
{
MultiArrayView<2, T, StridedArrayTag> tr = transpose(res);
Matrix<T> offset(rowCount(A), 1), scaling(rowCount(A), 1);
detail::prepareDataImpl(transpose(A), tr, offset, scaling, goals);
}
//@}
} // namespace linalg
using linalg::columnStatistics;
using linalg::prepareColumns;
using linalg::rowStatistics;
using linalg::prepareRows;
using linalg::ZeroMean;
using linalg::UnitVariance;
using linalg::UnitNorm;
} // namespace vigra } // namespace vigra
#endif // VIGRA_MATRIX_HXX #endif // VIGRA_MATRIX_HXX
 End of changes. 170 change blocks. 
410 lines changed or deleted 1962 lines changed or added


 memory.hxx   memory.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2002-2003 by Ullrich Koethe, Hans Meine */ /* Copyright 2002-2003 by Ullrich Koethe, Hans Meine */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 46 skipping to change at line 46
/************************************************************************/ /************************************************************************/
#ifndef VIGRA_MEMORY_HXX #ifndef VIGRA_MEMORY_HXX
#define VIGRA_MEMORY_HXX #define VIGRA_MEMORY_HXX
#include "metaprogramming.hxx" #include "metaprogramming.hxx"
namespace vigra { namespace detail { namespace vigra { namespace detail {
template <class T> template <class T>
void destroy_n(T * /* p */, int /* n */, VigraTrueType /* isPOD */) inline void destroy_n(T * /* p */, int /* n */, VigraTrueType /* isPOD */)
{ {
} }
template <class T> template <class T>
void destroy_n(T * p, int n, VigraFalseType /* isPOD */) inline void destroy_n(T * p, int n, VigraFalseType /* isPOD */)
{ {
T * end = p + n; T * end = p + n;
for(; p != end; ++p) for(; p != end; ++p)
p->~T(); p->~T();
} }
template <class T> template <class T>
void destroy_n(T * p, int n) inline void destroy_n(T * p, int n)
{ {
destroy_n(p, n, typename TypeTraits<T>::isPOD()); destroy_n(p, n, typename TypeTraits<T>::isPOD());
} }
/********************************************************************/ /********************************************************************/
// g++ 2.95 has std::destroy() in the STL // g++ 2.95 has std::destroy() in the STL
#if !defined(__GNUC__) || __GNUC__ >= 3 #if !defined(__GNUC__) || __GNUC__ >= 3
template <class T> template <class T>
void destroy(T * p, VigraTrueType /* isPOD */) inline void destroy(T * p, VigraTrueType /* isPOD */)
{ {
} }
template <class T> template <class T>
void destroy(T * p, VigraFalseType /* isPOD */) inline void destroy(T * p, VigraFalseType /* isPOD */)
{ {
p->~T(); p->~T();
} }
template <class T> template <class T>
void destroy(T * p) inline void destroy(T * p)
{ {
destroy(p, typename TypeTraits<T>::isPOD()); destroy(p, typename TypeTraits<T>::isPOD());
} }
#else #else
} } // namespace vigra::detail } } // namespace vigra::detail
#include <memory> #include <memory>
 End of changes. 8 change blocks. 
9 lines changed or deleted 9 lines changed or added


 metaprogramming.hxx   metaprogramming.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 42 skipping to change at line 42
/* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */ /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
/* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
/* OTHER DEALINGS IN THE SOFTWARE. */ /* OTHER DEALINGS IN THE SOFTWARE. */
/* */ /* */
/************************************************************************/ /************************************************************************/
#ifndef VIGRA_METAPROGRAMMING_HXX #ifndef VIGRA_METAPROGRAMMING_HXX
#define VIGRA_METAPROGRAMMING_HXX #define VIGRA_METAPROGRAMMING_HXX
#include "config.hxx" #include "config.hxx"
#include <limits.h>
namespace vigra { namespace vigra {
template <int N> template <int N>
class MetaInt class MetaInt
{ {
public: public:
enum { value = N }; enum { value = N };
}; };
skipping to change at line 77 skipping to change at line 78
/********************************************************/ /********************************************************/
/* */ /* */
/* StridedArrayTag */ /* StridedArrayTag */
/* */ /* */
/********************************************************/ /********************************************************/
/** tag for marking a MultiArray strided. /** tag for marking a MultiArray strided.
<b>\#include</b> <b>\#include</b>
"<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>" \<<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
struct StridedArrayTag {}; struct StridedArrayTag {};
/********************************************************/ /********************************************************/
/* */ /* */
/* UnstridedArrayTag */ /* UnstridedArrayTag */
/* */ /* */
/********************************************************/ /********************************************************/
/** tag for marking a MultiArray unstrided. /** tag for marking a MultiArray unstrided.
<b>\#include</b> <b>\#include</b>
"<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>" \<<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
struct UnstridedArrayTag {}; struct UnstridedArrayTag {};
template<class T> template<class T>
class TypeTraits class TypeTraits
{ {
public: public:
typedef VigraFalseType isConst; typedef VigraFalseType isConst;
skipping to change at line 137 skipping to change at line 138
class TypeTraits<T const *> class TypeTraits<T const *>
{ {
public: public:
typedef VigraFalseType isConst; typedef VigraFalseType isConst;
typedef VigraTrueType isPOD; typedef VigraTrueType isPOD;
typedef VigraTrueType isBuiltinType; typedef VigraTrueType isBuiltinType;
}; };
#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
#define VIGRA_TYPE_TRAITS(type) \ namespace detail {
template <int size>
struct SizeToType;
} // namespace detail
#define VIGRA_TYPE_TRAITS(type, size) \
template<> \ template<> \
class TypeTraits<type> \ class TypeTraits<type> \
{ \ { \
public: \ public: \
typedef VigraFalseType isConst; \ typedef VigraFalseType isConst; \
typedef VigraTrueType isPOD; \ typedef VigraTrueType isPOD; \
typedef VigraTrueType isBuiltinType; \ typedef VigraTrueType isBuiltinType; \
}; typedef char TypeToSize[size]; \
}; \
\
namespace detail { \
TypeTraits<type>::TypeToSize * typeToSize(type); \
\
template <> \
struct SizeToType<size> \
{ \
typedef type result; \
}; \
}
VIGRA_TYPE_TRAITS(char) VIGRA_TYPE_TRAITS(char, 1)
VIGRA_TYPE_TRAITS(signed char) VIGRA_TYPE_TRAITS(signed char, 2)
VIGRA_TYPE_TRAITS(unsigned char) VIGRA_TYPE_TRAITS(unsigned char, 3)
VIGRA_TYPE_TRAITS(short) VIGRA_TYPE_TRAITS(short, 4)
VIGRA_TYPE_TRAITS(unsigned short) VIGRA_TYPE_TRAITS(unsigned short, 5)
VIGRA_TYPE_TRAITS(int) VIGRA_TYPE_TRAITS(int, 6)
VIGRA_TYPE_TRAITS(unsigned int) VIGRA_TYPE_TRAITS(unsigned int, 7)
VIGRA_TYPE_TRAITS(long) VIGRA_TYPE_TRAITS(long, 8)
VIGRA_TYPE_TRAITS(unsigned long) VIGRA_TYPE_TRAITS(unsigned long, 9)
VIGRA_TYPE_TRAITS(float) VIGRA_TYPE_TRAITS(float, 10)
VIGRA_TYPE_TRAITS(double) VIGRA_TYPE_TRAITS(double, 11)
VIGRA_TYPE_TRAITS(long double) VIGRA_TYPE_TRAITS(long double, 12)
#ifdef LLONG_MAX
VIGRA_TYPE_TRAITS(long long, 13)
VIGRA_TYPE_TRAITS(unsigned long long, 14)
#endif
#undef VIGRA_TYPE_TRAITS #undef VIGRA_TYPE_TRAITS
//@} //@}
template <class A>
struct Not;
template <>
struct Not<VigraTrueType>
{
typedef VigraFalseType result;
static const bool boolResult = false;
};
template <>
struct Not<VigraFalseType>
{
typedef VigraTrueType result;
static const bool boolResult = true;
};
template <class L, class R> template <class L, class R>
struct And; struct And;
template <> template <>
struct And<VigraFalseType, VigraFalseType> struct And<VigraFalseType, VigraFalseType>
{ {
typedef VigraFalseType result; typedef VigraFalseType result;
static const bool boolResult = false; static const bool boolResult = false;
}; };
 End of changes. 9 change blocks. 
19 lines changed or deleted 59 lines changed or added


 multi_array.hxx   multi_array.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2003 by Gunnar Kedenburg */ /* Copyright 2003-2008 by Gunnar Kedenburg and Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 69 skipping to change at line 68
/* */ /* */
/* defaultStride */ /* defaultStride */
/* */ /* */
/********************************************************/ /********************************************************/
/* generates the stride for a gapless shape. /* generates the stride for a gapless shape.
Namespace: vigra::detail Namespace: vigra::detail
*/ */
template <unsigned int N> template <unsigned int N>
TinyVector <ptrdiff_t, N> defaultStride(const TinyVector <ptrdiff_t, N> &sh inline TinyVector <MultiArrayIndex, N>
ape) defaultStride(const TinyVector <MultiArrayIndex, N> &shape)
{ {
TinyVector <ptrdiff_t, N> ret; TinyVector <MultiArrayIndex, N> ret;
ret [0] = 1; ret [0] = 1;
for (unsigned int i = 1; i < N; ++i) for (int i = 1; i < (int)N; ++i)
ret [i] = ret [i-1] * shape [i-1]; ret [i] = ret [i-1] * shape [i-1];
return ret; return ret;
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* ScanOrderToOffset */
/* */
/********************************************************/
/* transforms an index in scan order sense to a pointer offset in a possibl
y
strided, multi-dimensional array.
Namespace: vigra::detail
*/
template <int K>
struct ScanOrderToOffset
{
template <int N>
static MultiArrayIndex
exec(MultiArrayIndex d, const TinyVector <MultiArrayIndex, N> &shape,
const TinyVector <MultiArrayIndex, N> & stride)
{
return stride[N-K] * (d % shape[N-K]) +
ScanOrderToOffset<K-1>::exec(d / shape[N-K], shape, stride);
}
};
template <>
struct ScanOrderToOffset<1>
{
template <int N>
static MultiArrayIndex
exec(MultiArrayIndex d, const TinyVector <MultiArrayIndex, N> & /*shape
*/,
const TinyVector <MultiArrayIndex, N> & stride)
{
return stride[N-1] * d;
}
};
template <int K>
struct ScanOrderToCoordinate
{
template <int N>
static void
exec(MultiArrayIndex d, const TinyVector <MultiArrayIndex, N> &shape,
TinyVector <MultiArrayIndex, N> & result)
{
result[N-K] = (d % shape[N-K]);
ScanOrderToCoordinate<K-1>::exec(d / shape[N-K], shape, result);
}
};
template <>
struct ScanOrderToCoordinate<1>
{
template <int N>
static void
exec(MultiArrayIndex d, const TinyVector <MultiArrayIndex, N> & /*shape
*/,
TinyVector <MultiArrayIndex, N> & result)
{
result[N-1] = d;
}
};
template <int K>
struct CoordinateToScanOrder
{
template <int N>
static MultiArrayIndex
exec(const TinyVector <MultiArrayIndex, N> &shape,
const TinyVector <MultiArrayIndex, N> & coordinate)
{
return coordinate[N-K] + shape[N-K] * CoordinateToScanOrder<K-1>::e
xec(shape, coordinate);
}
};
template <>
struct CoordinateToScanOrder<1>
{
template <int N>
static MultiArrayIndex
exec(const TinyVector <MultiArrayIndex, N> & /*shape*/,
const TinyVector <MultiArrayIndex, N> & coordinate)
{
return coordinate[N-1];
}
};
template <class C>
struct CoordinatesToOffest
{
template <int N>
static MultiArrayIndex
exec(const TinyVector <MultiArrayIndex, N> & stride, MultiArrayIndex x)
{
return stride[0] * x;
}
template <int N>
static MultiArrayIndex
exec(const TinyVector <MultiArrayIndex, N> & stride, MultiArrayIndex x,
MultiArrayIndex y)
{
return stride[0] * x + stride[1] * y;
}
};
template <>
struct CoordinatesToOffest<UnstridedArrayTag>
{
template <int N>
static MultiArrayIndex
exec(const TinyVector <MultiArrayIndex, N> & /*stride*/, MultiArrayInde
x x)
{
return x;
}
template <int N>
static MultiArrayIndex
exec(const TinyVector <MultiArrayIndex, N> & stride, MultiArrayIndex x,
MultiArrayIndex y)
{
return x + stride[1] * y;
}
};
/********************************************************/
/* */
/* MaybeStrided */ /* MaybeStrided */
/* */ /* */
/********************************************************/ /********************************************************/
/* metatag implementing a test for marking MultiArrays that were /* metatag implementing a test for marking MultiArrays that were
indexed at the zero'th dimension as strided, and all others as indexed at the zero'th dimension as strided, and all others as
unstrided. unstrided.
<b>\#include</b> <b>\#include</b>
"<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>" \<<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>\>
Namespace: vigra::detail Namespace: vigra::detail
*/ */
template <unsigned int N> template <unsigned int N>
struct MaybeStrided struct MaybeStrided
{ {
typedef UnstridedArrayTag type; typedef UnstridedArrayTag type;
}; };
template <> template <>
skipping to change at line 115 skipping to change at line 235
/********************************************************/ /********************************************************/
/* */ /* */
/* MultiIteratorChooser */ /* MultiIteratorChooser */
/* */ /* */
/********************************************************/ /********************************************************/
/* metatag implementing a test (by pattern matching) for marking /* metatag implementing a test (by pattern matching) for marking
MultiArrays that were indexed at the zero'th dimension as strided. MultiArrays that were indexed at the zero'th dimension as strided.
<b>\#include</b> <b>\#include</b>
"<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>" \<<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>\>
Namespace: vigra::detail Namespace: vigra::detail
*/ */
template <class O> template <class O>
struct MultiIteratorChooser struct MultiIteratorChooser
{ {
struct Nil {}; struct Nil {};
template <unsigned int N, class T, class REFERENCE, class POINTER> template <unsigned int N, class T, class REFERENCE, class POINTER>
struct Traverser struct Traverser
skipping to change at line 140 skipping to change at line 260
/********************************************************/ /********************************************************/
/* */ /* */
/* MultiIteratorChooser <StridedArrayTag> */ /* MultiIteratorChooser <StridedArrayTag> */
/* */ /* */
/********************************************************/ /********************************************************/
/* specialization of the MultiIteratorChooser for strided arrays. /* specialization of the MultiIteratorChooser for strided arrays.
<b>\#include</b> <b>\#include</b>
"<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>" \<<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>\>
Namespace: vigra::detail Namespace: vigra::detail
*/ */
template <> template <>
struct MultiIteratorChooser <StridedArrayTag> struct MultiIteratorChooser <StridedArrayTag>
{ {
template <unsigned int N, class T, class REFERENCE, class POINTER> template <unsigned int N, class T, class REFERENCE, class POINTER>
struct Traverser struct Traverser
{ {
typedef StridedMultiIterator <N, T, REFERENCE, POINTER> type; typedef StridedMultiIterator <N, T, REFERENCE, POINTER> type;
skipping to change at line 163 skipping to change at line 283
/********************************************************/ /********************************************************/
/* */ /* */
/* MultiIteratorChooser <UnstridedArrayTag> */ /* MultiIteratorChooser <UnstridedArrayTag> */
/* */ /* */
/********************************************************/ /********************************************************/
/* specialization of the MultiIteratorChooser for unstrided arrays. /* specialization of the MultiIteratorChooser for unstrided arrays.
<b>\#include</b> <b>\#include</b>
"<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>" \<<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>\>
Namespace: vigra::detail Namespace: vigra::detail
*/ */
template <> template <>
struct MultiIteratorChooser <UnstridedArrayTag> struct MultiIteratorChooser <UnstridedArrayTag>
{ {
template <unsigned int N, class T, class REFERENCE, class POINTER> template <unsigned int N, class T, class REFERENCE, class POINTER>
struct Traverser struct Traverser
{ {
typedef MultiIterator <N, T, REFERENCE, POINTER> type; typedef MultiIterator <N, T, REFERENCE, POINTER> type;
}; };
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* helper functions */ /* helper functions */
/* */ /* */
/********************************************************/ /********************************************************/
template <class DestIterator, class Shape, class T> template <class DestIterator, class Shape, class T>
void inline void
initMultiArrayData(DestIterator d, Shape const & shape, T const & init, Met aInt<0>) initMultiArrayData(DestIterator d, Shape const & shape, T const & init, Met aInt<0>)
{ {
DestIterator dend = d + shape[0]; DestIterator dend = d + shape[0];
for(; d != dend; ++d) for(; d < dend; ++d)
{ {
*d = init; *d = init;
} }
} }
template <class DestIterator, class Shape, class T, int N> template <class DestIterator, class Shape, class T, int N>
void void
initMultiArrayData(DestIterator d, Shape const & shape, T const & init, Met aInt<N>) initMultiArrayData(DestIterator d, Shape const & shape, T const & init, Met aInt<N>)
{ {
DestIterator dend = d + shape[N]; DestIterator dend = d + shape[N];
for(; d != dend; ++d) for(; d < dend; ++d)
{ {
initMultiArrayData(d.begin(), shape, init, MetaInt<N-1>()); initMultiArrayData(d.begin(), shape, init, MetaInt<N-1>());
} }
} }
template <class SrcIterator, class Shape, class DestIterator> #define VIGRA_COPY_MULTI_ARRAY_DATA(name, op) \
void template <class SrcIterator, class Shape, class DestIterator> \
copyMultiArrayData(SrcIterator s, Shape const & shape, DestIterator d, Meta inline void \
Int<0>) name##MultiArrayData(SrcIterator s, Shape const & shape, DestIterator d, Me
taInt<0>) \
{ \
SrcIterator send = s + shape[0]; \
for(; s < send; ++s, ++d) \
{ \
*d op *s; \
} \
} \
\
template <class SrcIterator, class Shape, class DestIterator, int N> \
void \
name##MultiArrayData(SrcIterator s, Shape const & shape, DestIterator d, Me
taInt<N>) \
{ \
SrcIterator send = s + shape[N]; \
for(; s < send; ++s, ++d) \
{ \
name##MultiArrayData(s.begin(), shape, d.begin(), MetaInt<N-1>());
\
} \
} \
\
template <class DestIterator, class Shape, class T> \
inline void \
name##ScalarMultiArrayData(DestIterator d, Shape const & shape, T const & i
nit, MetaInt<0>) \
{ \
DestIterator dend = d + shape[0]; \
for(; d < dend; ++d) \
{ \
*d op init; \
} \
} \
\
template <class DestIterator, class Shape, class T, int N> \
void \
name##ScalarMultiArrayData(DestIterator d, Shape const & shape, T const & i
nit, MetaInt<N>) \
{ \
DestIterator dend = d + shape[N]; \
for(; d < dend; ++d) \
{ \
name##ScalarMultiArrayData(d.begin(), shape, init, MetaInt<N-1>());
\
} \
}
VIGRA_COPY_MULTI_ARRAY_DATA(copy, =)
VIGRA_COPY_MULTI_ARRAY_DATA(copyAdd, +=)
VIGRA_COPY_MULTI_ARRAY_DATA(copySub, -=)
VIGRA_COPY_MULTI_ARRAY_DATA(copyMul, *=)
VIGRA_COPY_MULTI_ARRAY_DATA(copyDiv, /=)
#undef VIGRA_COPY_MULTI_ARRAY_DATA
template <class SrcIterator, class Shape, class T, class ALLOC>
inline void
uninitializedCopyMultiArrayData(SrcIterator s, Shape const & shape, T * & d
, ALLOC & a, MetaInt<0>)
{ {
SrcIterator send = s + shape[0]; SrcIterator send = s + shape[0];
for(; s != send; ++s, ++d) for(; s < send; ++s, ++d)
{ {
*d = *s; a.construct(d, static_cast<T const &>(*s));
} }
} }
template <class SrcIterator, class Shape, class DestIterator, int N> template <class SrcIterator, class Shape, class T, class ALLOC, int N>
void void
copyMultiArrayData(SrcIterator s, Shape const & shape, DestIterator d, Meta Int<N>) uninitializedCopyMultiArrayData(SrcIterator s, Shape const & shape, T * & d , ALLOC & a, MetaInt<N>)
{ {
SrcIterator send = s + shape[N]; SrcIterator send = s + shape[N];
for(; s != send; ++s, ++d) for(; s < send; ++s)
{ {
copyMultiArrayData(s.begin(), shape, d.begin(), MetaInt<N-1>()); uninitializedCopyMultiArrayData(s.begin(), shape, d, a, MetaInt<N-1 >());
} }
} }
template <class SrcIterator, class Shape, class T, class ALLOC> template <class SrcIterator, class Shape, class T>
void inline void
uninitializedCopyMultiArrayData(SrcIterator s, Shape const & shape, T * & d normMaxOfMultiArray(SrcIterator s, Shape const & shape, T & result, MetaInt
, ALLOC & a, MetaInt<0>) <0>)
{ {
SrcIterator send = s + shape[0]; SrcIterator send = s + shape[0];
for(; s != send; ++s, ++d) for(; s < send; ++s)
{ {
a.construct(d, *s); T v = norm(*s);
if(result < v)
result = v;
} }
} }
template <class SrcIterator, class Shape, class T, class ALLOC, int N> template <class SrcIterator, class Shape, class T, int N>
void void
uninitializedCopyMultiArrayData(SrcIterator s, Shape const & shape, T * & d , ALLOC & a, MetaInt<N>) normMaxOfMultiArray(SrcIterator s, Shape const & shape, T & result, MetaInt <N>)
{ {
SrcIterator send = s + shape[N]; SrcIterator send = s + shape[N];
for(; s != send; ++s) for(; s < send; ++s)
{ {
uninitializedCopyMultiArrayData(s.begin(), shape, d, a, MetaInt<N-1 >()); normMaxOfMultiArray(s.begin(), shape, result, MetaInt<N-1>());
} }
} }
template <class SrcIterator, class Shape, class T> template <class T>
void struct MultiArrayL1Functor
squaredNormOfMultiArray(SrcIterator s, Shape const & shape, T & result, Met {
aInt<0>) template <class U>
T operator()(U t) const
{ return norm(t); }
};
template <class T>
struct MultiArrayL2Functor
{
template <class U>
T operator()(U t) const
{ return squaredNorm(t); }
};
template <class T>
struct MultiArrayScaledL2Functor
{
T scale;
MultiArrayScaledL2Functor(T s)
: scale(s)
{}
template <class U>
T operator()(U t) const
{ return squaredNorm(T(t) / scale); }
};
template <class SrcIterator, class Shape, class Functor, class T>
inline void
sumOverMultiArray(SrcIterator s, Shape const & shape, Functor f, T & result
, MetaInt<0>)
{ {
SrcIterator send = s + shape[0]; SrcIterator send = s + shape[0];
for(; s != send; ++s) for(; s < send; ++s)
{ {
result += *s * *s; result += f(*s);
} }
} }
template <class SrcIterator, class Shape, class T, int N> template <class SrcIterator, class Shape, class Functor, class T, int N>
void void
squaredNormOfMultiArray(SrcIterator s, Shape const & shape, T & result, Met aInt<N>) sumOverMultiArray(SrcIterator s, Shape const & shape, Functor f, T & result , MetaInt<N>)
{ {
SrcIterator send = s + shape[N]; SrcIterator send = s + shape[N];
for(; s != send; ++s) for(; s < send; ++s)
{ {
squaredNormOfMultiArray(s.begin(), shape, result, MetaInt<N-1>()); sumOverMultiArray(s.begin(), shape, f, result, MetaInt<N-1>());
} }
} }
template <class SrcIterator, class Shape, class DestIterator>
inline bool
equalityOfMultiArrays(SrcIterator s, Shape const & shape, DestIterator d, M
etaInt<0>)
{
SrcIterator send = s + shape[0];
for(; s < send; ++s, ++d)
{
if(!(*s == *d))
return false;
}
return true;
}
template <class SrcIterator, class Shape, class DestIterator, int N>
bool
equalityOfMultiArrays(SrcIterator s, Shape const & shape, DestIterator d, M
etaInt<N>)
{
SrcIterator send = s + shape[N];
for(; s < send; ++s, ++d)
{
if(!equalityOfMultiArrays(s.begin(), shape, d.begin(), MetaInt<N-1>
()))
return false;
}
return true;
}
template <class SrcIterator, class Shape, class DestIterator>
inline void
swapDataImpl(SrcIterator s, Shape const & shape, DestIterator d, MetaInt<0>
)
{
SrcIterator send = s + shape[0];
for(; s < send; ++s, ++d)
std::swap(*s, *d);
}
template <class SrcIterator, class Shape, class DestIterator, int N>
void
swapDataImpl(SrcIterator s, Shape const & shape, DestIterator d, MetaInt<N>
)
{
SrcIterator send = s + shape[N];
for(; s < send; ++s, ++d)
swapDataImpl(s.begin(), shape, d.begin(), MetaInt<N-1>());
}
} // namespace detail } // namespace detail
/********************************************************/ /********************************************************/
/* */ /* */
/* MultiArrayView */ /* MultiArrayView */
/* */ /* */
/********************************************************/ /********************************************************/
// forward declaration // forward declaration
template <unsigned int N, class T, class C = UnstridedArrayTag> template <unsigned int N, class T, class C = UnstridedArrayTag>
class MultiArrayView; class MultiArrayView;
template <unsigned int N, class T, class A = std::allocator<T> > template <unsigned int N, class T, class A = std::allocator<T> >
class MultiArray; class MultiArray;
/********************************************************/
/* */
/* NormTraits */
/* */
/********************************************************/
template <unsigned int N, class T, class C>
struct NormTraits<MultiArrayView<N, T, C> >
{
typedef MultiArrayView<N, T, C> Ty
pe;
typedef typename NormTraits<T>::SquaredNormType SquaredNormType;
typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult No
rmType;
};
template <unsigned int N, class T, class A>
struct NormTraits<MultiArray<N, T, A> >
: public NormTraits<MultiArrayView<N, T, UnstridedArrayTag> >
{
typedef NormTraits<MultiArrayView<N, T, UnstridedArrayTag> > BaseType;
typedef MultiArray<N, T, A> Type;
typedef typename BaseType::SquaredNormType SquaredNor
mType;
typedef typename BaseType::NormType NormType;
};
/** \brief Base class for, and view to, \ref vigra::MultiArray. /** \brief Base class for, and view to, \ref vigra::MultiArray.
This class implements the interface of both MultiArray and This class implements the interface of both MultiArray and
MultiArrayView. By default, MultiArrayViews are tagged as MultiArrayView. By default, MultiArrayViews are tagged as
unstrided. If necessary, strided arrays are constructed automatically unstrided. If necessary, strided arrays are constructed automatically
by calls to a variant of the bind...() function. by calls to a variant of the bind...() function.
If you want to apply an algorithm requiring an image to a If you want to apply an algorithm requiring an image to a
<tt>MultiArrayView</tt> of appropriate (2-dimensional) shape, you can <tt>MultiArrayView</tt> of appropriate (2-dimensional) shape, you can
create a \ref vigra::BasicImageView that acts as a wrapper with the create a \ref vigra::BasicImageView that acts as a wrapper with the
skipping to change at line 312 skipping to change at line 585
C: a tag determining whether the array's inner dimension is strided C: a tag determining whether the array's inner dimension is strided
or not. An array is unstrided if the array elements occupy consecuti ve or not. An array is unstrided if the array elements occupy consecuti ve
memory location, strided if there is an offset in between (e.g. memory location, strided if there is an offset in between (e.g.
when a view is created that skips every other array element). when a view is created that skips every other array element).
The compiler can generate faster code for unstrided arrays. The compiler can generate faster code for unstrided arrays.
Possible values: UnstridedArrayTag (default), StridedArrayTag Possible values: UnstridedArrayTag (default), StridedArrayTag
\endcode \endcode
<b>\#include</b> <b>\#include</b>
"<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>" \<<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
class MultiArrayView class MultiArrayView
{ {
public: public:
/** the array's actual dimensionality. /** the array's actual dimensionality.
This ensures that MultiArrayView can also be used for This ensures that MultiArrayView can also be used for
skipping to change at line 350 skipping to change at line 623
typedef const value_type &const_reference; typedef const value_type &const_reference;
/** pointer type /** pointer type
*/ */
typedef value_type *pointer; typedef value_type *pointer;
/** const pointer type /** const pointer type
*/ */
typedef const value_type *const_pointer; typedef const value_type *const_pointer;
/** difference type (used for offsetting) /** difference type (used for multi-dimensional offsets and indices )
*/ */
typedef TinyVector <ptrdiff_t, actual_dimension> difference_type; typedef typename MultiArrayShape<actual_dimension>::type difference_typ e;
/** size type /** size type
*/ */
typedef difference_type size_type; typedef difference_type size_type;
/** difference and index type for a single dimension
*/
typedef MultiArrayIndex difference_type_1;
/** traverser (MultiIterator) type /** traverser (MultiIterator) type
*/ */
typedef typename detail::MultiIteratorChooser < typedef typename vigra::detail::MultiIteratorChooser <
C>::template Traverser <actual_dimension, T, T &, T *>::type traver ser; C>::template Traverser <actual_dimension, T, T &, T *>::type traver ser;
/** const traverser (MultiIterator) type /** const traverser (MultiIterator) type
*/ */
typedef typename detail::MultiIteratorChooser < typedef typename vigra::detail::MultiIteratorChooser <
C>::template Traverser <actual_dimension, T, T const &, T const *>: :type const_traverser; C>::template Traverser <actual_dimension, T, T const &, T const *>: :type const_traverser;
/** the view type associated with this array. /** the view type associated with this array.
*/ */
typedef MultiArrayView <N, T, C> view_type; typedef MultiArrayView <N, T, C> view_type;
/** the matrix type associated with this array. /** the matrix type associated with this array.
*/ */
typedef MultiArray <N, T> matrix_type; typedef MultiArray <N, T> matrix_type;
/** the squared norm type (return type of array.squaredNorm()).
*/
typedef typename NormTraits<T>::SquaredNormType SquaredNormType;
/** the norm type (return type of array.norm()).
*/
typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult No
rmType;
protected: protected:
typedef typename difference_type::value_type diff_zero_t; typedef typename difference_type::value_type diff_zero_t;
/** the shape of the image pointed to is stored here. /** the shape of the image pointed to is stored here.
*/ */
difference_type m_shape; difference_type m_shape;
/** the strides (offset of a sample to the next) for every dimensio n /** the strides (offset of a sample to the next) for every dimensio n
are stored here. are stored here.
*/ */
difference_type m_stride; difference_type m_stride;
/** pointer to the image. /** pointer to the image.
*/ */
pointer m_ptr; pointer m_ptr;
template <class U, class CN>
void copyImpl(const MultiArrayView <N, U, CN>& rhs);
template <class U, class CN>
void swapDataImpl(MultiArrayView <N, U, CN> rhs);
template <class U, class CN>
bool arraysOverlap(const MultiArrayView <N, U, CN>& rhs) const;
public: public:
/** default constructor: create an empty image of size 0. /** default constructor: create an empty image of size 0.
*/ */
MultiArrayView () MultiArrayView ()
: m_shape (diff_zero_t(0)), m_stride (diff_zero_t(0)), m_ptr (0) : m_shape (diff_zero_t(0)), m_stride (diff_zero_t(0)), m_ptr (0)
{} {}
/** construct from shape and pointer /** construct from shape and pointer
*/ */
MultiArrayView (const difference_type &shape, pointer ptr); MultiArrayView (const difference_type &shape, pointer ptr)
: m_shape (shape),
m_stride (detail::defaultStride <MultiArrayView<N,T>::actual_dimensio
n> (shape)),
m_ptr (ptr)
{}
/** construct from shape, strides (offset of a sample to the next) /** construct from shape, strides (offset of a sample to the next)
for every dimension) and pointer for every dimension) and pointer
*/ */
MultiArrayView (const difference_type &shape, MultiArrayView (const difference_type &shape,
const difference_type &stride, const difference_type &stride,
pointer ptr); pointer ptr)
: m_shape (shape),
m_stride (stride),
m_ptr (ptr)
{}
/** Assignment. There are 3 cases:
<ul>
<li> When this <tt>MultiArrayView</tt> does not point to valid
data
(e.g. after default construction), it becomes a copy of \a
rhs.
<li> When the shapes of the two arrays match, the array content
s are copied.
<li> Otherwise, a <tt>PreconditionViolation</tt> exception is t
hrown.
</ul>
*/
MultiArrayView & operator=(MultiArrayView const & rhs);
/** Assignment of a differently typed MultiArrayView. Fails with
<tt>PreconditionViolation</tt> exception when the shapes do not
match.
*/
template<class U, class C1>
MultiArrayView & operator=(MultiArrayView<N, U, C1> const & rhs)
{
vigra_precondition(this->shape() == rhs.shape(),
"MultiArrayView::operator=() size mismatch.");
this->copyImpl(rhs);
return *this;
}
/** Add-assignment of a compatible MultiArrayView. Fails with
<tt>PreconditionViolation</tt> exception when the shapes do not
match.
*/
template<class U, class C1>
MultiArrayView & operator+=(MultiArrayView<N, U, C1> const & rhs);
/** Subtract-assignment of a compatible MultiArrayView. Fails with
<tt>PreconditionViolation</tt> exception when the shapes do not
match.
*/
template<class U, class C1>
MultiArrayView & operator-=(MultiArrayView<N, U, C1> const & rhs);
/** Multiply-assignment of a compatible MultiArrayView. Fails with
<tt>PreconditionViolation</tt> exception when the shapes do not
match.
*/
template<class U, class C1>
MultiArrayView & operator*=(MultiArrayView<N, U, C1> const & rhs);
/** Divide-assignment of a compatible MultiArrayView. Fails with
<tt>PreconditionViolation</tt> exception when the shapes do not
match.
*/
template<class U, class C1>
MultiArrayView & operator/=(MultiArrayView<N, U, C1> const & rhs);
/** Add-assignment of a scalar.
*/
MultiArrayView & operator+=(T const & rhs)
{
detail::copyAddScalarMultiArrayData(traverser_begin(), shape(), rhs
, MetaInt<actual_dimension-1>());
return *this;
}
/** Subtract-assignment of a scalar.
*/
MultiArrayView & operator-=(T const & rhs)
{
detail::copySubScalarMultiArrayData(traverser_begin(), shape(), rhs
, MetaInt<actual_dimension-1>());
return *this;
}
/** Multiply-assignment of a scalar.
*/
MultiArrayView & operator*=(T const & rhs)
{
detail::copyMulScalarMultiArrayData(traverser_begin(), shape(), rhs
, MetaInt<actual_dimension-1>());
return *this;
}
/** Divide-assignment of a scalar.
*/
MultiArrayView & operator/=(T const & rhs)
{
detail::copyDivScalarMultiArrayData(traverser_begin(), shape(), rhs
, MetaInt<actual_dimension-1>());
return *this;
}
/** array access. /** array access.
*/ */
reference operator[] (const difference_type &d) reference operator[] (const difference_type &d)
{ {
return m_ptr [dot (d, m_stride)]; return m_ptr [dot (d, m_stride)];
} }
/** array access. /** array access.
*/ */
const_reference operator[] (const difference_type &d) const const_reference operator[] (const difference_type &d) const
{ {
return m_ptr [dot (d, m_stride)]; return m_ptr [dot (d, m_stride)];
} }
/** array access in scan-order sense.
Mostly useful to support standard indexing for 1-dimensional mu
lti-arrays,
but works for any N. Use scanOrderIndexToCoordinate() and
coordinateToScanOrderIndex() for conversion between indices and
coordinates.
*/
reference operator[](difference_type_1 d)
{
return m_ptr [detail::ScanOrderToOffset<actual_dimension>::exec(d,
m_shape, m_stride)];
}
/** array access in scan-order sense.
Mostly useful to support standard indexing for 1-dimensional mu
lti-arrays,
but works for any N. Use scanOrderIndexToCoordinate() and
coordinateToScanOrderIndex() for conversion between indices and
coordinates.
*/
const_reference operator[](difference_type_1 d) const
{
return m_ptr [detail::ScanOrderToOffset<actual_dimension>::exec(d,
m_shape, m_stride)];
}
/** convert scan-order index to coordinate.
*/
difference_type scanOrderIndexToCoordinate(difference_type_1 d) const
{
difference_type result;
detail::ScanOrderToCoordinate<actual_dimension>::exec(d, m_shape, r
esult);
return result;
}
/** convert coordinate to scan-order index.
*/
difference_type_1 coordinateToScanOrderIndex(const difference_type &d)
const
{
return detail::CoordinateToScanOrder<actual_dimension>::exec(m_shap
e, d);
}
/** 1D array access. Use only if N == 1. /** 1D array access. Use only if N == 1.
*/ */
reference operator() (int x) reference operator() (difference_type_1 x)
{ {
return m_ptr [m_stride[0]*x]; return m_ptr [detail::CoordinatesToOffest<C>::exec(m_stride, x)];
} }
/** 2D array access. Use only if N == 2. /** 2D array access. Use only if N == 2.
*/ */
reference operator() (int x, int y) reference operator() (difference_type_1 x, difference_type_1 y)
{ {
return m_ptr [m_stride[0]*x + m_stride[1]*y]; return m_ptr [detail::CoordinatesToOffest<C>::exec(m_stride, x, y)] ;
} }
/** 3D array access. Use only if N == 3. /** 3D array access. Use only if N == 3.
*/ */
reference operator() (int x, int y, int z) reference operator() (difference_type_1 x, difference_type_1 y, differe nce_type_1 z)
{ {
return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z]; return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z];
} }
/** 4D array access. Use only if N == 4. /** 4D array access. Use only if N == 4.
*/ */
reference operator() (int x, int y, int z, int u) reference operator() (difference_type_1 x, difference_type_1 y,
difference_type_1 z, difference_type_1 u)
{ {
return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_str ide[3]*u]; return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_str ide[3]*u];
} }
/** 5D array access. Use only if N == 5. /** 5D array access. Use only if N == 5.
*/ */
reference operator() (int x, int y, int z, int u, int v) reference operator() (difference_type_1 x, difference_type_1 y, differe
nce_type_1 z,
difference_type_1 u, difference_type_1 v)
{ {
return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_str ide[3]*u + m_stride[4]*v]; return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_str ide[3]*u + m_stride[4]*v];
} }
/** 1D const array access. Use only if N == 1. /** 1D const array access. Use only if N == 1.
*/ */
const_reference operator() (int x) const const_reference operator() (difference_type_1 x) const
{ {
return m_ptr [m_stride[0]*x]; return m_ptr [detail::CoordinatesToOffest<C>::exec(m_stride, x)];
} }
/** 2D const array access. Use only if N == 2. /** 2D const array access. Use only if N == 2.
*/ */
const_reference operator() (int x, int y) const const_reference operator() (difference_type_1 x, difference_type_1 y) c onst
{ {
return m_ptr [m_stride[0]*x + m_stride[1]*y]; return m_ptr [detail::CoordinatesToOffest<C>::exec(m_stride, x, y)] ;
} }
/** 3D const array access. Use only if N == 3. /** 3D const array access. Use only if N == 3.
*/ */
const_reference operator() (int x, int y, int z) const const_reference operator() (difference_type_1 x, difference_type_1 y, d ifference_type_1 z) const
{ {
return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z]; return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z];
} }
/** 4D const array access. Use only if N == 4. /** 4D const array access. Use only if N == 4.
*/ */
const_reference operator() (int x, int y, int z, int u) const const_reference operator() (difference_type_1 x, difference_type_1 y,
difference_type_1 z, difference_type_1 u) c
onst
{ {
return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_str ide[3]*u]; return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_str ide[3]*u];
} }
/** 5D const array access. Use only if N == 5. /** 5D const array access. Use only if N == 5.
*/ */
const_reference operator() (int x, int y, int z, int u, int v) const const_reference operator() (difference_type_1 x, difference_type_1 y, d
ifference_type_1 z,
difference_type_1 u, difference_type_1 v) c
onst
{ {
return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_str ide[3]*u + m_stride[4]*v]; return m_ptr [m_stride[0]*x + m_stride[1]*y + m_stride[2]*z + m_str ide[3]*u + m_stride[4]*v];
} }
/** Init with a constant. /** Init with a constant.
*/ */
template <class U> template <class U>
void init(const U & init); MultiArrayView & init(const U & init)
{
detail::copyScalarMultiArrayData(traverser_begin(), shape(), init,
MetaInt<actual_dimension-1>());
return *this;
}
/** Copy the data of the right-hand array (array shapes must match)
.
*/
void copy(const MultiArrayView & rhs)
{
if(this == &rhs)
return;
this->copyImpl(rhs);
}
/** Copy the data of the right-hand array (array shapes must match) . /** Copy the data of the right-hand array (array shapes must match) .
*/ */
template <class U, class CN> template <class U, class CN>
void copy(const MultiArrayView <N, U, CN>& rhs); void copy(const MultiArrayView <N, U, CN>& rhs)
{
this->copyImpl(rhs);
}
/** swap the data between two MultiArrayView objects.
The shapes of the two array must match.
*/
void swapData(MultiArrayView rhs)
{
if(this != &rhs)
swapDataImpl(rhs);
}
/** swap the data between two MultiArrayView objects.
The shapes of the two array must match.
*/
template <class T2, class C2>
void swapData(MultiArrayView <N, T2, C2> rhs)
{
swapDataImpl(rhs);
}
/** bind the M outmost dimensions to certain indices. /** bind the M outmost dimensions to certain indices.
this reduces the dimensionality of the image to this reduces the dimensionality of the image to
max { 1, N-M } max { 1, N-M }.
<b>Usage:</b>
\code
// create a 3D array of size 40x30x20
typedef MultiArray<3, double>::difference_type Shape;
MultiArray<3, double> array3(Shape(40, 30, 20));
// get a 1D array by fixing index 1 to 12, and index 2 to 10
MultiArrayView <1, double> array1 = array3.bindOuter(TinyVector
<int, 2>(12, 10));
\endcode
*/ */
template <unsigned int M> template <unsigned int M>
MultiArrayView <N-M, T, C> bindOuter (const TinyVector <ptrdiff_t, M> & d) const; MultiArrayView <N-M, T, C> bindOuter (const TinyVector <MultiArrayIndex , M> &d) const;
/** bind the M innermost dimensions to certain indices. /** bind the M innermost dimensions to certain indices.
this reduces the dimensionality of the image to this reduces the dimensionality of the image to
max { 1, N-M } max { 1, N-M }.
<b>Usage:</b>
\code
// create a 3D array of size 40x30x20
typedef MultiArray<3, double>::difference_type Shape;
MultiArray<3, double> array3(Shape(40, 30, 20));
// get a 1D array by fixing index 0 to 12, and index 1 to 10
MultiArrayView <1, double, StridedArrayTag> array1 = array3.bin
dInner(TinyVector<int, 2>(12, 10));
\endcode
*/ */
template <unsigned int M> template <unsigned int M>
MultiArrayView <N-M, T, StridedArrayTag> MultiArrayView <N-M, T, StridedArrayTag>
bindInner (const TinyVector <ptrdiff_t, M> &d) const; bindInner (const TinyVector <MultiArrayIndex, M> &d) const;
/** bind dimension M to index d. /** bind dimension M to index d.
this reduces the dimensionality of the image to this reduces the dimensionality of the image to
max { 1, N-1 } max { 1, N-1 }.
<b>Usage:</b>
\code
// create a 3D array of size 40x30x20
typedef MultiArray<3, double>::difference_type Shape;
MultiArray<3, double> array3(Shape(40, 30, 20));
// get a 2D array by fixing index 1 to 12
MultiArrayView <2, double> array2 = array3.bind<1>(12);
// get a 2D array by fixing index 0 to 23
MultiArrayView <2, double, StridedArrayTag> array2a = array3.bi
nd<0>(23);
\endcode
*/ */
template <unsigned int M> template <unsigned int M>
MultiArrayView <N-1, T, typename detail::MaybeStrided <M>::type > MultiArrayView <N-1, T, typename vigra::detail::MaybeStrided <M>::type
bind (int d) const; >
bind (difference_type_1 d) const;
/** bind the outmost dimension to a certain index. /** bind the outmost dimension to a certain index.
this reduces the dimensionality of the image to this reduces the dimensionality of the image to
max { 1, N-1 } max { 1, N-1 }.
<b>Usage:</b>
\code
// create a 3D array of size 40x30x20
typedef MultiArray<3, double>::difference_type Shape;
MultiArray<3, double> array3(Shape(40, 30, 20));
// get a 2D array by fixing the outermost index (i.e. index 2)
to 12
MultiArrayView <2, double> array2 = array3.bindOuter(12);
\endcode
*/ */
MultiArrayView <N-1, T, C> bindOuter (int d) const; MultiArrayView <N-1, T, C> bindOuter (difference_type_1 d) const;
/** bind the innermost dimension to a certain index. /** bind the innermost dimension to a certain index.
this reduces the dimensionality of the image to this reduces the dimensionality of the image to
max { 1, N-1 } max { 1, N-1 }.
<b>Usage:</b>
\code
// create a 3D array of size 40x30x20
typedef MultiArray<3, double>::difference_type Shape;
MultiArray<3, double> array3(Shape(40, 30, 20));
// get a 2D array by fixing the innermost index (i.e. index 0)
to 23
MultiArrayView <2, double, StridedArrayTag> array2 = array3.bin
dInner(23);
\endcode
*/ */
MultiArrayView <N-1, T, StridedArrayTag> bindInner (int d) const; MultiArrayView <N-1, T, StridedArrayTag> bindInner (difference_type_1 d ) const;
/** bind dimension m to index d. /** bind dimension m to index d.
this reduces the dimensionality of the image to this reduces the dimensionality of the image to
max { 1, N-1 } max { 1, N-1 }.
<b>Usage:</b>
\code
// create a 3D array of size 40x30x20
typedef MultiArray<3, double>::difference_type Shape;
MultiArray<3, double> array3(Shape(40, 30, 20));
// get a 2D array by fixing index 2 to 15
MultiArrayView <2, double, StridedArrayTag> array2 = array3.bin
dAt(2, 15);
\endcode
*/ */
MultiArrayView <N-1, T, StridedArrayTag> MultiArrayView <N-1, T, StridedArrayTag>
bindAt (int m, int d) const; bindAt (difference_type_1 m, difference_type_1 d) const;
/** create a rectangular subarray that spans between the /** create a rectangular subarray that spans between the
points p and q, where p is in the subarray, q not. points p and q, where p is in the subarray, q not.
<b>Usage:</b>
\code
// create a 3D array of size 40x30x20
typedef MultiArray<3, double>::difference_type Shape;
MultiArray<3, double> array3(Shape(40, 30, 20));
// get a subarray set is smaller by one element at all sides
MultiArrayView <3, double> subarray = array3.subarray(Shape(1,1
,1), Shape(39, 29, 19));
\endcode
*/ */
MultiArrayView subarray (const difference_type &p, MultiArrayView subarray (const difference_type &p,
const difference_type &q) const const difference_type &q) const
{ {
const int offset = dot (m_stride, p); const difference_type_1 offset = dot (m_stride, p);
return MultiArrayView (q - p, m_stride, m_ptr + offset); return MultiArrayView (q - p, m_stride, m_ptr + offset);
} }
/** apply an additional striding to the image, thereby reducing /** apply an additional striding to the image, thereby reducing
the shape of the array. the shape of the array.
for example, multiplying the stride of dimension one by three for example, multiplying the stride of dimension one by three
turns an appropriately layed out (interleaved) rgb image into turns an appropriately layed out (interleaved) rgb image into
a single band image. a single band image.
*/ */
MultiArrayView <N, T, StridedArrayTag> MultiArrayView <N, T, StridedArrayTag>
stridearray (const difference_type &s) const stridearray (const difference_type &s) const
{ {
difference_type shape = m_shape; difference_type shape = m_shape;
for (unsigned int i = 0; i < actual_dimension; ++i) for (unsigned int i = 0; i < actual_dimension; ++i)
shape [i] /= s [i]; shape [i] /= s [i];
return MultiArrayView <N, T, StridedArrayTag> return MultiArrayView <N, T, StridedArrayTag>
(shape, m_stride * s, m_ptr); (shape, m_stride * s, m_ptr);
} }
/** permute the dimensions of the array.
The function exchanges the meaning of the dimensions without co
pying the data.
In case of a 2-dimensional array, this is simply array transpos
ition. In higher dimensions,
there are more possibilities.
<b>Usage:</b><br>
\code
typedef MultiArray<2, double>::difference_type Shape;
MultiArray<2, double> array(10, 20);
MultiArray<2, double, StridedArrayTag> transposed = array.permu
teDimensions(Shape(1,0));
for(int i=0; i<array.shape(0), ++i)
for(int j=0; j<array.shape(1); ++j)
assert(array(i, j) == transposed(j, i));
\endcode
*/
MultiArrayView <N, T, StridedArrayTag>
permuteDimensions (const difference_type &s) const
{
difference_type shape, stride, check((typename difference_type::val
ue_type)0);
for (unsigned int i = 0; i < actual_dimension; ++i)
{
shape[i] = m_shape[s[i]];
stride[i] = m_stride[s[i]];
++check[s[i]];
}
vigra_precondition(check == difference_type(1),
"MultiArrayView::permuteDimensions(): every dimension must occur
exactly once.");
return MultiArrayView <N, T, StridedArrayTag>(shape, stride, m_ptr)
;
}
/** transpose a 2-dimensional array. Use only if N==2.
<b>Usage:</b><br>
\code
typedef MultiArray<2, double>::difference_type Shape;
MultiArray<2, double> array(10, 20);
MultiArray<2, double, StridedArrayTag> transposed = array.trans
pose();
for(int i=0; i<array.shape(0), ++i)
for(int j=0; j<array.shape(1); ++j)
assert(array(i, j) == transposed(j, i));
\endcode
*/
MultiArrayView <2, T, StridedArrayTag>
transpose () const
{
difference_type shape(m_shape[1], m_shape[0]),
stride(m_stride[1], m_stride[0]);
return MultiArrayView <2, T, StridedArrayTag>(shape, stride, m_ptr)
;
}
/** number of the elements in the array. /** number of the elements in the array.
*/ */
std::size_t elementCount () const difference_type_1 elementCount () const
{ {
std::size_t ret = m_shape[0]; difference_type_1 ret = m_shape[0];
for(unsigned int i = 1; i < actual_dimension; ++i) for(int i = 1; i < actual_dimension; ++i)
ret *= m_shape[i]; ret *= m_shape[i];
return ret; return ret;
} }
/** return the array's size. /** number of the elements in the array.
Same as <tt>elementCount()</tt>. Mostly useful to support the s
td::vector interface.
*/ */
const size_type & size () const difference_type_1 size () const
{ {
return m_shape; return elementCount();
} }
/** return the array's shape (same as the <tt>size()</tt>). /** return the array's shape.
*/ */
const difference_type & shape () const const difference_type & shape () const
{ {
return m_shape; return m_shape;
} }
/** return the array's size at a certain dimension. /** return the array's size at a certain dimension.
*/ */
int size (int n) const difference_type_1 size (difference_type_1 n) const
{ {
return m_shape [n]; return m_shape [n];
} }
/** return the array's shape at a certain dimension /** return the array's shape at a certain dimension
(same as <tt>size(n)</tt>). (same as <tt>size(n)</tt>).
*/ */
int shape (int n) const difference_type_1 shape (difference_type_1 n) const
{ {
return m_shape [n]; return m_shape [n];
} }
/** return the array's stride for every dimension. /** return the array's stride for every dimension.
*/ */
const difference_type & stride () const const difference_type & stride () const
{ {
return m_stride; return m_stride;
} }
/** return the array's stride at a certain dimension. /** return the array's stride at a certain dimension.
*/ */
int stride (int n) const difference_type_1 stride (int n) const
{ {
return m_stride [n]; return m_stride [n];
} }
/** check whether two arrays are elementwise equal.
*/
template <class U, class C1>
bool operator==(MultiArrayView<N, U, C1> const & rhs) const
{
if(this->shape() != rhs.shape())
return false;
return detail::equalityOfMultiArrays(traverser_begin(), shape(), rh
s.traverser_begin(), MetaInt<actual_dimension-1>());
}
/** check whether two arrays are not elementwise equal.
Also true when the two arrays have different shapes.
*/
template <class U, class C1>
bool operator!=(MultiArrayView<N, U, C1> const & rhs) const
{
return !operator==(rhs);
}
/** check whether the given point is in the array range. /** check whether the given point is in the array range.
*/ */
bool isInside (difference_type const & p) const bool isInside (difference_type const & p) const
{ {
for(int d=0; d<actual_dimension; ++d) for(int d=0; d<actual_dimension; ++d)
if(p[d] < 0 || p[d] >= shape(d)) if(p[d] < 0 || p[d] >= shape(d))
return false; return false;
return true; return true;
} }
/** return the squared norm of the array (sum of squares of the arr ay elements). /** Compute the squared Euclidean norm of the array (sum of squares of the array elements).
*/ */
SquaredNormType squaredNorm() const typename NormTraits<MultiArrayView>::SquaredNormType squaredNorm() cons t
{ {
typedef typename NormTraits<MultiArrayView>::SquaredNormType Square dNormType;
SquaredNormType res = NumericTraits<SquaredNormType>::zero(); SquaredNormType res = NumericTraits<SquaredNormType>::zero();
detail::squaredNormOfMultiArray(traverser_begin(), shape(), res, Me detail::sumOverMultiArray(traverser_begin(), shape(), detail::Multi
taInt<actual_dimension-1>()); ArrayL2Functor<SquaredNormType>(),
res, MetaInt<actual_dimension-1>());
return res; return res;
} }
/** return the norm of the array (equals <tt>sqrt(array.squaredNorm /** Compute various norms of the array.
())</tt>). The norm is determined by parameter \a type:
<ul>
<li> type == 0: maximum norm (L-infinity): maximum of absolute
values of the array elements
<li> type == 1: Manhattan norm (L1): sum of absolute values of
the array elements
<li> type == 2: Euclidean norm (L2): square root of <tt>squared
Norm()</tt> when \a useSquaredNorm is <tt>true</tt>,<br>
or direct algorithm that avoids underflow/overflow otherwi
se.
</ul>
Parameter \a useSquaredNorm has no effect when \a type != 2. De
faults: compute L2 norm as square root of
<tt>squaredNorm()</tt>.
*/ */
NormType norm() const typename NormTraits<MultiArrayView>::NormType norm(int type = 2, bool u
{ seSquaredNorm = true) const;
return sqrt(static_cast<typename SquareRootTraits<SquaredNormType>:
:SquareRootArgument>(this->squaredNorm()));
}
/** return the pointer to the image data /** return the pointer to the image data
*/ */
pointer data () const pointer data () const
{ {
return m_ptr; return m_ptr;
} }
/** returns the N-dimensional MultiIterator pointing /** returns the N-dimensional MultiIterator pointing
to the first element in every dimension. to the first element in every dimension.
skipping to change at line 715 skipping to change at line 1313
return ret; return ret;
} }
view_type view () view_type view ()
{ {
return *this; return *this;
} }
}; };
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
MultiArrayView <N, T, C>::MultiArrayView (const difference_type &shape, MultiArrayView<N, T, C> &
pointer ptr) MultiArrayView <N, T, C>::operator=(MultiArrayView<N, T, C> const & rhs)
: m_shape (shape), m_stride (detail::defaultStride <MultiArrayView<N,T> {
::actual_dimension> (shape)), m_ptr (ptr) if(this == &rhs)
{} return *this;
vigra_precondition(this->shape() == rhs.shape() || m_ptr == 0,
"MultiArrayView::operator=(MultiArrayView const &) size mismatch -
use MultiArrayView::reset().");
if(m_ptr == 0)
{
m_shape = rhs.m_shape;
m_stride = rhs.m_stride;
m_ptr = rhs.m_ptr;
}
else
this->copyImpl(rhs);
return *this;
}
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
MultiArrayView <N, T, C>::MultiArrayView template <class U, class CN>
(const difference_type &shape, const difference_type &stride, pointer ptr) bool
: m_shape (shape), m_stride (stride), m_ptr (ptr) MultiArrayView <N, T, C>::arraysOverlap(const MultiArrayView <N, U, CN>& rh
{} s) const
{
vigra_precondition (shape () == rhs.shape (),
"MultiArrayView::arraysOverlap(): shape mismatch.");
const_pointer first_element = this->m_ptr,
last_element = first_element + dot(this->m_shape - differ
ence_type(1), this->m_stride);
typename MultiArrayView <N, U, CN>::const_pointer
rhs_first_element = rhs.data(),
rhs_last_element = rhs_first_element + dot(rhs.shape() - differe
nce_type(1), rhs.stride());
return !(last_element < rhs_first_element || rhs_last_element < first_e
lement);
}
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
template <class U> template <class U, class CN>
void void
MultiArrayView <N, T, C>::init(const U & init) MultiArrayView <N, T, C>::copyImpl(const MultiArrayView <N, U, CN>& rhs)
{ {
detail::initMultiArrayData(traverser_begin(), shape(), init, MetaInt<ac if(!arraysOverlap(rhs))
tual_dimension-1>()); {
// no overlap -- can copy directly
detail::copyMultiArrayData(rhs.traverser_begin(), shape(), traverse
r_begin(), MetaInt<actual_dimension-1>());
}
else
{
// overlap: we got different views to the same data -- copy to inte
rmediate memory in order to avoid
// overwriting elements that are still needed on the rhs.
MultiArray<N, T> tmp(rhs);
detail::copyMultiArrayData(tmp.traverser_begin(), shape(), traverse
r_begin(), MetaInt<actual_dimension-1>());
}
}
#define VIGRA_MULTI_ARRY_COMPUTED_ASSIGNMENT(name, op) \
template <unsigned int N, class T, class C> \
template<class U, class C1> \
MultiArrayView<N, T, C> & \
MultiArrayView <N, T, C>::operator op(MultiArrayView<N, U, C1> const & rhs)
\
{ \
vigra_precondition(this->shape() == rhs.shape(), "MultiArrayView::opera
tor" #op "() size mismatch."); \
if(!arraysOverlap(rhs)) \
{ \
detail::name##MultiArrayData(rhs.traverser_begin(), shape(), traver
ser_begin(), MetaInt<actual_dimension-1>()); \
} \
else \
{ \
MultiArray<N, T> tmp(rhs); \
detail::name##MultiArrayData(tmp.traverser_begin(), shape(), traver
ser_begin(), MetaInt<actual_dimension-1>()); \
} \
return *this; \
} }
VIGRA_MULTI_ARRY_COMPUTED_ASSIGNMENT(copyAdd, +=)
VIGRA_MULTI_ARRY_COMPUTED_ASSIGNMENT(copySub, -=)
VIGRA_MULTI_ARRY_COMPUTED_ASSIGNMENT(copyMul, *=)
VIGRA_MULTI_ARRY_COMPUTED_ASSIGNMENT(copyDiv, /=)
#undef VIGRA_MULTI_ARRY_COMPUTED_ASSIGNMENT
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
template <class U, class CN> template <class U, class CN>
void void
MultiArrayView <N, T, C>::copy(const MultiArrayView <N, U, CN>&; rhs) MultiArrayView <N, T, C>::swapDataImpl(MultiArrayView <N, U, CN>; rhs)
{ {
if(this == &rhs)
return;
vigra_precondition (shape () == rhs.shape (), vigra_precondition (shape () == rhs.shape (),
"MultiArrayView::copy(): shape mismatch."); "MultiArrayView::swapData(): shape mismatch.");
detail::copyMultiArrayData(rhs.traverser_begin(), shape(), traverser_be
gin(), MetaInt<actual_dimension-1>()); // check for overlap of this and rhs
const_pointer first_element = this->m_ptr,
last_element = first_element + dot(this->m_shape - differ
ence_type(1), this->m_stride);
typename MultiArrayView <N, U, CN>::const_pointer
rhs_first_element = rhs.data(),
rhs_last_element = rhs_first_element + dot(rhs.shape() - differe
nce_type(1), rhs.stride());
if(last_element < rhs_first_element || rhs_last_element < first_element
)
{
// no overlap -- can swap directly
detail::swapDataImpl(traverser_begin(), shape(), rhs.traverser_begi
n(), MetaInt<actual_dimension-1>());
}
else
{
// overlap: we got different views to the same data -- copy to inte
rmediate memory in order to avoid
// overwriting elements that are still needed.
MultiArray<N, T> tmp(*this);
copy(rhs);
rhs.copy(tmp);
}
} }
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
template <unsigned int M> template <unsigned int M>
MultiArrayView <N-M, T, C> MultiArrayView <N-M, T, C>
MultiArrayView <N, T, C>::bindOuter (const TinyVector <ptrdiff_t, M> &d) co nst MultiArrayView <N, T, C>::bindOuter (const TinyVector <MultiArrayIndex, M> &d) const
{ {
TinyVector <ptrdiff_t, M> stride; TinyVector <MultiArrayIndex, M> stride;
stride.init (m_stride.begin () + N-M, m_stride.end ()); stride.init (m_stride.begin () + N-M, m_stride.end ());
pointer ptr = m_ptr + dot (d, stride); pointer ptr = m_ptr + dot (d, stride);
static const int NNew = (N-M == 0) ? 1 : N-M; static const int NNew = (N-M == 0) ? 1 : N-M;
TinyVector <ptrdiff_t, NNew> inner_shape, inner_stride; TinyVector <MultiArrayIndex, NNew> inner_shape, inner_stride;
if (N-M == 0) if (N-M == 0)
{ {
inner_shape [0] = 1; inner_shape [0] = 1;
inner_stride [0] = 0; inner_stride [0] = 0;
} }
else else
{ {
inner_shape.init (m_shape.begin (), m_shape.end () - M); inner_shape.init (m_shape.begin (), m_shape.end () - M);
inner_stride.init (m_stride.begin (), m_stride.end () - M); inner_stride.init (m_stride.begin (), m_stride.end () - M);
} }
return MultiArrayView <N-M, T, C> (inner_shape, inner_stride, ptr); return MultiArrayView <N-M, T, C> (inner_shape, inner_stride, ptr);
} }
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
template <unsigned int M> template <unsigned int M>
MultiArrayView <N - M, T, StridedArrayTag> MultiArrayView <N - M, T, StridedArrayTag>
MultiArrayView <N, T, C>::bindInner (const TinyVector <ptrdiff_t, M> &d) co nst MultiArrayView <N, T, C>::bindInner (const TinyVector <MultiArrayIndex, M> &d) const
{ {
TinyVector <ptrdiff_t, M> stride; TinyVector <MultiArrayIndex, M> stride;
stride.init (m_stride.begin (), m_stride.end () - N + M); stride.init (m_stride.begin (), m_stride.end () - N + M);
pointer ptr = m_ptr + dot (d, stride); pointer ptr = m_ptr + dot (d, stride);
static const int NNew = (N-M == 0) ? 1 : N-M; static const int NNew = (N-M == 0) ? 1 : N-M;
TinyVector <ptrdiff_t, NNew> outer_shape, outer_stride; TinyVector <MultiArrayIndex, NNew> outer_shape, outer_stride;
if (N-M == 0) if (N-M == 0)
{ {
outer_shape [0] = 1; outer_shape [0] = 1;
outer_stride [0] = 0; outer_stride [0] = 0;
} }
else else
{ {
outer_shape.init (m_shape.begin () + M, m_shape.end ()); outer_shape.init (m_shape.begin () + M, m_shape.end ());
outer_stride.init (m_stride.begin () + M, m_stride.end ()); outer_stride.init (m_stride.begin () + M, m_stride.end ());
} }
return MultiArrayView <N-M, T, StridedArrayTag> return MultiArrayView <N-M, T, StridedArrayTag>
(outer_shape, outer_stride, ptr); (outer_shape, outer_stride, ptr);
} }
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
template <unsigned int M> template <unsigned int M>
MultiArrayView <N-1, T, typename detail::MaybeStrided <M>::type > MultiArrayView <N-1, T, typename detail::MaybeStrided <M>::type >
MultiArrayView <N, T, C>::bind (int d) const MultiArrayView <N, T, C>::bind (difference_type_1 d) const
{ {
static const int NNew = (N-1 == 0) ? 1 : N-1; static const int NNew = (N-1 == 0) ? 1 : N-1;
TinyVector <ptrdiff_t, NNew> shape, stride; TinyVector <MultiArrayIndex, NNew> shape, stride;
// the remaining dimensions are 0..n-1,n+1..N-1 // the remaining dimensions are 0..n-1,n+1..N-1
if (N-1 == 0) if (N-1 == 0)
{ {
shape[0] = 1; shape[0] = 1;
stride[0] = 0; stride[0] = 0;
} }
else else
{ {
std::copy (m_shape.begin (), m_shape.begin () + M, shape.begin ()); std::copy (m_shape.begin (), m_shape.begin () + M, shape.begin ());
std::copy (m_shape.begin () + M+1, m_shape.end (), std::copy (m_shape.begin () + M+1, m_shape.end (),
skipping to change at line 821 skipping to change at line 1495
std::copy (m_stride.begin (), m_stride.begin () + M, stride.begin ( )); std::copy (m_stride.begin (), m_stride.begin () + M, stride.begin ( ));
std::copy (m_stride.begin () + M+1, m_stride.end (), std::copy (m_stride.begin () + M+1, m_stride.end (),
stride.begin () + M); stride.begin () + M);
} }
return MultiArrayView <N-1, T, typename detail::MaybeStrided <M>::type> return MultiArrayView <N-1, T, typename detail::MaybeStrided <M>::type>
(shape, stride, m_ptr + d * m_stride[M]); (shape, stride, m_ptr + d * m_stride[M]);
} }
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
MultiArrayView <N - 1, T, C> MultiArrayView <N - 1, T, C>
MultiArrayView <N, T, C>::bindOuter (int d) const MultiArrayView <N, T, C>::bindOuter (difference_type_1 d) const
{ {
static const int NNew = (N-1 == 0) ? 1 : N-1; static const int NNew = (N-1 == 0) ? 1 : N-1;
TinyVector <ptrdiff_t, NNew> inner_shape, inner_stride; TinyVector <MultiArrayIndex, NNew> inner_shape, inner_stride;
if (N-1 == 0) if (N-1 == 0)
{ {
inner_shape [0] = 1; inner_shape [0] = 1;
inner_stride [0] = 0; inner_stride [0] = 0;
} }
else else
{ {
inner_shape.init (m_shape.begin (), m_shape.end () - 1); inner_shape.init (m_shape.begin (), m_shape.end () - 1);
inner_stride.init (m_stride.begin (), m_stride.end () - 1); inner_stride.init (m_stride.begin (), m_stride.end () - 1);
} }
return MultiArrayView <N-1, T, C> (inner_shape, inner_stride, return MultiArrayView <N-1, T, C> (inner_shape, inner_stride,
m_ptr + d * m_stride [N-1]); m_ptr + d * m_stride [N-1]);
} }
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
MultiArrayView <N - 1, T, StridedArrayTag> MultiArrayView <N - 1, T, StridedArrayTag>
MultiArrayView <N, T, C>::bindInner (int d) const MultiArrayView <N, T, C>::bindInner (difference_type_1 d) const
{ {
static const int NNew = (N-1 == 0) ? 1 : N-1; static const int NNew = (N-1 == 0) ? 1 : N-1;
TinyVector <ptrdiff_t, NNew> outer_shape, outer_stride; TinyVector <MultiArrayIndex, NNew> outer_shape, outer_stride;
if (N-1 == 0) if (N-1 == 0)
{ {
outer_shape [0] = 1; outer_shape [0] = 1;
outer_stride [0] = 0; outer_stride [0] = 0;
} }
else else
{ {
outer_shape.init (m_shape.begin () + 1, m_shape.end ()); outer_shape.init (m_shape.begin () + 1, m_shape.end ());
outer_stride.init (m_stride.begin () + 1, m_stride.end ()); outer_stride.init (m_stride.begin () + 1, m_stride.end ());
} }
return MultiArrayView <N-1, T, StridedArrayTag> return MultiArrayView <N-1, T, StridedArrayTag>
(outer_shape, outer_stride, m_ptr + d * m_stride [0]); (outer_shape, outer_stride, m_ptr + d * m_stride [0]);
} }
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
MultiArrayView <N - 1, T, StridedArrayTag> MultiArrayView <N - 1, T, StridedArrayTag>
MultiArrayView <N, T, C>::bindAt (int n, int d) const MultiArrayView <N, T, C>::bindAt (difference_type_1 n, difference_type_1 d) const
{ {
vigra_precondition ( vigra_precondition (
n < static_cast <int> (N), n < static_cast <int> (N),
"MultiArrayView <N, T, C>::bindAt(): dimension out of range."); "MultiArrayView <N, T, C>::bindAt(): dimension out of range.");
static const int NNew = (N-1 == 0) ? 1 : N-1; static const int NNew = (N-1 == 0) ? 1 : N-1;
TinyVector <ptrdiff_t, NNew> shape, stride; TinyVector <MultiArrayIndex, NNew> shape, stride;
// the remaining dimensions are 0..n-1,n+1..N-1 // the remaining dimensions are 0..n-1,n+1..N-1
if (N-1 == 0) if (N-1 == 0)
{ {
shape [0] = 1; shape [0] = 1;
stride [0] = 0; stride [0] = 0;
} }
else else
{ {
std::copy (m_shape.begin (), m_shape.begin () + n, shape.begin ()); std::copy (m_shape.begin (), m_shape.begin () + n, shape.begin ());
std::copy (m_shape.begin () + n+1, m_shape.end (), std::copy (m_shape.begin () + n+1, m_shape.end (),
shape.begin () + n); shape.begin () + n);
std::copy (m_stride.begin (), m_stride.begin () + n, stride.begin ( )); std::copy (m_stride.begin (), m_stride.begin () + n, stride.begin ( ));
std::copy (m_stride.begin () + n+1, m_stride.end (), std::copy (m_stride.begin () + n+1, m_stride.end (),
stride.begin () + n); stride.begin () + n);
} }
return MultiArrayView <N-1, T, StridedArrayTag> return MultiArrayView <N-1, T, StridedArrayTag>
(shape, stride, m_ptr + d * m_stride[n]); (shape, stride, m_ptr + d * m_stride[n]);
} }
template <unsigned int N, class T, class C>
typename NormTraits<MultiArrayView <N, T, C> >::NormType
MultiArrayView <N, T, C>::norm(int type, bool useSquaredNorm) const
{
typedef typename NormTraits<MultiArrayView>::NormType NormType;
switch(type)
{
case 0:
{
NormType res = NumericTraits<NormType>::zero();
detail::normMaxOfMultiArray(traverser_begin(), shape(), res, MetaIn
t<actual_dimension-1>());
return res;
}
case 1:
{
NormType res = NumericTraits<NormType>::zero();
detail::sumOverMultiArray(traverser_begin(), shape(), detail::Multi
ArrayL1Functor<NormType>(),
res, MetaInt<actual_dimension-1>());
return res;
}
case 2:
{
if(useSquaredNorm)
{
return sqrt((NormType)squaredNorm());
}
else
{
NormType normMax = NumericTraits<NormType>::zero();
detail::normMaxOfMultiArray(traverser_begin(), shape(), normMax
, MetaInt<actual_dimension-1>());
if(normMax == NumericTraits<NormType>::zero())
return normMax;
NormType res = NumericTraits<NormType>::zero();
detail::sumOverMultiArray(traverser_begin(), shape(), detail::M
ultiArrayScaledL2Functor<NormType>(normMax),
res, MetaInt<actual_dimension-1>());
return sqrt(res)*normMax;
}
}
default:
vigra_precondition(false, "MultiArrayView::norm(): Unknown norm typ
e.");
return NumericTraits<NormType>::zero(); // unreachable
}
}
/********************************************************/ /********************************************************/
/* */ /* */
/* norm */ /* norm */
/* */ /* */
/********************************************************/ /********************************************************/
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
struct NormTraits<MultiArrayView <N, T, C> > inline typename NormTraits<MultiArrayView <N, T, C> >::SquaredNormType
{
typedef MultiArrayView <N, T, C> Type;
typedef typename Type::SquaredNormType SquaredNormType;
typedef typename Type::NormType NormType;
};
template <unsigned int N, class T, class C>
inline typename MultiArrayView <N, T, C>::SquaredNormType
squaredNorm(MultiArrayView <N, T, C> const & a) squaredNorm(MultiArrayView <N, T, C> const & a)
{ {
return a.squaredNorm(); return a.squaredNorm();
} }
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
inline typename MultiArrayView <N, T, C>::NormType inline typename NormTraits<MultiArrayView <N, T, C> >::NormType
norm(MultiArrayView <N, T, C> const & a) norm(MultiArrayView <N, T, C> const & a)
{ {
return a.norm(); return a.norm();
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* MultiArray */ /* MultiArray */
/* */ /* */
/********************************************************/ /********************************************************/
skipping to change at line 939 skipping to change at line 1650
\code \code
N: the array dimension N: the array dimension
T: the type of the array elements T: the type of the array elements
A: the allocator used for internal storage management A: the allocator used for internal storage management
(default: std::allocator<T>) (default: std::allocator<T>)
\endcode \endcode
<b>\#include</b> <b>\#include</b>
"<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>" \<<a href="multi__array_8hxx-source.html">vigra/multi_array.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <unsigned int N, class T, class A /* default already declared abov e */> template <unsigned int N, class T, class A /* default already declared abov e */>
class MultiArray : public MultiArrayView <N, T> class MultiArray : public MultiArrayView <N, T>
{ {
public: public:
using MultiArrayView <N, T>::actual_dimension; using MultiArrayView <N, T>::actual_dimension;
skipping to change at line 986 skipping to change at line 1697
typedef typename view_type::reference reference; typedef typename view_type::reference reference;
/** const reference type (result of operator[] const) /** const reference type (result of operator[] const)
*/ */
typedef typename view_type::const_reference const_reference; typedef typename view_type::const_reference const_reference;
/** size type /** size type
*/ */
typedef typename view_type::size_type size_type; typedef typename view_type::size_type size_type;
/** difference type (used for offsetting) /** difference type (used for multi-dimensional offsets and indices )
*/ */
typedef typename view_type::difference_type difference_type; typedef typename view_type::difference_type difference_type;
/** difference and index type for a single dimension
*/
typedef typename view_type::difference_type_1 difference_type_1;
/** traverser type /** traverser type
*/ */
typedef typename detail::MultiIteratorChooser < typedef typename vigra::detail::MultiIteratorChooser <
UnstridedArrayTag>::template Traverser <N, T, T &, T *>::type UnstridedArrayTag>::template Traverser <N, T, T &, T *>::type
traverser; traverser;
/** traverser type to const data /** traverser type to const data
*/ */
typedef typename detail::MultiIteratorChooser < typedef typename vigra::detail::MultiIteratorChooser <
UnstridedArrayTag>::template Traverser <N, T, T const &, T const *> ::type UnstridedArrayTag>::template Traverser <N, T, T const &, T const *> ::type
const_traverser; const_traverser;
/** sequential (random access) iterator type /** sequential (random access) iterator type
*/ */
typedef T * iterator; typedef T * iterator;
/** sequential (random access) const iterator type /** sequential (random access) const iterator type
*/ */
typedef T * const_iterator; typedef T * const_iterator;
/** the squared norm type (return type of squaredNorm(array)).
*/
typedef typename view_type::SquaredNormType SquaredNormType;
/** the norm type (return type of norm(array)).
*/
typedef typename view_type::NormType NormType;
protected: protected:
typedef typename difference_type::value_type diff_zero_t; typedef typename difference_type::value_type diff_zero_t;
/** the allocator used to allocate the memory /** the allocator used to allocate the memory
*/ */
allocator_type m_alloc; allocator_type m_alloc;
/** allocate memory for s pixels, write its address into the given /** allocate memory for s pixels, write its address into the given
pointer and initialize the pixels with init. pointer and initialize the pixels with init.
*/ */
void allocate (pointer &ptr, std::size_t s, const_reference init); void allocate (pointer &ptr, difference_type_1 s, const_reference init) ;
/** allocate memory for s pixels, write its address into the given /** allocate memory for s pixels, write its address into the given
pointer and initialize the linearized pixels to the values of i nit. pointer and initialize the linearized pixels to the values of i nit.
*/ */
template <class U> template <class U>
void allocate (pointer &ptr, std::size_t s, U const * init); void allocate (pointer &ptr, difference_type_1 s, U const * init);
/** allocate memory, write its address into the given /** allocate memory, write its address into the given
pointer and initialize it by copying the data from the given Mu ltiArrayView. pointer and initialize it by copying the data from the given Mu ltiArrayView.
*/ */
template <class U, class C> template <class U, class C>
void allocate (pointer &ptr, MultiArrayView<N, U, C> const & init); void allocate (pointer &ptr, MultiArrayView<N, U, C> const & init);
/** deallocate the memory (of length s) starting at the given addre ss. /** deallocate the memory (of length s) starting at the given addre ss.
*/ */
void deallocate (pointer &ptr, std::size_t s); void deallocate (pointer &ptr, difference_type_1 s);
template <class U, class C>
void copyOrReshape (const MultiArrayView<N, U, C> &rhs);
public: public:
/** default constructor /** default constructor
*/ */
MultiArray (); MultiArray ()
: MultiArrayView <N, T> (difference_type (diff_zero_t(0)),
difference_type (diff_zero_t(0)), 0)
{}
/** construct with given allocator /** construct with given allocator
*/ */
MultiArray (allocator_type const & alloc); MultiArray (allocator_type const & alloc)
: MultiArrayView <N, T> (difference_type (diff_zero_t(0)),
difference_type (diff_zero_t(0)), 0),
m_alloc(alloc)
{}
/** construct with given shape /** construct with given shape
*/ */
explicit MultiArray (const difference_type &shape, explicit MultiArray (const difference_type &shape,
allocator_type const & alloc = allocator_type()); allocator_type const & alloc = allocator_type());
/** construct from shape with an initial value /** construct from shape with an initial value
*/ */
MultiArray (const difference_type &shape, const_reference init, MultiArray (const difference_type &shape, const_reference init,
allocator_type const & alloc = allocator_type()); allocator_type const & alloc = allocator_type());
/** construct from shape and copy values from the given array /** construct from shape and copy values from the given array
*/ */
MultiArray (const difference_type &shape, const_pointer init, MultiArray (const difference_type &shape, const_pointer init,
allocator_type const & alloc = allocator_type()); allocator_type const & alloc = allocator_type());
/** copy constructor /** copy constructor
*/ */
MultiArray (const MultiArray &rhs); MultiArray (const MultiArray &rhs)
: MultiArrayView <N, T> (rhs.m_shape, rhs.m_stride, 0),
m_alloc (rhs.m_alloc)
{
allocate (this->m_ptr, this->elementCount (), rhs.data ());
}
/** construct by copying from a MultiArrayView /** construct by copying from a MultiArrayView
*/ */
template <class U, class C> template <class U, class C>
MultiArray (const MultiArrayView<N, U, C> &rhs, MultiArray (const MultiArrayView<N, U, C> &rhs,
allocator_type const & alloc = allocator_type()); allocator_type const & alloc = allocator_type());
/** assignment.<br> /** assignment.<br>
If the size of \a rhs is the same as the left-hand side arrays' s old size, only If the size of \a rhs is the same as the left-hand side arrays' s old size, only
the data are copied. Otherwise, new storage is allocated, which invalidates all the data are copied. Otherwise, new storage is allocated, which invalidates all
objects (array views, iterators) depending on the lhs array. objects (array views, iterators) depending on the lhs array.
*/ */
MultiArray &operator= (const MultiArray &rhs) MultiArray & operator= (const MultiArray &rhs)
{ {
return this->operator=(static_cast<view_type const &>(rhs)); if (this != &rhs)
this->copyOrReshape(rhs);
return *this;
} }
/** assignment from arbitrary MultiArrayView.<br> /** assignment from arbitrary MultiArrayView.<br>
If the size of \a rhs is the same as the left-hand side arrays' s old size, only If the size of \a rhs is the same as the left-hand side arrays' s old size, only
the data are copied. Otherwise, new storage is allocated, which invalidates all the data are copied. Otherwise, new storage is allocated, which invalidates all
objects (array views, iterators) depending on the lhs array. objects (array views, iterators) depending on the lhs array.
*/ */
template <class U, class C> template <class U, class C>
MultiArray &operator= (const MultiArrayView<N, U, C> &rhs); MultiArray &operator= (const MultiArrayView<N, U, C> &rhs)
{
this->copyOrReshape(rhs);
return *this;
}
/** Add-assignment from arbitrary MultiArrayView. Fails with
<tt>PreconditionViolation</tt> exception when the shapes do not
match.
*/
template <class U, class C>
MultiArray &operator+= (const MultiArrayView<N, U, C> &rhs)
{
view_type::operator+=(rhs);
return *this;
}
/** Subtract-assignment from arbitrary MultiArrayView. Fails with
<tt>PreconditionViolation</tt> exception when the shapes do not
match.
*/
template <class U, class C>
MultiArray &operator-= (const MultiArrayView<N, U, C> &rhs)
{
view_type::operator-=(rhs);
return *this;
}
/** Multiply-assignment from arbitrary MultiArrayView. Fails with
<tt>PreconditionViolation</tt> exception when the shapes do not
match.
*/
template <class U, class C>
MultiArray &operator*= (const MultiArrayView<N, U, C> &rhs)
{
view_type::operator*=(rhs);
return *this;
}
/** Divide-assignment from arbitrary MultiArrayView. Fails with
<tt>PreconditionViolation</tt> exception when the shapes do not
match.
*/
template <class U, class C>
MultiArray &operator/= (const MultiArrayView<N, U, C> &rhs)
{
view_type::operator/=(rhs);
return *this;
}
/** Add-assignment of a scalar.
*/
MultiArray &operator+= (const T &rhs)
{
view_type::operator+=(rhs);
return *this;
}
/** Subtract-assignment of a scalar.
*/
MultiArray &operator-= (const T &rhs)
{
view_type::operator-=(rhs);
return *this;
}
/** Multiply-assignment of a scalar.
*/
MultiArray &operator*= (const T &rhs)
{
view_type::operator*=(rhs);
return *this;
}
/** Divide-assignment of a scalar.
*/
MultiArray &operator/= (const T &rhs)
{
view_type::operator/=(rhs);
return *this;
}
/** destructor /** destructor
*/ */
~MultiArray (); ~MultiArray ()
{
deallocate (this->m_ptr, this->elementCount ());
}
/** init elements with a constant
*/
template <class U>
MultiArray & init(const U & init)
{
view_type::init(init);
return *this;
}
/** change the shape and allocate new memory.<br> /** change the shape and allocate new memory.<br>
<em>Note:</em> this operation invalidates all dependent objects <em>Note:</em> this operation invalidates all dependent objects
(array views and iterators) (array views and iterators)
*/ */
void reshape (const difference_type &shape) void reshape (const difference_type &shape)
{ {
reshape (shape, NumericTraits <T>::zero ()); reshape (shape, NumericTraits <T>::zero ());
} }
skipping to change at line 1164 skipping to change at line 1974
/** get the allocator. /** get the allocator.
*/ */
allocator_type const & allocator () const allocator_type const & allocator () const
{ {
return m_alloc; return m_alloc;
} }
}; };
template <unsigned int N, class T, class A> template <unsigned int N, class T, class A>
MultiArray <N, T, A>::MultiArray ()
: MultiArrayView <N, T> (difference_type (diff_zero_t(0)),
difference_type (diff_zero_t(0)), 0)
{}
template <unsigned int N, class T, class A>
MultiArray <N, T, A>::MultiArray (allocator_type const & alloc)
: MultiArrayView <N, T> (difference_type (diff_zero_t(0)),
difference_type (diff_zero_t(0)), 0),
m_alloc(alloc)
{}
template <unsigned int N, class T, class A>
MultiArray <N, T, A>::MultiArray (const difference_type &shape, MultiArray <N, T, A>::MultiArray (const difference_type &shape,
allocator_type const & alloc) allocator_type const & alloc)
: MultiArrayView <N, T> (shape, detail::defaultStride <MultiArrayView<N : MultiArrayView <N, T> (shape,
,T>::actual_dimension> (shape), 0), detail::defaultStride <MultiArrayView<N,T>::actual
m_alloc(alloc) _dimension> (shape),
0),
m_alloc(alloc)
{ {
if (N == 0) if (N == 0)
{ {
this->m_shape [0] = 1; this->m_shape [0] = 1;
this->m_stride [0] = 0; this->m_stride [0] = 0;
} }
allocate (this->m_ptr, this->elementCount (), NumericTraits<T>::zero () ); allocate (this->m_ptr, this->elementCount (), NumericTraits<T>::zero () );
} }
template <unsigned int N, class T, class A> template <unsigned int N, class T, class A>
MultiArray <N, T, A>::MultiArray (const difference_type &shape, MultiArray <N, T, A>::MultiArray (const difference_type &shape, const_refer
const_reference init, ence init,
allocator_type const & alloc) allocator_type const & alloc)
: MultiArrayView <N, T> (shape, detail::defaultStride <MultiArrayView<N : MultiArrayView <N, T> (shape,
,T>::actual_dimension> (shape), 0), detail::defaultStride <MultiArrayView<N,T>::actual
m_alloc(alloc) _dimension> (shape),
0),
m_alloc(alloc)
{ {
if (N == 0) if (N == 0)
{ {
this->m_shape [0] = 1; this->m_shape [0] = 1;
this->m_stride [0] = 0; this->m_stride [0] = 0;
} }
allocate (this->m_ptr, this->elementCount (), init); allocate (this->m_ptr, this->elementCount (), init);
} }
template <unsigned int N, class T, class A> template <unsigned int N, class T, class A>
MultiArray <N, T, A>::MultiArray (const difference_type &shape, MultiArray <N, T, A>::MultiArray (const difference_type &shape, const_point
const_pointer init, er init,
allocator_type const & alloc) allocator_type const & alloc)
: MultiArrayView <N, T> (shape, detail::defaultStride <MultiArrayView<N : MultiArrayView <N, T> (shape,
,T>::actual_dimension> (shape), 0), detail::defaultStride <MultiArrayView<N,T>::actual
m_alloc(alloc) _dimension> (shape),
0),
m_alloc(alloc)
{ {
if (N == 0) if (N == 0)
{ {
this->m_shape [0] = 1; this->m_shape [0] = 1;
this->m_stride [0] = 0; this->m_stride [0] = 0;
} }
allocate (this->m_ptr, this->elementCount (), init); allocate (this->m_ptr, this->elementCount (), init);
} }
template <unsigned int N, class T, class A> template <unsigned int N, class T, class A>
MultiArray <N, T, A>::MultiArray (const MultiArray &rhs)
: MultiArrayView <N, T> (rhs.m_shape, rhs.m_stride, 0),
m_alloc (rhs.m_alloc)
{
allocate (this->m_ptr, this->elementCount (), rhs.data ());
}
template <unsigned int N, class T, class A>
template <class U, class C> template <class U, class C>
MultiArray <N, T, A>::MultiArray (const MultiArrayView<N, U, C> &rhs, MultiArray <N, T, A>::MultiArray(const MultiArrayView<N, U, C> &rhs,
allocator_type const & alloc) allocator_type const & alloc)
: MultiArrayView <N, T> (rhs.shape(), : MultiArrayView <N, T> (rhs.shape(),
detail::defaultStride <MultiArrayView<N,T>::ac detail::defaultStride <MultiArrayView<N,T>::actual
tual_dimension> (rhs.shape()), 0), _dimension>(rhs.shape()),
m_alloc (alloc) 0),
m_alloc (alloc)
{ {
allocate (this->m_ptr, rhs); allocate (this->m_ptr, rhs);
} }
template <unsigned int N, class T, class A> template <unsigned int N, class T, class A>
MultiArray <N, T, A>::~MultiArray ()
{
deallocate (this->m_ptr, this->elementCount ());
}
template <unsigned int N, class T, class A>
template <class U, class C> template <class U, class C>
MultiArray <N, T, A> & void
MultiArray <N, T, A>::operator= (const MultiArrayView<N, U, C> &rhs) MultiArray <N, T, A>::copyOrReshape(const MultiArrayView<N, U, C> &rhs)
{ {
if (this == &rhs)
return *this;
if (this->shape() == rhs.shape()) if (this->shape() == rhs.shape())
this->copy(rhs); this->copy(rhs);
else else
{ {
pointer new_ptr; MultiArray t(rhs);
allocate (new_ptr, rhs); this->swap(t);
deallocate (this->m_ptr, this->elementCount ());
this->m_shape = rhs.shape();
this->m_stride = rhs.stride();
this->m_ptr = new_ptr;
} }
return *this;
} }
template <unsigned int N, class T, class A> template <unsigned int N, class T, class A>
void MultiArray <N, T, A>::reshape (const difference_type & new_shape, void MultiArray <N, T, A>::reshape (const difference_type & new_shape,
const_reference init) const_reference initial)
{ {
if (N== 0) if (N== 0)
{
return; return;
}
difference_type new_stride = detail::defaultStride <MultiArrayView<N,T> else if(new_shape == this->shape())
::actual_dimension> (new_shape); {
std::size_t new_size = new_shape [MultiArrayView<N,T>::actual_dimension this->init(initial);
-1] * new_stride [MultiArrayView<N,T>::actual_dimension-1]; }
T *new_ptr; else
allocate (new_ptr, new_size, init); {
deallocate (this->m_ptr, this->elementCount ()); difference_type new_stride = detail::defaultStride <MultiArrayView<
this->m_ptr = new_ptr; N,T>::actual_dimension> (new_shape);
this->m_shape = new_shape; difference_type_1 new_size = new_shape [MultiArrayView<N,T>::actual
this->m_stride = new_stride; _dimension-1] * new_stride [MultiArrayView<N,T>::actual_dimension-1];
T *new_ptr;
allocate (new_ptr, new_size, initial);
deallocate (this->m_ptr, this->elementCount ());
this->m_ptr = new_ptr;
this->m_shape = new_shape;
this->m_stride = new_stride;
}
} }
template <unsigned int N, class T, class A> template <unsigned int N, class T, class A>
void MultiArray <N, T, A>::swap (MultiArray <N, T, A> & other) inline void
MultiArray <N, T, A>::swap (MultiArray <N, T, A> & other)
{ {
if (this == &other) if (this == &other)
return; return;
std::swap(this->m_shape, other.m_shape); std::swap(this->m_shape, other.m_shape);
std::swap(this->m_stride, other.m_stride); std::swap(this->m_stride, other.m_stride);
std::swap(this->m_ptr, other.m_ptr); std::swap(this->m_ptr, other.m_ptr);
std::swap(this->m_alloc, other.m_alloc); std::swap(this->m_alloc, other.m_alloc);
} }
template <unsigned int N, class T, class A> template <unsigned int N, class T, class A>
void MultiArray <N, T, A>::allocate (pointer & ptr, std::size_t s, void MultiArray <N, T, A>::allocate (pointer & ptr, difference_type_1 s,
const_reference init) const_reference init)
{ {
ptr = m_alloc.allocate (s); ptr = m_alloc.allocate ((typename A::size_type)s);
std::size_t i; difference_type_1 i;
try { try {
for (i = 0; i < s; ++i) for (i = 0; i < s; ++i)
m_alloc.construct (ptr + i, init); m_alloc.construct (ptr + i, init);
} }
catch (...) { catch (...) {
for (std::size_t j = 0; j < i; ++j) for (difference_type_1 j = 0; j < i; ++j)
m_alloc.destroy (ptr + j); m_alloc.destroy (ptr + j);
m_alloc.deallocate (ptr, s); m_alloc.deallocate (ptr, (typename A::size_type)s);
throw; throw;
} }
} }
template <unsigned int N, class T, class A> template <unsigned int N, class T, class A>
template <class U> template <class U>
void MultiArray <N, T, A>::allocate (pointer & ptr, std::size_t s, void MultiArray <N, T, A>::allocate (pointer & ptr, difference_type_1 s,
U const * init) U const * init)
{ {
ptr = m_alloc.allocate (s); ptr = m_alloc.allocate ((typename A::size_type)s);
std::size_t i; difference_type_1 i;
try { try {
for (i = 0; i < s; ++i, ++init) for (i = 0; i < s; ++i, ++init)
m_alloc.construct (ptr + i, *init); m_alloc.construct (ptr + i, *init);
} }
catch (...) { catch (...) {
for (std::size_t j = 0; j < i; ++j) for (difference_type_1 j = 0; j < i; ++j)
m_alloc.destroy (ptr + j); m_alloc.destroy (ptr + j);
m_alloc.deallocate (ptr, s); m_alloc.deallocate (ptr, (typename A::size_type)s);
throw; throw;
} }
} }
template <unsigned int N, class T, class A> template <unsigned int N, class T, class A>
template <class U, class C> template <class U, class C>
void MultiArray <N, T, A>::allocate (pointer & ptr, MultiArrayView<N, U, C> const & init) void MultiArray <N, T, A>::allocate (pointer & ptr, MultiArrayView<N, U, C> const & init)
{ {
std::size_t s = init.elementCount(); difference_type_1 s = init.elementCount();
ptr = m_alloc.allocate (s); ptr = m_alloc.allocate ((typename A::size_type)s);
pointer p = ptr; pointer p = ptr;
try { try {
detail::uninitializedCopyMultiArrayData(init.traverser_begin(), ini t.shape(), detail::uninitializedCopyMultiArrayData(init.traverser_begin(), ini t.shape(),
p, m_alloc, MetaInt<actual_ dimension-1>()); p, m_alloc, MetaInt<actual_ dimension-1>());
} }
catch (...) { catch (...) {
for (pointer pp = ptr; pp < p; ++pp) for (pointer pp = ptr; pp < p; ++pp)
m_alloc.destroy (pp); m_alloc.destroy (pp);
m_alloc.deallocate (ptr, s); m_alloc.deallocate (ptr, (typename A::size_type)s);
throw; throw;
} }
} }
template <unsigned int N, class T, class A> template <unsigned int N, class T, class A>
void MultiArray <N, T, A>::deallocate (pointer & ptr, std::size_t s) inline void MultiArray <N, T, A>::deallocate (pointer & ptr, difference_typ e_1 s)
{ {
if (ptr == 0) if (ptr == 0)
return; return;
for (std::size_t i = 0; i < s; ++i) for (difference_type_1 i = 0; i < s; ++i)
m_alloc.destroy (ptr + i); m_alloc.destroy (ptr + i);
m_alloc.deallocate (ptr, s); m_alloc.deallocate (ptr, (typename A::size_type)s);
ptr = 0; ptr = 0;
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* NormTraits */
/* */
/********************************************************/
template <unsigned int N, class T, class A>
struct NormTraits<MultiArray <N, T, A> >
{
typedef MultiArray <N, T, A> Type;
typedef typename Type::SquaredNormType SquaredNormType;
typedef typename Type::NormType NormType;
};
/********************************************************/
/* */
/* argument object factories */ /* argument object factories */
/* */ /* */
/********************************************************/ /********************************************************/
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
inline triple<typename MultiArrayView<N,T,C>::const_traverser, inline triple<typename MultiArrayView<N,T,C>::const_traverser,
typename MultiArrayView<N,T,C>::difference_type, typename MultiArrayView<N,T,C>::difference_type,
typename AccessorTraits<T>::default_const_accessor > typename AccessorTraits<T>::default_const_accessor >
srcMultiArrayRange( MultiArrayView<N,T,C> const & array ) srcMultiArrayRange( MultiArrayView<N,T,C> const & array )
{ {
return triple<typename MultiArrayView<N,T,C>::const_traverser, return triple<typename MultiArrayView<N,T,C>::const_traverser,
typename MultiArrayView<N,T,C>::difference_type, typename MultiArrayView<N,T,C>::difference_type,
typename AccessorTraits<T>::default_const_accessor > typename AccessorTraits<T>::default_const_accessor >
( array.traverser_begin(), ( array.traverser_begin(),
array.shape(), array.shape(),
typename AccessorTraits<T>::default_const_accessor() ); typename AccessorTraits<T>::default_const_accessor() );
} }
template <unsigned int N, class T, class C, class Accessor> template <unsigned int N, class T, class C, class Accessor>
inline triple<typename MultiArrayView<N,T,C>::const_traverser, inline triple<typename MultiArrayView<N,T,C>::const_traverser,
typename MultiArrayView<N,T,C>::difference_type, typename MultiArrayView<N,T,C>::difference_type,
Accessor > Accessor >
srcMultiArrayRange( MultiArrayView<N,T,C> const & array, Accessor a ) srcMultiArrayRange( MultiArrayView<N,T,C> const & array, Accessor a )
{ {
return triple<typename MultiArrayView<N,T,C>::const_traverser, return triple<typename MultiArrayView<N,T,C>::const_traverser,
typename MultiArrayView<N,T,C>::difference_type, typename MultiArrayView<N,T,C>::difference_type,
Accessor > Accessor >
( array.traverser_begin(), ( array.traverser_begin(),
array.shape(), array.shape(),
a); a);
} }
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
inline pair<typename MultiArrayView<N,T,C>::const_traverser, inline pair<typename MultiArrayView<N,T,C>::const_traverser,
typename AccessorTraits<T>::default_const_accessor > typename AccessorTraits<T>::default_const_accessor >
srcMultiArray( MultiArrayView<N,T,C> const & array ) srcMultiArray( MultiArrayView<N,T,C> const & array )
{ {
return pair<typename MultiArrayView<N,T,C>::const_traverser, return pair<typename MultiArrayView<N,T,C>::const_traverser,
typename AccessorTraits<T>::default_const_accessor > typename AccessorTraits<T>::default_const_accessor >
( array.traverser_begin(), ( array.traverser_begin(),
typename AccessorTraits<T>::default_const_accessor() ); typename AccessorTraits<T>::default_const_accessor() );
} }
template <unsigned int N, class T, class C, class Accessor> template <unsigned int N, class T, class C, class Accessor>
inline pair<typename MultiArrayView<N,T,C>::const_traverser, inline pair<typename MultiArrayView<N,T,C>::const_traverser,
Accessor > Accessor >
srcMultiArray( MultiArrayView<N,T,C> const & array, Accessor a ) srcMultiArray( MultiArrayView<N,T,C> const & array, Accessor a )
{ {
return pair<typename MultiArrayView<N,T,C>::const_traverser, return pair<typename MultiArrayView<N,T,C>::const_traverser,
Accessor > Accessor >
( array.traverser_begin(), a ); ( array.traverser_begin(), a );
} }
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
inline triple<typename MultiArrayView<N,T,C>::traverser, inline triple<typename MultiArrayView<N,T,C>::traverser,
typename MultiArrayView<N,T,C>::difference_type, typename MultiArrayView<N,T,C>::difference_type,
typename AccessorTraits<T>::default_accessor > typename AccessorTraits<T>::default_accessor >
destMultiArrayRange( MultiArrayView<N,T,C> & array ) destMultiArrayRange( MultiArrayView<N,T,C> & array )
{ {
return triple<typename MultiArrayView<N,T,C>::traverser, return triple<typename MultiArrayView<N,T,C>::traverser,
typename MultiArrayView<N,T,C>::difference_type, typename MultiArrayView<N,T,C>::difference_type,
typename AccessorTraits<T>::default_accessor > typename AccessorTraits<T>::default_accessor >
( array.traverser_begin(), ( array.traverser_begin(),
array.shape(), array.shape(),
typename AccessorTraits<T>::default_accessor() ); typename AccessorTraits<T>::default_accessor() );
} }
template <unsigned int N, class T, class C, class Accessor> template <unsigned int N, class T, class C, class Accessor>
inline triple<typename MultiArrayView<N,T,C>::traverser, inline triple<typename MultiArrayView<N,T,C>::traverser,
typename MultiArrayView<N,T,C>::difference_type, typename MultiArrayView<N,T,C>::difference_type,
Accessor > Accessor >
destMultiArrayRange( MultiArrayView<N,T,C> & array, Accessor a ) destMultiArrayRange( MultiArrayView<N,T,C> & array, Accessor a )
{ {
return triple<typename MultiArrayView<N,T,C>::traverser, return triple<typename MultiArrayView<N,T,C>::traverser,
typename MultiArrayView<N,T,C>::difference_type, typename MultiArrayView<N,T,C>::difference_type,
Accessor > Accessor >
( array.traverser_begin(), ( array.traverser_begin(),
array.shape(), array.shape(),
a ); a );
} }
template <unsigned int N, class T, class C> template <unsigned int N, class T, class C>
inline pair<typename MultiArrayView<N,T,C>::traverser, inline pair<typename MultiArrayView<N,T,C>::traverser,
typename AccessorTraits<T>::default_accessor > typename AccessorTraits<T>::default_accessor >
destMultiArray( MultiArrayView<N,T,C> & array ) destMultiArray( MultiArrayView<N,T,C> & array )
{ {
return pair<typename MultiArrayView<N,T,C>::traverser, return pair<typename MultiArrayView<N,T,C>::traverser,
typename AccessorTraits<T>::default_accessor > typename AccessorTraits<T>::default_accessor >
( array.traverser_begin(), ( array.traverser_begin(),
typename AccessorTraits<T>::default_accessor() ); typename AccessorTraits<T>::default_accessor() );
} }
template <unsigned int N, class T, class C, class Accessor> template <unsigned int N, class T, class C, class Accessor>
inline pair<typename MultiArrayView<N,T,C>::traverser, inline pair<typename MultiArrayView<N,T,C>::traverser,
Accessor > Accessor >
destMultiArray( MultiArrayView<N,T,C> & array, Accessor a ) destMultiArray( MultiArrayView<N,T,C> & array, Accessor a )
{ {
return pair<typename MultiArrayView<N,T,C>::traverser, return pair<typename MultiArrayView<N,T,C>::traverser,
Accessor > Accessor >
( array.traverser_begin(), a ); ( array.traverser_begin(), a );
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* makeBasicImageView */ /* makeBasicImageView */
skipping to change at line 1525 skipping to change at line 2301
return BasicImageView <T> (array.data (), return BasicImageView <T> (array.data (),
array.shape (0)*array.shape (1), array.shape (2)); array.shape (0)*array.shape (1), array.shape (2));
} }
/** Create a \ref vigra::BasicImageView from a 3-dimensional /** Create a \ref vigra::BasicImageView from a 3-dimensional
\ref vigra::MultiArray. \ref vigra::MultiArray.
This wrapper only works if <tt>T</tt> is a scalar type and the This wrapper only works if <tt>T</tt> is a scalar type and the
array's innermost dimension has size 3. It then re-interprets array's innermost dimension has size 3. It then re-interprets
the data array as a 2-dimensional array with value_type the data array as a 2-dimensional array with value_type
<tt>RGBValue< T &gt;</tt>. <tt>RGBValue<T&gt;</tt>.
*/ */
template <class T> template <class T>
BasicImageView <RGBValue<T> > BasicImageView <RGBValue<T> >
makeRGBImageView (MultiArray<3, T> const &array) makeRGBImageView (MultiArray<3, T> const &array)
{ {
vigra_precondition ( vigra_precondition (
array.shape (0) == 3, "makeRGBImageView(): array.shape(0) must be 3 ."); array.shape (0) == 3, "makeRGBImageView(): array.shape(0) must be 3 .");
return BasicImageView <RGBValue<T> > ( return BasicImageView <RGBValue<T> > (
reinterpret_cast <RGBValue <T> *> (array.data ()), reinterpret_cast <RGBValue <T> *> (array.data ()),
array.shape (1), array.shape (2)); array.shape (1), array.shape (2));
 End of changes. 183 change blocks. 
296 lines changed or deleted 1168 lines changed or added


 multi_convolution.hxx   multi_convolution.hxx 
//-- -*- c++ -*- //-- -*- c++ -*-
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2003 by Christian-Dennis Rahn */ /* Copyright 2003 by Christian-Dennis Rahn */
/* and Ullrich Koethe */ /* and Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 181 skipping to change at line 181
// apply each kernel from the sequence `kernels // apply each kernel from the sequence `kernels
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor, class KernelItera tor> class DestIterator, class DestAccessor, class KernelItera tor>
void void
separableConvolveMultiArray(SrcIterator siter, SrcShape const & sha pe, SrcAccessor src, separableConvolveMultiArray(SrcIterator siter, SrcShape const & sha pe, SrcAccessor src,
DestIterator diter, DestAccessor dest, DestIterator diter, DestAccessor dest,
KernelIterator kernels); KernelIterator kernels);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
// apply the same kernel to all dimensions // apply the same kernel to all dimensions
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor, class T> class DestIterator, class DestAccessor, class T>
void void
separableConvolveMultiArray(triple<SrcIterator, SrcShape, SrcAccess or> const & source, separableConvolveMultiArray(triple<SrcIterator, SrcShape, SrcAccess or> const & source,
pair<DestIterator, DestAccessor> const & dest, pair<DestIterator, DestAccessor> const & dest,
Kernel1D<T> const & kernel); Kernel1D<T> const & kernel);
skipping to change at line 204 skipping to change at line 204
class DestIterator, class DestAccessor, class KernelItera tor> class DestIterator, class DestAccessor, class KernelItera tor>
void void
separableConvolveMultiArray(triple<SrcIterator, SrcShape, SrcAccess or> const & source, separableConvolveMultiArray(triple<SrcIterator, SrcShape, SrcAccess or> const & source,
pair<DestIterator, DestAccessor> const & dest, pair<DestIterator, DestAccessor> const & dest,
KernelIterator kernels); KernelIterator kernels);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="multi__convolution_8hxx-source.html">vigra/m ulti_convolution.hxx</a>" <b>\#include</b> \<<a href="multi__convolution_8hxx-source.html">vigra/ multi_convolution.hxx</a>\>
\code \code
MultiArray<3, unsigned char>::size_type shape(width, height, depth); MultiArray<3, unsigned char>::size_type shape(width, height, depth);
MultiArray<3, unsigned char> source(shape); MultiArray<3, unsigned char> source(shape);
MultiArray<3, float> dest(shape); MultiArray<3, float> dest(shape);
... ...
Kernel1D<float> gauss; Kernel1D<float> gauss;
gauss.initGaussian(sigma); gauss.initGaussian(sigma);
// create 3 Gauss kernels, one for each dimension // create 3 Gauss kernels, one for each dimension
ArrayVector<Kernel1D<float> > kernels(3, gauss); ArrayVector<Kernel1D<float> > kernels(3, gauss);
// perform Gaussian smoothing on all dimensions // perform Gaussian smoothing on all dimensions
separableConvolveMultiArray(srcMultiArrayRange(source), destMultiArray( dest), separableConvolveMultiArray(srcMultiArrayRange(source), destMultiArray( dest),
kernels.begin()); kernels.begin());
\endcode \endcode
\see vigra::Kernel1D, convolveLine() \see vigra::Kernel1D, convolveLine()
*/ */
doxygen_overloaded_function(template <...> void separableConvolveMultiArray
)
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor, class KernelIterator> class DestIterator, class DestAccessor, class KernelIterator>
void void
separableConvolveMultiArray( SrcIterator s, SrcShape const & shape, SrcAcce ssor src, separableConvolveMultiArray( SrcIterator s, SrcShape const & shape, SrcAcce ssor src,
DestIterator d, DestAccessor dest, KernelItera tor kernels ) DestIterator d, DestAccessor dest, KernelItera tor kernels )
{ {
typedef typename NumericTraits<typename DestAccessor::value_type>::Real Promote TmpType; typedef typename NumericTraits<typename DestAccessor::value_type>::Real Promote TmpType;
if(!IsSameType<TmpType, typename DestAccessor::value_type>::boolResult) if(!IsSameType<TmpType, typename DestAccessor::value_type>::boolResult)
{ {
skipping to change at line 312 skipping to change at line 314
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor, class T> class DestIterator, class DestAccessor, class T>
void void
convolveMultiArrayOneDimension(SrcIterator siter, SrcShape const & shape, SrcAccessor src, convolveMultiArrayOneDimension(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
DestIterator diter, DestAccessor des t, DestIterator diter, DestAccessor des t,
unsigned int dim, vigra::Kernel1D<T> const & kernel); unsigned int dim, vigra::Kernel1D<T> const & kernel);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor, class T> class DestIterator, class DestAccessor, class T>
void void
convolveMultiArrayOneDimension(triple<SrcIterator, SrcShape, SrcAcc essor> const & source, convolveMultiArrayOneDimension(triple<SrcIterator, SrcShape, SrcAcc essor> const & source,
pair<DestIterator, DestAccessor> con st & dest, pair<DestIterator, DestAccessor> con st & dest,
unsigned int dim, vigra::Kernel1D<T> const & kernel); unsigned int dim, vigra::Kernel1D<T> const & kernel);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="multi__convolution_8hxx-source.html">vigra/m ulti_convolution.hxx</a>" <b>\#include</b> \<<a href="multi__convolution_8hxx-source.html">vigra/ multi_convolution.hxx</a>\>
\code \code
MultiArray<3, unsigned char>::size_type shape(width, height, depth); MultiArray<3, unsigned char>::size_type shape(width, height, depth);
MultiArray<3, unsigned char> source(shape); MultiArray<3, unsigned char> source(shape);
MultiArray<3, float> dest(shape); MultiArray<3, float> dest(shape);
... ...
Kernel1D<float> gauss; Kernel1D<float> gauss;
gauss.initGaussian(sigma); gauss.initGaussian(sigma);
// perform Gaussian smoothing along dimensions 1 (height) // perform Gaussian smoothing along dimensions 1 (height)
convolveMultiArrayOneDimension(srcMultiArrayRange(source), destMultiArr ay(dest), 1, gauss); convolveMultiArrayOneDimension(srcMultiArrayRange(source), destMultiArr ay(dest), 1, gauss);
\endcode \endcode
\see separableConvolveMultiArray() \see separableConvolveMultiArray()
*/ */
doxygen_overloaded_function(template <...> void convolveMultiArrayOneDimens
ion)
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor, class T> class DestIterator, class DestAccessor, class T>
void void
convolveMultiArrayOneDimension(SrcIterator s, SrcShape const & shape, SrcAc cessor src, convolveMultiArrayOneDimension(SrcIterator s, SrcShape const & shape, SrcAc cessor src,
DestIterator d, DestAccessor dest, DestIterator d, DestAccessor dest,
unsigned int dim, vigra::Kernel1D<T> const & kernel ) unsigned int dim, vigra::Kernel1D<T> const & kernel )
{ {
enum { N = 1 + SrcIterator::level }; enum { N = 1 + SrcIterator::level };
vigra_precondition( dim < N, vigra_precondition( dim < N,
"convolveMultiArrayOneDimension(): The dimension nu mber to convolve must be smaller " "convolveMultiArrayOneDimension(): The dimension nu mber to convolve must be smaller "
skipping to change at line 419 skipping to change at line 423
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
gaussianSmoothMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src, gaussianSmoothMultiArray(SrcIterator siter, SrcShape const & shape, SrcAccessor src,
DestIterator diter, DestAccessor dest, DestIterator diter, DestAccessor dest,
double sigma); double sigma);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
gaussianSmoothMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source, gaussianSmoothMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & source,
pair<DestIterator, DestAccessor> const & d est, pair<DestIterator, DestAccessor> const & d est,
double sigma); double sigma);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="multi__convolution_8hxx-source.html">vigra/m ulti_convolution.hxx</a>" <b>\#include</b> \<<a href="multi__convolution_8hxx-source.html">vigra/ multi_convolution.hxx</a>\>
\code \code
MultiArray<3, unsigned char>::size_type shape(width, height, depth); MultiArray<3, unsigned char>::size_type shape(width, height, depth);
MultiArray<3, unsigned char> source(shape); MultiArray<3, unsigned char> source(shape);
MultiArray<3, float> dest(shape); MultiArray<3, float> dest(shape);
... ...
// perform isotropic Gaussian smoothing at scale `sigma // perform isotropic Gaussian smoothing at scale `sigma
gaussianSmoothMultiArray(srcMultiArrayRange(source), destMultiArray(des t), sigma); gaussianSmoothMultiArray(srcMultiArrayRange(source), destMultiArray(des t), sigma);
\endcode \endcode
\see separableConvolveMultiArray() \see separableConvolveMultiArray()
*/ */
doxygen_overloaded_function(template <...> void gaussianSmoothMultiArray)
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
gaussianSmoothMultiArray( SrcIterator s, SrcShape const & shape, SrcAccesso r src, gaussianSmoothMultiArray( SrcIterator s, SrcShape const & shape, SrcAccesso r src,
DestIterator d, DestAccessor dest, double sigma ) DestIterator d, DestAccessor dest, double sigma )
{ {
typedef typename NumericTraits<typename DestAccessor::value_type>::Real Promote kernel_type; typedef typename NumericTraits<typename DestAccessor::value_type>::Real Promote kernel_type;
Kernel1D<kernel_type> gauss; Kernel1D<kernel_type> gauss;
gauss.initGaussian( sigma ); gauss.initGaussian( sigma );
skipping to change at line 504 skipping to change at line 510
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
gaussianGradientMultiArray(SrcIterator siter, SrcShape const & shap e, SrcAccessor src, gaussianGradientMultiArray(SrcIterator siter, SrcShape const & shap e, SrcAccessor src,
DestIterator diter, DestAccessor dest, DestIterator diter, DestAccessor dest,
double sigma); double sigma);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
gaussianGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccesso r> const & source, gaussianGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccesso r> const & source,
pair<DestIterator, DestAccessor> const & dest, pair<DestIterator, DestAccessor> const & dest,
double sigma); double sigma);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="multi__convolution_8hxx-source.html">vigra/m ulti_convolution.hxx</a>" <b>\#include</b> \<<a href="multi__convolution_8hxx-source.html">vigra/ multi_convolution.hxx</a>\>
\code \code
MultiArray<3, unsigned char>::size_type shape(width, height, depth); MultiArray<3, unsigned char>::size_type shape(width, height, depth);
MultiArray<3, unsigned char> source(shape); MultiArray<3, unsigned char> source(shape);
MultiArray<3, TinyVector<float, 3> > dest(shape); MultiArray<3, TinyVector<float, 3> > dest(shape);
... ...
// compute Gaussian gradient at scale sigma // compute Gaussian gradient at scale sigma
gaussianGradientMultiArray(srcMultiArrayRange(source), destMultiArray(d est), sigma); gaussianGradientMultiArray(srcMultiArrayRange(source), destMultiArray(d est), sigma);
\endcode \endcode
skipping to change at line 540 skipping to change at line 546
see \ref convolveImage(), in addition: see \ref convolveImage(), in addition:
\code \code
int dimension = 0; int dimension = 0;
VectorElementAccessor<DestAccessor> elementAccessor(0, dest); VectorElementAccessor<DestAccessor> elementAccessor(0, dest);
\endcode \endcode
\see separableConvolveMultiArray() \see separableConvolveMultiArray()
*/ */
doxygen_overloaded_function(template <...> void gaussianGradientMultiArray)
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
gaussianGradientMultiArray( SrcIterator si, SrcShape const & shape, SrcAcce ssor src, gaussianGradientMultiArray( SrcIterator si, SrcShape const & shape, SrcAcce ssor src,
DestIterator di, DestAccessor dest, double sigma ) DestIterator di, DestAccessor dest, double sigma )
{ {
typedef typename DestAccessor::value_type DestType; typedef typename DestAccessor::value_type DestType;
typedef typename NumericTraits<typename DestType::value_type>::RealProm ote kernel_type; typedef typename NumericTraits<typename DestType::value_type>::RealProm ote kernel_type;
Kernel1D<kernel_type> gauss, derivative; Kernel1D<kernel_type> gauss, derivative;
skipping to change at line 603 skipping to change at line 611
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
symmetricGradientMultiArray(SrcIterator siter, SrcShape const & sha pe, SrcAccessor src, symmetricGradientMultiArray(SrcIterator siter, SrcShape const & sha pe, SrcAccessor src,
DestIterator diter, DestAccessor dest); DestIterator diter, DestAccessor dest);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
symmetricGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccess or> const & source, symmetricGradientMultiArray(triple<SrcIterator, SrcShape, SrcAccess or> const & source,
pair<DestIterator, DestAccessor> const & dest); pair<DestIterator, DestAccessor> const & dest);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="multi__convolution_8hxx-source.html">vigra/m ulti_convolution.hxx</a>" <b>\#include</b> \<<a href="multi__convolution_8hxx-source.html">vigra/ multi_convolution.hxx</a>\>
\code \code
MultiArray<3, unsigned char>::size_type shape(width, height, depth); MultiArray<3, unsigned char>::size_type shape(width, height, depth);
MultiArray<3, unsigned char> source(shape); MultiArray<3, unsigned char> source(shape);
MultiArray<3, TinyVector<float, 3> > dest(shape); MultiArray<3, TinyVector<float, 3> > dest(shape);
... ...
// compute gradient // compute gradient
symmetricGradientMultiArray(srcMultiArrayRange(source), destMultiArray( dest)); symmetricGradientMultiArray(srcMultiArrayRange(source), destMultiArray( dest));
\endcode \endcode
skipping to change at line 638 skipping to change at line 646
see \ref convolveImage(), in addition: see \ref convolveImage(), in addition:
\code \code
int dimension = 0; int dimension = 0;
VectorElementAccessor<DestAccessor> elementAccessor(0, dest); VectorElementAccessor<DestAccessor> elementAccessor(0, dest);
\endcode \endcode
\see convolveMultiArrayOneDimension() \see convolveMultiArrayOneDimension()
*/ */
doxygen_overloaded_function(template <...> void symmetricGradientMultiArray
)
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
symmetricGradientMultiArray(SrcIterator si, SrcShape const & shape, SrcAcce ssor src, symmetricGradientMultiArray(SrcIterator si, SrcShape const & shape, SrcAcce ssor src,
DestIterator di, DestAccessor dest) DestIterator di, DestAccessor dest)
{ {
typedef typename DestAccessor::value_type DestType; typedef typename DestAccessor::value_type DestType;
typedef typename NumericTraits<typename DestType::value_type>::RealProm ote kernel_type; typedef typename NumericTraits<typename DestType::value_type>::RealProm ote kernel_type;
Kernel1D<kernel_type> filter; Kernel1D<kernel_type> filter;
 End of changes. 17 change blocks. 
13 lines changed or deleted 26 lines changed or added


 multi_impex.hxx   multi_impex.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2003 by Gunnar Kedenburg */ /* Copyright 2003 by Gunnar Kedenburg */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 46 skipping to change at line 46
/************************************************************************/ /************************************************************************/
#ifndef VIGRA_MULTI_IMPEX_HXX #ifndef VIGRA_MULTI_IMPEX_HXX
#define VIGRA_MULTI_IMPEX_HXX #define VIGRA_MULTI_IMPEX_HXX
#include <memory> #include <memory>
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <fstream>
#include "config.hxx" #include "config.hxx"
#include "basicimageview.hxx" #include "basicimageview.hxx"
#include "impex.hxx" #include "impex.hxx"
#include "multi_array.hxx" #include "multi_array.hxx"
#include "multi_pointoperators.hxx"
#ifdef _MSC_VER
# include <direct.h>
#else
# include <unistd.h>
#endif
namespace vigra { namespace vigra {
class VolumeImportInfo
{
public:
typedef ImageImportInfo::PixelType PixelType;
/// type of volume size returned by shape()
typedef MultiArrayShape<3>::type ShapeType;
/// provided for backwards-compatibility (deprecated)
typedef ShapeType size_type;
/// 3D resolution type returned by resolution()
typedef TinyVector<float, 3> Resolution;
VIGRA_EXPORT VolumeImportInfo(const std::string &filename);
VIGRA_EXPORT VolumeImportInfo(const std::string &baseName, const std::s
tring &extension);
VIGRA_EXPORT ShapeType shape() const { return shape_; }
/**
* resolution() contains the alignment and resolution of the
* volume. resolution()[0] is the x increment in a left-handed
* world coordinate system of one unstrided step in the volume
* memory. The [1] and [2] elements contain the y resp. z
* increments of the strided row resp. slice steps in the
* volume.
*
* EXAMPLES: (1.f, 1.f, 4.f) means that the slices are four
* times thicker than the x/y resolution.
* (1.f, -1.f, 1.f) means that the volume coordinate system is
* right-handed.
*/
VIGRA_EXPORT Resolution resolution() const { return resolution_; }
VIGRA_EXPORT PixelType pixelType() const { return pixelType_; }
VIGRA_EXPORT int numBands() const { return numBands_; }
VIGRA_EXPORT bool isGrayscale() const { return numBands_ == 1; }
VIGRA_EXPORT bool isColor() const { return numBands_ > 1; }
// get base file name without path, image index, and extension
VIGRA_EXPORT const std::string &name() const { return name_; }
VIGRA_EXPORT const std::string &description() const { return descriptio
n_; }
template <class T, class Allocator>
void importImpl(MultiArray <3, T, Allocator> &volume) const;
protected:
void getVolumeInfoFromFirstSlice(const std::string &filename);
size_type shape_;
Resolution resolution_;
PixelType pixelType_;
int numBands_;
std::string path_, name_, description_;
std::string rawFilename_;
std::string baseName_, extension_;
std::vector<std::string> numbers_;
};
template <class T, class Allocator>
void VolumeImportInfo::importImpl(MultiArray <3, T, Allocator> &volume) con
st
{
volume.reshape(this->shape());
if(rawFilename_.size())
{
std::string dirName, baseName;
char oldCWD[2048];
#ifdef _MSC_VER
_getcwd(oldCWD, 2048);
if(_chdir(path_.c_str()))
perror("chdir");
#else
getcwd(oldCWD, 2048);
if(chdir(path_.c_str()))
perror("chdir");
#endif
std::ifstream s(rawFilename_.c_str(), std::ios::binary);
vigra_precondition(s.good(), "RAW file could not be opened");
s.read((char*)volume.begin(), shape_[0]*shape_[1]*shape_[2]*sizeof(
T));
#ifdef _MSC_VER
_chdir(oldCWD);
#else
chdir(oldCWD);
#endif
vigra_postcondition(
volume.shape() == shape(), "imported volume has wrong size");
}
else
{
for (unsigned int i = 0; i < numbers_.size(); ++i)
{
// build the filename
std::string name = baseName_ + numbers_[i] + extension_;
// import the image
ImageImportInfo info (name.c_str ());
// generate a basic image view to the current layer
MultiArrayView <2, T> array_view (volume.bindOuter (i));
BasicImageView <T> view = makeBasicImageView (array_view);
vigra_precondition(view.size() == info.size(),
"importVolume(): image size mismatch.");
importImage (info, destImage(view));
}
}
}
VIGRA_EXPORT void findImageSequence(const std::string &name_base, VIGRA_EXPORT void findImageSequence(const std::string &name_base,
const std::string &name_ext, const std::string &name_ext,
std::vector<std::string> & numbers); std::vector<std::string> & numbers);
/** \addtogroup VolumeImpex Import/export of volume data. /** \addtogroup VolumeImpex Import/export of volume data.
*/ */
//@{ //@{
/********************************************************/ /********************************************************/
skipping to change at line 80 skipping to change at line 206
The data are expected to be stored in a by-slice manner, The data are expected to be stored in a by-slice manner,
where the slices are enumerated from <tt>name_base+"[0-9]+"+name_ext</t t>. where the slices are enumerated from <tt>name_base+"[0-9]+"+name_ext</t t>.
<tt>name_base</tt> may contain a path. All slice files with the same na me base and <tt>name_base</tt> may contain a path. All slice files with the same na me base and
extension are considered part of the same volume. Slice numbers must be non-negative, extension are considered part of the same volume. Slice numbers must be non-negative,
but can otherwise start anywhere and need not be successive. Slices wil l be read but can otherwise start anywhere and need not be successive. Slices wil l be read
in ascending numerical (not lexicographic) order. All slices must have the in ascending numerical (not lexicographic) order. All slices must have the
same size. The <tt>volume</tt> will be reshaped to match the count and same size. The <tt>volume</tt> will be reshaped to match the count and
size of the slices found. size of the slices found.
<b>\#include</b> <b>\#include</b>
"<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>" \<<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class T, class Allocator> template <class T, class Allocator>
void importVolume (MultiArray <3, T, Allocator> & volume, void importVolume (MultiArray <3, T, Allocator> & volume,
const std::string &name_base, const std::string &name_base,
const std::string &name_ext) const std::string &name_ext)
{ {
std::vector<std::string> numbers; VolumeImportInfo info(name_base, name_ext);
findImageSequence(name_base, name_ext, numbers);
std::string message("importVolume(): No files matching '"); info.importImpl(volume);
message += name_base + "[0-9]+" + name_ext + "' found."; }
vigra_precondition(numbers.size() > 0, message.c_str());
for (unsigned int i = 0; i < numbers.size(); ++i) /** \brief Function for importing a 3D volume.
The data can be given in two ways:
<UL>
<LI> If the volume is stored in a by-slice manner (e.g. one image per s
lice),
the <tt>filename</tt> can refer to an arbitrary image from the set
. <tt>importVolume()</tt>
then assumes that the slices are enumerated like <tt>name_base+"[0
-9]+"+name_ext</tt>,
where <tt>name_base</tt>, the index, and <tt>name_ext</tt> are det
ermined automatically.
All slice files with the same name base and extension are consider
ed part of the same
volume. Slice numbers must be non-negative, but can otherwise star
t anywhere and need
not be successive. Slices will be read in ascending numerical (not
lexicographic) order.
All slices must have the same size.
<li> Otherwise, <tt>importVolume()</tt> will try to read <tt>filename</
tt> as an
info text file with the following key-value pairs:
<UL>
<LI> name = [short descriptive name of the volume] (optional)
<LI> filename = [absolute or relative path to raw voxel data file]
(required)
<li> gradfile = [absolute or relative path to gradient data file]
(currently ignored)
<li> description = [arbitrary description of the data set] (optio
nal)
<li> width = [positive integer] (required)
<li> height = [positive integer] (required)
<li> depth = [positive integer] (required)
<li> datatype = [UNSIGNED_CHAR | UNSIGNED_BYTE] (default: UNSIGNED
_CHAR)
</UL>
The voxel type is currently assumed to be binary compatible to the
<tt>value_type T</TT>
of the <tt>MuliArray</tt>. Lines starting with "#" are ignored.
</UL>
In either case, the <tt>volume</tt> will be reshaped to match the count
and
size of the slices found.
<b>\#include</b>
\<<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>\>
Namespace: vigra
*/
template <class T, class Allocator>
void importVolume(MultiArray <3, T, Allocator> &volume,
const std::string &filename)
{
VolumeImportInfo info(filename);
info.importImpl(volume);
}
/** \brief Function for importing a 3D volume.
Read the volume data set <tt>info</tt> refers to. Explicit construction
of the info object allows to allocate a <tt>volume</tt> object type who
se
<tt>value_type</tt> matches the voxel type of the stored data.
The <tt>volume</tt> will be reshaped to match the count and
size of the slices found.
<b>\#include</b>
\<<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>\>
Namespace: vigra
*/
template <class T, class Allocator>
void importVolume(VolumeImportInfo const & info, MultiArray <3, T, Allocato
r> &volume)
{
info.importImpl(volume);
}
namespace detail {
template <class T>
void setRangeMapping(std::string const & pixeltype,
FindMinMax<T> const & minmax, ImageExportInfo & info)
{
if(pixeltype == "UINT8")
info.setForcedRangeMapping(minmax.min, minmax.max,
(double)NumericTraits<Int8>::min(),
(double)NumericTraits<Int8>::max());
else if(pixeltype == "INT16")
info.setForcedRangeMapping(minmax.min, minmax.max,
(double)NumericTraits<Int16>::min(),
(double)NumericTraits<Int16>::max());
else if(pixeltype == "UINT16")
info.setForcedRangeMapping(minmax.min, minmax.max,
(double)NumericTraits<UInt16>::min(),
(double)NumericTraits<UInt16>::max());
else if(pixeltype == "INT32")
info.setForcedRangeMapping(minmax.min, minmax.max,
(double)NumericTraits<Int32>::min(),
(double)NumericTraits<Int32>::max());
else if(pixeltype == "UINT32")
info.setForcedRangeMapping(minmax.min, minmax.max,
(double)NumericTraits<UInt32>::min(),
(double)NumericTraits<UInt32>::max());
else if(pixeltype == "FLOAT")
info.setForcedRangeMapping(minmax.min, minmax.max, 0.0, 1.0);
else if(pixeltype == "DOUBLE")
info.setForcedRangeMapping(minmax.min, minmax.max, 0.0, 1.0);
}
template <class T, class Tag>
void setRangeMapping(MultiArrayView <3, T, Tag> const & volume,
ImageExportInfo & info, VigraTrueType /* isScalar */)
{
std::string pixeltype = info.getPixelType();
bool downcast = negotiatePixelType(getEncoderType(info.getFileName(), i
nfo.getFileType()),
TypeAsString<T>::result(), pixeltype
);
if(downcast)
{ {
// build the filename FindMinMax<T> minmax;
std::string name = name_base + numbers[i] + name_ext; inspectMultiArray(srcMultiArrayRange(volume), minmax);
setRangeMapping(pixeltype, minmax, info);
}
}
// import the image template <class T, class Tag>
ImageImportInfo info (name.c_str ()); void setRangeMapping(MultiArrayView <3, T, Tag> const & volume,
ImageExportInfo & info, VigraFalseType /* isScalar */)
{
typedef typename T::value_type SrcComponent;
std::string pixeltype = info.getPixelType();
bool downcast = negotiatePixelType(getEncoderType(info.getFileName(), i
nfo.getFileType()),
TypeAsString<SrcComponent>::result()
, pixeltype);
// reshape the array according to size of first image if(downcast)
if(i == 0) {
unsigned int bands = volume(0,0,0).size();
FindMinMax<SrcComponent> minmax;
for(unsigned int i=0; i<bands; ++i)
{ {
typedef typename MultiArray <3, T>::difference_type Size; VectorComponentValueAccessor<T> band(i);
volume.reshape(Size(info.width(), info.height(), numbers.size() inspectMultiArray(srcMultiArrayRange(volume, band), minmax );
));
} }
setRangeMapping(pixeltype, minmax, info);
// generate a basic image view to the current layer
MultiArrayView <2, T> array_view (volume.bindOuter (i));
BasicImageView <T> view = makeBasicImageView (array_view);
vigra_precondition(view.size() == info.size(),
"importVolume(): image size mismatch.");
importImage (info, destImage(view));
} }
} }
} // namespace detail
/********************************************************/ /********************************************************/
/* */ /* */
/* exportVolume */ /* exportVolume */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Function for exporting a 3D volume. /** \brief Function for exporting a 3D volume.
The volume is exported in a by-slice manner, where the number of slices equals The volume is exported in a by-slice manner, where the number of slices equals
the depth of the volume. The file names will be enumerated like the depth of the volume. The file names will be enumerated like
<tt>name_base+"000"+name_ext</tt>, <tt>name_base+"001"+name_ext</tt> et c. <tt>name_base+"000"+name_ext</tt>, <tt>name_base+"001"+name_ext</tt> et c.
(the actual number of zeros depends on the depth). (the actual number of zeros depends on the depth). If the target image
type
does not support the source voxel type, all slices will be mapped simul
taneously
to the appropriate target range.
<b>\#include</b> <b>\#include</b>
"<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>" \<<a href="multi__impex_8hxx-source.html">vigra/multi_impex.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <class T, class Tag> template <class T, class Tag>
void exportVolume (MultiArrayView <3, T, Tag> const & volume, void exportVolume (MultiArrayView <3, T, Tag> const & volume,
const std::string &name_base, const std::string &name_base,
const std::string &name_ext) const std::string &name_ext)
{ {
std::string name = name_base + name_ext;
ImageExportInfo info(name.c_str());
detail::setRangeMapping(volume, info, typename NumericTraits<T>::isScal
ar());
const unsigned int depth = volume.shape (2); const unsigned int depth = volume.shape (2);
int numlen = static_cast <int> (std::ceil (std::log10 ((double)depth))) ; int numlen = static_cast <int> (std::ceil (std::log10 ((double)depth))) ;
for (unsigned int i = 0; i < depth; ++i) for (unsigned int i = 0; i < depth; ++i)
{ {
// build the filename // build the filename
std::stringstream stream; std::stringstream stream;
stream << std::setfill ('0') << std::setw (numlen) << i; stream << std::setfill ('0') << std::setw (numlen) << i;
std::string name_num; std::string name_num;
stream >> name_num; stream >> name_num;
std::string name = name_base + name_num + name_ext; std::string name = name_base + name_num + name_ext;
if(i == 0)
{
}
// generate a basic image view to the current layer // generate a basic image view to the current layer
MultiArrayView <2, T, Tag> array_view (volume.bindOuter (i)); MultiArrayView <2, T, Tag> array_view (volume.bindOuter (i));
BasicImageView <T> view = makeBasicImageView (array_view); BasicImageView <T> view = makeBasicImageView (array_view);
// export the image // export the image
ImageExportInfo info(name.c_str ()); info.setFileName(name.c_str ());
exportImage(srcImageRange(view), info); exportImage(srcImageRange(view), info);
} }
} }
//@} //@}
} // namespace vigra } // namespace vigra
#endif // VIGRA_MULTI_IMPEX_HXX #endif // VIGRA_MULTI_IMPEX_HXX
 End of changes. 20 change blocks. 
30 lines changed or deleted 301 lines changed or added


 multi_iterator.hxx   multi_iterator.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2003 by Gunnar Kedenburg */ /* Copyright 2003-2008 by Gunnar Kedenburg and Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* ( Version 1.3.0, Sep 10 2004 ) */ /* ( Version 1.3.0, Sep 10 2004 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 58 skipping to change at line 57
template <unsigned int N, class T, template <unsigned int N, class T,
class REFERENCE = T &, class POINTER = T *> class MultiIterator; class REFERENCE = T &, class POINTER = T *> class MultiIterator;
template <unsigned int N, class T, template <unsigned int N, class T,
class REFERENCE = T &, class POINTER = T *> class StridedMultiIte rator; class REFERENCE = T &, class POINTER = T *> class StridedMultiIte rator;
/** \page MultiIteratorPage Multi-dimensional Array Iterators /** \page MultiIteratorPage Multi-dimensional Array Iterators
General iterators for arrays of arbitrary dimension. General iterators for arrays of arbitrary dimension.
<p> <p>
<DL> <UL style="list-style-image:url(documents/bullet.gif)">
<DT> <LI> \ref vigra::MultiArrayShape
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <BR>&nbsp;&nbsp;&nbsp;<em>Iterator for unstrided \ref vigra::MultiArra
\ref vigra::MultiIterator yView</em>
<DD> <em>Iterator for unstrided \ref vigra::MultiArrayView</em> <LI> \ref vigra::MultiIterator
<DT> <BR>&nbsp;&nbsp;&nbsp;<em>Iterator for unstrided \ref vigra::MultiArra
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> yView</em>
\ref vigra::MultiIteratorBase::type <LI> \ref vigra::StridedMultiIterator
<DD> <em>Inner class implementing most of the functionality of \ref vig <BR>&nbsp;&nbsp;&nbsp;<em>Iterator for strided \ref vigra::MultiArrayV
ra::MultiIterator</em> iew</em>
<DT> </UL>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref vigra::StridedMultiIterator
<DD> <em>Iterator for strided \ref vigra::MultiArrayView</em>
<DT>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref vigra::StridedMultiIteratorBase::type
<DD> <em>Inner class implementing most of the functionality of \ref vig
ra::StridedMultiIterator</em>
</DL>
</p> </p>
<p> <p>
The Multidimensional Iterator concept allows navigation on arrays The Multidimensional Iterator concept allows navigation on arrays
of arbitrary dimension. It provides two modes of iteration: of arbitrary dimension. It provides two modes of iteration:
<em>direct traveral</em>, and <em>hierarchical traversal</em>. <em>direct traveral</em>, and <em>hierarchical traversal</em>.
In general, hierarchical traversal will be faster, while only In general, hierarchical traversal will be faster, while only
direct traversal allows for true random access in all dimensions. direct traversal allows for true random access in all dimensions.
Via the <tt>dim<K>()</tt> function, operations applying to a particular Via the <tt>dim<K>()</tt> function, operations applying to a particular
dimension can be used in the direct traversal mode. In contrast, dimension can be used in the direct traversal mode. In contrast,
direct traversal functions should not be used in the hierarchical mode direct traversal functions should not be used in the hierarchical mode
because the hierarchical functions are only well-defined if the because the hierarchical functions are only well-defined if the
iterator points to element 0 in all dimensions below its current dimens ion. iterator points to element 0 in all dimensions below its current dimens ion.
The current dimension of a <tt>MultiIterator<N, ..&gt;</tt> is <tt>N -1</tt>. The current dimension of a <tt>MultiIterator<N, ...></tt> is <tt>N-1</t t>.
</p> </p>
<h3>Gerneral Requirements for MultiIterator</h3> <h3>Gerneral Requirements for MultiIterator</h3>
<p> <p>
<table border=2 cellspacing=0 cellpadding=2 width="100%"> <table border=2 cellspacing=0 cellpadding=2 width="100%">
<tr><td> <tr><th colspan=2>
\htmlonly
<th colspan=2>
\endhtmlonly
Local Types Local Types
\htmlonly
</th><th> </th><th>
\endhtmlonly
Meaning Meaning
\htmlonly
</th> </th>
\endhtmlonly </tr>
</td></tr> <tr><td colspan=2>
<tr><td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>MultiIterator::value_type</tt></td><td>the underlying arrays's pixe l type</td> <tt>MultiIterator::value_type</tt></td><td>the underlying arrays's pixe l type</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>MultiIterator::reference</tt></td> <tt>MultiIterator::reference</tt></td>
<td>the iterator's reference type (return type of <TT>*iter</TT>). Will be <td>the iterator's reference type (return type of <TT>*iter</TT>). Will be
<tt>value_type &</tt> for a mutable iterator, and convertible to <tt>value_type &</tt> for a mutable iterator, and convertible to
<tt>value_type const &</tt> for a const iterator.</td> <tt>value_type const &</tt> for a const iterator.</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>MultiIterator::pointer</tt></td> <tt>MultiIterator::pointer</tt></td>
<td>the iterator's pointer type (return type of <TT>iter.operator->()</ TT>). Will be <td>the iterator's pointer type (return type of <TT>iter.operator->()</ TT>). Will be
<tt>value_type *</tt> for a mutable iterator, and convertible to <tt>value_type *</tt> for a mutable iterator, and convertible to
<tt>value_type const *</tt> for a const iterator.</td> <tt>value_type const *</tt> for a const iterator.</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>MultiIterator::iterator_category</tt></td> <tt>MultiIterator::iterator_category</tt></td>
<td>the iterator tag (<tt>vigra::multi_dimensional_traverser_tag</tt>)< /td> <td>the iterator tag (<tt>vigra::multi_dimensional_traverser_tag</tt>)< /td>
</tr> </tr>
<tr><td> <tr><th>
\htmlonly
<th>
\endhtmlonly
Operation Operation
\htmlonly
</th><th> </th><th>
\endhtmlonly
Result Result
\htmlonly
</th><th> </th><th>
\endhtmlonly
Semantics Semantics
\htmlonly
</th> </th>
\endhtmlonly </tr>
</td></tr> <tr><td colspan=2>
<tr><td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>MultiIterator k;</tt></td><td>default constructor</td> <tt>MultiIterator k;</tt></td><td>default constructor</td>
</tr> </tr>
<tr><td> <tr><td colspan=2>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>MultiIterator k(i);</tt></td><td>copy constructor</td> <tt>MultiIterator k(i);</tt></td><td>copy constructor</td>
</tr> </tr>
<tr> <tr>
<td><tt>k = i</tt></td> <td><tt>k = i</tt></td>
<td><tt>MultiIterator &</tt></td><td>assignment</td> <td><tt>MultiIterator &</tt></td><td>assignment</td>
</tr> </tr>
<tr> <tr>
<td><tt>i == j</tt></td><td><tt>bool</tt></td> <td><tt>i == j</tt></td><td><tt>bool</tt></td>
<td>equality (iterators point to the same element)</td> <td>equality (iterators point to the same element)</td>
</tr> </tr>
skipping to change at line 195 skipping to change at line 147
</tr> </tr>
<tr> <tr>
<td><tt>i->member()</tt></td><td>depends on operation</td> <td><tt>i->member()</tt></td><td>depends on operation</td>
<td>call member function of underlying pixel type via <tt>operator-></t t> of iterator</td> <td>call member function of underlying pixel type via <tt>operator-></t t> of iterator</td>
</tr> </tr>
</table> </table>
</p> </p>
<h3>Requirements for Direct Traversal</h3> <h3>Requirements for Direct Traversal</h3>
<p> <p>
<table border=2 cellspacing=0 cellpadding=2 width="100%"> <table border=2 cellspacing=0 cellpadding=2 width="100%">
<tr><td> <tr><th colspan=2>
\htmlonly
<th colspan=2>
\endhtmlonly
Local Types Local Types
\htmlonly
</th><th> </th><th>
\endhtmlonly
Meaning Meaning
\htmlonly
</th> </th>
\endhtmlonly </tr>
</td></tr> <tr><td colspan=2>
<tr><td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>MultiIterator::multi_difference_type</tt></td> <tt>MultiIterator::multi_difference_type</tt></td>
<td>the iterator's multi-dimensional difference type (<TT>TinyVector< ;ptrdiff_t, N&gt;</TT>)</td> <td>the iterator's multi-dimensional difference type (<TT>TinyVector<Mu ltiArrayIndex, N&gt;</TT>)</td>
</tr> </tr>
<tr><td> <tr><th>
\htmlonly
<th>
\endhtmlonly
Operation Operation
\htmlonly
</th><th> </th><th>
\endhtmlonly
Result Result
\htmlonly
</th><th> </th><th>
\endhtmlonly
Semantics Semantics
\htmlonly
</th> </th>
\endhtmlonly </tr>
</td></tr>
<tr> <tr>
<td><tt>i += diff</tt></td><td><tt>MultiIterator &</tt></td> <td><tt>i += diff</tt></td><td><tt>MultiIterator &</tt></td>
<td>add offset to current position</td> <td>add offset to current position</td>
</tr> </tr>
<tr> <tr>
<td><tt>i -= diff</tt></td><td><tt>MultiIterator &</tt></td> <td><tt>i -= diff</tt></td><td><tt>MultiIterator &</tt></td>
<td>subtract offset from current position</td> <td>subtract offset from current position</td>
</tr> </tr>
<tr> <tr>
<td><tt>i + diff</tt></td><td><tt>MultiIterator</tt></td> <td><tt>i + diff</tt></td><td><tt>MultiIterator</tt></td>
skipping to change at line 253 skipping to change at line 186
</tr> </tr>
<tr> <tr>
<td><tt>i - diff</tt></td><td><tt>MultiIterator</tt></td> <td><tt>i - diff</tt></td><td><tt>MultiIterator</tt></td>
<td>create traverser by subtracting offset</td> <td>create traverser by subtracting offset</td>
</tr> </tr>
<tr> <tr>
<td><tt>i[diff]</tt></td><td><tt>MultiIterator::reference</tt></td> <td><tt>i[diff]</tt></td><td><tt>MultiIterator::reference</tt></td>
<td>access element at offset <tt>diff</tt></td> <td>access element at offset <tt>diff</tt></td>
</tr> </tr>
<tr> <tr>
<td><tt>i.dim<K>()</tt></td><td><tt>MultiIterator<K+1, T, ...&gt;</t t></td> <td><tt>i.dim<K>()</tt></td><td><tt>MultiIterator<K+1, T, ...></tt></td >
<td>Access the traverser with the current dimension set to K. Typically used to call <td>Access the traverser with the current dimension set to K. Typically used to call
navigation functions referring to a particular dimension.<br> navigation functions referring to a particular dimension.<br>
Example (assuming <tt>i, j</tt> are 3-dimensional):<br> Example (assuming <tt>i, j</tt> are 3-dimensional):<br>
\code \code
i.dim<0>()++; // increment dimension 0 i.dim<0>()++; // increment dimension 0
i.dim<1>()++; // increment dimension 1 i.dim<1>()++; // increment dimension 1
i.dim<2>()++; // increment dimension 2 i.dim<2>()++; // increment dimension 2
j += MultiIterator::multi_difference_type(1,1,1); // same effect j += MultiIterator::multi_difference_type(1,1,1); // same effect
\endcode \endcode
</td> </td>
</tr> </tr>
<tr><td> <tr><td colspan=3>
\htmlonly
<td colspan=3>
\endhtmlonly
<tt>i, j</tt> are of type <tt>MultiIterator</tt><br> <tt>i, j</tt> are of type <tt>MultiIterator</tt><br>
<tt>diff</tt> is of type <tt>MultiIterator::multi_difference_type</t t><br> <tt>diff</tt> is of type <tt>MultiIterator::multi_difference_type</t t><br>
<tt>K</tt> is an integer compile-time constant <tt>K</tt> is an integer compile-time constant
</td> </td>
</tr> </tr>
</table> </table>
</p> </p>
<p> <p>
Note that it is impossible to support an <tt>operator-</tt> between two ite rators which returns Note that it is impossible to support an <tt>operator-</tt> between two ite rators which returns
a <tt>MultiIterator::multi_difference_type</tt> because it is impossible to decide to which a <tt>MultiIterator::multi_difference_type</tt> because it is impossible to decide to which
skipping to change at line 291 skipping to change at line 221
let <tt>j = i + multi_difference_type(width, 0)</tt>, <tt>k = i + multi_dif ference_type(0,1)</tt>, let <tt>j = i + multi_difference_type(width, 0)</tt>, <tt>k = i + multi_dif ference_type(0,1)</tt>,
where <tt>width</tt> is the array's total width. In general, <tt>j</tt> and <tt>k</tt> point to where <tt>width</tt> is the array's total width. In general, <tt>j</tt> and <tt>k</tt> point to
the same memory location, so that the two cases cannot easily be distinguis hed (it is possible, the same memory location, so that the two cases cannot easily be distinguis hed (it is possible,
but iterator performance will suffer significantly, as is experienced with but iterator performance will suffer significantly, as is experienced with
\ref vigra::ImageIterator where differencing is allowed). \ref vigra::ImageIterator where differencing is allowed).
</p> </p>
<h3>Requirements for Hierarchical Traversal</h3> <h3>Requirements for Hierarchical Traversal</h3>
<p> <p>
<table border=2 cellspacing=0 cellpadding=2 width="100%"> <table border=2 cellspacing=0 cellpadding=2 width="100%">
<tr><td> <tr><th colspan=2>
\htmlonly
<th colspan=2>
\endhtmlonly
Local Types Local Types
\htmlonly
</th><th> </th><th>
\endhtmlonly
Meaning Meaning
\htmlonly
</th> </th>
\endhtmlonly </tr>
</td></tr> <tr><td colspan=2>
<tr>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>MultiIterator::difference_type</tt></td> <tt>MultiIterator::difference_type</tt></td>
<td>the iterator's difference type (<TT>ptrdiff_t</TT>)</td> <td>the iterator's difference type (<TT>MultiArrayIndex</TT>)</td>
</tr> </tr>
<tr> <tr><td colspan=2>
<td>
\htmlonly
<td colspan=2>
\endhtmlonly
<tt>MultiIterator::next_type</tt></td><td>type of the next iterator <tt>MultiIterator::next_type</tt></td><td>type of the next iterator
(referring to the next lower dimension) in the hierarchy</td> (referring to the next lower dimension) in the hierarchy</td>
</tr> </tr>
<tr><td> <tr><th>
\htmlonly
<th>
\endhtmlonly
Operation Operation
\htmlonly
</th><th> </th><th>
\endhtmlonly
Result Result
\htmlonly
</th><th> </th><th>
\endhtmlonly
Semantics Semantics
\htmlonly
</th> </th>
\endhtmlonly </tr>
</td></tr>
<tr> <tr>
<td><tt>++i</tt></td><td><tt>MultiIterator &</tt></td> <td><tt>++i</tt></td><td><tt>MultiIterator &</tt></td>
<td>pre-increment iterator in its current dimension</td> <td>pre-increment iterator in its current dimension</td>
</tr> </tr>
<tr> <tr>
<td><tt>i++</tt></td><td><tt>MultiIterator</tt></td> <td><tt>i++</tt></td><td><tt>MultiIterator</tt></td>
<td>post-increment iterator in its current dimension</td> <td>post-increment iterator in its current dimension</td>
</tr> </tr>
<tr> <tr>
<td><tt>--i</tt></td><td><tt>MultiIterator &</tt></td> <td><tt>--i</tt></td><td><tt>MultiIterator &</tt></td>
skipping to change at line 417 skipping to change at line 323
\endcode \endcode
</td> </td>
</tr> </tr>
<tr> <tr>
<td><tt>i.end()</tt></td><td><tt>next_type</tt></td> <td><tt>i.end()</tt></td><td><tt>next_type</tt></td>
<td>create the hierarchical iterator poiting to the past-the-end locati on in the <td>create the hierarchical iterator poiting to the past-the-end locati on in the
next lower dimension.<br> next lower dimension.<br>
<em>Note:</em> The result of this operation is undefined if the iterato r <em>Note:</em> The result of this operation is undefined if the iterato r
doesn't point to element 0 in all dimensions below its current dimensio n.</td> doesn't point to element 0 in all dimensions below its current dimensio n.</td>
</tr> </tr>
<tr> <tr><td colspan=3>
<td>
\htmlonly
<td colspan=3>
\endhtmlonly
<tt>i, j</tt> are of type <tt>MultiIterator</tt><br> <tt>i, j</tt> are of type <tt>MultiIterator</tt><br>
<tt>d</tt> is of type <tt>MultiIterator::difference_type</tt> <tt>d</tt> is of type <tt>MultiIterator::difference_type</tt>
</td> </td>
</tr> </tr>
</table> </table>
</p> </p>
*/ */
/** \addtogroup MultiIteratorGroup Multi-dimensional Array Iterators /** \addtogroup MultiIteratorGroup Multi-dimensional Array Iterators
\brief General iterators for arrays of arbitrary dimension. \brief General iterators for arrays of arbitrary dimension.
*/ */
//@{ //@{
/********************************************************/ /** Index type for a single dimension of a MultiArrayView or
/* */ MultiArray.
/* MultiIteratorBase */ */
/* */ typedef std::ptrdiff_t MultiArrayIndex;
/********************************************************/
/** \brief Enclosing class for \ref vigra::MultiIterator base classes.
This design is necessary for compilers that do not support partial
specialization (otherwise, MultiIterator could be specialized directly).
<b>\#include</b> "<a href="multi__iterator_8hxx-source.html">vigra/multi_it
erator.hxx</a>"
Namespace: vigra /** Traits class for the difference type of all MultiIterator, MultiArr
*/ ayView, and
MultiArray variants.
*/
template <unsigned int N> template <unsigned int N>
class MultiIteratorBase class MultiArrayShape
{ {
public: public:
/** \brief Base class for \ref vigra::MultiIterator. /** The difference type of all MultiIterator, MultiArrayView, and
MultiArray variants.
This class implements the multi-iterator by means of the enclosed t
emplate
class <tt>type</tt>. This design is necessary for compilers that do
not support partial
specialization (otherwise, MultiIterator could be specialized direc
tly).
<b>\#include</b> "<a href="multi__iterator_8hxx-source.html">vigra/
multi_iterator.hxx</a>"
Namespace: vigra
*/ */
template <class T, class REFERENCE, class POINTER> typedef TinyVector<MultiArrayIndex, N> type;
class type : public MultiIterator <N-1, T, REFERENCE, POINTER> };
{
public:
/** the type of the parent in the inheritance hierarchy.
*/
typedef MultiIterator <N-1, T, REFERENCE, POINTER> base_type;
public: /********************************************************/
/* */
/* MultiIterator */
/* */
/********************************************************/
/** the iterator's level in the dimension hierarchy template <unsigned int N, class T, class REFERENCE, class POINTER>
*/ class MultiIterator;
enum { level = N-1 };
/** the iterator's value type /********************************************************/
*/ /* */
typedef T value_type; /* MultiIterator<1> */
/* */
/********************************************************/
/** reference type (result of operator[] and operator*()) //
*/ template <class T, class REFERENCE, class POINTER>
typedef REFERENCE reference; class MultiIterator<1, T, REFERENCE, POINTER>
{
public:
enum { level = 0 };
typedef T value_type;
typedef REFERENCE reference;
typedef const value_type &const_reference;
typedef POINTER pointer;
typedef const value_type *const_pointer;
typedef typename MultiArrayShape<1>::type multi_difference_type;
typedef MultiArrayIndex difference_type;
typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
typedef std::random_access_iterator_tag iterator_category;
/** pointer type (result of operator->()) protected:
*/ pointer m_ptr;
typedef POINTER pointer;
/** difference type (used for offsetting along one axis) public:
*/ MultiIterator ()
typedef ptrdiff_t difference_type; : m_ptr (0)
{}
/** multi difference type MultiIterator (pointer ptr,
(used for offsetting along all axes simultaneously) const difference_type *,
*/ const difference_type *)
typedef TinyVector<difference_type, N> multi_difference_type; : m_ptr (ptr)
{}
/** the next type, this is a non-standard typedef denoting the void operator++ ()
type of the multi-iterator with the next-lower dimension. {
*/ ++m_ptr;
typedef MultiIterator <level, T, REFERENCE, POINTER> next_type; }
/** the 1-dimensional iterator for this iterator hierarchy void operator-- ()
(result of iteratorForDimension()). {
*/ --m_ptr;
typedef StridedMultiIterator <1, T, REFERENCE, POINTER> iterator; }
/** the iterator tag (image traverser) MultiIterator operator++ (int)
*/ {
typedef multi_dimensional_traverser_tag iterator_category; MultiIterator ret = *this;
++(*this);
return ret;
}
/* use default copy constructor and assignment operator */ MultiIterator operator-- (int)
{
MultiIterator ret = *this;
--(*this);
return ret;
}
/** default constructor. MultiIterator &operator+= (difference_type n)
*/ {
type () m_ptr += n;
{} return *this;
}
/** construct from pointer, strides (offset of a sample to the MultiIterator & operator+= (multi_difference_type const & d)
next) for every dimension, and the shape. {
*/ m_ptr += d[level];
type (pointer ptr, return *this;
const difference_type *stride, }
const difference_type *shape)
: base_type (ptr, stride, shape)
{}
/** prefix-increment the iterator in it's current dimension MultiIterator &operator-= (difference_type n)
*/ {
void operator++ () m_ptr -= n;
{ return *this;
type::m_ptr += type::m_stride [level]; }
}
/** prefix-decrement the iterator in it's current dimension MultiIterator & operator-= (multi_difference_type const & d)
*/ {
void operator-- () m_ptr -= d[level];
{ return *this;
type::m_ptr -= type::m_stride [level]; }
}
/** postfix-increment the iterator in it's current dimension MultiIterator operator+ (difference_type n) const
*/ {
type operator++ (int) MultiIterator ret = *this;
{ ret += n;
type ret = *this; return ret;
++(*this); }
return ret;
}
/** postfix-decrement the iterator in it's current dimension MultiIterator operator+ (multi_difference_type const & d) const
*/ {
type operator-- (int) MultiIterator ret = *this;
{ ret += d;
type ret = *this; return ret;
--(*this); }
return ret;
}
/** increment the iterator in it's current dimension difference_type operator- (MultiIterator const & d) const
by the given value. {
*/ return (m_ptr - d.m_ptr);
type & operator+= (difference_type n) }
{
type::m_ptr += n * type::m_stride [level];
return *this;
}
/** increment the iterator in all dimensions MultiIterator operator- (difference_type n) const
by the given offset. {
*/ MultiIterator ret = *this;
type & operator+= (multi_difference_type const & d) ret -= n;
{ return ret;
type::m_ptr += total_stride(d.begin()); }
return *this;
}
/** decrement the iterator in it's current dimension MultiIterator operator- (multi_difference_type const & d) const
by the given value. {
*/ MultiIterator ret = *this;
type & operator-= (difference_type n) ret -= d;
{ return ret;
type::m_ptr -= n * type::m_stride [level]; }
return *this;
}
/** decrement the iterator in all dimensions reference operator[] (difference_type n) const
by the given offset. {
*/ return m_ptr [n];
type & operator-= (multi_difference_type const & d) }
{
type::m_ptr -= total_stride(d.begin());
return *this;
}
/** difference of two iterators in the current dimension. reference operator[] (multi_difference_type const & d) const
The result of this operation is undefined if the iterator {
doesn't point to element 0 in all dimensions below its curr return m_ptr [d[level]];
ent dimension. }
*/
difference_type operator- (type const & d) const
{
return (type::m_ptr - d.m_ptr) / type::m_stride[level];
}
/* operators *, ->, ==, !=, < inherited */ reference operator* () const
{
return *m_ptr;
}
/** access the array element at the given offset in pointer get () const
the current dimension. {
*/ return m_ptr;
reference operator[] (difference_type n) const }
{
return type::m_ptr [n* type::m_stride [level]];
}
/** access the array element at the given offset. pointer operator->() const
*/ {
reference operator[] (multi_difference_type const & d) const return &(operator*());
{ }
return type::m_ptr [total_stride(d.begin())];
}
/** Return the (N-1)-dimensional multi-iterator that points to bool operator!= (const MultiIterator &rhs) const
the first (N-1)-dimensional subarray of the {
N-dimensional array this iterator is referring to. return m_ptr != rhs.m_ptr;
The result is only valid if this iterator refers to locatio }
n
0 in <em>all</em> dimensions below its current dimension N,
otherwise it is undefined. Usage:
\code bool operator== (const MultiIterator &rhs) const
{
return m_ptr == rhs.m_ptr;
}
MultiIterator<2, int> outer = ...; // this iterator bool operator< (const MultiIterator &rhs) const
{
return m_ptr < rhs.m_ptr;
}
MultiIterator<2, int>::next_type inner = outer.begin(); bool operator<= (const MultiIterator &rhs) const
for(; inner != outer.end(); ++inner) {
{ return m_ptr <= rhs.m_ptr;
// manipulate current 1D subimage }
}
\endcode
*/
next_type begin () const
{
return *this;
}
/** Return the (N-1)-dimensional multi-iterator that points bey bool operator> (const MultiIterator &rhs) const
ond {
the last (N-1)-dimensional subarray of the return m_ptr > rhs.m_ptr;
N-dimensional array this iterator is referring to. }
The result is only valid if this iterator refers to locatio
n
0 in <em>all</em> dimensions below its current dimension N,
otherwise it is undefined.
*/
next_type end () const
{
next_type ret = *this;
ret += type::m_shape [level-1];
return ret;
}
/** Get a 1-dimensional, STL-compatible iterator for the bool operator>= (const MultiIterator &rhs) const
given dimension, pointing to the current element of <TT>thi {
s</TT>. return m_ptr >= rhs.m_ptr;
Usage: }
\code iterator iteratorForDimension(unsigned int d) const
{
vigra_precondition(d == 0,
"MultiIterator<1>::iteratorForDimension(d): d == 0 required");
const difference_type stride = 1;
return iterator(m_ptr, &stride, 0);
}
MultiIterator<3, int> outer = ...; // this iterator template <unsigned int K>
MultiIterator<K+1, T, REFERENCE, POINTER> &
dim()
{
return *this;
}
MultiIterator<3, int>::iterator i = outer.iteratorForDimens MultiIterator<1, T, REFERENCE, POINTER> &
ion(1); dim0() { return *this; }
MultiIterator<3, int>::iterator end = i + height;
for(; i != end; ++i)
{
// go down the current column starting at the location
of 'outer'
}
\endcode
*/
iterator iteratorForDimension(unsigned int d) const
{
vigra_precondition(d <= level,
"MultiIterator<N>::iteratorForDimension(d): d < N required"
);
return iterator(type::m_ptr, &type::m_stride [d], 0);
}
protected: protected:
difference_type difference_type
total_stride(typename multi_difference_type::const_iterator d) cons total_stride(typename multi_difference_type::const_iterator d) const
t {
{ return d[level];
return d[level]*type::m_stride[level] + base_type::total_stride }
(d);
}
};
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* MultiIteratorBase <2> */ /* MultiIterator<2> */
/* */ /* */
/********************************************************/ /********************************************************/
// //
template <> template <class T, class REFERENCE, class POINTER>
class MultiIteratorBase <2> class MultiIterator<2, T, REFERENCE, POINTER>
: public MultiIterator<1, T, REFERENCE, POINTER>
{ {
public: public:
template <class T, class REFERENCE, class POINTER>
class type : public MultiIterator <1, T, REFERENCE, POINTER>
{
public:
enum { level = 1 };
typedef MultiIterator <1, T, REFERENCE, POINTER> base_type;
typedef T value_type;
typedef REFERENCE reference;
typedef const value_type &const_reference;
typedef POINTER pointer;
typedef const value_type *const_pointer;
typedef ptrdiff_t difference_type;
typedef MultiIterator <1, T, REFERENCE, POINTER> next_type;
typedef StridedMultiIterator <1, T, REFERENCE, POINTER> iterator;
typedef TinyVector<difference_type, 2> multi_difference_type;
typedef std::random_access_iterator_tag iterator_category;
const difference_type *m_stride;
const difference_type *m_shape;
/* use default copy constructor and assignment operator */
type ()
: base_type (),
m_stride (0), m_shape (0)
{}
type (pointer ptr,
const difference_type *stride,
const difference_type *shape)
: base_type (ptr, stride, shape),
m_stride (stride), m_shape (shape)
{}
void operator++ ()
{
type::m_ptr += m_stride [level];
}
void operator-- ()
{
type::m_ptr -= m_stride [level];
}
type operator++ (int)
{
type ret = *this;
++(*this);
return ret;
}
type operator-- (int)
{
type ret = *this;
--(*this);
return ret;
}
type & operator+= (difference_type n)
{
type::m_ptr += n * m_stride [level];
return *this;
}
type & operator+= (multi_difference_type const & d)
{
type::m_ptr += total_stride(d.begin());
return *this;
}
type &operator-= (difference_type n)
{
type::m_ptr -= n * m_stride [level];
return *this;
}
type & operator-= (multi_difference_type const & d)
{
type::m_ptr -= total_stride(d.begin());
return *this;
}
difference_type operator- (type const & d) const
{
return (type::m_ptr - d.m_ptr) / m_stride[level];
}
reference operator[] (difference_type n) const
{
return type::m_ptr [n*m_stride [level]];
}
reference operator[] (multi_difference_type const & d) const
{
return type::m_ptr [total_stride(d.begin())];
}
next_type begin () const
{
return *this;
}
next_type end () const
{
next_type ret = *this;
ret += m_shape [level-1];
return ret;
}
iterator iteratorForDimension(unsigned int d) const
{
vigra_precondition(d <= level,
"MultiIterator<N>::iteratorForDimension(d): d < N required"
);
return iterator(type::m_ptr, &m_stride [d], 0);
}
protected:
difference_type typedef MultiIterator<1, T, REFERENCE, POINTER> base_type;
total_stride(typename multi_difference_type::const_iterator d) cons enum { level = 1 };
t typedef T value_type;
{ typedef REFERENCE reference;
return d[level]*m_stride[level] + base_type::total_stride(d); typedef const value_type &const_reference;
} typedef POINTER pointer;
}; typedef const value_type *const_pointer;
}; typedef typename MultiArrayShape<2>::type multi_difference_type;
typedef MultiArrayIndex difference_type;
typedef base_type next_type;
typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
typedef multi_dimensional_traverser_tag iterator_category;
/********************************************************/ protected:
/* */ const difference_type *m_stride;
/* MultiIteratorBase <1> */ const difference_type *m_shape;
/* */
/********************************************************/
//
template <>
class MultiIteratorBase <1>
{
public: public:
template <class T, class REFERENCE, class POINTER> /* use default copy constructor and assignment operator */
class type
{
public:
enum { level = 0 };
typedef T value_type;
typedef REFERENCE reference;
typedef const value_type &const_reference;
typedef POINTER pointer;
typedef const value_type *const_pointer;
typedef ptrdiff_t difference_type;
typedef void next_type;
typedef StridedMultiIterator <1, T, REFERENCE, POINTER> iterator;
typedef TinyVector<difference_type, 1> multi_difference_type;
typedef multi_dimensional_traverser_tag iterator_category;
pointer m_ptr;
/* use default copy constructor and assignment operator */ MultiIterator ()
: base_type (),
m_stride (0), m_shape (0)
{}
type () MultiIterator (pointer ptr,
: m_ptr (0) const difference_type *stride,
{} const difference_type *shape)
: base_type (ptr, stride, shape),
m_stride (stride), m_shape (shape)
{}
type (pointer ptr, void operator++ ()
const difference_type *, {
const difference_type *) this->m_ptr += m_stride [level];
: m_ptr (ptr) }
{}
void operator++ () void operator-- ()
{ {
++m_ptr; this->m_ptr -= m_stride [level];
} }
void operator-- () MultiIterator operator++ (int)
{ {
--m_ptr; MultiIterator ret = *this;
} ++(*this);
return ret;
}
type operator++ (int) MultiIterator operator-- (int)
{ {
type ret = *this; MultiIterator ret = *this;
++(*this); --(*this);
return ret; return ret;
} }
type operator-- (int) MultiIterator & operator+= (difference_type n)
{ {
type ret = *this; this->m_ptr += n * m_stride [level];
--(*this); return *this;
return ret; }
}
type &operator+= (difference_type n) MultiIterator & operator+= (multi_difference_type const & d)
{ {
m_ptr += n; this->m_ptr += total_stride(d.begin());
return *this; return *this;
} }
type & operator+= (multi_difference_type const & d) MultiIterator &operator-= (difference_type n)
{ {
m_ptr += d[level]; this->m_ptr -= n * m_stride [level];
return *this; return *this;
} }
type &operator-= (difference_type n) MultiIterator & operator-= (multi_difference_type const & d)
{ {
m_ptr -= n; this->m_ptr -= total_stride(d.begin());
return *this; return *this;
} }
type & operator-= (multi_difference_type const & d) MultiIterator operator+ (difference_type n) const
{ {
m_ptr -= d[level]; MultiIterator ret = *this;
return *this; ret += n;
} return ret;
}
reference operator* () const MultiIterator operator+ (multi_difference_type const & d) const
{ {
return *m_ptr; MultiIterator ret = *this;
} ret += d;
return ret;
}
pointer get () const difference_type operator- (MultiIterator const & d) const
{ {
return m_ptr; return (this->m_ptr - d.m_ptr) / this->m_stride[level];
} }
pointer operator->() const MultiIterator operator- (difference_type n) const
{ {
return &(operator*()); MultiIterator ret = *this;
} ret -= n;
return ret;
}
reference operator[] (difference_type n) const MultiIterator operator- (multi_difference_type const & d) const
{ {
return m_ptr [n]; MultiIterator ret = *this;
} ret -= d;
return ret;
}
reference operator[] (multi_difference_type const & d) const reference operator[] (difference_type n) const
{ {
return m_ptr [d[level]]; return this->m_ptr [n*m_stride [level]];
} }
difference_type operator- (type const & d) const reference operator[] (multi_difference_type const & d) const
{ {
return (m_ptr - d.m_ptr); return this->m_ptr [total_stride(d.begin())];
} }
bool operator!= (const type &rhs) const next_type begin () const
{ {
return m_ptr != rhs.m_ptr; return *this;
} }
bool operator== (const type &rhs) const next_type end () const
{ {
return m_ptr == rhs.m_ptr; next_type ret = *this;
} ret += m_shape [level-1];
return ret;
}
bool operator< (const type &rhs) const iterator iteratorForDimension(unsigned int d) const
{ {
return m_ptr < rhs.m_ptr; vigra_precondition(d <= level,
} "MultiIterator<N>::iteratorForDimension(d): d < N required");
return iterator(this->m_ptr, &m_stride [d], 0);
}
bool operator<= (const type &rhs) const template <unsigned int K>
{ MultiIterator<K+1, T, REFERENCE, POINTER> &
return m_ptr <= rhs.m_ptr; dim()
} {
return *this;
}
iterator iteratorForDimension(unsigned int d) const MultiIterator<1, T, REFERENCE, POINTER> &
{ dim0() { return *this; }
vigra_precondition(d == 0, MultiIterator<2, T, REFERENCE, POINTER> &
"MultiIterator<1>::iteratorForDimension(d): d == 0 required dim1() { return *this; }
");
const difference_type stride = 1;
return iterator(m_ptr, &stride, 0);
}
protected: protected:
difference_type difference_type
total_stride(typename multi_difference_type::const_iterator d) cons total_stride(typename multi_difference_type::const_iterator d) const
t {
{ return d[level]*m_stride[level] + base_type::total_stride(d);
return d[level]; }
}
};
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* MultiIterator */ /* MultiIterator<N> */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief A multi-dimensional hierarchical iterator to be used with /** \brief A multi-dimensional hierarchical iterator to be used with
\ref vigra::MultiArrayView if it is not strided. \ref vigra::MultiArrayView if it is not strided.
This class wraps the MultiIteratorBase in a template of arity two. See \ref MultiIteratorPage for further documentation.
<b>\#include</b> "<a href="multi__iterator_8hxx-source.html">vigra/multi_it erator.hxx</a>" <b>\#include</b> \<<a href="multi__iterator_8hxx-source.html">vigra/multi_i terator.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <unsigned int N, class T, class REFERENCE, class POINTER> template <unsigned int N, class T, class REFERENCE, class POINTER>
class MultiIterator class MultiIterator
: public MultiIteratorBase <N>::template type <T, REFERENCE, POINTER> : public MultiIterator<N-1, T, REFERENCE, POINTER>
{ {
public: public:
/** the type of the parent in the inheritance hierarchy. /** the type of the parent in the inheritance hierarchy.
*/ */
typedef typename MultiIteratorBase <N>::template type <T, REFERENCE, PO typedef MultiIterator<N-1, T, REFERENCE, POINTER> base_type;
INTER> base_type;
/** the iterator's level in the dimension hierarchy
*/
enum { level = N-1 };
/** the iterator's value type /** the iterator's value type
*/ */
typedef T value_type; typedef T value_type;
/** reference type (result of operator[]) /** reference type (result of operator[])
*/ */
typedef REFERENCE reference; typedef REFERENCE reference;
/** const reference type (result of operator[] const) /** const reference type (result of operator[] const)
skipping to change at line 1036 skipping to change at line 790
typedef const value_type &const_reference; typedef const value_type &const_reference;
/** pointer type /** pointer type
*/ */
typedef POINTER pointer; typedef POINTER pointer;
/** const pointer type /** const pointer type
*/ */
typedef const value_type *const_pointer; typedef const value_type *const_pointer;
/** difference type (used for offsetting)
*/
typedef ptrdiff_t difference_type;
/** multi difference type /** multi difference type
(used for offsetting along all axes simultaneously) (used for offsetting along all axes simultaneously)
*/ */
typedef TinyVector<difference_type, N> multi_difference_type; typedef typename MultiArrayShape<N>::type multi_difference_type;
/** difference type (used for offsetting)
*/
typedef MultiArrayIndex difference_type;
/** the MultiIterator for the next lower dimension. /** the MultiIterator for the next lower dimension.
*/ */
typedef typename base_type::next_type next_type; typedef base_type next_type;
/** the 1-dimensional iterator for this iterator hierarchy /** the 1-dimensional iterator for this iterator hierarchy
(result of iteratorForDimension()). (result of iteratorForDimension()).
*/ */
typedef StridedMultiIterator <1, T, REFERENCE, POINTER> iterator; typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
/** the iterator tag (image traverser) /** the iterator tag (image traverser)
*/ */
typedef typename base_type::iterator_category iterator_category; typedef multi_dimensional_traverser_tag iterator_category;
/* use default copy constructor and assignment operator */ /* use default copy constructor and assignment operator */
/** default constructor. /** default constructor.
*/ */
MultiIterator () MultiIterator ()
{} {}
/** construct from pointer, strides (offset of a sample to the /** construct from pointer, strides (offset of a sample to the
next) for every dimension, and the shape. next) for every dimension, and the shape.
*/ */
MultiIterator (pointer ptr, MultiIterator (pointer ptr,
const difference_type *stride, const difference_type *stride,
const difference_type *shape) const difference_type *shape)
: base_type (ptr, stride, shape) : base_type (ptr, stride, shape)
{} {}
/** prefix-increment the iterator in it's current dimension
*/
void operator++ ()
{
this->m_ptr += this->m_stride [level];
}
/** prefix-decrement the iterator in it's current dimension
*/
void operator-- ()
{
this->m_ptr -= this->m_stride [level];
}
/** postfix-increment the iterator in it's current dimension
*/
MultiIterator operator++ (int)
{
MultiIterator ret = *this;
++(*this);
return ret;
}
/** postfix-decrement the iterator in it's current dimension
*/
MultiIterator operator-- (int)
{
MultiIterator ret = *this;
--(*this);
return ret;
}
/** increment the iterator in it's current dimension
by the given value.
*/
MultiIterator & operator+= (difference_type n)
{
this->m_ptr += n * this->m_stride [level];
return *this;
}
/** increment the iterator in all dimensions
by the given offset.
*/
MultiIterator & operator+= (multi_difference_type const & d)
{
this->m_ptr += total_stride(d.begin());
return *this;
}
/** decrement the iterator in it's current dimension
by the given value.
*/
MultiIterator & operator-= (difference_type n)
{
this->m_ptr -= n * this->m_stride [level];
return *this;
}
/** decrement the iterator in all dimensions
by the given offset.
*/
MultiIterator & operator-= (multi_difference_type const & d)
{
this->m_ptr -= total_stride(d.begin());
return *this;
}
/** addition within current dimension /** addition within current dimension
*/ */
MultiIterator operator+ (difference_type n) const MultiIterator operator+ (difference_type n) const
{ {
MultiIterator ret = *this; MultiIterator ret = *this;
ret += n; ret += n;
return ret; return ret;
} }
/** addition along all dimensions /** addition along all dimensions
skipping to change at line 1098 skipping to change at line 920
ret += d; ret += d;
return ret; return ret;
} }
/** difference of two iterators in the current dimension. /** difference of two iterators in the current dimension.
The result of this operation is undefined if the iterator The result of this operation is undefined if the iterator
doesn't point to element 0 in all dimensions below its current dimension. doesn't point to element 0 in all dimensions below its current dimension.
*/ */
difference_type operator- (MultiIterator const & d) const difference_type operator- (MultiIterator const & d) const
{ {
return base_type::operator-(d); return (this->m_ptr - d.m_ptr) / this->m_stride[level];
} }
/** subtraction within current dimension /** subtraction within current dimension
*/ */
MultiIterator operator- (difference_type n) const MultiIterator operator- (difference_type n) const
{ {
MultiIterator ret = *this; MultiIterator ret = *this;
ret -= n; ret -= n;
return ret; return ret;
} }
/** subtraction along all dimensions /** subtraction along all dimensions
*/ */
MultiIterator operator- (multi_difference_type const & d) const MultiIterator operator- (multi_difference_type const & d) const
{ {
MultiIterator ret = *this; MultiIterator ret = *this;
ret -= d; ret -= d;
return ret; return ret;
} }
#ifdef DOXYGEN /* documentation only: operators *, ->, ==, !=, <, <=, >, >=
are inherited */
/** derefenrence item
*/
reference operator* () const;
/** get address of current item
*/
pointer get () const;
/** call method of current item
*/
pointer operator->() const;
/** inequality. True if iterators reference different items.
*/
bool operator!= (const MultiIterator &rhs) const;
/** equality. True if iterators reference the same items.
*/
bool operator== (const MultiIterator &rhs) const;
/** less than.
*/
bool operator< (const MultiIterator &rhs) const;
/** less or equal.
*/
bool operator<= (const MultiIterator &rhs) const;
/** greater than.
*/
bool operator> (const MultiIterator &rhs) const;
/** greater or equal.
*/
bool operator>= (const MultiIterator &rhs) const;
#endif
/** access the array element at the given offset in
the current dimension.
*/
reference operator[] (difference_type n) const
{
return this->m_ptr [n* this->m_stride [level]];
}
/** access the array element at the given offset.
*/
reference operator[] (multi_difference_type const & d) const
{
return this->m_ptr [total_stride(d.begin())];
}
/** Return the (N-1)-dimensional multi-iterator that points to
the first (N-1)-dimensional subarray of the
N-dimensional array this iterator is referring to.
The result is only valid if this iterator refers to location
0 in <em>all</em> dimensions below its current dimension N,
otherwise it is undefined. Usage:
\code
MultiIterator<2, int> outer = ...; // this iterator
MultiIterator<2, int>::next_type inner = outer.begin();
for(; inner != outer.end(); ++inner)
{
// manipulate current 1D subimage
}
\endcode
*/
next_type begin () const
{
return *this;
}
/** Return the (N-1)-dimensional multi-iterator that points beyond
the last (N-1)-dimensional subarray of the
N-dimensional array this iterator is referring to.
The result is only valid if this iterator refers to location
0 in <em>all</em> dimensions below its current dimension N,
otherwise it is undefined.
*/
next_type end () const
{
next_type ret = *this;
ret += this->m_shape [level-1];
return ret;
}
/** Get a 1-dimensional, STL-compatible iterator for the
given dimension, pointing to the current element of <TT>this</T
T>.
Usage:
\code
MultiIterator<3, int> outer = ...; // this iterator
MultiIterator<3, int>::iterator i = outer.iteratorForDimension(
1);
MultiIterator<3, int>::iterator end = i + height;
for(; i != end; ++i)
{
// go down the current column starting at the location of '
outer'
}
\endcode
*/
iterator iteratorForDimension(unsigned int d) const
{
vigra_precondition(d <= level,
"MultiIterator<N>::iteratorForDimension(d): d < N required");
return iterator(this->m_ptr, &this->m_stride [d], 0);
}
/** Return the multi-iterator that operates on dimension K in order /** Return the multi-iterator that operates on dimension K in order
to manipulate this dimension directly. Usage: to manipulate this dimension directly. Usage:
\code \code
MultiIterator<3, int> i3 = ...; MultiIterator<3, int> i3 = ...;
i3.template dim<2>()++; // increment outer dimension i3.template dim<2>()++; // increment outer dimension
i3.template dim<0>()++; // increment inner dimension i3.template dim<0>()++; // increment inner dimension
\endcode \endcode
skipping to change at line 1158 skipping to change at line 1092
MultiIterator<1, T, REFERENCE, POINTER> & MultiIterator<1, T, REFERENCE, POINTER> &
dim0() { return *this; } dim0() { return *this; }
MultiIterator<2, T, REFERENCE, POINTER> & MultiIterator<2, T, REFERENCE, POINTER> &
dim1() { return *this; } dim1() { return *this; }
MultiIterator<3, T, REFERENCE, POINTER> & MultiIterator<3, T, REFERENCE, POINTER> &
dim2() { return *this; } dim2() { return *this; }
MultiIterator<4, T, REFERENCE, POINTER> & MultiIterator<4, T, REFERENCE, POINTER> &
dim3() { return *this; } dim3() { return *this; }
MultiIterator<5, T, REFERENCE, POINTER> & MultiIterator<5, T, REFERENCE, POINTER> &
dim4() { return *this; } dim4() { return *this; }
protected:
difference_type
total_stride(typename multi_difference_type::const_iterator d) const
{
return d[level]*this->m_stride[level] + base_type::total_stride(d);
}
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* StridedMultiIteratorBase */ /* StridedMultiIterator */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Encloses the base class for \ref vigra::StridedMultiIterator. template <unsigned int N, class T, class REFERENCE, class POINTER>
class StridedMultiIterator;
This design is necessary for compilers that do not support partial
specialization (otherwise, StridedMultiIterator could be specialized direct
ly).
<b>\#include</b> "<a href="multi__iterator_8hxx-source.html">vigra/multi_it /********************************************************/
erator.hxx</a>" /* */
/* StridedMultiIterator<1> */
/* */
/********************************************************/
Namespace: vigra //
*/ template <class T, class REFERENCE, class POINTER>
template <unsigned int N> class StridedMultiIterator<1, T, REFERENCE, POINTER>
class StridedMultiIteratorBase
{ {
public: public:
/** \brief Base class for \ref vigra::StridedMultiIterator. enum { level = 0 };
typedef T value_type;
This class implements the multi-iterator for strided arrays typedef REFERENCE reference;
by means of the enclosed template typedef const value_type &const_reference;
class <tt>type</tt>. This design is necessary for compilers that do typedef POINTER pointer;
not support partial typedef const value_type *const_pointer;
specialization (otherwise, MultiIterator could be specialized direc typedef typename MultiArrayShape<1>::type multi_difference_type;
tly). typedef MultiArrayIndex difference_type;
typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
<b>\#include</b> "<a href="multi__iterator_8hxx-source.html">vigra/ typedef std::random_access_iterator_tag iterator_category;
multi_iterator.hxx</a>"
Namespace: vigra
*/
template <class T, class REFERENCE, class POINTER>
class type : public StridedMultiIterator <N-1, T, REFERENCE, POINTER>
{
public:
/** the type of the parent in the inheritance hierarchy.
*/
typedef StridedMultiIterator <N-1, T, REFERENCE, POINTER> base_type
;
public:
/** the iterator's level in the dimension hierarchy
*/
enum { level = N-1 };
/** the iterator's value type
*/
typedef T value_type;
/** reference type (result of operator[])
*/
typedef REFERENCE reference;
/** const reference type (result of operator[] const)
*/
typedef const value_type &const_reference;
/** pointer type protected:
*/ pointer m_ptr;
typedef POINTER pointer; difference_type m_stride;
/** const pointer type /* use default copy constructor and assignment operator */
*/
typedef const value_type *const_pointer;
/** difference type (used for offsetting) public:
*/ StridedMultiIterator ()
typedef ptrdiff_t difference_type; : m_ptr (0), m_stride (0)
{}
/** multi difference type StridedMultiIterator (pointer ptr,
(used for offsetting along all axes simultaneously) const difference_type *stride,
*/ const difference_type *)
typedef TinyVector<difference_type, N> multi_difference_type; : m_ptr (ptr), m_stride (stride [level])
{}
/** the next type, this is a non-standard typedef denoting the void operator++ ()
type of the multi-iterator with the next-lower dimension. {
*/ m_ptr += m_stride;
typedef StridedMultiIterator <level, T, REFERENCE, POINTER> next_ty }
pe;
/** the 1-dimensional iterator for this iterator hierarchy void operator-- ()
(result of iteratorForDimension()). {
*/ m_ptr -= m_stride;
typedef StridedMultiIterator <1, T, REFERENCE, POINTER> iterator; }
/** the iterator tag (image traverser) StridedMultiIterator operator++ (int)
*/ {
typedef multi_dimensional_traverser_tag iterator_category; StridedMultiIterator ret = *this;
++(*this);
return ret;
}
/* use default copy constructor and assignment operator */ StridedMultiIterator operator-- (int)
{
StridedMultiIterator ret = *this;
--(*this);
return ret;
}
/** default constructor. StridedMultiIterator &operator+= (difference_type n)
*/ {
type () m_ptr += n * m_stride;
{} return *this;
}
/** construct from pointer, strides (offset of a sample to the StridedMultiIterator & operator+= (multi_difference_type const & d)
next) for every dimension, and the shape. {
*/ m_ptr += d[level] * m_stride;
type (pointer ptr, return *this;
const difference_type *stride, }
const difference_type *shape)
: base_type (ptr, stride, shape)
{}
/** prefix-increment the iterator in it's current dimension StridedMultiIterator &operator-= (difference_type n)
*/ {
void operator++ () m_ptr -= n * m_stride;
{ return *this;
type::m_ptr += type::m_stride [level]; }
}
/** prefix-decrement the iterator in it's current dimension StridedMultiIterator & operator-= (multi_difference_type const & d)
*/ {
void operator-- () m_ptr -= d[level] * m_stride;
{ return *this;
type::m_ptr -= type::m_stride [level]; }
}
/** postfix-increment the iterator in it's current dimension StridedMultiIterator operator+ (difference_type n) const
*/ {
type operator++ (int) StridedMultiIterator ret = *this;
{ ret += n;
type ret = *this; return ret;
++(*this); }
return ret;
}
/** postfix-decrement the iterator in it's current dimension StridedMultiIterator operator+ (multi_difference_type const & d) const
*/ {
type operator-- (int) StridedMultiIterator ret = *this;
{ ret += d;
type ret = *this; return ret;
--(*this); }
return ret;
}
/** increment the iterator in it's current dimension difference_type operator- (StridedMultiIterator const & d) const
by the given value. {
*/ return (m_ptr - d.m_ptr) / m_stride;
type &operator+= (difference_type n) }
{
type::m_ptr += n * type::m_stride [level];
return *this;
}
/** increment the iterator in all dimensions StridedMultiIterator operator- (difference_type n) const
by the given offset. {
*/ StridedMultiIterator ret = *this;
type & operator+= (multi_difference_type const & d) ret -= n;
{ return ret;
type::m_ptr += total_stride(d.begin()); }
return *this;
}
/** decrement the iterator in it's current dimension StridedMultiIterator operator- (multi_difference_type const & d) const
by the given value. {
*/ StridedMultiIterator ret = *this;
type &operator-= (difference_type n) ret -= d;
{ return ret;
type::m_ptr -= n * type::m_stride [level]; }
return *this;
}
/** decrement the iterator in all dimensions reference operator[] (difference_type n) const
by the given offset. {
*/ return m_ptr [n*m_stride];
type & operator-= (multi_difference_type const & d) }
{
type::m_ptr -= total_stride(d.begin());
return *this;
}
/** difference of two iterators in the current dimension. reference operator[] (multi_difference_type const & d) const
The result of this operation is undefined if the iterator {
doesn't point to element 0 in all dimensions below its curr return m_ptr [d[level]*m_stride];
ent dimension. }
*/
difference_type operator- (type const & d) const
{
return (type::m_ptr - d.m_ptr) / type::m_stride[level];
}
/* operators *, ->, ==, !=, < inherited */ reference operator* () const
{
return *m_ptr;
}
/** access the array element at the given offset pointer get () const
in the iterator's current dimension. {
*/ return m_ptr;
reference operator[] (difference_type n) const }
{
return type::m_ptr [n* type::m_stride [level]];
}
/** access the array element at the given offset. pointer operator->() const
*/ {
reference operator[] (multi_difference_type const & d) const return &(operator*());
{ }
return type::m_ptr [total_stride(d.begin())];
}
/** Return the (N-1)-dimensional multi-iterator that points to bool operator!= (const StridedMultiIterator &rhs) const
the first (N-1)-dimensional subarray of the {
N-dimensional array this iterator is referring to. return m_ptr != rhs.m_ptr;
The result is only valid if this iterator refers to locatio }
n
0 in <em>all</em> dimensions below its current dimension N,
otherwise it is undefined. Usage:
\code bool operator== (const StridedMultiIterator &rhs) const
{
return m_ptr == rhs.m_ptr;
}
MultiIterator<2, int> outer = ...; // this iterator bool operator< (const StridedMultiIterator &rhs) const
{
return m_ptr < rhs.m_ptr;
}
MultiIterator<2, int>::next_type inner = outer.begin(); bool operator<= (const StridedMultiIterator &rhs) const
for(; inner != outer.end(); ++inner) {
{ return m_ptr <= rhs.m_ptr;
// manipulate current 1D subimage }
}
\endcode
*/
next_type begin () const
{
return *this;
}
/** Return the (N-1)-dimensional multi-iterator that points bey bool operator> (const StridedMultiIterator &rhs) const
ond {
the last (N-1)-dimensional subarray of the return m_ptr > rhs.m_ptr;
N-dimensional array this iterator is referring to. }
The result is only valid if this iterator refers to locatio
n
0 in <em>all</em> dimensions below its current dimension N,
otherwise it is undefined. Usage:
*/
next_type end () const
{
next_type ret = *this;
ret += type::m_shape [level-1];
return ret;
}
/** Get a 1-dimensional, STL-compatible iterator for the bool operator>= (const StridedMultiIterator &rhs) const
given dimension, pointing to the current element of <TT>thi {
s</TT>. return m_ptr >= rhs.m_ptr;
Usage: }
\code iterator iteratorForDimension(unsigned int d) const
{
vigra_precondition(d == 0,
"StridedMultiIterator<1>::iteratorForDimension(d): d == 0 requi
red");
const difference_type stride = 1;
return iterator(m_ptr, &stride, 0);
}
StridedMultiIterator<3, int> outer = ...; // this iterator template <unsigned int K>
StridedMultiIterator<K+1, T, REFERENCE, POINTER> &
dim()
{
return *this;
}
StridedMultiIterator<3, int>::iterator i = outer.iteratorFo StridedMultiIterator<1, T, REFERENCE, POINTER> &
rDimension(1); dim0() { return *this; }
StridedMultiIterator<3, int>::iterator end = i + height;
for(; i != end; ++i)
{
// go down the current column starting at the location
of 'outer'
}
\endcode
*/
iterator iteratorForDimension(unsigned int d) const
{
vigra_precondition(d <= N,
"StridedMultiIterator<N>::iteratorForDimension(d): d <= N r
equired");
return iterator(type::m_ptr, &type::m_stride [d], 0);
}
protected: protected:
difference_type difference_type
total_stride(typename multi_difference_type::const_iterator d) cons total_stride(typename multi_difference_type::const_iterator d) const
t {
{ return d[level] * m_stride;
return d[level]*type::m_stride[level] + base_type::total_stride }
(d);
}
};
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* StridedMultiIteratorBase <2> */ /* StridedMultiIterator<2> */
/* */ /* */
/********************************************************/ /********************************************************/
// //
template <> template <class T, class REFERENCE, class POINTER>
class StridedMultiIteratorBase <2> class StridedMultiIterator<2, T, REFERENCE, POINTER>
: public StridedMultiIterator<1, T, REFERENCE, POINTER>
{ {
public: public:
template <class T, class REFERENCE, class POINTER>
class type : public StridedMultiIterator <1, T, REFERENCE, POINTER>
{
public:
enum { level = 1 };
typedef StridedMultiIterator <1, T, REFERENCE, POINTER> base_type;
typedef T value_type;
typedef REFERENCE reference;
typedef const value_type &const_reference;
typedef POINTER pointer;
typedef const value_type *const_pointer;
typedef ptrdiff_t difference_type;
typedef TinyVector<difference_type, 2> multi_difference_type;
typedef StridedMultiIterator <1, T, REFERENCE, POINTER> next_type;
typedef StridedMultiIterator <1, T, REFERENCE, POINTER> iterator;
typedef multi_dimensional_traverser_tag iterator_category;
const difference_type *m_stride;
const difference_type *m_shape;
/* use default copy constructor and assignment operator */
type ()
: base_type (),
m_stride (0), m_shape (0)
{}
type (pointer ptr,
const difference_type *stride,
const difference_type *shape)
: base_type (ptr, stride, shape),
m_stride (stride), m_shape (shape)
{}
void operator++ ()
{
type::m_ptr += m_stride [level];
}
void operator-- ()
{
type::m_ptr -= m_stride [level];
}
type operator++ (int)
{
type ret = *this;
++(*this);
return ret;
}
type operator-- (int)
{
type ret = *this;
--(*this);
return ret;
}
type &operator+= (int n)
{
type::m_ptr += n * m_stride [level];
return *this;
}
type & operator+= (multi_difference_type const & d)
{
type::m_ptr += total_stride(d.begin());
return *this;
}
type &operator-= (difference_type n)
{
type::m_ptr -= n * m_stride [level];
return *this;
}
type & operator-= (multi_difference_type const & d) typedef StridedMultiIterator<1, T, REFERENCE, POINTER> base_type;
{ enum { level = 1 };
type::m_ptr -= total_stride(d.begin()); typedef T value_type;
return *this; typedef REFERENCE reference;
} typedef const value_type &const_reference;
typedef POINTER pointer;
reference operator[] (difference_type n) const typedef const value_type *const_pointer;
{ typedef typename MultiArrayShape<2>::type multi_difference_type;
return type::m_ptr [n*m_stride [level]]; typedef MultiArrayIndex difference_type;
} typedef base_type next_type;
typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
difference_type operator- (type const & d) const typedef multi_dimensional_traverser_tag iterator_category;
{
return (type::m_ptr - d.m_ptr) / m_stride[level];
}
reference operator[] (multi_difference_type const & d) const
{
return type::m_ptr [total_stride(d.begin())];
}
next_type begin () const
{
return *this;
}
next_type end () const
{
next_type ret = *this;
ret += m_shape [level-1];
return ret;
}
iterator iteratorForDimension(unsigned int d) const
{
vigra_precondition(d <= type::N,
"StridedMultiIterator<N>::iteratorForDimension(d): d <= N r
equired");
return iterator(type::m_ptr, &m_stride [d], 0);
}
protected:
difference_type
total_stride(typename multi_difference_type::const_iterator d) cons
t
{
return d[level]*m_stride[level] + base_type::total_stride(d);
}
};
};
/********************************************************/ protected:
/* */ const difference_type *m_stride;
/* StridedMultiIteratorBase <1> */ const difference_type *m_shape;
/* */
/********************************************************/
//
template <>
class StridedMultiIteratorBase <1>
{
public: public:
template <class T, class REFERENCE, class POINTER> /* use default copy constructor and assignment operator */
class type
{
public:
enum { level = 0 };
typedef T value_type;
typedef REFERENCE reference;
typedef const value_type &const_reference;
typedef POINTER pointer;
typedef const value_type *const_pointer;
typedef ptrdiff_t difference_type;
typedef TinyVector<difference_type, 1> multi_difference_type;
typedef void next_type;
typedef StridedMultiIterator <1, T, REFERENCE, POINTER> iterator;
typedef std::random_access_iterator_tag iterator_category;
pointer m_ptr;
difference_type m_stride;
/* use default copy constructor and assignment operator */ StridedMultiIterator ()
: base_type (),
m_stride (0), m_shape (0)
{}
type () StridedMultiIterator (pointer ptr,
: m_ptr (0), m_stride (0) const difference_type *stride,
{} const difference_type *shape)
: base_type (ptr, stride, shape),
m_stride (stride), m_shape (shape)
{}
type (pointer ptr, void operator++ ()
const difference_type *stride, {
const difference_type *) this->m_ptr += m_stride [level];
: m_ptr (ptr), m_stride (stride [level]) }
{}
reference operator* () const void operator-- ()
{ {
return *m_ptr; this->m_ptr -= m_stride [level];
} }
pointer get () const StridedMultiIterator operator++ (int)
{ {
return m_ptr; StridedMultiIterator ret = *this;
} ++(*this);
return ret;
}
pointer operator-> () const StridedMultiIterator operator-- (int)
{ {
return &(operator*()); StridedMultiIterator ret = *this;
} --(*this);
return ret;
}
void operator++ () StridedMultiIterator & operator+= (difference_type n)
{ {
m_ptr += m_stride; this->m_ptr += n * m_stride [level];
} return *this;
}
void operator-- () StridedMultiIterator & operator+= (multi_difference_type const & d)
{ {
m_ptr -= m_stride; this->m_ptr += total_stride(d.begin());
} return *this;
}
type operator++ (int) StridedMultiIterator &operator-= (difference_type n)
{ {
type ret = *this; this->m_ptr -= n * m_stride [level];
++(*this); return *this;
return ret; }
}
type operator-- (int) StridedMultiIterator & operator-= (multi_difference_type const & d)
{ {
type ret = *this; this->m_ptr -= total_stride(d.begin());
--(*this); return *this;
return ret; }
}
type &operator+= (difference_type n) StridedMultiIterator operator+ (difference_type n) const
{ {
m_ptr += n * m_stride; StridedMultiIterator ret = *this;
return *this; ret += n;
} return ret;
}
type & operator+= (multi_difference_type const & d) StridedMultiIterator operator+ (multi_difference_type const & d) const
{ {
m_ptr += d[level] * m_stride; StridedMultiIterator ret = *this;
return *this; ret += d;
} return ret;
}
type &operator-= (difference_type n) difference_type operator- (StridedMultiIterator const & d) const
{ {
m_ptr -= n * m_stride; return (this->m_ptr - d.m_ptr) / this->m_stride[level];
return *this; }
}
type & operator-= (multi_difference_type const & d) StridedMultiIterator operator- (difference_type n) const
{ {
m_ptr -= d[level] * m_stride; StridedMultiIterator ret = *this;
return *this; ret -= n;
} return ret;
}
difference_type operator- (type const & d) const StridedMultiIterator operator- (multi_difference_type const & d) const
{ {
return (m_ptr - d.m_ptr) / m_stride; StridedMultiIterator ret = *this;
} ret -= d;
return ret;
}
reference operator[] (difference_type n) const reference operator[] (difference_type n) const
{ {
return m_ptr [n*m_stride]; return this->m_ptr [n*m_stride [level]];
} }
reference operator[] (multi_difference_type const & d) const reference operator[] (multi_difference_type const & d) const
{ {
return m_ptr [d[level]*m_stride]; return this->m_ptr [total_stride(d.begin())];
} }
bool operator!= (const type &rhs) const next_type begin () const
{ {
return m_ptr != rhs.m_ptr; return *this;
} }
bool operator== (const type &rhs) const next_type end () const
{ {
return m_ptr == rhs.m_ptr; next_type ret = *this;
} ret += m_shape [level-1];
return ret;
}
bool operator< (const type &rhs) const iterator iteratorForDimension(unsigned int d) const
{ {
return m_ptr < rhs.m_ptr; vigra_precondition(d <= level,
} "StridedMultiIterator<N>::iteratorForDimension(d): d < N requir
ed");
return iterator(this->m_ptr, &m_stride [d], 0);
}
bool operator<= (const type &rhs) const template <unsigned int K>
{ StridedMultiIterator<K+1, T, REFERENCE, POINTER> &
return m_ptr <= rhs.m_ptr; dim()
} {
return *this;
}
iterator iteratorForDimension(unsigned int d) const StridedMultiIterator<1, T, REFERENCE, POINTER> &
{ dim0() { return *this; }
vigra_precondition(d == 0, StridedMultiIterator<2, T, REFERENCE, POINTER> &
"StridedMultiIterator<1>::iteratorForDimension(d): d == 0 r dim1() { return *this; }
equired");
return *this;
}
protected: protected:
difference_type difference_type
total_stride(typename multi_difference_type::const_iterator d) cons total_stride(typename multi_difference_type::const_iterator d) const
t {
{ return d[level]*m_stride[level] + base_type::total_stride(d);
return d[level]*m_stride; }
}
};
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* StridedMultiIterator */ /* StridedMultiIterator<N> */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief A multi-dimensional hierarchical iterator to be used with /** \brief A multi-dimensional hierarchical iterator to be used with
\ref vigra::MultiArrayView if it is strided. \ref vigra::MultiArrayView if it is not strided.
This class wraps the StridedMultiIteratorBase in a template of arity two. See \ref MultiIteratorPage for further documentation.
<b>\#include</b> "<a href="multi__iterator_8hxx-source.html">vigra/multi_it erator.hxx</a>" <b>\#include</b> \<<a href="multi__iterator_8hxx-source.html">vigra/multi_i terator.hxx</a>\>
Namespace: vigra Namespace: vigra
*/ */
template <unsigned int N, class T, class REFERENCE, class POINTER> template <unsigned int N, class T, class REFERENCE, class POINTER>
class StridedMultiIterator class StridedMultiIterator
: public StridedMultiIteratorBase <N>::template type <T, REFERENCE, POI NTER> : public StridedMultiIterator<N-1, T, REFERENCE, POINTER>
{ {
public: public:
/** the type of the parent in the inheritance hierarchy. /** the type of the parent in the inheritance hierarchy.
*/ */
typedef typename StridedMultiIteratorBase < typedef StridedMultiIterator<N-1, T, REFERENCE, POINTER> base_type;
N>::template type <T, REFERENCE, POINTER> base_type;
/** the iterator's level in the dimension hierarchy
*/
enum { level = N-1 };
/** the iterator's value type /** the iterator's value type
*/ */
typedef T value_type; typedef T value_type;
/** reference type (result of operator[]) /** reference type (result of operator[])
*/ */
typedef REFERENCE reference; typedef REFERENCE reference;
/** const reference type (result of operator[] const) /** const reference type (result of operator[] const)
skipping to change at line 1769 skipping to change at line 1539
typedef const value_type &const_reference; typedef const value_type &const_reference;
/** pointer type /** pointer type
*/ */
typedef POINTER pointer; typedef POINTER pointer;
/** const pointer type /** const pointer type
*/ */
typedef const value_type *const_pointer; typedef const value_type *const_pointer;
/** difference type (used for offsetting)
*/
typedef ptrdiff_t difference_type;
/** multi difference type /** multi difference type
(used for offsetting along all axes simultaneously) (used for offsetting along all axes simultaneously)
*/ */
typedef TinyVector<difference_type, N> multi_difference_type; typedef typename MultiArrayShape<N>::type multi_difference_type;
/** difference type (used for offsetting)
*/
typedef MultiArrayIndex difference_type;
/** the StridedMultiIterator for the next lower dimension. /** the StridedMultiIterator for the next lower dimension.
*/ */
typedef typename base_type::next_type next_type; typedef base_type next_type;
/** the 1-dimensional iterator for this iterator hierarchy /** the 1-dimensional iterator for this iterator hierarchy
(result of iteratorForDimension()). (result of iteratorForDimension()).
*/ */
typedef StridedMultiIterator <1, T, REFERENCE, POINTER> iterator; typedef StridedMultiIterator<1, T, REFERENCE, POINTER> iterator;
/** the iterator tag (image traverser) /** the iterator tag (image traverser)
*/ */
typedef typename base_type::iterator_category iterator_category; typedef multi_dimensional_traverser_tag iterator_category;
/* use default copy constructor and assignment operator */ /* use default copy constructor and assignment operator */
/** default constructor. /** default constructor.
*/ */
StridedMultiIterator () StridedMultiIterator ()
{} {}
/** construct from pointer, strides (offset of a sample to the /** construct from pointer, strides (offset of a sample to the
next) for every dimension, and the shape. next) for every dimension, and the shape.
*/ */
StridedMultiIterator (pointer ptr, StridedMultiIterator (pointer ptr,
const difference_type *stride, const difference_type *stride,
const difference_type *shape) const difference_type *shape)
: base_type (ptr, stride, shape) : base_type (ptr, stride, shape)
{} {}
/** prefix-increment the iterator in it's current dimension
*/
void operator++ ()
{
this->m_ptr += this->m_stride [level];
}
/** prefix-decrement the iterator in it's current dimension
*/
void operator-- ()
{
this->m_ptr -= this->m_stride [level];
}
/** postfix-increment the iterator in it's current dimension
*/
StridedMultiIterator operator++ (int)
{
StridedMultiIterator ret = *this;
++(*this);
return ret;
}
/** postfix-decrement the iterator in it's current dimension
*/
StridedMultiIterator operator-- (int)
{
StridedMultiIterator ret = *this;
--(*this);
return ret;
}
/** increment the iterator in it's current dimension
by the given value.
*/
StridedMultiIterator & operator+= (difference_type n)
{
this->m_ptr += n * this->m_stride [level];
return *this;
}
/** increment the iterator in all dimensions
by the given offset.
*/
StridedMultiIterator & operator+= (multi_difference_type const & d)
{
this->m_ptr += total_stride(d.begin());
return *this;
}
/** decrement the iterator in it's current dimension
by the given value.
*/
StridedMultiIterator & operator-= (difference_type n)
{
this->m_ptr -= n * this->m_stride [level];
return *this;
}
/** decrement the iterator in all dimensions
by the given offset.
*/
StridedMultiIterator & operator-= (multi_difference_type const & d)
{
this->m_ptr -= total_stride(d.begin());
return *this;
}
/** addition within current dimension /** addition within current dimension
*/ */
StridedMultiIterator operator+ (difference_type n) const StridedMultiIterator operator+ (difference_type n) const
{ {
StridedMultiIterator ret = *this; StridedMultiIterator ret = *this;
ret += n; ret += n;
return ret; return ret;
} }
/** addition along all dimensions /** addition along all dimensions
skipping to change at line 1831 skipping to change at line 1669
ret += d; ret += d;
return ret; return ret;
} }
/** difference of two iterators in the current dimension. /** difference of two iterators in the current dimension.
The result of this operation is undefined if the iterator The result of this operation is undefined if the iterator
doesn't point to element 0 in all dimensions below its current dimension. doesn't point to element 0 in all dimensions below its current dimension.
*/ */
difference_type operator- (StridedMultiIterator const & d) const difference_type operator- (StridedMultiIterator const & d) const
{ {
return base_type::operator-(d); return (this->m_ptr - d.m_ptr) / this->m_stride[level];
} }
/** subtraction within current dimension /** subtraction within current dimension
*/ */
StridedMultiIterator operator- (difference_type n) const StridedMultiIterator operator- (difference_type n) const
{ {
StridedMultiIterator ret = *this; StridedMultiIterator ret = *this;
ret -= n; ret -= n;
return ret; return ret;
} }
/** subtraction along all dimensions /** subtraction along all dimensions
*/ */
StridedMultiIterator operator- (multi_difference_type const & d) const StridedMultiIterator operator- (multi_difference_type const & d) const
{ {
StridedMultiIterator ret = *this; StridedMultiIterator ret = *this;
ret -= d; ret -= d;
return ret; return ret;
} }
#ifdef DOXYGEN /* documentation only: operators *, ->, ==, !=, <, <=, >, >=
are inherited */
/** derefenrence item
*/
reference operator* () const;
/** get address of current item
*/
pointer get () const;
/** call method of current item
*/
pointer operator->() const;
/** inequality. True if iterators reference different items.
*/
bool operator!= (const StridedMultiIterator &rhs) const;
/** equality. True if iterators reference the same items.
*/
bool operator== (const StridedMultiIterator &rhs) const;
/** less than.
*/
bool operator< (const StridedMultiIterator &rhs) const;
/** less or equal.
*/
bool operator<= (const StridedMultiIterator &rhs) const;
/** greater than.
*/
bool operator> (const StridedMultiIterator &rhs) const;
/** greater or equal.
*/
bool operator>= (const StridedMultiIterator &rhs) const;
#endif
/** access the array element at the given offset in
the current dimension.
*/
reference operator[] (difference_type n) const
{
return this->m_ptr [n* this->m_stride [level]];
}
/** access the array element at the given offset.
*/
reference operator[] (multi_difference_type const & d) const
{
return this->m_ptr [total_stride(d.begin())];
}
/** Return the (N-1)-dimensional multi-iterator that points to
the first (N-1)-dimensional subarray of the
N-dimensional array this iterator is referring to.
The result is only valid if this iterator refers to location
0 in <em>all</em> dimensions below its current dimension N,
otherwise it is undefined. Usage:
\code
StridedMultiIterator<2, int> outer = ...; // this iterator
StridedMultiIterator<2, int>::next_type inner = outer.begin();
for(; inner != outer.end(); ++inner)
{
// manipulate current 1D subimage
}
\endcode
*/
next_type begin () const
{
return *this;
}
/** Return the (N-1)-dimensional multi-iterator that points beyond
the last (N-1)-dimensional subarray of the
N-dimensional array this iterator is referring to.
The result is only valid if this iterator refers to location
0 in <em>all</em> dimensions below its current dimension N,
otherwise it is undefined.
*/
next_type end () const
{
next_type ret = *this;
ret += this->m_shape [level-1];
return ret;
}
/** Get a 1-dimensional, STL-compatible iterator for the
given dimension, pointing to the current element of <TT>this</T
T>.
Usage:
\code
StridedMultiIterator<3, int> outer = ...; // this iterator
StridedMultiIterator<3, int>::iterator i = outer.iteratorForDim
ension(1);
StridedMultiIterator<3, int>::iterator end = i + height;
for(; i != end; ++i)
{
// go down the current column starting at the location of '
outer'
}
\endcode
*/
iterator iteratorForDimension(unsigned int d) const
{
vigra_precondition(d <= level,
"StridedMultiIterator<N>::iteratorForDimension(d): d < N requir
ed");
return iterator(this->m_ptr, &this->m_stride [d], 0);
}
/** Return the multi-iterator that operates on dimension K in order /** Return the multi-iterator that operates on dimension K in order
to manipulate this dimension directly. Usage: to manipulate this dimension directly. Usage:
\code \code
StridedMultiIterator<3, int> i3 = ...; StridedMultiIterator<3, int> i3 = ...;
i3.template dim<2>()++; // increment outer dimension i3.template dim<2>()++; // increment outer dimension
i3.template dim<0>()++; // increment inner dimension i3.template dim<0>()++; // increment inner dimension
\endcode \endcode
skipping to change at line 1891 skipping to change at line 1841
StridedMultiIterator<1, T, REFERENCE, POINTER> & StridedMultiIterator<1, T, REFERENCE, POINTER> &
dim0() { return *this; } dim0() { return *this; }
StridedMultiIterator<2, T, REFERENCE, POINTER> & StridedMultiIterator<2, T, REFERENCE, POINTER> &
dim1() { return *this; } dim1() { return *this; }
StridedMultiIterator<3, T, REFERENCE, POINTER> & StridedMultiIterator<3, T, REFERENCE, POINTER> &
dim2() { return *this; } dim2() { return *this; }
StridedMultiIterator<4, T, REFERENCE, POINTER> & StridedMultiIterator<4, T, REFERENCE, POINTER> &
dim3() { return *this; } dim3() { return *this; }
StridedMultiIterator<5, T, REFERENCE, POINTER> & StridedMultiIterator<5, T, REFERENCE, POINTER> &
dim4() { return *this; } dim4() { return *this; }
protected:
difference_type
total_stride(typename multi_difference_type::const_iterator d) const
{
return d[level]*this->m_stride[level] + base_type::total_stride(d);
}
}; };
//@} //@}
} // namespace vigra } // namespace vigra
#endif // VIGRA_MULTI_ITERATOR_HXX #endif // VIGRA_MULTI_ITERATOR_HXX
 End of changes. 222 change blocks. 
1166 lines changed or deleted 1097 lines changed or added


 multi_pointoperators.hxx   multi_pointoperators.hxx 
//-- -*- c++ -*- //-- -*- c++ -*-
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2003 by Ullrich Koethe */ /* Copyright 2003 by Ullrich Koethe, B. Seppke, F. Heinrich */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 60 skipping to change at line 60
namespace vigra namespace vigra
{ {
/** \addtogroup MultiPointoperators Point operators for multi-dimensional a rrays. /** \addtogroup MultiPointoperators Point operators for multi-dimensional a rrays.
Copy, transform, and inspect arbitrary dimensional arrays which are rep resented Copy, transform, and inspect arbitrary dimensional arrays which are rep resented
by iterators compatible to \ref MultiIteratorPage. Note that are range is here by iterators compatible to \ref MultiIteratorPage. Note that are range is here
specified by a pair: an iterator referring to the first point of the ar ray specified by a pair: an iterator referring to the first point of the ar ray
and a shape object specifying the size of the (rectangular) ROI. and a shape object specifying the size of the (rectangular) ROI.
<b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr a/multi_pointoperators.hxx</a>" <b>\#include</b> \<<a href="multi__pointoperators_8hxx-source.html">vig ra/multi_pointoperators.hxx</a>\>
*/ */
//@{ //@{
/********************************************************/ /********************************************************/
/* */ /* */
/* initMultiArray */ /* initMultiArray */
/* */ /* */
/********************************************************/ /********************************************************/
template <class Iterator, class Shape, class Accessor, template <class Iterator, class Shape, class Accessor,
class VALUETYPE> class VALUETYPE>
inline void inline void
initMultiArrayImpl(Iterator s, Shape const & shape, Accessor a, VALUETYPE v, MetaInt<0>) initMultiArrayImpl(Iterator s, Shape const & shape, Accessor a, VALUETYPE const & v, MetaInt<0>)
{ {
initLine(s, s + shape[0], a, v); initLine(s, s + shape[0], a, v);
} }
template <class Iterator, class Shape, class Accessor, template <class Iterator, class Shape, class Accessor,
class VALUETYPE, int N> class VALUETYPE, int N>
void void
initMultiArrayImpl(Iterator s, Shape const & shape, Accessor a, initMultiArrayImpl(Iterator s, Shape const & shape, Accessor a,
VALUETYPE v, MetaInt<N>) VALUETYPE const & v, MetaInt<N>)
{ {
Iterator send = s + shape[N]; Iterator send = s + shape[N];
for(; s != send; ++s) for(; s < send; ++s)
{ {
initMultiArrayImpl(s.begin(), shape, a, v, MetaInt<N-1>()); initMultiArrayImpl(s.begin(), shape, a, v, MetaInt<N-1>());
} }
} }
/** \brief Write a value to every pixel in a multi-dimensional array. /** \brief Write a value to every pixel in a multi-dimensional array.
This function can be used to init the array which must be represented b y This function can be used to init the array which must be represented b y
a pair of iterators compatible to \ref vigra::MultiIterator. a pair of iterators compatible to \ref vigra::MultiIterator.
It uses an accessor to access the data alements. Note that the iterator range It uses an accessor to access the data alements. Note that the iterator range
must be specified by a shape object, because otherwise we could not con trol must be specified by a shape object, because otherwise we could not con trol
the range simultaneously in all dimensions (this is a necessary consequ ence the range simultaneously in all dimensions (this is a necessary consequ ence
of the \ref vigra::MultiIterator design). of the \ref vigra::MultiIterator design).
The initial value can either be a constant of appropriate type (compati
ble with
the destination's value_type), or a functor with compatible result_type
. These two
cases are automatically distinguished when <tt>FunctorTraits<FUNCTOR>::
isInitializer</tt>
yields <tt>VigraTrueType</tt>. Since the functor is passed by <tt>const
</tt> reference, its
<tt>operator()</tt> must be const, and ist internal state may need to b
e <tt>mutable</tt>.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class Iterator, class Shape, class Accessor, class VALUET YPE> template <class Iterator, class Shape, class Accessor, class VALUET YPE>
void void
initMultiArray(Iterator s, Shape const & shape, Accessor a, VALUET YPE v); initMultiArray(Iterator s, Shape const & shape, Accessor a, VALUET YPE const & v);
template <class Iterator, class Shape, class Accessor, class FUNCTO R> template <class Iterator, class Shape, class Accessor, class FUNCTO R>
void void
initMultiArray(Iterator s, Shape const & shape, Accessor a, FUNCTO R const & f); initMultiArray(Iterator s, Shape const & shape, Accessor a, FUNCTO R const & f);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class Iterator, class Shape, class Accessor, class VALUET YPE> template <class Iterator, class Shape, class Accessor, class VALUET YPE>
void void
initMultiArray(triple<Iterator, Shape, Accessor> const & s, VALUETY PE v); initMultiArray(triple<Iterator, Shape, Accessor> const & s, VALUETY PE const & v);
template <class Iterator, class Shape, class Accessor, class FUNCTO R> template <class Iterator, class Shape, class Accessor, class FUNCTO R>
void void
initMultiArray(triple<Iterator, Shape, Accessor> const & s, FUNCTOR const & f); initMultiArray(triple<Iterator, Shape, Accessor> const & s, FUNCTOR const & f);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr a/multi_pointoperators.hxx</a>"<br> <b>\#include</b> \<<a href="multi__pointoperators_8hxx-source.html">vig ra/multi_pointoperators.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
typedef vigra::MultiArray<3, int> Array; typedef vigra::MultiArray<3, int> Array;
Array array(Array::size_type(100, 200, 50)); Array array(Array::size_type(100, 200, 50));
// zero the array // zero the array
vigra::initMultiArray(destMultiArrayRange(array), 0); vigra::initMultiArray(destMultiArrayRange(array), 0);
\endcode \endcode
skipping to change at line 157 skipping to change at line 163
Accessor accessor; Accessor accessor;
VALUETYPE v; VALUETYPE v;
accessor.set(v, begin); accessor.set(v, begin);
\endcode \endcode
or a functor that is called (without argument) at every location, or a functor that is called (without argument) at every location,
and the result is written into the current element. Internally, and the result is written into the current element. Internally,
functors are recognized by the meta function functors are recognized by the meta function
<tt>FunctorTraits<FUNCTOR&gt;::</tt><tt>isInitializer</tt> yielding <tt>VigraTrueType</tt>. <tt>FunctorTraits<FUNCTOR>::isInitializer</tt> yielding <tt>VigraTrueTy pe</tt>.
Make sure that your functor correctly defines <tt>FunctorTraits</tt> be cause Make sure that your functor correctly defines <tt>FunctorTraits</tt> be cause
otherwise the code will not compile. otherwise the code will not compile.
\code \code
MultiIterator begin; MultiIterator begin;
Accessor accessor; Accessor accessor;
FUNCTOR f; FUNCTOR f;
assert(typeid(FunctorTraits<FUNCTOR>::isInitializer) == typeid(VigraTru eType)); assert(typeid(FunctorTraits<FUNCTOR>::isInitializer) == typeid(VigraTru eType));
accessor.set(f(), begin); accessor.set(f(), begin);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void initMultiArray)
template <class Iterator, class Shape, class Accessor, class VALUETYPE> template <class Iterator, class Shape, class Accessor, class VALUETYPE>
inline void inline void
initMultiArray(Iterator s, Shape const & shape, Accessor a, VALUETYPE v) initMultiArray(Iterator s, Shape const & shape, Accessor a, VALUETYPE cons t & v)
{ {
initMultiArrayImpl(s, shape, a, v, MetaInt<Iterator::level>()); initMultiArrayImpl(s, shape, a, v, MetaInt<Iterator::level>());
} }
template <class Iterator, class Shape, class Accessor, class VALUETYPE> template <class Iterator, class Shape, class Accessor, class VALUETYPE>
inline inline
void void
initMultiArray(triple<Iterator, Shape, Accessor> const & s, VALUETYPE v) initMultiArray(triple<Iterator, Shape, Accessor> const & s, VALUETYPE const & v)
{ {
initMultiArray(s.first, s.second, s.third, v); initMultiArray(s.first, s.second, s.third, v);
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* initMultiArrayBorder */
/* */
/********************************************************/
/** \brief Write value to the specified border values in the array.
*/template <class Iterator, class Diff_type, class Accessor, class VALUETYP
E>
inline void initMultiArrayBorder( Iterator upperleft, Diff_type shape,
Accessor a, int border_width, VALUETYPE
v)
{
Diff_type border(shape);
for(unsigned int dim=0; dim<shape.size(); dim++){
border[dim] = (border_width > shape[dim]) ? shape[dim] : border_wid
th;
}
for(unsigned int dim=0; dim<shape.size(); dim++){
Diff_type start(shape),
offset(shape);
start = start-shape;
offset[dim]=border[dim];
initMultiArray(upperleft+start, offset, a, v);
start[dim]=shape[dim]-border[dim];
initMultiArray(upperleft+start, offset, a, v);
}
}
template <class Iterator, class Diff_type, class Accessor, class VALUETYPE>
inline void initMultiArrayBorder( triple<Iterator, Diff_type, Accessor> mul
tiArray,
int border_width, VALUETYPE v)
{
initMultiArrayBorder(multiArray.first, multiArray.second, multiArray.th
ird, border_width, v);
}
/********************************************************/
/* */
/* copyMultiArray */ /* copyMultiArray */
/* */ /* */
/********************************************************/ /********************************************************/
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestShape, class DestAccessor> class DestIterator, class DestShape, class DestAccessor>
void void
copyMultiArrayImpl(SrcIterator s, SrcShape const & sshape, SrcAccessor src, copyMultiArrayImpl(SrcIterator s, SrcShape const & sshape, SrcAccessor src,
DestIterator d, DestShape const & dshape, DestAccessor dest, MetaInt<0>) DestIterator d, DestShape const & dshape, DestAccessor dest, MetaInt<0>)
{ {
skipping to change at line 218 skipping to change at line 263
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestShape, class DestAccessor, int N> class DestIterator, class DestShape, class DestAccessor, int N>
void void
copyMultiArrayImpl(SrcIterator s, SrcShape const & sshape, SrcAccessor src, copyMultiArrayImpl(SrcIterator s, SrcShape const & sshape, SrcAccessor src,
DestIterator d, DestShape const & dshape, DestAccessor d est, MetaInt<N>) DestIterator d, DestShape const & dshape, DestAccessor d est, MetaInt<N>)
{ {
DestIterator dend = d + dshape[N]; DestIterator dend = d + dshape[N];
if(sshape[N] == 1) if(sshape[N] == 1)
{ {
for(; d != dend; ++d) for(; d < dend; ++d)
{ {
copyMultiArrayImpl(s.begin(), sshape, src, d.begin(), dshape, d est, MetaInt<N-1>()); copyMultiArrayImpl(s.begin(), sshape, src, d.begin(), dshape, d est, MetaInt<N-1>());
} }
} }
else else
{ {
for(; d != dend; ++s, ++d) for(; d < dend; ++s, ++d)
{ {
copyMultiArrayImpl(s.begin(), sshape, src, d.begin(), dshape, d est, MetaInt<N-1>()); copyMultiArrayImpl(s.begin(), sshape, src, d.begin(), dshape, d est, MetaInt<N-1>());
} }
} }
} }
/** \brief Copy a multi-dimensional array. /** \brief Copy a multi-dimensional array.
This function can be applied in two modes: This function can be applied in two modes:
skipping to change at line 260 skipping to change at line 305
The arrays must be represented by The arrays must be represented by
iterators compatible with \ref vigra::MultiIterator, and the iteration range iterators compatible with \ref vigra::MultiIterator, and the iteration range
is specified by means of shape objects. If only the source shape is giv en is specified by means of shape objects. If only the source shape is giv en
the destination array is assumed to have the same shape, and standard m ode the destination array is assumed to have the same shape, and standard m ode
is applied. If two shapes are given, the size of corresponding dimensio ns is applied. If two shapes are given, the size of corresponding dimensio ns
must be either equal (standard copy), or the source length must be 1 must be either equal (standard copy), or the source length must be 1
(expanding copy). The function uses accessors to access the data elemen ts. (expanding copy). The function uses accessors to access the data elemen ts.
<b> Declarations:</b> <b> Declarations:</b>
<b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr a/multi_pointoperators.hxx</a>"<br> <b>\#include</b> \<<a href="multi__pointoperators_8hxx-source.html">vig ra/multi_pointoperators.hxx</a>\><br>
Namespace: vigra Namespace: vigra
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
copyMultiArray(SrcIterator s, copyMultiArray(SrcIterator s,
SrcShape const & shape, SrcAccessor src, SrcShape const & shape, SrcAccessor src,
DestIterator d, DestAccessor dest); DestIterator d, DestAccessor dest);
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestShape, class DestAccessor> class DestIterator, class DestShape, class DestAccessor>
void void
copyMultiArray(SrcIterator s, SrcShape const & sshape, SrcAccessor src, copyMultiArray(SrcIterator s, SrcShape const & sshape, SrcAccessor src,
DestIterator d, DestShape const & dshape, DestAccess or dest); DestIterator d, DestShape const & dshape, DestAccess or dest);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
copyMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & s rc, copyMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> const & s rc,
pair<DestIterator, DestAccessor> const & dest); pair<DestIterator, DestAccessor> const & dest);
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestShape, class DestAccessor> class DestIterator, class DestShape, class DestAccessor>
skipping to change at line 338 skipping to change at line 383
MultiIterator src_begin, dest_begin; MultiIterator src_begin, dest_begin;
SrcAccessor src_accessor; SrcAccessor src_accessor;
DestAccessor dest_accessor; DestAccessor dest_accessor;
dest_accessor.set(src_accessor(src_begin), dest_begin); dest_accessor.set(src_accessor(src_begin), dest_begin);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void copyMultiArray)
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void inline void
copyMultiArray(SrcIterator s, copyMultiArray(SrcIterator s,
SrcShape const & shape, SrcAccessor src, SrcShape const & shape, SrcAccessor src,
DestIterator d, DestAccessor dest) DestIterator d, DestAccessor dest)
{ {
copyMultiArrayImpl(s, shape, src, d, shape, dest, MetaInt<SrcIterator:: level>()); copyMultiArrayImpl(s, shape, src, d, shape, dest, MetaInt<SrcIterator:: level>());
} }
skipping to change at line 400 skipping to change at line 447
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestShape, class DestAccessor, class DestIterator, class DestShape, class DestAccessor,
class Functor> class Functor>
void void
transformMultiArrayReduceImpl(SrcIterator s, SrcShape const & sshape, SrcAc cessor src, transformMultiArrayReduceImpl(SrcIterator s, SrcShape const & sshape, SrcAc cessor src,
DestIterator d, DestShape const & dshape, DestAccessor dest, DestIterator d, DestShape const & dshape, DestAccessor dest,
SrcShape const & reduceShape, SrcShape const & reduceShape,
Functor const & ff, MetaInt<0>) Functor const & ff, MetaInt<0>)
{ {
DestIterator dend = d + dshape[0]; DestIterator dend = d + dshape[0];
for(; d != dend; ++s.template dim<0>(), ++d) for(; d < dend; ++s.template dim<0>(), ++d)
{ {
Functor f = ff; Functor f = ff;
inspectMultiArray(s, reduceShape, src, f); inspectMultiArray(s, reduceShape, src, f);
dest.set(f(), d); dest.set(f(), d);
} }
} }
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestShape, class DestAccessor, class DestIterator, class DestShape, class DestAccessor,
class Functor, int N> class Functor, int N>
void void
transformMultiArrayReduceImpl(SrcIterator s, SrcShape const & sshape, SrcAc cessor src, transformMultiArrayReduceImpl(SrcIterator s, SrcShape const & sshape, SrcAc cessor src,
DestIterator d, DestShape const & dshape, DestAccessor d est, DestIterator d, DestShape const & dshape, DestAccessor d est,
SrcShape const & reduceShape, SrcShape const & reduceShape,
Functor const & f, MetaInt<N>) Functor const & f, MetaInt<N>)
{ {
DestIterator dend = d + dshape[N]; DestIterator dend = d + dshape[N];
for(; d != dend; ++s.template dim<N>(), ++d) for(; d < dend; ++s.template dim<N>(), ++d)
{ {
transformMultiArrayReduceImpl(s, sshape, src, d.begin(), dshape, de st, transformMultiArrayReduceImpl(s, sshape, src, d.begin(), dshape, de st,
reduceShape, f, MetaInt<N-1>()); reduceShape, f, MetaInt<N-1>());
} }
} }
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestShape, class DestAccessor, class DestIterator, class DestShape, class DestAccessor,
class Functor> class Functor>
void void
skipping to change at line 477 skipping to change at line 524
class DestIterator, class DestShape, class DestAccessor, class DestIterator, class DestShape, class DestAccessor,
class Functor, int N> class Functor, int N>
void void
transformMultiArrayExpandImpl(SrcIterator s, SrcShape const & sshape, SrcAc cessor src, transformMultiArrayExpandImpl(SrcIterator s, SrcShape const & sshape, SrcAc cessor src,
DestIterator d, DestShape const & dshape, DestAccessor d est, DestIterator d, DestShape const & dshape, DestAccessor d est,
Functor const & f, MetaInt<N>) Functor const & f, MetaInt<N>)
{ {
DestIterator dend = d + dshape[N]; DestIterator dend = d + dshape[N];
if(sshape[N] == 1) if(sshape[N] == 1)
{ {
for(; d != dend; ++d) for(; d < dend; ++d)
{ {
transformMultiArrayExpandImpl(s.begin(), sshape, src, d.begin() , dshape, dest, transformMultiArrayExpandImpl(s.begin(), sshape, src, d.begin() , dshape, dest,
f, MetaInt<N-1>()); f, MetaInt<N-1>());
} }
} }
else else
{ {
for(; d != dend; ++s, ++d) for(; d < dend; ++s, ++d)
{ {
transformMultiArrayExpandImpl(s.begin(), sshape, src, d.begin() , dshape, dest, transformMultiArrayExpandImpl(s.begin(), sshape, src, d.begin() , dshape, dest,
f, MetaInt<N-1>()); f, MetaInt<N-1>());
} }
} }
} }
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestShape, class DestAccessor, class DestIterator, class DestShape, class DestAccessor,
class Functor> class Functor>
skipping to change at line 556 skipping to change at line 603
is applied. If two shapes are given, the size of corresponding dimensio ns is applied. If two shapes are given, the size of corresponding dimensio ns
must be either equal (standard copy), or the source length must be 1 must be either equal (standard copy), or the source length must be 1
(expand mode), or the destination length must be 1 (reduce mode). Howev er, (expand mode), or the destination length must be 1 (reduce mode). Howev er,
reduction and expansion cannot be executed at the same time, so the lat ter reduction and expansion cannot be executed at the same time, so the lat ter
conditions are mutual exclusive, even if they apply to different dimens ions. conditions are mutual exclusive, even if they apply to different dimens ions.
The function uses accessors to access the data elements. The function uses accessors to access the data elements.
<b> Declarations:</b> <b> Declarations:</b>
<b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr a/multi_pointoperators.hxx</a>"<br> <b>\#include</b> \<<a href="multi__pointoperators_8hxx-source.html">vig ra/multi_pointoperators.hxx</a>\><br>
Namespace: vigra Namespace: vigra
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class Functor> class Functor>
void void
transformMultiArray(SrcIterator s, SrcShape const & shape, SrcAcces sor src, transformMultiArray(SrcIterator s, SrcShape const & shape, SrcAcces sor src,
skipping to change at line 579 skipping to change at line 626
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestShape, class DestAccessor, class DestIterator, class DestShape, class DestAccessor,
class Functor> class Functor>
void void
transformMultiArray(SrcIterator s, SrcShape const & sshape, SrcAcce ssor src, transformMultiArray(SrcIterator s, SrcShape const & sshape, SrcAcce ssor src,
DestIterator d, DestShape const & dshape, DestA ccessor dest, DestIterator d, DestShape const & dshape, DestA ccessor dest,
Functor const & f); Functor const & f);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class Functor> class Functor>
void void
transformMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> cons t & src, transformMultiArray(triple<SrcIterator, SrcShape, SrcAccessor> cons t & src,
pair<DestIterator, DestAccessor> const & dest, Functor const & f); pair<DestIterator, DestAccessor> const & dest, Functor const & f);
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
skipping to change at line 681 skipping to change at line 728
DestAccessor dest_accessor; DestAccessor dest_accessor;
Functor functor; Functor functor;
dest_accessor.set(functor(src_accessor(src_begin)), dest_begin); dest_accessor.set(functor(src_accessor(src_begin)), dest_begin);
\endcode \endcode
In reduce mode, it must be a model of UnaryAnalyser (i.e. support funct ion call In reduce mode, it must be a model of UnaryAnalyser (i.e. support funct ion call
with one argument and no return vakue <tt>functor(arg)</tt>) and Initia lizer with one argument and no return vakue <tt>functor(arg)</tt>) and Initia lizer
(i.e. support function call with no argument, but return value (i.e. support function call with no argument, but return value
<tt>res = functor()</tt>). Internally, such functors are recognized by the <tt>res = functor()</tt>). Internally, such functors are recognized by the
meta functions <tt>FunctorTraits&lt;FUNCTOR&gt;::</tt><tt>isUnaryAnalys meta functions <tt>FunctorTraits<FUNCTOR>::isUnaryAnalyser</tt> and
er</tt> and <tt>FunctorTraits<FUNCTOR>::isInitializer</tt> which must both yield
<tt>FunctorTraits&lt;FUNCTOR&gt;::</tt><tt>isInitializer</tt> which mus
t both yield
<tt>VigraTrueType</tt>. Make sure that your functor correctly defines <tt>VigraTrueType</tt>. Make sure that your functor correctly defines
<tt>FunctorTraits</tt> because otherwise reduce mode will not work. In addition, <tt>FunctorTraits</tt> because otherwise reduce mode will not work. In addition,
the functor must be copy constructible in order to start each reduction the functor must be copy constructible in order to start each reduction
with a fresh functor. with a fresh functor.
\code \code
MultiIterator src_begin, src_end, dest_begin; MultiIterator src_begin, src_end, dest_begin;
SrcAccessor src_accessor; SrcAccessor src_accessor;
DestAccessor dest_accessor; DestAccessor dest_accessor;
FUNCTOR initial_functor, functor(initial_functor); FUNCTOR initial_functor, functor(initial_functor);
assert(typeid(FunctorTraits<FUNCTOR>::isInitializer) == typeid(VigraTru eType)); assert(typeid(FunctorTraits<FUNCTOR>::isInitializer) == typeid(VigraTru eType));
assert(typeid(FunctorTraits<FUNCTOR>::isUnaryAnalyser) == typeid(VigraT rueType)); assert(typeid(FunctorTraits<FUNCTOR>::isUnaryAnalyser) == typeid(VigraT rueType));
functor(src_accessor(src_begin)); functor(src_accessor(src_begin));
dest_accessor.set(functor(), dest_begin); dest_accessor.set(functor(), dest_begin);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void transformMultiArray)
template <class SrcIterator, class SrcShape, class SrcAccessor, template <class SrcIterator, class SrcShape, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class Functor> class Functor>
inline void inline void
transformMultiArray(SrcIterator s, SrcShape const & shape, SrcAccessor src, transformMultiArray(SrcIterator s, SrcShape const & shape, SrcAccessor src,
DestIterator d, DestAccessor dest, Functor const & f) DestIterator d, DestAccessor dest, Functor const & f)
{ {
transformMultiArrayExpandImpl(s, shape, src, d, shape, dest, transformMultiArrayExpandImpl(s, shape, src, d, shape, dest,
f, MetaInt<SrcIterator::level>()); f, MetaInt<SrcIterator::level>());
} }
skipping to change at line 775 skipping to change at line 824
class Functor> class Functor>
void void
combineTwoMultiArraysReduceImpl( combineTwoMultiArraysReduceImpl(
SrcIterator1 s1, SrcShape const & sshape, SrcAccessor1 src1, SrcIterator1 s1, SrcShape const & sshape, SrcAccessor1 src1,
SrcIterator2 s2, SrcAccessor2 src2, SrcIterator2 s2, SrcAccessor2 src2,
DestIterator d, DestShape const & dshape, DestAccessor dest , DestIterator d, DestShape const & dshape, DestAccessor dest ,
SrcShape const & reduceShape, SrcShape const & reduceShape,
Functor const & ff, MetaInt<0>) Functor const & ff, MetaInt<0>)
{ {
DestIterator dend = d + dshape[0]; DestIterator dend = d + dshape[0];
for(; d != dend; ++s1.template dim<0>(), ++s2.template dim<0>(), ++d) for(; d < dend; ++s1.template dim<0>(), ++s2.template dim<0>(), ++d)
{ {
Functor f = ff; Functor f = ff;
inspectTwoMultiArrays(s1, reduceShape, src1, s2, src2, f); inspectTwoMultiArrays(s1, reduceShape, src1, s2, src2, f);
dest.set(f(), d); dest.set(f(), d);
} }
} }
template <class SrcIterator1, class SrcShape, class SrcAccessor1, template <class SrcIterator1, class SrcShape, class SrcAccessor1,
class SrcIterator2, class SrcAccessor2, class SrcIterator2, class SrcAccessor2,
class DestIterator, class DestShape, class DestAccessor, class DestIterator, class DestShape, class DestAccessor,
class Functor, int N> class Functor, int N>
void void
combineTwoMultiArraysReduceImpl( combineTwoMultiArraysReduceImpl(
SrcIterator1 s1, SrcShape const & sshape, SrcAccessor1 src1, SrcIterator1 s1, SrcShape const & sshape, SrcAccessor1 src1,
SrcIterator2 s2, SrcAccessor2 src2, SrcIterator2 s2, SrcAccessor2 src2,
DestIterator d, DestShape const & dshape, DestAccessor dest , DestIterator d, DestShape const & dshape, DestAccessor dest ,
SrcShape const & reduceShape, SrcShape const & reduceShape,
Functor const & f, MetaInt<N>) Functor const & f, MetaInt<N>)
{ {
DestIterator dend = d + dshape[N]; DestIterator dend = d + dshape[N];
for(; d != dend; ++s1.template dim<N>(), ++s2.template dim<N>(), ++d) for(; d < dend; ++s1.template dim<N>(), ++s2.template dim<N>(), ++d)
{ {
combineTwoMultiArraysReduceImpl(s1, sshape, src1, s2, src2, combineTwoMultiArraysReduceImpl(s1, sshape, src1, s2, src2,
d.begin(), dshape, dest, d.begin(), dshape, dest,
reduceShape, f, MetaInt<N-1>()); reduceShape, f, MetaInt<N-1>());
} }
} }
template <class SrcIterator1, class SrcShape1, class SrcAccessor1, template <class SrcIterator1, class SrcShape1, class SrcAccessor1,
class SrcIterator2, class SrcShape2, class SrcAccessor2, class SrcIterator2, class SrcShape2, class SrcAccessor2,
class DestIterator, class DestShape, class DestAccessor, class DestIterator, class DestShape, class DestAccessor,
skipping to change at line 852 skipping to change at line 901
Functor const & f, MetaInt<0>) Functor const & f, MetaInt<0>)
{ {
DestIterator dend = d + dshape[0]; DestIterator dend = d + dshape[0];
if(sshape1[0] == 1 && sshape2[0] == 1) if(sshape1[0] == 1 && sshape2[0] == 1)
{ {
initLine(d, dend, dest, f(src1(s1), src2(s2))); initLine(d, dend, dest, f(src1(s1), src2(s2)));
} }
else if(sshape1[0] == 1) else if(sshape1[0] == 1)
{ {
typename SrcAccessor1::value_type sv1 = src1(s1); typename SrcAccessor1::value_type sv1 = src1(s1);
for(; d != dend; ++d, ++s2) for(; d < dend; ++d, ++s2)
dest.set(f(sv1, src2(s2)), d); dest.set(f(sv1, src2(s2)), d);
} }
else if(sshape2[0] == 1) else if(sshape2[0] == 1)
{ {
typename SrcAccessor2::value_type sv2 = src2(s2); typename SrcAccessor2::value_type sv2 = src2(s2);
for(; d != dend; ++d, ++s1) for(; d < dend; ++d, ++s1)
dest.set(f(src1(s1), sv2), d); dest.set(f(src1(s1), sv2), d);
} }
else else
{ {
combineTwoLines(s1, s1 + sshape1[0], src1, s2, src2, d, dest, f); combineTwoLines(s1, s1 + sshape1[0], src1, s2, src2, d, dest, f);
} }
} }
template <class SrcIterator1, class SrcShape1, class SrcAccessor1, template <class SrcIterator1, class SrcShape1, class SrcAccessor1,
class SrcIterator2, class SrcShape2, class SrcAccessor2, class SrcIterator2, class SrcShape2, class SrcAccessor2,
skipping to change at line 885 skipping to change at line 934
DestIterator d, DestShape const & dshape, DestAccessor dest, DestIterator d, DestShape const & dshape, DestAccessor dest,
Functor const & f, MetaInt<N>) Functor const & f, MetaInt<N>)
{ {
DestIterator dend = d + dshape[N]; DestIterator dend = d + dshape[N];
int s1inc = sshape1[N] == 1 int s1inc = sshape1[N] == 1
? 0 ? 0
: 1; : 1;
int s2inc = sshape2[N] == 1 int s2inc = sshape2[N] == 1
? 0 ? 0
: 1; : 1;
for(; d != dend; ++d, s1 += s1inc, s2 += s2inc) for(; d < dend; ++d, s1 += s1inc, s2 += s2inc)
{ {
combineTwoMultiArraysExpandImpl(s1.begin(), sshape1, src1, combineTwoMultiArraysExpandImpl(s1.begin(), sshape1, src1,
s2.begin(), sshape2, src2, s2.begin(), sshape2, src2,
d.begin(), dshape, dest, d.begin(), dshape, dest,
f, MetaInt<N-1>()); f, MetaInt<N-1>());
} }
} }
template <class SrcIterator1, class SrcShape1, class SrcAccessor1, template <class SrcIterator1, class SrcShape1, class SrcAccessor1,
class SrcIterator2, class SrcShape2, class SrcAccessor2, class SrcIterator2, class SrcShape2, class SrcAccessor2,
skipping to change at line 966 skipping to change at line 1015
must be either equal (standard copy), or the length of this dimension m ust must be either equal (standard copy), or the length of this dimension m ust
be 1 in one or both source arrays be 1 in one or both source arrays
(expand mode), or the destination length must be 1 (reduce mode). Howev er, (expand mode), or the destination length must be 1 (reduce mode). Howev er,
reduction and expansion cannot be executed at the same time, so the lat ter reduction and expansion cannot be executed at the same time, so the lat ter
conditions are mutual exclusive, even if they apply to different dimens ions. conditions are mutual exclusive, even if they apply to different dimens ions.
The function uses accessors to access the data elements. The function uses accessors to access the data elements.
<b> Declarations:</b> <b> Declarations:</b>
<b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr a/multi_pointoperators.hxx</a>"<br> <b>\#include</b> \<<a href="multi__pointoperators_8hxx-source.html">vig ra/multi_pointoperators.hxx</a>\><br>
Namespace: vigra Namespace: vigra
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator1, class SrcShape, class SrcAccessor1, template <class SrcIterator1, class SrcShape, class SrcAccessor1,
class SrcIterator2, class SrcAccessor2, class SrcIterator2, class SrcAccessor2,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class Functor> class Functor>
void combineTwoMultiArrays( void combineTwoMultiArrays(
skipping to change at line 993 skipping to change at line 1042
class DestIterator, class DestShape, class DestAccessor, class DestIterator, class DestShape, class DestAccessor,
class Functor> class Functor>
void combineTwoMultiArrays( void combineTwoMultiArrays(
SrcIterator1 s1, SrcShape1 const & sshape1, SrcAcces sor1 src1, SrcIterator1 s1, SrcShape1 const & sshape1, SrcAcces sor1 src1,
SrcIterator2 s2, SrcShape2 const & sshape2, SrcAcces sor2 src2, SrcIterator2 s2, SrcShape2 const & sshape2, SrcAcces sor2 src2,
DestIterator d, DestShape const & dshape, DestAccess or dest, DestIterator d, DestShape const & dshape, DestAccess or dest,
Functor const & f); Functor const & f);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator1, class SrcShape, class SrcAccessor1, template <class SrcIterator1, class SrcShape, class SrcAccessor1,
class SrcIterator2, class SrcAccessor2, class SrcIterator2, class SrcAccessor2,
class DestIterator, class DestAccessor, class Functor> class DestIterator, class DestAccessor, class Functor>
void combineTwoMultiArrays( void combineTwoMultiArrays(
triple<SrcIterator1, SrcShape, SrcAccessor1> const & src1, triple<SrcIterator1, SrcShape, SrcAccessor1> const & src1,
pair<SrcIterator2, SrcAccessor2> const & src2, pair<SrcIterator2, SrcAccessor2> const & src2,
pair<DestIterator, DestAccessor> const & dest, Funct or const & f); pair<DestIterator, DestAccessor> const & dest, Funct or const & f);
skipping to change at line 1120 skipping to change at line 1169
dest_accessor.set( dest_accessor.set(
functor(src1_accessor(src1_begin), src2_accessor(src2_begin)), functor(src1_accessor(src1_begin), src2_accessor(src2_begin)),
dest_begin); dest_begin);
\endcode \endcode
In reduce mode, it must be a model of BinaryAnalyser (i.e. support func tion call In reduce mode, it must be a model of BinaryAnalyser (i.e. support func tion call
with two arguments and no return vakue <tt>functor(arg1, arg2)</tt>) an d Initializer with two arguments and no return vakue <tt>functor(arg1, arg2)</tt>) an d Initializer
(i.e. support function call with no argument, but return value (i.e. support function call with no argument, but return value
<tt>res = functor()</tt>). Internally, such functors are recognized by the <tt>res = functor()</tt>). Internally, such functors are recognized by the
meta functions <tt>FunctorTraits&lt;FUNCTOR&gt;::</tt><tt>isBinaryAnaly meta functions <tt>FunctorTraits<FUNCTOR>::isBinaryAnalyser</tt> and
ser</tt> and <tt>FunctorTraits<FUNCTOR>::isInitializer</tt> which must both yield
<tt>FunctorTraits&lt;FUNCTOR&gt;::</tt><tt>isInitializer</tt> which mus
t both yield
<tt>VigraTrueType</tt>. Make sure that your functor correctly defines <tt>VigraTrueType</tt>. Make sure that your functor correctly defines
<tt>FunctorTraits</tt> because otherwise reduce mode will not work. In addition, <tt>FunctorTraits</tt> because otherwise reduce mode will not work. In addition,
the functor must be copy constructible in order to start each reduction the functor must be copy constructible in order to start each reduction
with a fresh functor. with a fresh functor.
\code \code
MultiIterator src1_begin, src2_begin, dest_begin; MultiIterator src1_begin, src2_begin, dest_begin;
SrcAccessor1 src1_accessor; SrcAccessor1 src1_accessor;
SrcAccessor2 src2_accessor; SrcAccessor2 src2_accessor;
skipping to change at line 1143 skipping to change at line 1192
FUNCTOR initial_functor, functor(initial_functor); FUNCTOR initial_functor, functor(initial_functor);
assert(typeid(FunctorTraits<FUNCTOR>::isInitializer) == typeid(VigraTru eType)); assert(typeid(FunctorTraits<FUNCTOR>::isInitializer) == typeid(VigraTru eType));
assert(typeid(FunctorTraits<FUNCTOR>::isBinaryAnalyser) == typeid(Vigra TrueType)); assert(typeid(FunctorTraits<FUNCTOR>::isBinaryAnalyser) == typeid(Vigra TrueType));
functor(src1_accessor(src1_begin), src2_accessor(src2_begin)); functor(src1_accessor(src1_begin), src2_accessor(src2_begin));
dest_accessor.set(functor(), dest_begin); dest_accessor.set(functor(), dest_begin);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void combineTwoMultiArrays)
template <class SrcIterator1, class SrcShape, class SrcAccessor1, template <class SrcIterator1, class SrcShape, class SrcAccessor1,
class SrcIterator2, class SrcAccessor2, class SrcIterator2, class SrcAccessor2,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class Functor> class Functor>
inline void inline void
combineTwoMultiArrays(SrcIterator1 s1, SrcShape const & shape, SrcAccessor1 src1, combineTwoMultiArrays(SrcIterator1 s1, SrcShape const & shape, SrcAccessor1 src1,
SrcIterator2 s2, SrcAccessor2 src2, SrcIterator2 s2, SrcAccessor2 src2,
DestIterator d, DestAccessor dest, Functor const & f) DestIterator d, DestAccessor dest, Functor const & f)
{ {
combineTwoMultiArraysExpandImpl(s1, shape, src1, s2, shape, src2, d, sh ape, dest, f, combineTwoMultiArraysExpandImpl(s1, shape, src1, s2, shape, src2, d, sh ape, dest, f,
skipping to change at line 1241 skipping to change at line 1292
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class Functor, int N> class Functor, int N>
void void
combineThreeMultiArraysImpl(SrcIterator1 s1, SrcShape const & shape, SrcAcc essor1 src1, combineThreeMultiArraysImpl(SrcIterator1 s1, SrcShape const & shape, SrcAcc essor1 src1,
SrcIterator2 s2, SrcAccessor2 src2, SrcIterator2 s2, SrcAccessor2 src2,
SrcIterator3 s3, SrcAccessor3 src3, SrcIterator3 s3, SrcAccessor3 src3,
DestIterator d, DestAccessor dest, DestIterator d, DestAccessor dest,
Functor const & f, MetaInt<N>) Functor const & f, MetaInt<N>)
{ {
SrcIterator1 s1end = s1 + shape[N]; SrcIterator1 s1end = s1 + shape[N];
for(; s1 != s1end; ++s1, ++s2, ++s3, ++d) for(; s1 < s1end; ++s1, ++s2, ++s3, ++d)
{ {
combineThreeMultiArraysImpl(s1.begin(), shape, src1, combineThreeMultiArraysImpl(s1.begin(), shape, src1,
s2.begin(), src2, s3.begin(), src3, d.beg in(), dest, s2.begin(), src2, s3.begin(), src3, d.beg in(), dest,
f, MetaInt<N-1>()); f, MetaInt<N-1>());
} }
} }
/** \brief Combine three multi-dimensional arrays into one using a /** \brief Combine three multi-dimensional arrays into one using a
ternary function or functor. ternary function or functor.
skipping to change at line 1273 skipping to change at line 1324
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class Functor> class Functor>
void void
combineThreeMultiArrays(SrcIterator1 s1, SrcShape const & shape, Sr cAccessor1 src1, combineThreeMultiArrays(SrcIterator1 s1, SrcShape const & shape, Sr cAccessor1 src1,
SrcIterator2 s2, SrcAccessor2 src2, SrcIterator2 s2, SrcAccessor2 src2,
SrcIterator3 s3, SrcAccessor3 src3, SrcIterator3 s3, SrcAccessor3 src3,
DestIterator d, DestAccessor dest, Functor const & f ); DestIterator d, DestAccessor dest, Functor const & f );
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator1, class SrcShape, class SrcAccessor1, template <class SrcIterator1, class SrcShape, class SrcAccessor1,
class SrcIterator2, class SrcAccessor2, class SrcIterator2, class SrcAccessor2,
class SrcIterator3, class SrcAccessor3, class SrcIterator3, class SrcAccessor3,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class Functor> class Functor>
inline void inline void
combineThreeMultiArrays(triple<SrcIterator1, SrcShape, SrcAccessor1 > const & src1, combineThreeMultiArrays(triple<SrcIterator1, SrcShape, SrcAccessor1 > const & src1,
pair<SrcIterator2, SrcAccessor2> const & src2, pair<SrcIterator2, SrcAccessor2> const & src2,
pair<SrcIterator3, SrcAccessor3> const & src3, pair<SrcIterator3, SrcAccessor3> const & src3,
pair<DestIterator, DestAccessor> const & dest, Funct or const & f); pair<DestIterator, DestAccessor> const & dest, Funct or const & f);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr a/multi_pointoperators.hxx</a>"<br> <b>\#include</b> \<<a href="multi__pointoperators_8hxx-source.html">vig ra/multi_pointoperators.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
#include <functional> // for plus #include <functional> // for plus
typedef vigra::MultiArray<3, int> Array; typedef vigra::MultiArray<3, int> Array;
Array src1(Array::size_type(100, 200, 50)), Array src1(Array::size_type(100, 200, 50)),
src2(Array::size_type(100, 200, 50)), src2(Array::size_type(100, 200, 50)),
src3(Array::size_type(100, 200, 50)), src3(Array::size_type(100, 200, 50)),
dest(Array::size_type(100, 200, 50)); dest(Array::size_type(100, 200, 50));
skipping to change at line 1313 skipping to change at line 1364
vigra::combineThreeMultiArrays( vigra::combineThreeMultiArrays(
srcMultiArrayRange(src1), srcMultiArrayRange(src1),
srcMultiArray(src2), srcMultiArray(src2),
srcMultiArray(src3), srcMultiArray(src3),
destMultiArray(dest), destMultiArray(dest),
SomeThreeArgumentFunctor()); SomeThreeArgumentFunctor());
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void combineThreeMultiArrays)
template <class SrcIterator1, class SrcShape, class SrcAccessor1, template <class SrcIterator1, class SrcShape, class SrcAccessor1,
class SrcIterator2, class SrcAccessor2, class SrcIterator2, class SrcAccessor2,
class SrcIterator3, class SrcAccessor3, class SrcIterator3, class SrcAccessor3,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class Functor> class Functor>
inline void inline void
combineThreeMultiArrays(SrcIterator1 s1, SrcShape const & shape, SrcAccesso r1 src1, combineThreeMultiArrays(SrcIterator1 s1, SrcShape const & shape, SrcAccesso r1 src1,
SrcIterator2 s2, SrcAccessor2 src2, SrcIterator2 s2, SrcAccessor2 src2,
SrcIterator3 s3, SrcAccessor3 src3, SrcIterator3 s3, SrcAccessor3 src3,
DestIterator d, DestAccessor dest, Functor const & f) DestIterator d, DestAccessor dest, Functor const & f)
skipping to change at line 1363 skipping to change at line 1416
inspectMultiArrayImpl(Iterator s, Shape const & shape, Accessor a, Functor & f, MetaInt<0>) inspectMultiArrayImpl(Iterator s, Shape const & shape, Accessor a, Functor & f, MetaInt<0>)
{ {
inspectLine(s, s + shape[0], a, f); inspectLine(s, s + shape[0], a, f);
} }
template <class Iterator, class Shape, class Accessor, class Functor, int N > template <class Iterator, class Shape, class Accessor, class Functor, int N >
void void
inspectMultiArrayImpl(Iterator s, Shape const & shape, Accessor a, Functor & f, MetaInt<N>) inspectMultiArrayImpl(Iterator s, Shape const & shape, Accessor a, Functor & f, MetaInt<N>)
{ {
Iterator send = s + shape[N]; Iterator send = s + shape[N];
for(; s != send; ++s) for(; s < send; ++s)
{ {
inspectMultiArrayImpl(s.begin(), shape, a, f, MetaInt<N-1>()); inspectMultiArrayImpl(s.begin(), shape, a, f, MetaInt<N-1>());
} }
} }
/** \brief Call an analyzing functor at every element of a multi-dimensiona l array. /** \brief Call an analyzing functor at every element of a multi-dimensiona l array.
This function can be used to collect statistics of the array etc. This function can be used to collect statistics of the array etc.
The results must be stored in the functor, which serves as a return The results must be stored in the functor, which serves as a return
value. The arrays must be represented by value. The arrays must be represented by
skipping to change at line 1391 skipping to change at line 1444
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class Iterator, class Shape, class Accessor, class Functo r> template <class Iterator, class Shape, class Accessor, class Functo r>
void void
inspectMultiArray(Iterator s, Shape const & shape, Accessor a, Fun ctor & f); inspectMultiArray(Iterator s, Shape const & shape, Accessor a, Fun ctor & f);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class Iterator, class Shape, class Accessor, class Functo r> template <class Iterator, class Shape, class Accessor, class Functo r>
void void
inspectMultiArray(triple<Iterator, Shape, Accessor> const & s, Func tor & f); inspectMultiArray(triple<Iterator, Shape, Accessor> const & s, Func tor & f);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr a/multi_pointoperators.hxx</a>"<br> <b>\#include</b> \<<a href="multi__pointoperators_8hxx-source.html">vig ra/multi_pointoperators.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
typedef vigra::MultiArray<3, int> Array; typedef vigra::MultiArray<3, int> Array;
Array array(Array::size_type(100, 200, 50)); Array array(Array::size_type(100, 200, 50));
// init functor // init functor
vigra::FindMinMax<int> minmax; vigra::FindMinMax<int> minmax;
vigra::inspectMultiArray(srcMultiArrayRange(array), minmax); vigra::inspectMultiArray(srcMultiArrayRange(array), minmax);
skipping to change at line 1430 skipping to change at line 1483
\code \code
MultiIterator src_begin; MultiIterator src_begin;
Accessor accessor; Accessor accessor;
Functor functor; Functor functor;
functor(accessor(src_begin)); functor(accessor(src_begin));
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void inspectMultiArray)
template <class Iterator, class Shape, class Accessor, class Functor> template <class Iterator, class Shape, class Accessor, class Functor>
inline void inline void
inspectMultiArray(Iterator s, Shape const & shape, Accessor a, Functor & f ) inspectMultiArray(Iterator s, Shape const & shape, Accessor a, Functor & f )
{ {
inspectMultiArrayImpl(s, shape, a, f, MetaInt<Iterator::level>()); inspectMultiArrayImpl(s, shape, a, f, MetaInt<Iterator::level>());
} }
template <class Iterator, class Shape, class Accessor, class Functor> template <class Iterator, class Shape, class Accessor, class Functor>
inline void inline void
inspectMultiArray(triple<Iterator, Shape, Accessor> const & s, Functor & f) inspectMultiArray(triple<Iterator, Shape, Accessor> const & s, Functor & f)
skipping to change at line 1470 skipping to change at line 1525
template <class Iterator1, class Shape, class Accessor1, template <class Iterator1, class Shape, class Accessor1,
class Iterator2, class Accessor2, class Iterator2, class Accessor2,
class Functor, int N> class Functor, int N>
void void
inspectTwoMultiArraysImpl(Iterator1 s1, Shape const & shape, Accessor1 a1, inspectTwoMultiArraysImpl(Iterator1 s1, Shape const & shape, Accessor1 a1,
Iterator2 s2, Accessor2 a2, Iterator2 s2, Accessor2 a2,
Functor & f, MetaInt<N>) Functor & f, MetaInt<N>)
{ {
Iterator1 s1end = s1 + shape[N]; Iterator1 s1end = s1 + shape[N];
for(; s1 != s1end; ++s1, ++s2) for(; s1 < s1end; ++s1, ++s2)
{ {
inspectTwoMultiArraysImpl(s1.begin(), shape, a1, inspectTwoMultiArraysImpl(s1.begin(), shape, a1,
s2.begin(), a2, f, MetaInt<N-1>()); s2.begin(), a2, f, MetaInt<N-1>());
} }
} }
/** \brief Call an analyzing functor at all corresponding elements of /** \brief Call an analyzing functor at all corresponding elements of
two multi-dimensional arrays. two multi-dimensional arrays.
This function can be used to collect statistics of the array etc. This function can be used to collect statistics of the array etc.
skipping to change at line 1503 skipping to change at line 1558
namespace vigra { namespace vigra {
template <class Iterator1, class Shape, class Accessor1, template <class Iterator1, class Shape, class Accessor1,
class Iterator2, class Accessor2, class Iterator2, class Accessor2,
class Functor> class Functor>
void void
inspectTwoMultiArrays(Iterator1 s1, Shape const & shape, Accessor1 a1, inspectTwoMultiArrays(Iterator1 s1, Shape const & shape, Accessor1 a1,
Iterator2 s2, Accessor2 a2, Functor & f); Iterator2 s2, Accessor2 a2, Functor & f);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class Iterator1, class Shape1, class Accessor1, template <class Iterator1, class Shape1, class Accessor1,
class Iterator2, class Accessor2, class Iterator2, class Accessor2,
class Functor> class Functor>
void void
inspectTwoMultiArrays(triple<Iterator1, Shape1, Accessor1> const & s1, inspectTwoMultiArrays(triple<Iterator1, Shape1, Accessor1> const & s1,
pair<Iterator2, Accessor2> const & s2, Functo r & f); pair<Iterator2, Accessor2> const & s2, Functo r & f);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="multi__pointoperators_8hxx-source.html">vigr a/multi_pointoperators.hxx</a>"<br> <b>\#include</b> \<<a href="multi__pointoperators_8hxx-source.html">vig ra/multi_pointoperators.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
typedef vigra::MultiArray<3, int> Array; typedef vigra::MultiArray<3, int> Array;
Array array1(Array::size_type(100, 200, 50)), Array array1(Array::size_type(100, 200, 50)),
array2(Array::size_type(100, 200, 50)); array2(Array::size_type(100, 200, 50));
// init functor // init functor
SomeStatisticsFunctor stats(..); SomeStatisticsFunctor stats(..);
skipping to change at line 1544 skipping to change at line 1599
\code \code
MultiIterator src1_begin, src2_begin; MultiIterator src1_begin, src2_begin;
Accessor a1, a2; Accessor a1, a2;
Functor functor; Functor functor;
functor(a1(src1_begin), a2(src2_begin)); functor(a1(src1_begin), a2(src2_begin));
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void inspectTwoMultiArrays)
template <class Iterator1, class Shape, class Accessor1, template <class Iterator1, class Shape, class Accessor1,
class Iterator2, class Accessor2, class Iterator2, class Accessor2,
class Functor> class Functor>
inline void inline void
inspectTwoMultiArrays(Iterator1 s1, Shape const & shape, Accessor1 a1, inspectTwoMultiArrays(Iterator1 s1, Shape const & shape, Accessor1 a1,
Iterator2 s2, Accessor2 a2, Functor & f) Iterator2 s2, Accessor2 a2, Functor & f)
{ {
inspectTwoMultiArraysImpl(s1, shape, a1, s2, a2, f, MetaInt<Iterator1:: level>()); inspectTwoMultiArraysImpl(s1, shape, a1, s2, a2, f, MetaInt<Iterator1:: level>());
} }
skipping to change at line 1568 skipping to change at line 1625
void void
inspectTwoMultiArrays(triple<Iterator1, Shape, Accessor1> const & s1, inspectTwoMultiArrays(triple<Iterator1, Shape, Accessor1> const & s1,
pair<Iterator2, Accessor2> const & s2, Functor & f) pair<Iterator2, Accessor2> const & s2, Functor & f)
{ {
inspectTwoMultiArrays(s1.first, s1.second, s1.third, inspectTwoMultiArrays(s1.first, s1.second, s1.third,
s2.first, s2.second, f); s2.first, s2.second, f);
} }
//@} //@}
} //-- namespace vigra } //-- namespace vigra
#endif //-- VIGRA_MULTI_POINTOPERATORS_H #endif //-- VIGRA_MULTI_POINTOPERATORS_H
 End of changes. 53 change blocks. 
50 lines changed or deleted 113 lines changed or added


 navigator.hxx   navigator.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2004 by Ullrich Koethe */ /* Copyright 2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 67 skipping to change at line 67
array (represented by a vigra::MultiIterator/shape pair), and the desir ed array (represented by a vigra::MultiIterator/shape pair), and the desir ed
inner loop dimension <TT>d</TT>, it moves the encapsulated iterator to all possible inner loop dimension <TT>d</TT>, it moves the encapsulated iterator to all possible
starting points of 1D subsets along the given dimension (e.g. all colum ns). By calling starting points of 1D subsets along the given dimension (e.g. all colum ns). By calling
<TT>begin()</TT> and <TT>end()</TT>, one can then obtain an STL-compati ble 1-dimensional <TT>begin()</TT> and <TT>end()</TT>, one can then obtain an STL-compati ble 1-dimensional
iterator for the current subset. iterator for the current subset.
The template parameters specify the embedded iterator type and its dime nsion. The template parameters specify the embedded iterator type and its dime nsion.
<b>Usage:</b> <b>Usage:</b>
<b>\#include</b> "<a href="navigator_8hxx-source.html">vigra/navigator. hxx</a>" <b>\#include</b> \<<a href="navigator_8hxx-source.html">vigra/navigator .hxx</a>\>
Namespace: vigra Namespace: vigra
\code \code
typedef vigra::MultiArray<3, int> Array; typedef vigra::MultiArray<3, int> Array;
Array a(Array::size_type(X, Y, Z)); Array a(Array::size_type(X, Y, Z));
typedef vigra::MultiArrayNavigator<Array::traverser, 3> Navigator; typedef vigra::MultiArrayNavigator<Array::traverser, 3> Navigator;
 End of changes. 3 change blocks. 
4 lines changed or deleted 4 lines changed or added


 noise_normalization.hxx   noise_normalization.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2006 by Ullrich Koethe */ /* Copyright 1998-2006 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 76 skipping to change at line 76
/********************************************************/ /********************************************************/
/** \brief Pass options to one of the noise normalization functions. /** \brief Pass options to one of the noise normalization functions.
<tt>NoiseNormalizationOptions</tt> is an argument object that holds va rious optional <tt>NoiseNormalizationOptions</tt> is an argument object that holds va rious optional
parameters used by the noise normalization functions. If a parameter is not explicitly parameters used by the noise normalization functions. If a parameter is not explicitly
set, a suitable default will be used. set, a suitable default will be used.
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="noise__normalization_8hxx-source.html">v igra/noise_normalization.hxx</a>"<br> <b>\#include</b> \<<a href="noise__normalization_8hxx-source.html"> vigra/noise_normalization.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h); vigra::BImage src(w,h);
std::vector<vigra::TinyVector<double, 2> > result; std::vector<vigra::TinyVector<double, 2> > result;
... ...
vigra::noiseVarianceEstimation(srcImageRange(src), result, vigra::noiseVarianceEstimation(srcImageRange(src), result,
vigra::NoiseNormalizationOptions().window Radius(9).noiseVarianceInitialGuess(25.0)); vigra::NoiseNormalizationOptions().window Radius(9).noiseVarianceInitialGuess(25.0));
\endcode \endcode
skipping to change at line 974 skipping to change at line 974
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, class BackInsertabl e> template <class SrcIterator, class SrcAccessor, class BackInsertabl e>
void noiseVarianceEstimation(SrcIterator sul, SrcIterator slr, SrcA ccessor src, void noiseVarianceEstimation(SrcIterator sul, SrcIterator slr, SrcA ccessor src,
BackInsertable & result, BackInsertable & result,
NoiseNormalizationOptions const & opti ons = NoiseNormalizationOptions()); NoiseNormalizationOptions const & opti ons = NoiseNormalizationOptions());
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, class BackInsertabl e> template <class SrcIterator, class SrcAccessor, class BackInsertabl e>
void noiseVarianceEstimation(triple<SrcIterator, SrcIterator, SrcAc cessor> src, void noiseVarianceEstimation(triple<SrcIterator, SrcIterator, SrcAc cessor> src,
BackInsertable & result, BackInsertable & result,
NoiseNormalizationOptions const & opti ons = NoiseNormalizationOptions()); NoiseNormalizationOptions const & opti ons = NoiseNormalizationOptions());
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="noise__normalization_8hxx-source.html">v igra/noise_normalization.hxx</a>"<br> <b>\#include</b> \<<a href="noise__normalization_8hxx-source.html"> vigra/noise_normalization.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h); vigra::BImage src(w,h);
std::vector<vigra::TinyVector<double, 2> > result; std::vector<vigra::TinyVector<double, 2> > result;
... ...
vigra::noiseVarianceEstimation(srcImageRange(src), result, vigra::noiseVarianceEstimation(srcImageRange(src), result,
vigra::NoiseNormalizationOptions().window Radius(9).noiseVarianceInitialGuess(25.0)); vigra::NoiseNormalizationOptions().window Radius(9).noiseVarianceInitialGuess(25.0));
skipping to change at line 1020 skipping to change at line 1020
assert(isScalar::asBool == true); assert(isScalar::asBool == true);
double value = src(uperleft); double value = src(uperleft);
BackInsertable result; BackInsertable result;
typedef BackInsertable::value_type ResultType; typedef BackInsertable::value_type ResultType;
double intensity, variance; double intensity, variance;
result.push_back(ResultType(intensity, variance)); result.push_back(ResultType(intensity, variance));
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void noiseVarianceEstimation)
template <class SrcIterator, class SrcAccessor, class BackInsertable> template <class SrcIterator, class SrcAccessor, class BackInsertable>
inline inline
void noiseVarianceEstimation(SrcIterator sul, SrcIterator slr, SrcAccessor src, void noiseVarianceEstimation(SrcIterator sul, SrcIterator slr, SrcAccessor src,
BackInsertable & result, BackInsertable & result,
NoiseNormalizationOptions const & options = Nois eNormalizationOptions()) NoiseNormalizationOptions const & options = Nois eNormalizationOptions())
{ {
typedef typename BackInsertable::value_type ResultType; typedef typename BackInsertable::value_type ResultType;
typedef typename SrcAccessor::value_type SrcType; typedef typename SrcAccessor::value_type SrcType;
typedef typename NumericTraits<SrcType>::isScalar isScalar; typedef typename NumericTraits<SrcType>::isScalar isScalar;
skipping to change at line 1074 skipping to change at line 1076
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, class BackInsertabl e> template <class SrcIterator, class SrcAccessor, class BackInsertabl e>
void noiseVarianceClustering(SrcIterator sul, SrcIterator slr, SrcA ccessor src, void noiseVarianceClustering(SrcIterator sul, SrcIterator slr, SrcA ccessor src,
BackInsertable & result, BackInsertable & result,
NoiseNormalizationOptions const & options = NoiseNormalizationOptions()); NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, class BackInsertabl e> template <class SrcIterator, class SrcAccessor, class BackInsertabl e>
void noiseVarianceClustering(triple<SrcIterator, SrcIterator, SrcAc cessor> src, void noiseVarianceClustering(triple<SrcIterator, SrcIterator, SrcAc cessor> src,
BackInsertable & result, BackInsertable & result,
NoiseNormalizationOptions const & options = NoiseNormalizationOptions()); NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="noise__normalization_8hxx-source.html">v igra/noise_normalization.hxx</a>"<br> <b>\#include</b> \<<a href="noise__normalization_8hxx-source.html"> vigra/noise_normalization.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h); vigra::BImage src(w,h);
std::vector<vigra::TinyVector<double, 2> > result; std::vector<vigra::TinyVector<double, 2> > result;
... ...
vigra::noiseVarianceClustering(srcImageRange(src), result, vigra::noiseVarianceClustering(srcImageRange(src), result,
vigra::NoiseNormalizationOptions().window Radius(9).noiseVarianceInitialGuess(25.0). vigra::NoiseNormalizationOptions().window Radius(9).noiseVarianceInitialGuess(25.0).
clusterCount(15)); clusterCount(15));
// print the intensity / variance pairs representing the cluster center s // print the intensity / variance pairs representing the cluster center s
for(int k=0; k<result.size(); ++k) for(int k=0; k<result.size(); ++k)
std::cout << "Cluster: " << k << ", intensity: " << result[k][0] << ", estimated variance: " << result[k][1] << std::endl; std::cout << "Cluster: " << k << ", intensity: " << result[k][0] << ", estimated variance: " << result[k][1] << std::endl;
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
same as \ref noiseVarianceEstimation() same as \ref noiseVarianceEstimation()
*/ */
doxygen_overloaded_function(template <...> void noiseVarianceClustering)
template <class SrcIterator, class SrcAccessor, class BackInsertable> template <class SrcIterator, class SrcAccessor, class BackInsertable>
inline inline
void noiseVarianceClustering(SrcIterator sul, SrcIterator slr, SrcAccessor src, void noiseVarianceClustering(SrcIterator sul, SrcIterator slr, SrcAccessor src,
BackInsertable & result, BackInsertable & result,
NoiseNormalizationOptions const & options = Nois eNormalizationOptions()) NoiseNormalizationOptions const & options = Nois eNormalizationOptions())
{ {
ArrayVector<TinyVector<double, 2> > variance; ArrayVector<TinyVector<double, 2> > variance;
noiseVarianceEstimation(sul, slr, src, variance, options); noiseVarianceEstimation(sul, slr, src, variance, options);
detail::noiseVarianceClusteringImpl(variance, result, options.cluster_c ount, options.averaging_quantile); detail::noiseVarianceClusteringImpl(variance, result, options.cluster_c ount, options.averaging_quantile);
} }
skipping to change at line 1167 skipping to change at line 1171
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
bool nonparametricNoiseNormalization(SrcIterator sul, SrcIterator s lr, SrcAccessor src, bool nonparametricNoiseNormalization(SrcIterator sul, SrcIterator s lr, SrcAccessor src,
DestIterator dul, DestAccessor dest, DestIterator dul, DestAccessor dest,
NoiseNormalizationOptions cons t & options = NoiseNormalizationOptions()); NoiseNormalizationOptions cons t & options = NoiseNormalizationOptions());
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
bool nonparametricNoiseNormalization(triple<SrcIterator, SrcIterato r, SrcAccessor> src, bool nonparametricNoiseNormalization(triple<SrcIterator, SrcIterato r, SrcAccessor> src,
pair<DestIterator, DestAccesso r> dest, pair<DestIterator, DestAccesso r> dest,
NoiseNormalizationOptions cons t & options = NoiseNormalizationOptions()); NoiseNormalizationOptions cons t & options = NoiseNormalizationOptions());
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="noise__normalization_8hxx-source.html">v igra/noise_normalization.hxx</a>"<br> <b>\#include</b> \<<a href="noise__normalization_8hxx-source.html"> vigra/noise_normalization.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BRGBImage src(w,h), dest(w, h); vigra::BRGBImage src(w,h), dest(w, h);
... ...
vigra::nonparametricNoiseNormalization(srcImageRange(src), destImage(de st), vigra::nonparametricNoiseNormalization(srcImageRange(src), destImage(de st),
vigra::NoiseNormalizationOptions ().windowRadius(9).noiseVarianceInitialGuess(25.0). vigra::NoiseNormalizationOptions ().windowRadius(9).noiseVarianceInitialGuess(25.0).
clusterCount(15)); clusterCount(15));
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
same as \ref noiseVarianceEstimation() same as \ref noiseVarianceEstimation()
*/ */
doxygen_overloaded_function(template <...> bool nonparametricNoiseNormaliza
tion)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline bool inline bool
nonparametricNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccess or src, nonparametricNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccess or src,
DestIterator dul, DestAccessor dest, DestIterator dul, DestAccessor dest,
NoiseNormalizationOptions const & options = NoiseNormalizationOptions()) NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
{ {
typedef typename SrcAccessor::value_type SrcType; typedef typename SrcAccessor::value_type SrcType;
return detail::nonparametricNoiseNormalizationImpl(sul, slr, src, dul, dest, options, return detail::nonparametricNoiseNormalizationImpl(sul, slr, src, dul, dest, options,
skipping to change at line 1245 skipping to change at line 1251
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
bool quadraticNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src, bool quadraticNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src,
DestIterator dul, DestAccessor des t, DestIterator dul, DestAccessor des t,
NoiseNormalizationOptions const & options = NoiseNormalizationOptions()); NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
bool quadraticNoiseNormalization(triple<SrcIterator, SrcIterator, S rcAccessor> src, bool quadraticNoiseNormalization(triple<SrcIterator, SrcIterator, S rcAccessor> src,
pair<DestIterator, DestAccessor> d est, pair<DestIterator, DestAccessor> d est,
NoiseNormalizationOptions const & options = NoiseNormalizationOptions()); NoiseNormalizationOptions const & options = NoiseNormalizationOptions());
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="noise__normalization_8hxx-source.html">v igra/noise_normalization.hxx</a>"<br> <b>\#include</b> \<<a href="noise__normalization_8hxx-source.html"> vigra/noise_normalization.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BRGBImage src(w,h), dest(w, h); vigra::BRGBImage src(w,h), dest(w, h);
... ...
vigra::quadraticNoiseNormalization(srcImageRange(src), destImage(dest), vigra::quadraticNoiseNormalization(srcImageRange(src), destImage(dest),
vigra::NoiseNormalizationOptions().w indowRadius(9).noiseVarianceInitialGuess(25.0). vigra::NoiseNormalizationOptions().w indowRadius(9).noiseVarianceInitialGuess(25.0).
clusterCount(15)); clusterCount(15));
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
same as \ref noiseVarianceEstimation() same as \ref noiseVarianceEstimation()
*/ */
doxygen_overloaded_function(template <...> bool quadraticNoiseNormalization
)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline bool inline bool
quadraticNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor s rc, quadraticNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor s rc,
DestIterator dul, DestAccessor dest, DestIterator dul, DestAccessor dest,
NoiseNormalizationOptions const & options = NoiseNormalizationOptions()) NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
{ {
typedef typename SrcAccessor::value_type SrcType; typedef typename SrcAccessor::value_type SrcType;
return detail::quadraticNoiseNormalizationImpl(sul, slr, src, dul, dest , options, return detail::quadraticNoiseNormalizationImpl(sul, slr, src, dul, dest , options,
skipping to change at line 1326 skipping to change at line 1334
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void quadraticNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src, void quadraticNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src,
DestIterator dul, DestAccessor des t, DestIterator dul, DestAccessor des t,
double a0, double a1, double a2); double a0, double a1, double a2);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void quadraticNoiseNormalization(triple<SrcIterator, SrcIterator, S rcAccessor> src, void quadraticNoiseNormalization(triple<SrcIterator, SrcIterator, S rcAccessor> src,
pair<DestIterator, DestAccessor> de st, pair<DestIterator, DestAccessor> de st,
double a0, double a1, double a2); double a0, double a1, double a2);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="noise__normalization_8hxx-source.html">v igra/noise_normalization.hxx</a>"<br> <b>\#include</b> \<<a href="noise__normalization_8hxx-source.html"> vigra/noise_normalization.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BRGBImage src(w,h), dest(w, h); vigra::BRGBImage src(w,h), dest(w, h);
... ...
vigra::quadraticNoiseNormalization(srcImageRange(src), destImage(dest), vigra::quadraticNoiseNormalization(srcImageRange(src), destImage(dest),
100, 0.02, 1e-6); 100, 0.02, 1e-6);
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
The source value type must be convertible to <tt>double</tt> or must be a vector whose elements The source value type must be convertible to <tt>double</tt> or must be a vector whose elements
are convertible to <tt>double</tt>. Likewise, the destination type must be assignable from <tt>double</tt> are convertible to <tt>double</tt>. Likewise, the destination type must be assignable from <tt>double</tt>
or a vector whose elements are assignable from <tt>double</tt>. or a vector whose elements are assignable from <tt>double</tt>.
*/ */
doxygen_overloaded_function(template <...> void quadraticNoiseNormalization
)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline void inline void
quadraticNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor s rc, quadraticNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor s rc,
DestIterator dul, DestAccessor dest, DestIterator dul, DestAccessor dest,
double a0, double a1, double a2) double a0, double a1, double a2)
{ {
typedef typename SrcAccessor::value_type SrcType; typedef typename SrcAccessor::value_type SrcType;
detail::quadraticNoiseNormalizationImpl(sul, slr, src, dul, dest, a0, a 1, a2, detail::quadraticNoiseNormalizationImpl(sul, slr, src, dul, dest, a0, a 1, a2,
skipping to change at line 1405 skipping to change at line 1415
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
bool linearNoiseNormalization(SrcIterator sul, SrcIterator slr, Src Accessor src, bool linearNoiseNormalization(SrcIterator sul, SrcIterator slr, Src Accessor src,
DestIterator dul, DestAccessor dest, DestIterator dul, DestAccessor dest,
NoiseNormalizationOptions const & opt ions = NoiseNormalizationOptions()); NoiseNormalizationOptions const & opt ions = NoiseNormalizationOptions());
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
bool linearNoiseNormalization(triple<SrcIterator, SrcIterator, SrcA ccessor> src, bool linearNoiseNormalization(triple<SrcIterator, SrcIterator, SrcA ccessor> src,
pair<DestIterator, DestAccessor> dest , pair<DestIterator, DestAccessor> dest ,
NoiseNormalizationOptions const & opt ions = NoiseNormalizationOptions()); NoiseNormalizationOptions const & opt ions = NoiseNormalizationOptions());
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="noise__normalization_8hxx-source.html">v igra/noise_normalization.hxx</a>"<br> <b>\#include</b> \<<a href="noise__normalization_8hxx-source.html"> vigra/noise_normalization.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BRGBImage src(w,h), dest(w, h); vigra::BRGBImage src(w,h), dest(w, h);
... ...
vigra::linearNoiseNormalization(srcImageRange(src), destImage(dest), vigra::linearNoiseNormalization(srcImageRange(src), destImage(dest),
vigra::NoiseNormalizationOptions().wind owRadius(9).noiseVarianceInitialGuess(25.0). vigra::NoiseNormalizationOptions().wind owRadius(9).noiseVarianceInitialGuess(25.0).
clusterCount(15)); clusterCount(15));
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
same as \ref noiseVarianceEstimation() same as \ref noiseVarianceEstimation()
*/ */
doxygen_overloaded_function(template <...> bool linearNoiseNormalization)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline bool inline bool
linearNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src, linearNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src,
DestIterator dul, DestAccessor dest, DestIterator dul, DestAccessor dest,
NoiseNormalizationOptions const & options = NoiseNormalizationOptions()) NoiseNormalizationOptions const & options = NoiseNormalizationOptions())
{ {
typedef typename SrcAccessor::value_type SrcType; typedef typename SrcAccessor::value_type SrcType;
return detail::linearNoiseNormalizationImpl(sul, slr, src, dul, dest, o ptions, return detail::linearNoiseNormalizationImpl(sul, slr, src, dul, dest, o ptions,
skipping to change at line 1486 skipping to change at line 1498
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void linearNoiseNormalization(SrcIterator sul, SrcIterator slr, Src Accessor src, void linearNoiseNormalization(SrcIterator sul, SrcIterator slr, Src Accessor src,
DestIterator dul, DestAccessor dest, DestIterator dul, DestAccessor dest,
double a0, double a1); double a0, double a1);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void linearNoiseNormalization(triple<SrcIterator, SrcIterator, SrcA ccessor> src, void linearNoiseNormalization(triple<SrcIterator, SrcIterator, SrcA ccessor> src,
pair<DestIterator, DestAccessor> dest , pair<DestIterator, DestAccessor> dest ,
double a0, double a1); double a0, double a1);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="noise__normalization_8hxx-source.html">v igra/noise_normalization.hxx</a>"<br> <b>\#include</b> \<<a href="noise__normalization_8hxx-source.html"> vigra/noise_normalization.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BRGBImage src(w,h), dest(w, h); vigra::BRGBImage src(w,h), dest(w, h);
... ...
vigra::linearNoiseNormalization(srcImageRange(src), destImage(dest), vigra::linearNoiseNormalization(srcImageRange(src), destImage(dest),
100, 0.02); 100, 0.02);
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
The source value type must be convertible to <tt>double</tt> or must be a vector whose elements The source value type must be convertible to <tt>double</tt> or must be a vector whose elements
are convertible to <tt>double</tt>. Likewise, the destination type must be assignable from <tt>double</tt> are convertible to <tt>double</tt>. Likewise, the destination type must be assignable from <tt>double</tt>
or a vector whose elements are assignable from <tt>double</tt>. or a vector whose elements are assignable from <tt>double</tt>.
*/ */
doxygen_overloaded_function(template <...> void linearNoiseNormalization)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline inline
void linearNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src, void linearNoiseNormalization(SrcIterator sul, SrcIterator slr, SrcAccessor src,
DestIterator dul, DestAccessor dest, DestIterator dul, DestAccessor dest,
double a0, double a1) double a0, double a1)
{ {
typedef typename SrcAccessor::value_type SrcType; typedef typename SrcAccessor::value_type SrcType;
detail::linearNoiseNormalizationImpl(sul, slr, src, dul, dest, a0, a1, detail::linearNoiseNormalizationImpl(sul, slr, src, dul, dest, a0, a1,
 End of changes. 24 change blocks. 
18 lines changed or deleted 35 lines changed or added


 nonlineardiffusion.hxx   nonlineardiffusion.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 255 skipping to change at line 255
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class DiffusivityFunctor> class DiffusivityFunctor>
void nonlinearDiffusion(SrcIterator sul, SrcIterator slr, SrcAccess or as, void nonlinearDiffusion(SrcIterator sul, SrcIterator slr, SrcAccess or as,
DestIterator dul, DestAccessor ad, DestIterator dul, DestAccessor ad,
DiffusivityFunctor const & weight, double scale) DiffusivityFunctor const & weight, double s
; cale);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class DiffusivityFunctor> class DiffusivityFunctor>
void nonlinearDiffusion( void nonlinearDiffusion(
triple<SrcIterator, SrcIterator, SrcAccessor> src, triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
DiffusivityFunctor const & weight, double scale); DiffusivityFunctor const & weight, double scale);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="nonlineardiffusion_8hxx-source.html">vigra/n onlineardiffusion.hxx</a>" <b>\#include</b> \<<a href="nonlineardiffusion_8hxx-source.html">vigra/ nonlineardiffusion.hxx</a>\>
\code \code
FImage src(w,h), dest(w,h); FImage src(w,h), dest(w,h);
float edge_threshold, scale; float edge_threshold, scale;
... ...
nonlinearDiffusion(srcImageRange(src), destImage(dest), nonlinearDiffusion(srcImageRange(src), destImage(dest),
DiffusivityFunctor<float>(edge_threshold), scale); DiffusivityFunctor<float>(edge_threshold), scale);
\endcode \endcode
skipping to change at line 303 skipping to change at line 303
<li> <TT>DiffusivityFunctor</TT> conforms to the requirements of <li> <TT>DiffusivityFunctor</TT> conforms to the requirements of
\ref gradientBasedTransform(). Its range is between 0 and 1. \ref gradientBasedTransform(). Its range is between 0 and 1.
<li> <TT>DiffusivityFunctor::value_type</TT> is an algebraic field <li> <TT>DiffusivityFunctor::value_type</TT> is an algebraic field
</ul> </ul>
<b> Precondition:</b> <b> Precondition:</b>
<TT>scale > 0</TT> <TT>scale > 0</TT>
*/ */
doxygen_overloaded_function(template <...> void nonlinearDiffusion)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class DiffusivityFunc> class DiffusivityFunc>
void nonlinearDiffusion(SrcIterator sul, SrcIterator slr, SrcAccessor as, void nonlinearDiffusion(SrcIterator sul, SrcIterator slr, SrcAccessor as,
DestIterator dul, DestAccessor ad, DestIterator dul, DestAccessor ad,
DiffusivityFunc const & weight, double scale) DiffusivityFunc const & weight, double scale)
{ {
vigra_precondition(scale > 0.0, "nonlinearDiffusion(): scale must be > 0"); vigra_precondition(scale > 0.0, "nonlinearDiffusion(): scale must be > 0");
double total_time = scale*scale/2.0; double total_time = scale*scale/2.0;
 End of changes. 7 change blocks. 
11 lines changed or deleted 13 lines changed or added


 numerictraits.hxx   numerictraits.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 57 skipping to change at line 57
/********************************************************/ /********************************************************/
/* */ /* */
/* NumericTraits */ /* NumericTraits */
/* */ /* */
/********************************************************/ /********************************************************/
/** \page NumericPromotionTraits Numeric and Promotion Traits /** \page NumericPromotionTraits Numeric and Promotion Traits
Meta-information about arithmetic types. Meta-information about arithmetic types.
<DL> <UL style="list-style-image:url(documents/bullet.gif)">
<DT> <LI> \ref NumericTraits
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <BR>&nbsp;&nbsp;&nbsp;<em>Unary traits for promotion, conversion,
\ref NumericTraits creation of arithmetic objects</em>
<DD><em>Unary traits for promotion, conversion, creation of arithmetic <LI> \ref PromoteTraits
objects</em> <BR>&nbsp;&nbsp;&nbsp;<em>Binary traits for promotion of arithmeti
<DT> c objects</em>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref SquareRootTraits
\ref PromoteTraits <BR>&nbsp;&nbsp;&nbsp;<em>Unary traits for the calculation of the
<DD><em>Binary traits for promotion of arithmetic objects</em> square root of arithmetic objects</em>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref NormTraits
\ref SquareRootTraits <BR>&nbsp;&nbsp;&nbsp;<em>Unary traits for the calculation of the
<DD><em>Unary traits for the calculation of the square root of arithmet norm and squared norm of arithmetic objects</em>
ic objects</em> </UL>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref NormTraits
<DD><em>Unary traits for the calculation of the norm and squared norm o
f arithmetic objects</em>
</DL>
These traits classes contain information that is used by generic These traits classes contain information that is used by generic
algorithms and data structures to determine intermediate and result algorithms and data structures to determine intermediate and result
types of numerical calculations, to convert between different types of numerical calculations, to convert between different
representations of arithmetic types, and to create certain important representations of arithmetic types, and to create certain important
constants of each type. Thus, algorithms and data structures constants of each type. Thus, algorithms and data structures
operating that need arithmetic operations can be made more operating that need arithmetic operations can be made more
independent from the actual data representation. independent from the actual data representation.
NumericTraits are implemented as template specializations of one NumericTraits are implemented as template specializations of one
arithmetic type, while PromoteTraits are specialized for a pair of arithmetic type, while PromoteTraits are specialized for a pair of
arithmetic types that shall be combined in one operation. arithmetic types that shall be combined in one operation.
*/ */
/** \page NumericTraits template<> struct NumericTraits<ArithmeticType> /** \page NumericTraits template<> struct NumericTraits<ArithmeticType>
Unary traits for promotion, conversion, creation of arithmetic objects. Unary traits for promotion, conversion, creation of arithmetic objects.
<b>\#include</b> <b>\#include</b>
"<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" \<<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>\ >
This traits class is used derive important properties of This traits class is used derive important properties of
an arithmetic type. Consider the following algorithm: an arithmetic type. Consider the following algorithm:
\code \code
// calculate the sum of a sequence of bytes // calculate the sum of a sequence of bytes
int sumBytes(unsigned char * begin, unsigned char * end) int sumBytes(unsigned char * begin, unsigned char * end)
{ {
int result = 0; int result = 0;
for(; begin != end; ++begin) result += *begin; for(; begin != end; ++begin) result += *begin;
skipping to change at line 321 skipping to change at line 315
<b> <TT>typedef ... isComplex;</TT></b> <b> <TT>typedef ... isComplex;</TT></b>
</td><td> </td><td>
VigraTrueType if <TT>ArithmeticType</TT> is a complex number, VigraTrueType if <TT>ArithmeticType</TT> is a complex number,
VigraFalseType otherwise VigraFalseType otherwise
</td></tr> </td></tr>
<tr><td> <tr><td>
</table> </table>
NumericTraits for the built-in types are defined in <b>\#include</b> NumericTraits for the built-in types are defined in <b>\#include</b>
"<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" \<<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>\ >
Namespace: vigra Namespace: vigra
*/ */
/** \page PromoteTraits template<> struct PromoteTraits<ArithmeticType1, Ar ithmeticType2> /** \page PromoteTraits template<> struct PromoteTraits<ArithmeticType1, Ar ithmeticType2>
Binary traits for promotion of arithmetic objects. Binary traits for promotion of arithmetic objects.
<b>\#include</b> <b>\#include</b>
"<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" \<<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>\ >
This traits class is used to determine the appropriate result type This traits class is used to determine the appropriate result type
of arithmetic expressions which depend of two arguments. Consider of arithmetic expressions which depend of two arguments. Consider
the following function: the following function:
\code \code
template <class T> template <class T>
T min(T t1, T t2) T min(T t1, T t2)
{ {
return (t1 < t2) ? t1 : t2; return (t1 < t2) ? t1 : t2;
skipping to change at line 384 skipping to change at line 378
<tr><td> <tr><td>
<b> <TT>static Promote toPromote(ArithmeticType1 v);</TT></b> <b> <TT>static Promote toPromote(ArithmeticType1 v);</TT></b>
<b> <TT>static Promote toPromote(ArithmeticType2 v);</TT></b> <b> <TT>static Promote toPromote(ArithmeticType2 v);</TT></b>
</td><td> </td><td>
convert to <TT>Promote</TT> type convert to <TT>Promote</TT> type
</td></tr> </td></tr>
</table> </table>
PromoteTraits for the built-in types are defined in <b>\#include</b> PromoteTraits for the built-in types are defined in <b>\#include</b>
"<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" \<<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>\ >
Namespace: vigra Namespace: vigra
*/ */
/** \page SquareRootTraits template<> struct SquareRootTraits<ArithmeticTyp e> /** \page SquareRootTraits template<> struct SquareRootTraits<ArithmeticTyp e>
Unary traits for the calculation of the square root of arithmetic objec ts. Unary traits for the calculation of the square root of arithmetic objec ts.
<b>\#include</b> <b>\#include</b>
"<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" \<<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>\ >
This traits class is used to determine appropriate argument and result types This traits class is used to determine appropriate argument and result types
for the function sqrt(). These traits are typically used like this: for the function sqrt(). These traits are typically used like this:
\code \code
ArithmeticType t = ...; ArithmeticType t = ...;
SquareRootTraits<ArithmeticType>::SquareRootResult r = SquareRootTraits<ArithmeticType>::SquareRootResult r =
sqrt((SquareRootTraits<ArithmeticType>::SquareRootArgument)t); sqrt((SquareRootTraits<ArithmeticType>::SquareRootArgument)t);
\endcode \endcode
skipping to change at line 430 skipping to change at line 424
required argument type for srqt(), i.e. <tt>sqrt((SquareRootArg ument)x)</tt> required argument type for srqt(), i.e. <tt>sqrt((SquareRootArg ument)x)</tt>
</td></tr> </td></tr>
<tr><td> <tr><td>
<b> <TT>typedef ... SquareRootResult;</TT></b> <b> <TT>typedef ... SquareRootResult;</TT></b>
</td><td> </td><td>
result of <tt>sqrt((SquareRootArgument)x)</tt> result of <tt>sqrt((SquareRootArgument)x)</tt>
</td></tr> </td></tr>
</table> </table>
NormTraits for the built-in types are defined in <b>\#include</b> NormTraits for the built-in types are defined in <b>\#include</b>
"<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" \<<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>\ >
Namespace: vigra Namespace: vigra
*/ */
/** \page NormTraits template<> struct NormTraits<ArithmeticType> /** \page NormTraits template<> struct NormTraits<ArithmeticType>
Unary traits for the calculation of the norm and squared norm of arithm etic objects. Unary traits for the calculation of the norm and squared norm of arithm etic objects.
<b>\#include</b> <b>\#include</b>
"<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" \<<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>\ >
This traits class is used to determine appropriate result types This traits class is used to determine appropriate result types
for the functions norm() and squaredNorm(). These functions are always for the functions norm() and squaredNorm(). These functions are always
declared like this (where <tt>ArithmeticType</tt> is a type thats suppo rts a norm): declared like this (where <tt>ArithmeticType</tt> is a type thats suppo rts a norm):
\code \code
NormTraits<ArithmeticType>::NormType norm(ArithmeticType const & t); NormTraits<ArithmeticType>::NormType norm(ArithmeticType const & t);
NormTraits<ArithmeticType>::SquaredNormType squaredNorm(ArithmeticType const & t); NormTraits<ArithmeticType>::SquaredNormType squaredNorm(ArithmeticType const & t);
\endcode \endcode
skipping to change at line 468 skipping to change at line 462
</td></tr> </td></tr>
<tr><td> <tr><td>
<b> <TT>typedef ... SquaredNormType;</TT></b> <b> <TT>typedef ... SquaredNormType;</TT></b>
</td><td> </td><td>
result of <tt>squaredNorm(ArithmeticType)</tt> result of <tt>squaredNorm(ArithmeticType)</tt>
</td></tr> </td></tr>
<tr><td> <tr><td>
<b> <TT>typedef ... NormType;</TT></b> <b> <TT>typedef ... NormType;</TT></b>
</td><td> </td><td>
result of <tt>norm(ArithmeticType)</tt><br> result of <tt>norm(ArithmeticType)</tt><br>
Usually equal to <tt>SquareRootTraits<SquaredNormType&gt;::S quareRootResult Usually equal to <tt>SquareRootTraits<SquaredNormType>::SquareR ootResult</tt>
</td></tr> </td></tr>
</table> </table>
NormTraits for the built-in types are defined in <b>\#include</b> NormTraits for the built-in types are defined in <b>\#include</b>
"<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>" \<<a href="numerictraits_8hxx-source.html">vigra/numerictraits.hxx</a>\ >
Namespace: vigra Namespace: vigra
*/ */
namespace vigra { namespace vigra {
struct Error_NumericTraits_not_specialized_for_this_case { }; struct Error_NumericTraits_not_specialized_for_this_case { };
struct Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_u nsigned_char { }; struct Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char_or_u nsigned_char { };
template<class A> template<class A>
struct NumericTraits struct NumericTraits
{ {
typedef Error_NumericTraits_not_specialized_for_this_case Type; typedef Error_NumericTraits_not_specialized_for_this_case Type;
typedef Error_NumericTraits_not_specialized_for_this_case Promote; typedef Error_NumericTraits_not_specialized_for_this_case Promote;
typedef Error_NumericTraits_not_specialized_for_this_case UnsignedPromo te;
typedef Error_NumericTraits_not_specialized_for_this_case RealPromote; typedef Error_NumericTraits_not_specialized_for_this_case RealPromote;
typedef Error_NumericTraits_not_specialized_for_this_case ComplexPromot e; typedef Error_NumericTraits_not_specialized_for_this_case ComplexPromot e;
typedef Error_NumericTraits_not_specialized_for_this_case ValueType; typedef Error_NumericTraits_not_specialized_for_this_case ValueType;
typedef Error_NumericTraits_not_specialized_for_this_case isScalar; typedef Error_NumericTraits_not_specialized_for_this_case isScalar;
typedef Error_NumericTraits_not_specialized_for_this_case isIntegral; typedef Error_NumericTraits_not_specialized_for_this_case isIntegral;
typedef Error_NumericTraits_not_specialized_for_this_case isSigned; typedef Error_NumericTraits_not_specialized_for_this_case isSigned;
typedef Error_NumericTraits_not_specialized_for_this_case isOrdered; typedef Error_NumericTraits_not_specialized_for_this_case isOrdered;
typedef Error_NumericTraits_not_specialized_for_this_case isComplex; typedef Error_NumericTraits_not_specialized_for_this_case isComplex;
}; };
template<> template<>
struct NumericTraits<char> struct NumericTraits<char>
{ {
typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char Type; typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char Type;
typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char Promote; typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char Promote;
typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char UnsignedPromote;
typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char RealPromote; typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char RealPromote;
typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char ComplexPromote; typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char ComplexPromote;
typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char ValueType; typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char ValueType;
typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char isScalar; typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char isScalar;
typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char isIntegral; typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char isIntegral;
typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char isSigned; typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char isSigned;
typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char isOrdered; typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char isOrdered;
typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char isComplex; typedef Error_NumericTraits_char_is_not_a_numeric_type__use_signed_char _or_unsigned_char isComplex;
}; };
#ifndef NO_BOOL #ifndef NO_BOOL
template<> template<>
struct NumericTraits<bool> struct NumericTraits<bool>
{ {
typedef bool Type; typedef bool Type;
typedef int Promote; typedef int Promote;
typedef unsigned int UnsignedPromote;
typedef double RealPromote; typedef double RealPromote;
typedef std::complex<RealPromote> ComplexPromote; typedef std::complex<RealPromote> ComplexPromote;
typedef Type ValueType; typedef Type ValueType;
typedef VigraTrueType isIntegral; typedef VigraTrueType isIntegral;
typedef VigraTrueType isScalar; typedef VigraTrueType isScalar;
typedef VigraFalseType isSigned; typedef VigraFalseType isSigned;
typedef VigraTrueType isOrdered; typedef VigraTrueType isOrdered;
typedef VigraFalseType isComplex; typedef VigraFalseType isComplex;
skipping to change at line 560 skipping to change at line 557
return (v == 0.0) ? false : true; return (v == 0.0) ? false : true;
} }
}; };
#endif #endif
template<> template<>
struct NumericTraits<signed char> struct NumericTraits<signed char>
{ {
typedef signed char Type; typedef signed char Type;
typedef int Promote; typedef int Promote;
typedef unsigned int UnsignedPromote;
typedef double RealPromote; typedef double RealPromote;
typedef std::complex<RealPromote> ComplexPromote; typedef std::complex<RealPromote> ComplexPromote;
typedef Type ValueType; typedef Type ValueType;
typedef VigraTrueType isIntegral; typedef VigraTrueType isIntegral;
typedef VigraTrueType isScalar; typedef VigraTrueType isScalar;
typedef VigraTrueType isSigned; typedef VigraTrueType isSigned;
typedef VigraTrueType isOrdered; typedef VigraTrueType isOrdered;
typedef VigraFalseType isComplex; typedef VigraFalseType isComplex;
skipping to change at line 604 skipping to change at line 602
? SCHAR_MAX ? SCHAR_MAX
: static_cast<signed char>(v + 0.5)); : static_cast<signed char>(v + 0.5));
} }
}; };
template<> template<>
struct NumericTraits<unsigned char> struct NumericTraits<unsigned char>
{ {
typedef unsigned char Type; typedef unsigned char Type;
typedef int Promote; typedef int Promote;
typedef unsigned int UnsignedPromote;
typedef double RealPromote; typedef double RealPromote;
typedef std::complex<RealPromote> ComplexPromote; typedef std::complex<RealPromote> ComplexPromote;
typedef Type ValueType; typedef Type ValueType;
typedef VigraTrueType isIntegral; typedef VigraTrueType isIntegral;
typedef VigraTrueType isScalar; typedef VigraTrueType isScalar;
typedef VigraFalseType isSigned; typedef VigraFalseType isSigned;
typedef VigraTrueType isOrdered; typedef VigraTrueType isOrdered;
typedef VigraFalseType isComplex; typedef VigraFalseType isComplex;
skipping to change at line 630 skipping to change at line 629
#ifdef NO_INLINE_STATIC_CONST_DEFINITION #ifdef NO_INLINE_STATIC_CONST_DEFINITION
enum { minConst = 0, maxConst = UCHAR_MAX }; enum { minConst = 0, maxConst = UCHAR_MAX };
#else #else
static const unsigned char minConst = 0; static const unsigned char minConst = 0;
static const unsigned char maxConst = UCHAR_MAX; static const unsigned char maxConst = UCHAR_MAX;
#endif #endif
static Promote toPromote(unsigned char v) { return v; } static Promote toPromote(unsigned char v) { return v; }
static RealPromote toRealPromote(unsigned char v) { return v; } static RealPromote toRealPromote(unsigned char v) { return v; }
static unsigned char fromPromote(Promote const & v) { static unsigned char fromPromote(Promote const & v) {
return ((v < 0) ? 0 : (v > UCHAR_MAX) ? UCHAR_MAX : v); return Type((v < 0)
? 0
: (v > (Promote)UCHAR_MAX)
? UCHAR_MAX
: v);
} }
static unsigned char fromRealPromote(RealPromote const & v) { static unsigned char fromRealPromote(RealPromote const & v) {
return ((v < 0.0) return Type((v < 0.0)
? 0 ? 0
: ((v > (RealPromote)UCHAR_MAX) : ((v > (RealPromote)UCHAR_MAX)
? UCHAR_MAX ? UCHAR_MAX
: static_cast<unsigned char>(v + 0.5))); : v + 0.5));
} }
}; };
template<> template<>
struct NumericTraits<short int> struct NumericTraits<short int>
{ {
typedef short int Type; typedef short int Type;
typedef int Promote; typedef int Promote;
typedef unsigned int UnsignedPromote;
typedef double RealPromote; typedef double RealPromote;
typedef std::complex<RealPromote> ComplexPromote; typedef std::complex<RealPromote> ComplexPromote;
typedef Type ValueType; typedef Type ValueType;
typedef VigraTrueType isIntegral; typedef VigraTrueType isIntegral;
typedef VigraTrueType isScalar; typedef VigraTrueType isScalar;
typedef VigraTrueType isSigned; typedef VigraTrueType isSigned;
typedef VigraTrueType isOrdered; typedef VigraTrueType isOrdered;
typedef VigraFalseType isComplex; typedef VigraFalseType isComplex;
skipping to change at line 691 skipping to change at line 695
? SHRT_MAX ? SHRT_MAX
: static_cast<short int>(v + 0.5))); : static_cast<short int>(v + 0.5)));
} }
}; };
template<> template<>
struct NumericTraits<short unsigned int> struct NumericTraits<short unsigned int>
{ {
typedef short unsigned int Type; typedef short unsigned int Type;
typedef int Promote; typedef int Promote;
typedef unsigned int UnsignedPromote;
typedef double RealPromote; typedef double RealPromote;
typedef std::complex<RealPromote> ComplexPromote; typedef std::complex<RealPromote> ComplexPromote;
typedef Type ValueType; typedef Type ValueType;
typedef VigraTrueType isIntegral; typedef VigraTrueType isIntegral;
typedef VigraTrueType isScalar; typedef VigraTrueType isScalar;
typedef VigraFalseType isSigned; typedef VigraFalseType isSigned;
typedef VigraTrueType isOrdered; typedef VigraTrueType isOrdered;
typedef VigraFalseType isComplex; typedef VigraFalseType isComplex;
skipping to change at line 717 skipping to change at line 722
#ifdef NO_INLINE_STATIC_CONST_DEFINITION #ifdef NO_INLINE_STATIC_CONST_DEFINITION
enum { minConst = 0, maxConst = USHRT_MAX }; enum { minConst = 0, maxConst = USHRT_MAX };
#else #else
static const short unsigned int minConst = 0; static const short unsigned int minConst = 0;
static const short unsigned int maxConst = USHRT_MAX; static const short unsigned int maxConst = USHRT_MAX;
#endif #endif
static Promote toPromote(short unsigned int v) { return v; } static Promote toPromote(short unsigned int v) { return v; }
static RealPromote toRealPromote(short unsigned int v) { return v; } static RealPromote toRealPromote(short unsigned int v) { return v; }
static short unsigned int fromPromote(Promote v) { static short unsigned int fromPromote(Promote v) {
return ((v < 0) ? 0 : (v > USHRT_MAX) ? USHRT_MAX : v); return Type((v < 0)
? 0
: (v > USHRT_MAX)
? USHRT_MAX
: v);
} }
static short unsigned int fromRealPromote(RealPromote v) { static short unsigned int fromRealPromote(RealPromote v) {
return ((v < 0.0) return Type((v < 0.0)
? 0 ? 0
: ((v > (RealPromote)USHRT_MAX) : ((v > (RealPromote)USHRT_MAX)
? USHRT_MAX ? USHRT_MAX
: static_cast<short unsigned int>(v + 0.5))); : v + 0.5));
} }
}; };
template<> template<>
struct NumericTraits<int> struct NumericTraits<int>
{ {
typedef int Type; typedef int Type;
typedef int Promote; typedef int Promote;
typedef unsigned int UnsignedPromote;
typedef double RealPromote; typedef double RealPromote;
typedef std::complex<RealPromote> ComplexPromote; typedef std::complex<RealPromote> ComplexPromote;
typedef Type ValueType; typedef Type ValueType;
typedef VigraTrueType isIntegral; typedef VigraTrueType isIntegral;
typedef VigraTrueType isScalar; typedef VigraTrueType isScalar;
typedef VigraTrueType isSigned; typedef VigraTrueType isSigned;
typedef VigraTrueType isOrdered; typedef VigraTrueType isOrdered;
typedef VigraFalseType isComplex; typedef VigraFalseType isComplex;
skipping to change at line 775 skipping to change at line 785
? INT_MAX ? INT_MAX
: static_cast<int>(v + 0.5))); : static_cast<int>(v + 0.5)));
} }
}; };
template<> template<>
struct NumericTraits<unsigned int> struct NumericTraits<unsigned int>
{ {
typedef unsigned int Type; typedef unsigned int Type;
typedef unsigned int Promote; typedef unsigned int Promote;
typedef unsigned int UnsignedPromote;
typedef double RealPromote; typedef double RealPromote;
typedef std::complex<RealPromote> ComplexPromote; typedef std::complex<RealPromote> ComplexPromote;
typedef Type ValueType; typedef Type ValueType;
typedef VigraTrueType isIntegral; typedef VigraTrueType isIntegral;
typedef VigraTrueType isScalar; typedef VigraTrueType isScalar;
typedef VigraFalseType isSigned; typedef VigraFalseType isSigned;
typedef VigraTrueType isOrdered; typedef VigraTrueType isOrdered;
typedef VigraFalseType isComplex; typedef VigraFalseType isComplex;
skipping to change at line 815 skipping to change at line 826
? UINT_MAX ? UINT_MAX
: static_cast<unsigned int>(v + 0.5))); : static_cast<unsigned int>(v + 0.5)));
} }
}; };
template<> template<>
struct NumericTraits<long> struct NumericTraits<long>
{ {
typedef long Type; typedef long Type;
typedef long Promote; typedef long Promote;
typedef unsigned long UnsignedPromote;
typedef double RealPromote; typedef double RealPromote;
typedef std::complex<RealPromote> ComplexPromote; typedef std::complex<RealPromote> ComplexPromote;
typedef Type ValueType; typedef Type ValueType;
typedef VigraTrueType isIntegral; typedef VigraTrueType isIntegral;
typedef VigraTrueType isScalar; typedef VigraTrueType isScalar;
typedef VigraTrueType isSigned; typedef VigraTrueType isSigned;
typedef VigraTrueType isOrdered; typedef VigraTrueType isOrdered;
typedef VigraFalseType isComplex; typedef VigraFalseType isComplex;
skipping to change at line 857 skipping to change at line 869
? LONG_MAX ? LONG_MAX
: static_cast<long>(v + 0.5))); : static_cast<long>(v + 0.5)));
} }
}; };
template<> template<>
struct NumericTraits<unsigned long> struct NumericTraits<unsigned long>
{ {
typedef unsigned long Type; typedef unsigned long Type;
typedef unsigned long Promote; typedef unsigned long Promote;
typedef unsigned long UnsignedPromote;
typedef double RealPromote; typedef double RealPromote;
typedef std::complex<RealPromote> ComplexPromote; typedef std::complex<RealPromote> ComplexPromote;
typedef Type ValueType; typedef Type ValueType;
typedef VigraTrueType isIntegral; typedef VigraTrueType isIntegral;
typedef VigraTrueType isScalar; typedef VigraTrueType isScalar;
typedef VigraFalseType isSigned; typedef VigraFalseType isSigned;
typedef VigraTrueType isOrdered; typedef VigraTrueType isOrdered;
typedef VigraFalseType isComplex; typedef VigraFalseType isComplex;
skipping to change at line 892 skipping to change at line 905
static unsigned long fromPromote(Promote v) { return v; } static unsigned long fromPromote(Promote v) { return v; }
static unsigned long fromRealPromote(RealPromote v) { static unsigned long fromRealPromote(RealPromote v) {
return ((v < 0.0) return ((v < 0.0)
? 0 ? 0
: ((v > (RealPromote)ULONG_MAX) : ((v > (RealPromote)ULONG_MAX)
? ULONG_MAX ? ULONG_MAX
: static_cast<unsigned long>(v + 0.5))); : static_cast<unsigned long>(v + 0.5)));
} }
}; };
#ifdef LLONG_MAX
template<>
struct NumericTraits<long long>
{
typedef long long Type;
typedef long long Promote;
typedef unsigned long long UnsignedPromote;
typedef double RealPromote;
typedef std::complex<RealPromote> ComplexPromote;
typedef Type ValueType;
typedef VigraTrueType isIntegral;
typedef VigraTrueType isScalar;
typedef VigraTrueType isSigned;
typedef VigraTrueType isOrdered;
typedef VigraFalseType isComplex;
static long long zero() { return 0; }
static long long one() { return 1; }
static long long nonZero() { return 1; }
static long long min() { return LLONG_MIN; }
static long long max() { return LLONG_MAX; }
#ifdef NO_INLINE_STATIC_CONST_DEFINITION
enum { minConst = LLONG_MIN, maxConst = LLONG_MAX };
#else
static const long long minConst = LLONG_MIN;
static const long long maxConst = LLONG_MAX;
#endif
static Promote toPromote(long long v) { return v; }
static RealPromote toRealPromote(long long v) { return v; }
static long long fromPromote(Promote v) { return v; }
static long long fromRealPromote(RealPromote v) {
return ((v < 0.0)
? ((v < (RealPromote)LLONG_MIN)
? LLONG_MIN
: static_cast<long long>(v - 0.5))
: ((v > (RealPromote)LLONG_MAX)
? LLONG_MAX
: static_cast<long long>(v + 0.5)));
}
};
template<>
struct NumericTraits<unsigned long long>
{
typedef unsigned long long Type;
typedef unsigned long long Promote;
typedef unsigned long long UnsignedPromote;
typedef double RealPromote;
typedef std::complex<RealPromote> ComplexPromote;
typedef Type ValueType;
typedef VigraTrueType isIntegral;
typedef VigraTrueType isScalar;
typedef VigraFalseType isSigned;
typedef VigraTrueType isOrdered;
typedef VigraFalseType isComplex;
static unsigned long long zero() { return 0; }
static unsigned long long one() { return 1; }
static unsigned long long nonZero() { return 1; }
static unsigned long long min() { return 0; }
static unsigned long long max() { return ULLONG_MAX; }
#ifdef NO_INLINE_STATIC_CONST_DEFINITION
enum { minConst = 0, maxConst = ULLONG_MAX };
#else
static const unsigned long long minConst = 0;
static const unsigned long long maxConst = ULLONG_MAX;
#endif
static Promote toPromote(unsigned long long v) { return v; }
static RealPromote toRealPromote(unsigned long long v) { return v; }
static unsigned long long fromPromote(Promote v) { return v; }
static unsigned long long fromRealPromote(RealPromote v) {
return ((v < 0.0)
? 0
: ((v > (RealPromote)ULLONG_MAX)
? ULONG_MAX
: static_cast<unsigned long long>(v + 0.5)));
}
};
#endif // LLONG_MAX
template<> template<>
struct NumericTraits<float> struct NumericTraits<float>
{ {
typedef float Type; typedef float Type;
typedef float Promote; typedef float Promote;
typedef float UnsignedPromote;
typedef float RealPromote; typedef float RealPromote;
typedef std::complex<RealPromote> ComplexPromote; typedef std::complex<RealPromote> ComplexPromote;
typedef Type ValueType; typedef Type ValueType;
typedef VigraFalseType isIntegral; typedef VigraFalseType isIntegral;
typedef VigraTrueType isScalar; typedef VigraTrueType isScalar;
typedef VigraTrueType isSigned; typedef VigraTrueType isSigned;
typedef VigraTrueType isOrdered; typedef VigraTrueType isOrdered;
typedef VigraFalseType isComplex; typedef VigraFalseType isComplex;
skipping to change at line 926 skipping to change at line 1026
static RealPromote toRealPromote(float v) { return v; } static RealPromote toRealPromote(float v) { return v; }
static float fromPromote(Promote v) { return v; } static float fromPromote(Promote v) { return v; }
static float fromRealPromote(RealPromote v) { return v; } static float fromRealPromote(RealPromote v) { return v; }
}; };
template<> template<>
struct NumericTraits<double> struct NumericTraits<double>
{ {
typedef double Type; typedef double Type;
typedef double Promote; typedef double Promote;
typedef double UnsignedPromote;
typedef double RealPromote; typedef double RealPromote;
typedef std::complex<RealPromote> ComplexPromote; typedef std::complex<RealPromote> ComplexPromote;
typedef Type ValueType; typedef Type ValueType;
typedef VigraFalseType isIntegral; typedef VigraFalseType isIntegral;
typedef VigraTrueType isScalar; typedef VigraTrueType isScalar;
typedef VigraTrueType isSigned; typedef VigraTrueType isSigned;
typedef VigraTrueType isOrdered; typedef VigraTrueType isOrdered;
typedef VigraFalseType isComplex; typedef VigraFalseType isComplex;
skipping to change at line 955 skipping to change at line 1056
static RealPromote toRealPromote(double v) { return v; } static RealPromote toRealPromote(double v) { return v; }
static double fromPromote(Promote v) { return v; } static double fromPromote(Promote v) { return v; }
static double fromRealPromote(RealPromote v) { return v; } static double fromRealPromote(RealPromote v) { return v; }
}; };
template<> template<>
struct NumericTraits<long double> struct NumericTraits<long double>
{ {
typedef long double Type; typedef long double Type;
typedef long double Promote; typedef long double Promote;
typedef long double UnsignedPromote;
typedef long double RealPromote; typedef long double RealPromote;
typedef std::complex<RealPromote> ComplexPromote; typedef std::complex<RealPromote> ComplexPromote;
typedef Type ValueType; typedef Type ValueType;
typedef VigraFalseType isIntegral; typedef VigraFalseType isIntegral;
typedef VigraTrueType isScalar; typedef VigraTrueType isScalar;
typedef VigraTrueType isSigned; typedef VigraTrueType isSigned;
typedef VigraTrueType isOrdered; typedef VigraTrueType isOrdered;
typedef VigraFalseType isComplex; typedef VigraFalseType isComplex;
skipping to change at line 986 skipping to change at line 1088
static long double fromRealPromote(RealPromote v) { return v; } static long double fromRealPromote(RealPromote v) { return v; }
}; };
#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
template<class T> template<class T>
struct NumericTraits<std::complex<T> > struct NumericTraits<std::complex<T> >
{ {
typedef std::complex<T> Type; typedef std::complex<T> Type;
typedef std::complex<typename NumericTraits<T>::Promote> Promote; typedef std::complex<typename NumericTraits<T>::Promote> Promote;
typedef std::complex<typename NumericTraits<T>::UnsignedPromote> Unsign edPromote;
typedef std::complex<typename NumericTraits<T>::RealPromote> RealPromot e; typedef std::complex<typename NumericTraits<T>::RealPromote> RealPromot e;
typedef std::complex<RealPromote> ComplexPromote; typedef std::complex<RealPromote> ComplexPromote;
typedef T ValueType; typedef T ValueType;
typedef VigraFalseType isIntegral; typedef VigraFalseType isIntegral;
typedef VigraFalseType isScalar; typedef VigraFalseType isScalar;
typedef typename NumericTraits<T>::isSigned isSigned; typedef typename NumericTraits<T>::isSigned isSigned;
typedef VigraFalseType isOrdered; typedef VigraFalseType isOrdered;
typedef VigraTrueType isComplex; typedef VigraTrueType isComplex;
skipping to change at line 1034 skipping to change at line 1137
/* */ /* */
/* NormTraits */ /* NormTraits */
/* */ /* */
/********************************************************/ /********************************************************/
struct Error_NormTraits_not_specialized_for_this_case { }; struct Error_NormTraits_not_specialized_for_this_case { };
template<class T> template<class T>
struct NormTraits struct NormTraits
{ {
typedef T Ty typedef T Type;
pe; typedef Error_NormTraits_not_specialized_for_this_case SquaredNormTyp
typedef typename T::SquaredNormType Sq e;
uaredNormType; typedef Error_NormTraits_not_specialized_for_this_case NormType;
typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult No
rmType;
}; };
#define VIGRA_DEFINE_NORM_TRAITS(T) \ #define VIGRA_DEFINE_NORM_TRAITS(T) \
template <> struct NormTraits<T> { \ template <> struct NormTraits<T> { \
typedef T Type; \ typedef T Type; \
typedef NumericTraits<T>::Promote SquaredNormType; \ typedef NumericTraits<T>::Promote SquaredNormType; \
typedef T NormType; \ typedef T NormType; \
}; };
VIGRA_DEFINE_NORM_TRAITS(bool) VIGRA_DEFINE_NORM_TRAITS(bool)
skipping to change at line 1059 skipping to change at line 1162
VIGRA_DEFINE_NORM_TRAITS(short) VIGRA_DEFINE_NORM_TRAITS(short)
VIGRA_DEFINE_NORM_TRAITS(unsigned short) VIGRA_DEFINE_NORM_TRAITS(unsigned short)
VIGRA_DEFINE_NORM_TRAITS(int) VIGRA_DEFINE_NORM_TRAITS(int)
VIGRA_DEFINE_NORM_TRAITS(unsigned int) VIGRA_DEFINE_NORM_TRAITS(unsigned int)
VIGRA_DEFINE_NORM_TRAITS(long) VIGRA_DEFINE_NORM_TRAITS(long)
VIGRA_DEFINE_NORM_TRAITS(unsigned long) VIGRA_DEFINE_NORM_TRAITS(unsigned long)
VIGRA_DEFINE_NORM_TRAITS(float) VIGRA_DEFINE_NORM_TRAITS(float)
VIGRA_DEFINE_NORM_TRAITS(double) VIGRA_DEFINE_NORM_TRAITS(double)
VIGRA_DEFINE_NORM_TRAITS(long double) VIGRA_DEFINE_NORM_TRAITS(long double)
#ifdef LLONG_MAX
VIGRA_DEFINE_NORM_TRAITS(long long)
VIGRA_DEFINE_NORM_TRAITS(unsigned long long)
#endif // LLONG_MAX
#undef VIGRA_DEFINE_NORM_TRAITS #undef VIGRA_DEFINE_NORM_TRAITS
#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
template<class T> template<class T>
struct NormTraits<std::complex<T> > struct NormTraits<std::complex<T> >
{ {
typedef std::complex<T> Ty pe; typedef std::complex<T> Ty pe;
typedef typename NormTraits<T>::SquaredNormType Sq uaredNormType; typedef typename NormTraits<T>::SquaredNormType Sq uaredNormType;
typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult No rmType; typedef typename SquareRootTraits<SquaredNormType>::SquareRootResult No rmType;
}; };
#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
/********************************************************/ /********************************************************/
/* */ /* */
/* PromoteTraits */ /* PromoteTraits */
/* */ /* */
/********************************************************/ /********************************************************/
struct Error_PromoteTraits_not_specialized_for_this_case { }; namespace detail {
template<class A, class B>
struct PromoteTraits
{
typedef Error_PromoteTraits_not_specialized_for_this_case Promote;
};
template<>
struct PromoteTraits<signed char, signed char>
{
typedef int Promote;
static Promote toPromote(signed char v) { return v; }
};
template<>
struct PromoteTraits<signed char, unsigned char>
{
typedef int Promote;
static Promote toPromote(signed char v) { return v; }
static Promote toPromote(unsigned char v) { return v; }
};
template<>
struct PromoteTraits<signed char, short int>
{
typedef int Promote;
static Promote toPromote(signed char v) { return v; }
static Promote toPromote(short int v) { return v; }
};
template<>
struct PromoteTraits<signed char, short unsigned int>
{
typedef unsigned int Promote;
static Promote toPromote(signed char v) { return v; }
static Promote toPromote(short unsigned int v) { return v; }
};
template<>
struct PromoteTraits<signed char, int>
{
typedef int Promote;
static Promote toPromote(signed char v) { return v; }
static Promote toPromote(int v) { return v; }
};
template<>
struct PromoteTraits<signed char, unsigned int>
{
typedef unsigned int Promote;
static Promote toPromote(signed char v) { return v; }
static Promote toPromote(unsigned int v) { return v; }
};
template<>
struct PromoteTraits<signed char, long>
{
typedef long Promote;
static Promote toPromote(signed char v) { return v; }
static Promote toPromote(long v) { return v; }
};
template<>
struct PromoteTraits<signed char, unsigned long>
{
typedef unsigned long Promote;
static Promote toPromote(signed char v) { return v; }
static Promote toPromote(unsigned long v) { return v; }
};
template<>
struct PromoteTraits<signed char, float>
{
typedef float Promote;
static Promote toPromote(signed char v) { return v; }
static Promote toPromote(float v) { return v; }
};
template<>
struct PromoteTraits<signed char, double>
{
typedef double Promote;
static Promote toPromote(signed char v) { return v; }
static Promote toPromote(double v) { return v; }
};
template<>
struct PromoteTraits<signed char, long double>
{
typedef long double Promote;
static Promote toPromote(signed char v) { return v; }
static Promote toPromote(long double v) { return v; }
};
template<>
struct PromoteTraits<unsigned char, signed char>
{
typedef int Promote;
static Promote toPromote(unsigned char v) { return v; }
static Promote toPromote(signed char v) { return v; }
};
template<>
struct PromoteTraits<unsigned char, unsigned char>
{
typedef int Promote;
static Promote toPromote(unsigned char v) { return v; }
};
template<>
struct PromoteTraits<unsigned char, short int>
{
typedef int Promote;
static Promote toPromote(unsigned char v) { return v; }
static Promote toPromote(short int v) { return v; }
};
template<>
struct PromoteTraits<unsigned char, short unsigned int>
{
typedef unsigned int Promote;
static Promote toPromote(unsigned char v) { return v; }
static Promote toPromote(short unsigned int v) { return v; }
};
template<>
struct PromoteTraits<unsigned char, int>
{
typedef int Promote;
static Promote toPromote(unsigned char v) { return v; }
static Promote toPromote(int v) { return v; }
};
template<>
struct PromoteTraits<unsigned char, unsigned int>
{
typedef unsigned int Promote;
static Promote toPromote(unsigned char v) { return v; }
static Promote toPromote(unsigned int v) { return v; }
};
template<>
struct PromoteTraits<unsigned char, long>
{
typedef long Promote;
static Promote toPromote(unsigned char v) { return v; }
static Promote toPromote(long v) { return v; }
};
template<>
struct PromoteTraits<unsigned char, unsigned long>
{
typedef unsigned long Promote;
static Promote toPromote(unsigned char v) { return v; }
static Promote toPromote(unsigned long v) { return v; }
};
template<>
struct PromoteTraits<unsigned char, float>
{
typedef float Promote;
static Promote toPromote(unsigned char v) { return v; }
static Promote toPromote(float v) { return v; }
};
template<>
struct PromoteTraits<unsigned char, double>
{
typedef double Promote;
static Promote toPromote(unsigned char v) { return v; }
static Promote toPromote(double v) { return v; }
};
template<>
struct PromoteTraits<unsigned char, long double>
{
typedef long double Promote;
static Promote toPromote(unsigned char v) { return v; }
static Promote toPromote(long double v) { return v; }
};
template<>
struct PromoteTraits<short int, signed char>
{
typedef int Promote;
static Promote toPromote(short int v) { return v; }
static Promote toPromote(signed char v) { return v; }
};
template<>
struct PromoteTraits<short int, unsigned char>
{
typedef int Promote;
static Promote toPromote(short int v) { return v; }
static Promote toPromote(unsigned char v) { return v; }
};
template<>
struct PromoteTraits<short int, short int>
{
typedef int Promote;
static Promote toPromote(short int v) { return v; }
};
template<>
struct PromoteTraits<short int, short unsigned int>
{
typedef unsigned int Promote;
static Promote toPromote(short int v) { return v; }
static Promote toPromote(short unsigned int v) { return v; }
};
template<>
struct PromoteTraits<short int, int>
{
typedef int Promote;
static Promote toPromote(short int v) { return v; }
static Promote toPromote(int v) { return v; }
};
template<>
struct PromoteTraits<short int, unsigned int>
{
typedef unsigned int Promote;
static Promote toPromote(short int v) { return v; }
static Promote toPromote(unsigned int v) { return v; }
};
template<>
struct PromoteTraits<short int, long>
{
typedef long Promote;
static Promote toPromote(short int v) { return v; }
static Promote toPromote(long v) { return v; }
};
template<>
struct PromoteTraits<short int, unsigned long>
{
typedef unsigned long Promote;
static Promote toPromote(short int v) { return v; }
static Promote toPromote(unsigned long v) { return v; }
};
template<>
struct PromoteTraits<short int, float>
{
typedef float Promote;
static Promote toPromote(short int v) { return v; }
static Promote toPromote(float v) { return v; }
};
template<>
struct PromoteTraits<short int, double>
{
typedef double Promote;
static Promote toPromote(short int v) { return v; }
static Promote toPromote(double v) { return v; }
};
template<>
struct PromoteTraits<short int, long double>
{
typedef long double Promote;
static Promote toPromote(short int v) { return v; }
static Promote toPromote(long double v) { return v; }
};
template<>
struct PromoteTraits<short unsigned int, signed char>
{
typedef unsigned int Promote;
static Promote toPromote(short unsigned int v) { return v; }
static Promote toPromote(signed char v) { return v; }
};
template<>
struct PromoteTraits<short unsigned int, unsigned char>
{
typedef unsigned int Promote;
static Promote toPromote(short unsigned int v) { return v; }
static Promote toPromote(unsigned char v) { return v; }
};
template<>
struct PromoteTraits<short unsigned int, short int>
{
typedef unsigned int Promote;
static Promote toPromote(short unsigned int v) { return v; }
static Promote toPromote(short int v) { return v; }
};
template<>
struct PromoteTraits<short unsigned int, short unsigned int>
{
typedef unsigned int Promote;
static Promote toPromote(short unsigned int v) { return v; }
};
template<>
struct PromoteTraits<short unsigned int, int>
{
typedef unsigned int Promote;
static Promote toPromote(short unsigned int v) { return v; }
static Promote toPromote(int v) { return v; }
};
template<>
struct PromoteTraits<short unsigned int, unsigned int>
{
typedef unsigned int Promote;
static Promote toPromote(short unsigned int v) { return v; }
static Promote toPromote(unsigned int v) { return v; }
};
template<>
struct PromoteTraits<short unsigned int, long>
{
typedef long Promote;
static Promote toPromote(short unsigned int v) { return v; }
static Promote toPromote(long v) { return v; }
};
template<>
struct PromoteTraits<short unsigned int, unsigned long>
{
typedef unsigned long Promote;
static Promote toPromote(short unsigned int v) { return v; }
static Promote toPromote(unsigned long v) { return v; }
};
template<>
struct PromoteTraits<short unsigned int, float>
{
typedef float Promote;
static Promote toPromote(short unsigned int v) { return v; }
static Promote toPromote(float v) { return v; }
};
template<>
struct PromoteTraits<short unsigned int, double>
{
typedef double Promote;
static Promote toPromote(short unsigned int v) { return v; }
static Promote toPromote(double v) { return v; }
};
template<>
struct PromoteTraits<short unsigned int, long double>
{
typedef long double Promote;
static Promote toPromote(short unsigned int v) { return v; }
static Promote toPromote(long double v) { return v; }
};
template<>
struct PromoteTraits<int, signed char>
{
typedef int Promote;
static Promote toPromote(int v) { return v; }
static Promote toPromote(signed char v) { return v; }
};
template<>
struct PromoteTraits<int, unsigned char>
{
typedef int Promote;
static Promote toPromote(int v) { return v; }
static Promote toPromote(unsigned char v) { return v; }
};
template<>
struct PromoteTraits<int, short int>
{
typedef int Promote;
static Promote toPromote(int v) { return v; }
static Promote toPromote(short int v) { return v; }
};
template<>
struct PromoteTraits<int, short unsigned int>
{
typedef unsigned int Promote;
static Promote toPromote(int v) { return v; }
static Promote toPromote(short unsigned int v) { return v; }
};
template<>
struct PromoteTraits<int, int>
{
typedef int Promote;
static Promote toPromote(int v) { return v; }
};
template<>
struct PromoteTraits<int, unsigned int>
{
typedef unsigned int Promote;
static Promote toPromote(int v) { return v; }
static Promote toPromote(unsigned int v) { return v; }
};
template<>
struct PromoteTraits<int, long>
{
typedef long Promote;
static Promote toPromote(int v) { return v; }
static Promote toPromote(long v) { return v; }
};
template<>
struct PromoteTraits<int, unsigned long>
{
typedef unsigned long Promote;
static Promote toPromote(int v) { return v; }
static Promote toPromote(unsigned long v) { return v; }
};
template<>
struct PromoteTraits<int, float>
{
typedef float Promote;
static Promote toPromote(int v) { return static_cast<Promote>(v); }
static Promote toPromote(float v) { return v; }
};
template<>
struct PromoteTraits<int, double>
{
typedef double Promote;
static Promote toPromote(int v) { return v; }
static Promote toPromote(double v) { return v; }
};
template<>
struct PromoteTraits<int, long double>
{
typedef long double Promote;
static Promote toPromote(int v) { return v; }
static Promote toPromote(long double v) { return v; }
};
template<>
struct PromoteTraits<unsigned int, signed char>
{
typedef unsigned int Promote;
static Promote toPromote(unsigned int v) { return v; }
static Promote toPromote(signed char v) { return v; }
};
template<>
struct PromoteTraits<unsigned int, unsigned char>
{
typedef unsigned int Promote;
static Promote toPromote(unsigned int v) { return v; }
static Promote toPromote(unsigned char v) { return v; }
};
template<>
struct PromoteTraits<unsigned int, short int>
{
typedef unsigned int Promote;
static Promote toPromote(unsigned int v) { return v; }
static Promote toPromote(short int v) { return v; }
};
template<>
struct PromoteTraits<unsigned int, short unsigned int>
{
typedef unsigned int Promote;
static Promote toPromote(unsigned int v) { return v; }
static Promote toPromote(short unsigned int v) { return v; }
};
template<>
struct PromoteTraits<unsigned int, int>
{
typedef unsigned int Promote;
static Promote toPromote(unsigned int v) { return v; }
static Promote toPromote(int v) { return v; }
};
template<>
struct PromoteTraits<unsigned int, unsigned int>
{
typedef unsigned int Promote;
static Promote toPromote(unsigned int v) { return v; }
};
template<>
struct PromoteTraits<unsigned int, long>
{
typedef long Promote;
static Promote toPromote(unsigned int v) { return v; }
static Promote toPromote(long v) { return v; }
};
template<>
struct PromoteTraits<unsigned int, unsigned long>
{
typedef unsigned long Promote;
static Promote toPromote(unsigned int v) { return v; }
static Promote toPromote(unsigned long v) { return v; }
};
template<>
struct PromoteTraits<unsigned int, float>
{
typedef float Promote;
static Promote toPromote(unsigned int v) { return static_cast<Promote>(
v); }
static Promote toPromote(float v) { return v; }
};
template<>
struct PromoteTraits<unsigned int, double>
{
typedef double Promote;
static Promote toPromote(unsigned int v) { return v; }
static Promote toPromote(double v) { return v; }
};
template<>
struct PromoteTraits<unsigned int, long double>
{
typedef long double Promote;
static Promote toPromote(unsigned int v) { return v; }
static Promote toPromote(long double v) { return v; }
};
template<>
struct PromoteTraits<long, signed char>
{
typedef long Promote;
static Promote toPromote(long v) { return v; }
static Promote toPromote(signed char v) { return v; }
};
template<>
struct PromoteTraits<long, unsigned char>
{
typedef long Promote;
static Promote toPromote(long v) { return v; }
static Promote toPromote(unsigned char v) { return v; }
};
template<>
struct PromoteTraits<long, short int>
{
typedef long Promote;
static Promote toPromote(long v) { return v; }
static Promote toPromote(short int v) { return v; }
};
template<>
struct PromoteTraits<long, short unsigned int>
{
typedef long Promote;
static Promote toPromote(long v) { return v; }
static Promote toPromote(short unsigned int v) { return v; }
};
template<>
struct PromoteTraits<long, int>
{
typedef long Promote;
static Promote toPromote(long v) { return v; }
static Promote toPromote(int v) { return v; }
};
template<>
struct PromoteTraits<long, unsigned int>
{
typedef long Promote;
static Promote toPromote(long v) { return v; }
static Promote toPromote(unsigned int v) { return v; }
};
template<>
struct PromoteTraits<long, long>
{
typedef long Promote;
static Promote toPromote(long v) { return v; }
};
template<>
struct PromoteTraits<long, unsigned long>
{
typedef unsigned long Promote;
static Promote toPromote(long v) { return v; }
static Promote toPromote(unsigned long v) { return v; }
};
template<>
struct PromoteTraits<long, float>
{
typedef float Promote;
static Promote toPromote(long v) { return static_cast<Promote>(v); }
static Promote toPromote(float v) { return v; }
};
template<>
struct PromoteTraits<long, double>
{
typedef double Promote;
static Promote toPromote(long v) { return v; }
static Promote toPromote(double v) { return v; }
};
template<>
struct PromoteTraits<long, long double>
{
typedef long double Promote;
static Promote toPromote(long v) { return v; }
static Promote toPromote(long double v) { return v; }
};
template<>
struct PromoteTraits<unsigned long, signed char>
{
typedef unsigned long Promote;
static Promote toPromote(unsigned long v) { return v; }
static Promote toPromote(signed char v) { return v; }
};
template<>
struct PromoteTraits<unsigned long, unsigned char>
{
typedef unsigned long Promote;
static Promote toPromote(unsigned long v) { return v; }
static Promote toPromote(unsigned char v) { return v; }
};
template<>
struct PromoteTraits<unsigned long, short int>
{
typedef unsigned long Promote;
static Promote toPromote(unsigned long v) { return v; }
static Promote toPromote(short int v) { return v; }
};
template<>
struct PromoteTraits<unsigned long, short unsigned int>
{
typedef unsigned long Promote;
static Promote toPromote(unsigned long v) { return v; }
static Promote toPromote(short unsigned int v) { return v; }
};
template<>
struct PromoteTraits<unsigned long, int>
{
typedef unsigned long Promote;
static Promote toPromote(unsigned long v) { return v; }
static Promote toPromote(int v) { return v; }
};
template<>
struct PromoteTraits<unsigned long, unsigned int>
{
typedef unsigned long Promote;
static Promote toPromote(unsigned long v) { return v; }
static Promote toPromote(unsigned int v) { return v; }
};
template<>
struct PromoteTraits<unsigned long, long>
{
typedef unsigned long Promote;
static Promote toPromote(unsigned long v) { return v; }
static Promote toPromote(long v) { return v; }
};
template<>
struct PromoteTraits<unsigned long, unsigned long>
{
typedef unsigned long Promote;
static Promote toPromote(unsigned long v) { return v; }
};
template<>
struct PromoteTraits<unsigned long, float>
{
typedef float Promote;
static Promote toPromote(unsigned long v) { return static_cast<Promote>
(v); }
static Promote toPromote(float v) { return v; }
};
template<>
struct PromoteTraits<unsigned long, double>
{
typedef double Promote;
static Promote toPromote(unsigned long v) { return v; }
static Promote toPromote(double v) { return v; }
};
template<>
struct PromoteTraits<unsigned long, long double>
{
typedef long double Promote;
static Promote toPromote(unsigned long v) { return v; }
static Promote toPromote(long double v) { return v; }
};
template<>
struct PromoteTraits<float, signed char>
{
typedef float Promote;
static Promote toPromote(float v) { return v; }
static Promote toPromote(signed char v) { return v; }
};
template<>
struct PromoteTraits<float, unsigned char>
{
typedef float Promote;
static Promote toPromote(float v) { return v; }
static Promote toPromote(unsigned char v) { return v; }
};
template<>
struct PromoteTraits<float, short int>
{
typedef float Promote;
static Promote toPromote(float v) { return v; }
static Promote toPromote(short int v) { return v; }
};
template<>
struct PromoteTraits<float, short unsigned int>
{
typedef float Promote;
static Promote toPromote(float v) { return v; }
static Promote toPromote(short unsigned int v) { return v; }
};
template<>
struct PromoteTraits<float, int>
{
typedef float Promote;
static Promote toPromote(float v) { return v; }
static Promote toPromote(int v) { return static_cast<Promote>(v); }
};
template<>
struct PromoteTraits<float, unsigned int>
{
typedef float Promote;
static Promote toPromote(float v) { return v; }
static Promote toPromote(unsigned int v) { return static_cast<Promote>(
v); }
};
template<>
struct PromoteTraits<float, long>
{
typedef float Promote;
static Promote toPromote(float v) { return v; }
static Promote toPromote(long v) { return static_cast<Promote>(v); }
};
template<>
struct PromoteTraits<float, unsigned long>
{
typedef float Promote;
static Promote toPromote(float v) { return v; }
static Promote toPromote(unsigned long v) { return static_cast<Promote>
(v); }
};
template<>
struct PromoteTraits<float, float>
{
typedef float Promote;
static Promote toPromote(float v) { return v; }
};
template<>
struct PromoteTraits<float, double>
{
typedef double Promote;
static Promote toPromote(float v) { return v; }
static Promote toPromote(double v) { return v; }
};
template<>
struct PromoteTraits<float, long double>
{
typedef long double Promote;
static Promote toPromote(float v) { return v; }
static Promote toPromote(long double v) { return v; }
};
template<>
struct PromoteTraits<double, signed char>
{
typedef double Promote;
static Promote toPromote(double v) { return v; }
static Promote toPromote(signed char v) { return v; }
};
template<>
struct PromoteTraits<double, unsigned char>
{
typedef double Promote;
static Promote toPromote(double v) { return v; }
static Promote toPromote(unsigned char v) { return v; }
};
template<>
struct PromoteTraits<double, short int>
{
typedef double Promote;
static Promote toPromote(double v) { return v; }
static Promote toPromote(short int v) { return v; }
};
template<>
struct PromoteTraits<double, short unsigned int>
{
typedef double Promote;
static Promote toPromote(double v) { return v; }
static Promote toPromote(short unsigned int v) { return v; }
};
template<>
struct PromoteTraits<double, int>
{
typedef double Promote;
static Promote toPromote(double v) { return v; }
static Promote toPromote(int v) { return v; }
};
template<>
struct PromoteTraits<double, unsigned int>
{
typedef double Promote;
static Promote toPromote(double v) { return v; }
static Promote toPromote(unsigned int v) { return v; }
};
template<>
struct PromoteTraits<double, long>
{
typedef double Promote;
static Promote toPromote(double v) { return v; }
static Promote toPromote(long v) { return v; }
};
template<>
struct PromoteTraits<double, unsigned long>
{
typedef double Promote;
static Promote toPromote(double v) { return v; }
static Promote toPromote(unsigned long v) { return v; }
};
template<>
struct PromoteTraits<double, float>
{
typedef double Promote;
static Promote toPromote(double v) { return v; }
static Promote toPromote(float v) { return v; }
};
template<>
struct PromoteTraits<double, double>
{
typedef double Promote;
static Promote toPromote(double v) { return v; }
};
template<>
struct PromoteTraits<double, long double>
{
typedef long double Promote;
static Promote toPromote(double v) { return v; }
static Promote toPromote(long double v) { return v; }
};
template<>
struct PromoteTraits<long double, signed char>
{
typedef long double Promote;
static Promote toPromote(long double v) { return v; }
static Promote toPromote(signed char v) { return v; }
};
template<>
struct PromoteTraits<long double, unsigned char>
{
typedef long double Promote;
static Promote toPromote(long double v) { return v; }
static Promote toPromote(unsigned char v) { return v; }
};
template<>
struct PromoteTraits<long double, short int>
{
typedef long double Promote;
static Promote toPromote(long double v) { return v; }
static Promote toPromote(short int v) { return v; }
};
template<>
struct PromoteTraits<long double, short unsigned int>
{
typedef long double Promote;
static Promote toPromote(long double v) { return v; }
static Promote toPromote(short unsigned int v) { return v; }
};
template<>
struct PromoteTraits<long double, int>
{
typedef long double Promote;
static Promote toPromote(long double v) { return v; }
static Promote toPromote(int v) { return v; }
};
template<> template <class T, class U>
struct PromoteTraits<long double, unsigned int> struct PromoteType
{ {
typedef long double Promote; static T & t();
static Promote toPromote(long double v) { return v; } static U & u();
static Promote toPromote(unsigned int v) { return v; } // let C++ figure out the promote type by adding a T and an U
typedef typename SizeToType<sizeof(*typeToSize(t() + u()))>::result Pro
mote;
static Promote toPromote(T t) { return Promote(t); }
static Promote toPromote(U u) { return Promote(u); }
}; };
template<> template <class T>
struct PromoteTraits<long double, long> struct PromoteType<T, T>
{ {
typedef long double Promote; static T & t();
static Promote toPromote(long double v) { return v; } // let C++ figure out the promote type by adding two Ts
static Promote toPromote(long v) { return v; } typedef typename SizeToType<sizeof(*typeToSize(t() + t()))>::result Pro
mote;
static Promote toPromote(T t) { return Promote(t); }
}; };
template<> } // namespace detail
struct PromoteTraits<long double, unsigned long>
{
typedef long double Promote;
static Promote toPromote(long double v) { return v; }
static Promote toPromote(unsigned long v) { return v; }
};
template<> struct Error_PromoteTraits_not_specialized_for_this_case { };
struct PromoteTraits<long double, float>
{
typedef long double Promote;
static Promote toPromote(long double v) { return v; }
static Promote toPromote(float v) { return v; }
};
template<> template<class A, class B>
struct PromoteTraits<long double, double> struct PromoteTraits
{ {
typedef long double Promote; typedef Error_PromoteTraits_not_specialized_for_this_case Promote;
static Promote toPromote(long double v) { return v; }
static Promote toPromote(double v) { return v; }
}; };
template<> #include "promote_traits.hxx"
struct PromoteTraits<long double, long double>
{
typedef long double Promote;
static Promote toPromote(long double v) { return v; }
};
#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
template <class T> template <class T>
struct PromoteTraits<std::complex<T>, std::complex<T> > struct PromoteTraits<std::complex<T>, std::complex<T> >
{ {
typedef std::complex<typename PromoteTraits<T, T>::Promote> Promote; typedef std::complex<typename PromoteTraits<T, T>::Promote> Promote;
static Promote toPromote(std::complex<T> const & v) { return v; } static Promote toPromote(std::complex<T> const & v) { return v; }
}; };
 End of changes. 46 change blocks. 
999 lines changed or deleted 173 lines changed or added


 orientedtensorfilters.hxx   orientedtensorfilters.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2002-2004 by Ullrich Koethe */ /* Copyright 2002-2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 63 skipping to change at line 63
/* */ /* */
/* hourGlassFilter */ /* hourGlassFilter */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Anisotropic tensor smoothing with the hourglass filter. /** \brief Anisotropic tensor smoothing with the hourglass filter.
This function implements anisotropic tensor smoothing by an This function implements anisotropic tensor smoothing by an
hourglass-shaped filters as described in hourglass-shaped filters as described in
U. K U. K&ouml;the: <a href="http://kogs-www.informatik.uni-hamburg.de/~koet he/papers/abstracts/structureTensor.html">
<i>"Edge and Junction Detection with an Improved Structure Tensor"</i>< /a>, <i>"Edge and Junction Detection with an Improved Structure Tensor"</i>< /a>,
in: Proc. of 25th DAGM Symposium, Magdeburg 2003, Lecture Notes in Com puter Science 2781, in: Proc. of 25th DAGM Symposium, Magdeburg 2003, Lecture Notes in Com puter Science 2781,
pp. 25-32, Heidelberg: Springer, 2003 pp. 25-32, Heidelberg: Springer, 2003
It is closely related to the structure tensor (see It is closely related to the structure tensor (see \ref structureTensor
\link CommonConvolutionFilters#structureTensor structureTensor\endlink( ()), but
)), but
replaces the linear tensor smoothing with a smoothing along edges only. replaces the linear tensor smoothing with a smoothing along edges only.
Smoothing accross edges is largely suppressed. This means that the Smoothing accross edges is largely suppressed. This means that the
image structure is preserved much better because nearby features image structure is preserved much better because nearby features
such as parallel edges are not blended into each other. such as parallel edges are not blended into each other.
The hourglass filter is typically applied to a gradient tensor, i.e. th e The hourglass filter is typically applied to a gradient tensor, i.e. th e
Euclidean product of the gradient with itself, which can be obtained by a Euclidean product of the gradient with itself, which can be obtained by a
gradient operator followed with \ref vectorToTensor(), see example belo w. gradient operator followed with \ref vectorToTensor(), see example belo w.
The hourglass shape of the filter can be interpreted as indicating the likely The hourglass shape of the filter can be interpreted as indicating the likely
continuations of a local edge element. The parameter <tt>sigma</tt> det ermines continuations of a local edge element. The parameter <tt>sigma</tt> det ermines
skipping to change at line 100 skipping to change at line 99
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void hourGlassFilter(SrcIterator sul, SrcIterator slr, SrcAccessor src, void hourGlassFilter(SrcIterator sul, SrcIterator slr, SrcAccessor src,
DestIterator dul, DestAccessor dest, DestIterator dul, DestAccessor dest,
double sigma, double rho); double sigma, double rho);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline inline
void hourGlassFilter(triple<SrcIterator, SrcIterator, SrcAccessor> s, void hourGlassFilter(triple<SrcIterator, SrcIterator, SrcAccessor> s,
pair<DestIterator, DestAccessor> d, pair<DestIterator, DestAccessor> d,
double sigma, double rho); double sigma, double rho);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="orientedtensorfilters_8hxx-source.html">vigr a/orientedtensorfilters.hxx</a>" <b>\#include</b> \<<a href="orientedtensorfilters_8hxx-source.html">vig ra/orientedtensorfilters.hxx</a>\>
\code \code
FImage img(w,h); FImage img(w,h);
FVector2Image gradient(w,h); FVector2Image gradient(w,h);
FVector3Image tensor(w,h), smoothedTensor(w,h); FVector3Image tensor(w,h), smoothedTensor(w,h);
gaussianGradient(srcImageRange(img), destImage(gradient), 1.0); gaussianGradient(srcImageRange(img), destImage(gradient), 1.0);
vectorToTensor(srcImageRange(gradient), destImage(tensor)); vectorToTensor(srcImageRange(gradient), destImage(tensor));
hourGlassFilter(srcImageRange(tensor), destImage(smoothedTensor), 2.0, 0.4); hourGlassFilter(srcImageRange(tensor), destImage(smoothedTensor), 2.0, 0.4);
\endcode \endcode
\see vectorToTensor() \see vectorToTensor()
*/ */
doxygen_overloaded_function(template <...> void hourGlassFilter)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void hourGlassFilter(SrcIterator sul, SrcIterator slr, SrcAccessor src, void hourGlassFilter(SrcIterator sul, SrcIterator slr, SrcAccessor src,
DestIterator dul, DestAccessor dest, DestIterator dul, DestAccessor dest,
double sigma, double rho) double sigma, double rho)
{ {
vigra_precondition(sigma >= 0.0 && rho >= 0.0, vigra_precondition(sigma >= 0.0 && rho >= 0.0,
"hourGlassFilter(): sigma and rho must be >= 0.0"); "hourGlassFilter(): sigma and rho must be >= 0.0");
vigra_precondition(src.size(sul) == 3, vigra_precondition(src.size(sul) == 3,
"hourGlassFilter(): input image must have 3 bands.") ; "hourGlassFilter(): input image must have 3 bands.") ;
 End of changes. 7 change blocks. 
9 lines changed or deleted 10 lines changed or added


 pixelneighborhood.hxx   pixelneighborhood.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2005 by Hans Meine, Ullrich Koethe */ /* Copyright 1998-2005 by Hans Meine, Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 49 skipping to change at line 49
#define VIGRA_PIXELNEIGHBORHOOD_HXX #define VIGRA_PIXELNEIGHBORHOOD_HXX
#include "utilities.hxx" #include "utilities.hxx"
namespace vigra { namespace vigra {
/** \addtogroup PixelNeighborhood Utilities to manage pixel neighborhoods /** \addtogroup PixelNeighborhood Utilities to manage pixel neighborhoods
4- and 8-neighborhood definitions and circulators. 4- and 8-neighborhood definitions and circulators.
<b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi xelneighborhood.hxx</a>"<br> <b>\#include</b> \<<a href="pixelneighborhood_8hxx-source.html">vigra/p ixelneighborhood.hxx</a>\><br>
<b>See also:</b> \ref vigra::NeighborhoodCirculator <b>See also:</b> \ref vigra::NeighborhoodCirculator
*/ */
//@{ //@{
/********************************************************/ /********************************************************/
/* */ /* */
/* AtImageBorder */ /* AtImageBorder */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Encode whether a point is near the image border. /** \brief Encode whether a point is near the image border.
This enum is used with \ref isAtImageBorder() and This enum is used with \ref isAtImageBorder() and
\ref vigra::RestrictedNeighborhoodCirculator. \ref vigra::RestrictedNeighborhoodCirculator.
<b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi xelneighborhood.hxx</a>"<br> <b>\#include</b> \<<a href="pixelneighborhood_8hxx-source.html">vigra/p ixelneighborhood.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
enum AtImageBorder enum AtImageBorder
{ {
NotAtBorder = 0, ///< &nbsp; NotAtBorder = 0, ///< &nbsp;
RightBorder = 1, ///< &nbsp; RightBorder = 1, ///< &nbsp;
LeftBorder = 2, ///< &nbsp; LeftBorder = 2, ///< &nbsp;
TopBorder = 4, ///< &nbsp; TopBorder = 4, ///< &nbsp;
BottomBorder = 8, ///< &nbsp; BottomBorder = 8, ///< &nbsp;
TopRightBorder = TopBorder | RightBorder, ///< &nbsp; FrontBorder = 16, ///< &nbsp;
TopLeftBorder = TopBorder | LeftBorder, ///< &nbsp; RearBorder = 32,
BottomLeftBorder = BottomBorder | LeftBorder, ///< &nbsp; TopRightBorder = TopBorder | RightBorder, //5
BottomRightBorder = BottomBorder | RightBorder ///< &nbsp; TopLeftBorder = TopBorder | LeftBorder, //6
TopFrontBorder = TopBorder | FrontBorder, //20
TopRearBorder = TopBorder | RearBorder, //36
BottomLeftBorder = BottomBorder | LeftBorder, //10
BottomRightBorder = BottomBorder | RightBorder, //9
BottomFrontBorder = BottomBorder | FrontBorder, //24
BottomRearBorder = BottomBorder | RearBorder, //40
FrontLeftBorder = FrontBorder | LeftBorder, //18
FrontRightBorder = FrontBorder | RightBorder, //17
RearLeftBorder = RearBorder | LeftBorder, //34
RearRightBorder = RearBorder | RightBorder, //33
TopRightFrontBorder = TopBorder | RightBorder | FrontBorder,
//21
TopLeftFrontBorder = TopBorder | LeftBorder | FrontBorder,
//22
BottomLeftFrontBorder = BottomBorder | LeftBorder | FrontBorder,
//26
BottomRightFrontBorder = BottomBorder | RightBorder | FrontBorder,
//25
TopRightRearBorder = TopBorder | RightBorder | RearBorder,
//37
TopLeftRearBorder = TopBorder | LeftBorder | RearBorder,
//38
BottomLeftRearBorder = BottomBorder | LeftBorder | RearBorder,
//42
BottomRightRearBorder = BottomBorder | RightBorder | RearBorder
//41
}; };
/** \brief Find out whether a point is at the image border. /** \brief Find out whether a point is at the image border.
This function checks if \a x == 0 or \a x == \a width - 1 and This function checks if \a x == 0 or \a x == \a width - 1 and
\a y == 0 or \a y == \a height - 1 and returns the appropriate value \a y == 0 or \a y == \a height - 1 and returns the appropriate value
of \ref vigra::AtImageBorder, or zero when the point is not at te image border. of \ref vigra::AtImageBorder, or zero when the point is not at te image border.
The behavior of the function is undefined if (x,y) is not inside the im age. The behavior of the function is undefined if (x,y) is not inside the im age.
<b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi xelneighborhood.hxx</a>"<br> <b>\#include</b> \<<a href="pixelneighborhood_8hxx-source.html">vigra/p ixelneighborhood.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
inline AtImageBorder isAtImageBorder(int x, int y, int width, int height) inline AtImageBorder isAtImageBorder(int x, int y, int width, int height)
{ {
return static_cast<AtImageBorder>((x == 0 return static_cast<AtImageBorder>((x == 0
? LeftBorder ? LeftBorder
: x == width-1 : x == width-1
? RightBorder ? RightBorder
: NotAtBorder) | : NotAtBorder) |
(y == 0 (y == 0
skipping to change at line 143 skipping to change at line 163
\code \code
using namespace FourNeighborhood; using namespace FourNeighborhood;
Direction d = East; Direction d = East;
\endcode \endcode
If you want to pass 4-neighborhood codes as a template parameter, use If you want to pass 4-neighborhood codes as a template parameter, use
the class FourNeighborhood::NeighborCode. the class FourNeighborhood::NeighborCode.
<b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi xelneighborhood.hxx</a>"<br> <b>\#include</b> \<<a href="pixelneighborhood_8hxx-source.html">vigra/p ixelneighborhood.hxx</a>\><br>
Namespace: vigra::FourNeighborhood Namespace: vigra::FourNeighborhood
*/ */
class NeighborCode class NeighborCode
{ {
public: public:
typedef Diff2D difference_type;
/** Freeman direction codes for the 4-neighborhood. /** Freeman direction codes for the 4-neighborhood.
<tt>East = 0</tt>, <tt>North = 1</tt> etc. <tt>East = 0</tt>, <tt>North = 1</tt> etc.
<tt>DirectionCount</tt> may be used for portable loop terminati on conditions. <tt>DirectionCount</tt> may be used for portable loop terminati on conditions.
<tt>CausalFirst</tt> and <tt>CausalLast</tt> are the first and last (inclusive) <tt>CausalFirst</tt> and <tt>CausalLast</tt> are the first and last (inclusive)
neighbors in the causal neighborhood, i.e. in the set of neighb ors that have neighbors in the causal neighborhood, i.e. in the set of neighb ors that have
already been visited when the image is traversed in scan order. already been visited when the image is traversed in scan order.
<tt>AntiCausalFirst</tt> and <tt>AntiCausalLast</tt> are the op posite. <tt>AntiCausalFirst</tt> and <tt>AntiCausalLast</tt> are the op posite.
*/ */
enum Direction { enum Direction {
Error = -1, ///< &nbsp; Error = -1, ///< &nbsp;
East = 0, ///< &nbsp; East = 0, ///< &nbsp;
North, ///< &nbsp; North, ///< &nbsp;
West, ///< &nbsp; West, ///< &nbsp;
South, ///< &nbsp; South, ///< &nbsp;
DirectionCount, ///< &nbsp; DirectionCount, ///< &nbsp;
CausalFirst = North, ///< &nbsp; CausalFirst = North, ///< &nbsp;
CausalLast = West, ///< &nbsp; CausalLast = West, ///< &nbsp;
AntiCausalFirst = South, ///< &nbsp; AntiCausalFirst = South, ///< &nbsp;
AntiCausalLast = East ///< &nbsp; AntiCausalLast = East, ///< &nbsp;
};
InitialDirection = East,
OppositeDirPrefix = 1,
OppositeOffset = West
};
static unsigned int directionBit(Direction d) static unsigned int directionBit(Direction d)
{ {
static unsigned int b[] = {1 << (East + 1), static unsigned int b[] = {1 << (East + 1),
1 << (North + 1), 1 << (North + 1),
1 << (West + 1), 1 << (West + 1),
1 << (South + 1)}; 1 << (South + 1)};
return b[d]; return b[d];
}; };
skipping to change at line 367 skipping to change at line 394
\code \code
using namespace EightNeighborhood; using namespace EightNeighborhood;
Direction d = East; Direction d = East;
\endcode \endcode
If you want to pass 8-neighborhood codes as a template parameter, use If you want to pass 8-neighborhood codes as a template parameter, use
the class EightNeighborhood::NeighborCode. the class EightNeighborhood::NeighborCode.
<b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi xelneighborhood.hxx</a>"<br> <b>\#include</b> \<<a href="pixelneighborhood_8hxx-source.html">vigra/p ixelneighborhood.hxx</a>\><br>
Namespace: vigra::EightNeighborhood Namespace: vigra::EightNeighborhood
*/ */
class NeighborCode class NeighborCode
{ {
public: public:
typedef Diff2D difference_type;
/** Freeman direction codes for the 8-neighborhood. /** Freeman direction codes for the 8-neighborhood.
<tt>East = 0</tt>, <tt>North = 1</tt> etc. <tt>East = 0</tt>, <tt>North = 1</tt> etc.
<tt>DirectionCount</tt> may be used for portable loop terminati on conditions. <tt>DirectionCount</tt> may be used for portable loop terminati on conditions.
<tt>CausalFirst</tt> and <tt>CausalLast</tt> are the first and last (inclusive) <tt>CausalFirst</tt> and <tt>CausalLast</tt> are the first and last (inclusive)
neighbors in the causal neighborhood, i.e. in the set of neighb ors that have neighbors in the causal neighborhood, i.e. in the set of neighb ors that have
already been visited when the image is traversed in scan order. already been visited when the image is traversed in scan order.
<tt>AntiCausalFirst</tt> and <tt>AntiCausalLast</tt> are the op posite. <tt>AntiCausalFirst</tt> and <tt>AntiCausalLast</tt> are the op posite.
*/ */
enum Direction { enum Direction {
Error = -1, ///< &nbsp; Error = -1, ///< &nbsp;
skipping to change at line 395 skipping to change at line 425
North, ///< &nbsp; North, ///< &nbsp;
NorthWest, ///< &nbsp; NorthWest, ///< &nbsp;
West, ///< &nbsp; West, ///< &nbsp;
SouthWest, ///< &nbsp; SouthWest, ///< &nbsp;
South, ///< &nbsp; South, ///< &nbsp;
SouthEast, ///< &nbsp; SouthEast, ///< &nbsp;
DirectionCount, ///< &nbsp; DirectionCount, ///< &nbsp;
CausalFirst = NorthEast, ///< &nbsp; CausalFirst = NorthEast, ///< &nbsp;
CausalLast = West, ///< &nbsp; CausalLast = West, ///< &nbsp;
AntiCausalFirst = SouthWest, ///< &nbsp; AntiCausalFirst = SouthWest, ///< &nbsp;
AntiCausalLast = East ///< &nbsp; AntiCausalLast = East, ///< &nbsp;
InitialDirection = East,
OppositeDirPrefix = 1,
OppositeOffset = West
}; };
static unsigned int directionBit(Direction d) static unsigned int directionBit(Direction d)
{ {
static unsigned int b[] = {1 << (East + 1), static unsigned int b[] = {1 << (East + 1),
1 << (NorthEast + 1), 1 << (NorthEast + 1),
1 << (North + 1), 1 << (North + 1),
1 << (NorthWest + 1), 1 << (NorthWest + 1),
1 << (West + 1), 1 << (West + 1),
1 << (SouthWest + 1), 1 << (SouthWest + 1),
skipping to change at line 631 skipping to change at line 665
\code \code
NeighborOffsetCirculator<EightNeighborCode> eight_circulator; NeighborOffsetCirculator<EightNeighborCode> eight_circulator;
NeighborOffsetCirculator<FourNeighborCode> four_circulator; NeighborOffsetCirculator<FourNeighborCode> four_circulator;
\endcode \endcode
Since this circulator doesn't now about the pixels in any particular im age, Since this circulator doesn't now about the pixels in any particular im age,
you usually doesn't use it directly but rather as a base class or helpe r for you usually doesn't use it directly but rather as a base class or helpe r for
neighborhood circulators refering to a particular image (e.g. Neighborh oodCirculator) neighborhood circulators refering to a particular image (e.g. Neighborh oodCirculator)
<b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi xelneighborhood.hxx</a>"<br> <b>\#include</b> \<<a href="pixelneighborhood_8hxx-source.html">vigra/p ixelneighborhood.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template<class NEIGHBORCODE> template<class NEIGHBORCODE>
class NeighborOffsetCirculator class NeighborOffsetCirculator
: public NEIGHBORCODE : public NEIGHBORCODE
{ {
public: public:
typedef NEIGHBORCODE NeighborCode; typedef NEIGHBORCODE NeighborCode;
/** return type of direction() /** return type of direction()
*/ */
typedef typename NEIGHBORCODE::Direction Direction; typedef typename NEIGHBORCODE::Direction Direction;
/** the circulator's value type /** the circulator's value type
*/ */
typedef Diff2D value_type; typedef typename NEIGHBORCODE::difference_type value_type;
/** the circulator's reference type (return type of <TT>*circ</TT>) /** the circulator's reference type (return type of <TT>*circ</TT>)
*/ */
typedef Diff2D const & reference; typedef value_type const & reference;
/** the circulator's index reference type (return type of <TT>circ[ n]</TT>) /** the circulator's index reference type (return type of <TT>circ[ n]</TT>)
*/ */
typedef Diff2D const & index_reference; typedef value_type const & index_reference;
/** the circulator's pointer type (return type of <TT>operator-></T T>) /** the circulator's pointer type (return type of <TT>operator-></T T>)
*/ */
typedef Diff2D const * pointer; typedef value_type const * pointer;
/** the circulator's difference type (argument type of <TT>circ[dif f]</TT>) /** the circulator's difference type (argument type of <TT>circ[dif f]</TT>)
*/ */
typedef int difference_type; typedef int difference_type;
/** the circulator tag (random access iterator) /** the circulator tag (random access iterator)
*/ */
typedef random_access_circulator_tag iterator_category; typedef random_access_circulator_tag iterator_category;
protected: protected:
Direction direction_; Direction direction_;
public: public:
/** Create circulator refering to the given direction. /** Create circulator refering to the given direction.
*/ */
NeighborOffsetCirculator(Direction dir = NEIGHBORCODE::East) NeighborOffsetCirculator(Direction dir = NEIGHBORCODE::InitialDirection )
: direction_(dir) : direction_(dir)
{ {
} }
/** pre-increment */ /** pre-increment */
NeighborOffsetCirculator & operator++() NeighborOffsetCirculator & operator++()
{ {
direction_ = static_cast<Direction>((direction_+1) % NEIGHBORCODE:: DirectionCount); direction_ = static_cast<Direction>((direction_+1) % NEIGHBORCODE:: DirectionCount);
return *this; return *this;
} }
skipping to change at line 814 skipping to change at line 848
{ {
return NEIGHBORCODE::diff(direction(d)); return NEIGHBORCODE::diff(direction(d));
} }
/** member access */ /** member access */
pointer operator->() const pointer operator->() const
{ {
return &diff(); return &diff();
} }
/** Get Diff2D offset from center to current neighbor. /** Get offset from center to current neighbor.
*/ */
Diff2D const & diff() const reference diff() const
{ {
return NEIGHBORCODE::diff(direction_); return NEIGHBORCODE::diff(direction_);
} }
/** Get Diff2D offset to given direction. /** Get offset to given direction.
*/ */
static Diff2D const & diff(Direction dir) static reference diff(Direction dir)
{ {
return NEIGHBORCODE::diff(dir); return NEIGHBORCODE::diff(dir);
} }
/** Get relative distance (Diff2D) from current neighbor to neighbo r /** Get relative distance from current neighbor to neighbor
at given offset. at given offset.
*/ */
Diff2D const &relativeDiff(difference_type offset) const value_type relativeDiff(difference_type offset) const
{ {
Direction toDir = static_cast<Direction>((direction_ + offset) % NE IGHBORCODE::DirectionCount); Direction toDir = static_cast<Direction>((direction_ + offset) % NE IGHBORCODE::DirectionCount);
if(toDir < 0) if(toDir < 0)
toDir = static_cast<Direction>(toDir + NEIGHBORCODE::DirectionC ount); toDir = static_cast<Direction>(toDir + NEIGHBORCODE::DirectionC ount);
return NEIGHBORCODE::relativeDiff(direction_, toDir); return NEIGHBORCODE::relativeDiff(direction_, toDir);
} }
/** X-component of diff() */ /** X-component of diff() */
int dX() const int dX() const
{ {
skipping to change at line 876 skipping to change at line 910
*/ */
unsigned int directionBit() const unsigned int directionBit() const
{ {
return NEIGHBORCODE::directionBit(direction_); return NEIGHBORCODE::directionBit(direction_);
} }
/** Get opposite of current direction. /** Get opposite of current direction.
*/ */
Direction opposite() const Direction opposite() const
{ {
return static_cast<Direction>((direction_ + NEIGHBORCODE::West) % N EIGHBORCODE::DirectionCount); return static_cast<Direction>((NEIGHBORCODE::OppositeDirPrefix*dire ction_ + NEIGHBORCODE::OppositeOffset) % NEIGHBORCODE::DirectionCount);
} }
/** Get opposite bit of current direction. /** Get opposite bit of current direction.
*/ */
unsigned int oppositeDirectionBit() const unsigned int oppositeDirectionBit() const
{ {
return NEIGHBORCODE::directionBit(opposite()); return NEIGHBORCODE::directionBit(opposite());
} }
/** Get direction code at offset of current direction. /** Get direction code at offset of current direction.
skipping to change at line 929 skipping to change at line 963
The template parameters define the kind of neighborhood used and the un derlying The template parameters define the kind of neighborhood used and the un derlying
image. The access functions return the value of the current neighbor pi xel. image. The access functions return the value of the current neighbor pi xel.
Use <tt>center()</tt> to access the center pixel of the neighborhood. Use <tt>center()</tt> to access the center pixel of the neighborhood.
The center can be changed by calling <tt>moveCenterToNeighbor()</tt> The center can be changed by calling <tt>moveCenterToNeighbor()</tt>
or <tt>swapCenterNeighbor()</tt>. Note that this circulator cannot or <tt>swapCenterNeighbor()</tt>. Note that this circulator cannot
when the center is at the image border. You must then use when the center is at the image border. You must then use
\ref vigra::RestrictedNeighborhoodCirculator \ref vigra::RestrictedNeighborhoodCirculator
<b>Usage:</b><br> <b>Usage:</b><br>
<b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi xelneighborhood.hxx</a>"<br> <b>\#include</b> \<<a href="pixelneighborhood_8hxx-source.html">vigra/p ixelneighborhood.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
BImage::traverser upperleft(...), lowerright(...); BImage::traverser upperleft(...), lowerright(...);
int width = lowerright.x - upperleft.x; int width = lowerright.x - upperleft.x;
int height = lowerright.y - upperleft.y; int height = lowerright.y - upperleft.y;
++upperleft.y; // avoid image border ++upperleft.y; // avoid image border
for(int y=1; y<height-1; ++y, ++upperleft.y) for(int y=1; y<height-1; ++y, ++upperleft.y)
skipping to change at line 986 skipping to change at line 1020
/** type of the direction code /** type of the direction code
*/ */
typedef typename NEIGHBORCODE::Direction Direction; typedef typename NEIGHBORCODE::Direction Direction;
/** the circulator's reference type (return type of <TT>*circ</TT>) /** the circulator's reference type (return type of <TT>*circ</TT>)
*/ */
typedef typename IMAGEITERATOR::reference reference; typedef typename IMAGEITERATOR::reference reference;
/** the circulator's index reference type (return type of <TT>circ[ n]</TT>) /** the circulator's index reference type (return type of <TT>circ[ n]</TT>)
*/ */
typedef typename IMAGEITERATOR::index_reference index_reference;
typedef reference index_reference;
/** the circulator's pointer type (return type of <TT>operator-></T T>) /** the circulator's pointer type (return type of <TT>operator-></T T>)
*/ */
typedef typename IMAGEITERATOR::pointer pointer; typedef typename IMAGEITERATOR::pointer pointer;
/** the circulator's difference type (argument type of <TT>circ[dif f]</TT>) /** the circulator's difference type (argument type of <TT>circ[dif f]</TT>)
*/ */
typedef typename NEIGHBOROFFSETCIRCULATOR::difference_type difference_t ype; typedef typename NEIGHBOROFFSETCIRCULATOR::difference_type difference_t ype;
/** the circulator tag (random_access_circulator_tag) /** the circulator tag (random_access_circulator_tag)
*/ */
typedef typename NEIGHBOROFFSETCIRCULATOR::iterator_category iterator_c ategory; typedef typename NEIGHBOROFFSETCIRCULATOR::iterator_category iterator_c ategory;
/** Construct circulator with given <tt>center</tt> pixel, pointing to the neighbor /** Construct circulator with given <tt>center</tt> pixel, pointing to the neighbor
at the given direction <tt>d</tt>. at the given direction <tt>d</tt>.
*/ */
NeighborhoodCirculator(IMAGEITERATOR const & center = IMAGEITERATOR(), NeighborhoodCirculator(IMAGEITERATOR const & center = IMAGEITERATOR(),
Direction d = NEIGHBOROFFSETCIRCULATOR::East) Direction d = NEIGHBOROFFSETCIRCULATOR::InitialD irection)
: IMAGEITERATOR(center), neighborCode_(d) : IMAGEITERATOR(center), neighborCode_(d)
{ {
IMAGEITERATOR::operator+=(neighborCode_.diff()); IMAGEITERATOR::operator+=(neighborCode_.diff());
} }
/** pre-increment */ /** pre-increment */
NeighborhoodCirculator & operator++() NeighborhoodCirculator & operator++()
{ {
return operator+=(1); return operator+=(1);
} }
skipping to change at line 1237 skipping to change at line 1272
would be outside the image und must not be accessed. would be outside the image und must not be accessed.
The template parameters define the kind of neighborhood used (four or e ight) The template parameters define the kind of neighborhood used (four or e ight)
and the underlying image, whereas the required neighbirhood restriction is and the underlying image, whereas the required neighbirhood restriction is
given by the last constructur argument. This below for typical usage. given by the last constructur argument. This below for typical usage.
The access functions return the value of the current neighbor pixel. Us e <tt>center()</tt> to The access functions return the value of the current neighbor pixel. Us e <tt>center()</tt> to
access the center pixel of the neighborhood. access the center pixel of the neighborhood.
<b>Usage:</b><br> <b>Usage:</b><br>
<b>\#include</b> "<a href="pixelneighborhood_8hxx-source.html">vigra/pi xelneighborhood.hxx</a>"<br> <b>\#include</b> \<<a href="pixelneighborhood_8hxx-source.html">vigra/p ixelneighborhood.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
BImage::traverser upperleft(...), lowerright(...); BImage::traverser upperleft(...), lowerright(...);
int width = lowerright.x - upperleft.x; int width = lowerright.x - upperleft.x;
int height = lowerright.y - upperleft.y; int height = lowerright.y - upperleft.y;
for(int y=0; y<height; ++y, ++upperleft.y) for(int y=0; y<height; ++y, ++upperleft.y)
{ {
 End of changes. 30 change blocks. 
37 lines changed or deleted 80 lines changed or added


 polynomial.hxx   polynomial.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2004 by Ullrich Koethe */ /* Copyright 1998-2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 68 skipping to change at line 68
/* */ /* */
/*****************************************************************/ /*****************************************************************/
/** Polynomial interface for an externally managed array. /** Polynomial interface for an externally managed array.
The coefficient type <tt>T</tt> can be either a scalar or complex The coefficient type <tt>T</tt> can be either a scalar or complex
(compatible to <tt>std::complex</tt>) type. (compatible to <tt>std::complex</tt>) type.
\see vigra::Polynomial, vigra::StaticPolynomial, polynomialRoots() \see vigra::Polynomial, vigra::StaticPolynomial, polynomialRoots()
<b>\#include</b> "<a href="polynomial_8hxx-source.html">vigra/polynomia l.hxx</a>"<br> <b>\#include</b> \<<a href="polynomial_8hxx-source.html">vigra/polynomi al.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\ingroup Polynomials \ingroup Polynomials
*/ */
template <class T> template <class T>
class PolynomialView class PolynomialView
{ {
public: public:
/** Coefficient type of the polynomial /** Coefficient type of the polynomial
skipping to change at line 437 skipping to change at line 437
/* Polynomial */ /* Polynomial */
/* */ /* */
/*****************************************************************/ /*****************************************************************/
/** Polynomial with internally managed array. /** Polynomial with internally managed array.
Most interesting functionality is inherited from \ref vigra::Polynomial View. Most interesting functionality is inherited from \ref vigra::Polynomial View.
\see vigra::PolynomialView, vigra::StaticPolynomial, polynomialRoots() \see vigra::PolynomialView, vigra::StaticPolynomial, polynomialRoots()
<b>\#include</b> "<a href="polynomial_8hxx-source.html">vigra/polynomia l.hxx</a>"<br> <b>\#include</b> \<<a href="polynomial_8hxx-source.html">vigra/polynomi al.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\ingroup Polynomials \ingroup Polynomials
*/ */
template <class T> template <class T>
class Polynomial class Polynomial
: public PolynomialView<T> : public PolynomialView<T>
{ {
typedef PolynomialView<T> BaseType; typedef PolynomialView<T> BaseType;
public: public:
skipping to change at line 568 skipping to change at line 568
/** Polynomial with internally managed array of static length. /** Polynomial with internally managed array of static length.
Most interesting functionality is inherited from \ref vigra::Polynomial View. Most interesting functionality is inherited from \ref vigra::Polynomial View.
This class differs from \ref vigra::Polynomial in that it allocates This class differs from \ref vigra::Polynomial in that it allocates
its memory statically which is much faster. Therefore, <tt>StaticPolyno mial</tt> its memory statically which is much faster. Therefore, <tt>StaticPolyno mial</tt>
can only represent polynomials up to the given <tt>MAXORDER</tt>. can only represent polynomials up to the given <tt>MAXORDER</tt>.
\see vigra::PolynomialView, vigra::Polynomial, polynomialRoots() \see vigra::PolynomialView, vigra::Polynomial, polynomialRoots()
<b>\#include</b> "<a href="polynomial_8hxx-source.html">vigra/polynomia l.hxx</a>"<br> <b>\#include</b> \<<a href="polynomial_8hxx-source.html">vigra/polynomi al.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\ingroup Polynomials \ingroup Polynomials
*/ */
template <unsigned int MAXORDER, class T> template <unsigned int MAXORDER, class T>
class StaticPolynomial class StaticPolynomial
: public PolynomialView<T> : public PolynomialView<T>
{ {
typedef PolynomialView<T> BaseType; typedef PolynomialView<T> BaseType;
skipping to change at line 921 skipping to change at line 921
\code \code
namespace vigra { namespace vigra {
template <class POLYNOMIAL, class VECTOR> template <class POLYNOMIAL, class VECTOR>
bool bool
polynomialRoots(POLYNOMIAL const & poriginal, VECTOR & roots, bool polishRoots = true); polynomialRoots(POLYNOMIAL const & poriginal, VECTOR & roots, bool polishRoots = true);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="polynomial_8hxx-source.html">vigra/polyn omial.hxx</a>"<br> <b>\#include</b> \<<a href="polynomial_8hxx-source.html">vigra/poly nomial.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
// encode the polynomial x^4 - 1 // encode the polynomial x^4 - 1
Polynomial<double> poly(4); Polynomial<double> poly(4);
poly[0] = -1.0; poly[0] = -1.0;
poly[4] = 1.0; poly[4] = 1.0;
ArrayVector<std::complex<double> > roots; ArrayVector<std::complex<double> > roots;
polynomialRoots(poly, roots); polynomialRoots(poly, roots);
skipping to change at line 1058 skipping to change at line 1058
\code \code
namespace vigra { namespace vigra {
template <class POLYNOMIAL, class VECTOR> template <class POLYNOMIAL, class VECTOR>
bool bool
polynomialRealRoots(POLYNOMIAL const & p, VECTOR & roots, bool poli shRoots = true); polynomialRealRoots(POLYNOMIAL const & p, VECTOR & roots, bool poli shRoots = true);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="polynomial_8hxx-source.html">vigra/polyn omial.hxx</a>"<br> <b>\#include</b> \<<a href="polynomial_8hxx-source.html">vigra/poly nomial.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
// encode the polynomial x^4 - 1 // encode the polynomial x^4 - 1
Polynomial<double> poly(4); Polynomial<double> poly(4);
poly[0] = -1.0; poly[0] = -1.0;
poly[4] = 1.0; poly[4] = 1.0;
ArrayVector<double> roots; ArrayVector<double> roots;
polynomialRealRoots(poly, roots); polynomialRealRoots(poly, roots);
 End of changes. 7 change blocks. 
8 lines changed or deleted 8 lines changed or added


 rational.hxx   rational.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2004 by Ullrich Koethe */ /* Copyright 1998-2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* It was adapted from the file boost/rational.hpp of the */ /* It was adapted from the file boost/rational.hpp of the */
/* boost library. */ /* boost library. */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 77 skipping to change at line 77
/* */ /* */
/* gcd */ /* gcd */
/* */ /* */
/********************************************************/ /********************************************************/
/*! Calculate the greatest common divisor. /*! Calculate the greatest common divisor.
This function works for arbitrary integer types, including user-defined This function works for arbitrary integer types, including user-defined
(e.g. infinite precision) ones. (e.g. infinite precision) ones.
<b>\#include</b> "<a href="rational_8hxx-source.html">vigra/rational.hx x</a>"<br> <b>\#include</b> \<<a href="rational_8hxx-source.html">vigra/rational.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <typename IntType> template <typename IntType>
IntType gcd(IntType n, IntType m) IntType gcd(IntType n, IntType m)
{ {
// Avoid repeated construction // Avoid repeated construction
IntType zero(0); IntType zero(0);
// This is abs() - given the existence of broken compilers with Koenig // This is abs() - given the existence of broken compilers with Koenig
// lookup issues and other problems, I code this explicitly. (Remember, // lookup issues and other problems, I code this explicitly. (Remember,
skipping to change at line 118 skipping to change at line 118
/* */ /* */
/* lcm */ /* lcm */
/* */ /* */
/********************************************************/ /********************************************************/
/*! Calculate the lowest common multiple. /*! Calculate the lowest common multiple.
This function works for arbitrary integer types, including user-defined This function works for arbitrary integer types, including user-defined
(e.g. infinite precision) ones. (e.g. infinite precision) ones.
<b>\#include</b> "<a href="rational_8hxx-source.html">vigra/rational.hx x</a>"<br> <b>\#include</b> \<<a href="rational_8hxx-source.html">vigra/rational.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <typename IntType> template <typename IntType>
IntType lcm(IntType n, IntType m) IntType lcm(IntType n, IntType m)
{ {
// Avoid repeated construction // Avoid repeated construction
IntType zero(0); IntType zero(0);
if (n == zero || m == zero) if (n == zero || m == zero)
return zero; return zero;
skipping to change at line 188 skipping to change at line 188
\ref AlgebraicField and the required \ref RationalTraits "numeric and \ref AlgebraicField and the required \ref RationalTraits "numeric and
promotion traits". All arithmetic and comparison operators, as well promotion traits". All arithmetic and comparison operators, as well
as the relevant algebraic functions are supported . as the relevant algebraic functions are supported .
<b>See also:</b> <b>See also:</b>
<ul> <ul>
<li> \ref RationalTraits <li> \ref RationalTraits
<li> \ref RationalOperations <li> \ref RationalOperations
</ul> </ul>
<b>\#include</b> "<a href="rational_8hxx-source.html">vigra/rational.hx x</a>"<br> <b>\#include</b> \<<a href="rational_8hxx-source.html">vigra/rational.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <typename IntType> template <typename IntType>
class Rational class Rational
{ {
public: public:
/** The type of numerator and denominator /** The type of numerator and denominator
*/ */
typedef IntType value_type; typedef IntType value_type;
skipping to change at line 733 skipping to change at line 733
typedef Type NormType; typedef Type NormType;
}; };
template <class T1, class T2> template <class T1, class T2>
struct PromoteTraits<Rational<T1>, Rational<T2> > struct PromoteTraits<Rational<T1>, Rational<T2> >
{ {
typedef Rational<typename PromoteTraits<T1, T2>::Promote> Promote; typedef Rational<typename PromoteTraits<T1, T2>::Promote> Promote;
}; };
\endcode \endcode
<b>\#include</b> "<a href="rational_8hxx-source.html">vigra/rational.hx x</a>"<br> <b>\#include</b> \<<a href="rational_8hxx-source.html">vigra/rational.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
template<class T> template<class T>
struct NumericTraits<Rational<T> > struct NumericTraits<Rational<T> >
{ {
typedef Rational<T> Type; typedef Rational<T> Type;
typedef Rational<typename NumericTraits<T>::Promote> Promote; typedef Rational<typename NumericTraits<T>::Promote> Promote;
skipping to change at line 819 skipping to change at line 819
#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION #endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
/********************************************************/ /********************************************************/
/* */ /* */
/* RationalOperations */ /* RationalOperations */
/* */ /* */
/********************************************************/ /********************************************************/
/** \addtogroup RationalOperations Functions for Rational /** \addtogroup RationalOperations Functions for Rational
\brief <b>\#include</b> "<a href="rational_8hxx-source.html">vigra/ rational.hxx</a>"<br> \brief <b>\#include</b> \<<a href="rational_8hxx-source.html">vigra /rational.hxx</a>\><br>
These functions fulfill the requirements of an \ref AlgebraicField. These functions fulfill the requirements of an \ref AlgebraicField.
Namespace: vigra Namespace: vigra
<p> <p>
*/ */
//@{ //@{
/********************************************************/ /********************************************************/
 End of changes. 7 change blocks. 
8 lines changed or deleted 8 lines changed or added


 recursiveconvolution.hxx   recursiveconvolution.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 93 skipping to change at line 93
\end{array} \end{array}
\f] \f]
The signal's value_type (SrcAccessor::value_type) must be a The signal's value_type (SrcAccessor::value_type) must be a
linear space over <TT>double</TT>, linear space over <TT>double</TT>,
i.e. addition of source values, multiplication with <TT>double</TT>, i.e. addition of source values, multiplication with <TT>double</TT>,
and <TT>NumericTraits</TT> must be defined. and <TT>NumericTraits</TT> must be defined.
<b> Declaration:</b> <b> Declaration:</b>
<b>First order recursive filter:<b> <b>First order recursive filter:</b>
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void recursiveFilterLine(SrcIterator is, SrcIterator isend, SrcAcce ssor as, void recursiveFilterLine(SrcIterator is, SrcIterator isend, SrcAcce ssor as,
DestIterator id, DestAccessor ad, DestIterator id, DestAccessor ad,
double b1, BorderTreatmentMode border) double b1, BorderTreatmentMode border)
} }
\endcode \endcode
<b>Second order recursive filter:<b> <b>Second order recursive filter:</b>
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void recursiveFilterLine(SrcIterator is, SrcIterator isend, SrcAcce ssor as, void recursiveFilterLine(SrcIterator is, SrcIterator isend, SrcAcce ssor as,
DestIterator id, DestAccessor ad, DestIterator id, DestAccessor ad,
double b1, double b2) double b1, double b2)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="recursiveconvolution_8hxx-source.html">vigra /recursiveconvolution.hxx</a>"<br> <b>\#include</b> \<<a href="recursiveconvolution_8hxx-source.html">vigr a/recursiveconvolution.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vector<float> src, dest; vector<float> src, dest;
... ...
vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor; vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor;
vigra::recursiveFilterLine(src.begin(), src.end(), FAccessor(), vigra::recursiveFilterLine(src.begin(), src.end(), FAccessor(),
dest.begin(), FAccessor(), dest.begin(), FAccessor(),
skipping to change at line 156 skipping to change at line 156
s = d * s; s = d * s;
dest_accessor.set( dest_accessor.set(
NumericTraits<DestAccessor::value_type>::fromRealPromote(s), id); NumericTraits<DestAccessor::value_type>::fromRealPromote(s), id);
\endcode \endcode
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
-1 < b < 1 -1 < b < 1
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void recursiveFilterLine)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void recursiveFilterLine(SrcIterator is, SrcIterator isend, SrcAccessor as, void recursiveFilterLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
DestIterator id, DestAccessor ad, double b, Border TreatmentMode border) DestIterator id, DestAccessor ad, double b, Border TreatmentMode border)
{ {
int w = isend - is; int w = isend - is;
SrcIterator istart = is; SrcIterator istart = is;
int x; int x;
skipping to change at line 378 skipping to change at line 380
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void recursiveSmoothLine(SrcIterator is, SrcIterator isend, SrcAcce ssor as, void recursiveSmoothLine(SrcIterator is, SrcIterator isend, SrcAcce ssor as,
DestIterator id, DestAccessor ad, double scale) DestIterator id, DestAccessor ad, double scale)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="recursiveconvolution_8hxx-source.html">vigra /recursiveconvolution.hxx</a>"<br> <b>\#include</b> \<<a href="recursiveconvolution_8hxx-source.html">vigr a/recursiveconvolution.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vector<float> src, dest; vector<float> src, dest;
... ...
vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor; vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor;
vigra::recursiveSmoothLine(src.begin(), src.end(), FAccessor(), vigra::recursiveSmoothLine(src.begin(), src.end(), FAccessor(),
dest.begin(), FAccessor(), 3.0); dest.begin(), FAccessor(), 3.0);
skipping to change at line 418 skipping to change at line 420
\endcode \endcode
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
scale > 0 scale > 0
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void recursiveSmoothLine)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline inline
void recursiveSmoothLine(SrcIterator is, SrcIterator isend, SrcAccessor as, void recursiveSmoothLine(SrcIterator is, SrcIterator isend, SrcAccessor as,
DestIterator id, DestAccessor ad, double scale) DestIterator id, DestAccessor ad, double scale)
{ {
vigra_precondition(scale >= 0, vigra_precondition(scale >= 0,
"recursiveSmoothLine(): scale must be >= 0.\n"); "recursiveSmoothLine(): scale must be >= 0.\n");
double b = (scale == 0.0) ? double b = (scale == 0.0) ?
skipping to change at line 462 skipping to change at line 466
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void recursiveFirstDerivativeLine(SrcIterator is, SrcIterator isend , SrcAccessor as, void recursiveFirstDerivativeLine(SrcIterator is, SrcIterator isend , SrcAccessor as,
DestIterator id, DestAccessor ad, double scale) DestIterator id, DestAccessor ad, double scale)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="recursiveconvolution_8hxx-source.html">vigra /recursiveconvolution.hxx</a>"<br> <b>\#include</b> \<<a href="recursiveconvolution_8hxx-source.html">vigr a/recursiveconvolution.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vector<float> src, dest; vector<float> src, dest;
... ...
vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor; vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor;
vigra::recursiveFirstDerivativeLine(src.begin(), src.end(), FAccessor() , vigra::recursiveFirstDerivativeLine(src.begin(), src.end(), FAccessor() ,
dest.begin(), FAccessor(), 3.0); dest.begin(), FAccessor(), 3.0);
skipping to change at line 503 skipping to change at line 507
\endcode \endcode
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
scale > 0 scale > 0
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void recursiveFirstDerivativeLin
e)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void recursiveFirstDerivativeLine(SrcIterator is, SrcIterator isend, SrcAcc essor as, void recursiveFirstDerivativeLine(SrcIterator is, SrcIterator isend, SrcAcc essor as,
DestIterator id, DestAccessor ad, double scale) DestIterator id, DestAccessor ad, double scale)
{ {
vigra_precondition(scale > 0, vigra_precondition(scale > 0,
"recursiveFirstDerivativeLine(): scale must be > 0.\n"); "recursiveFirstDerivativeLine(): scale must be > 0.\n");
int w = isend -is; int w = isend -is;
skipping to change at line 579 skipping to change at line 585
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void recursiveSecondDerivativeLine(SrcIterator is, SrcIterator isen d, SrcAccessor as, void recursiveSecondDerivativeLine(SrcIterator is, SrcIterator isen d, SrcAccessor as,
DestIterator id, DestAccessor ad, double scale) DestIterator id, DestAccessor ad, double scale)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="recursiveconvolution_8hxx-source.html">vigra /recursiveconvolution.hxx</a>"<br> <b>\#include</b> \<<a href="recursiveconvolution_8hxx-source.html">vigr a/recursiveconvolution.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vector<float> src, dest; vector<float> src, dest;
... ...
vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor; vigra::DefaultAccessor<vector<float>::iterator, float> FAccessor;
vigra::recursiveSecondDerivativeLine(src.begin(), src.end(), FAccessor( ), vigra::recursiveSecondDerivativeLine(src.begin(), src.end(), FAccessor( ),
dest.begin(), FAccessor(), 3.0); dest.begin(), FAccessor(), 3.0);
skipping to change at line 620 skipping to change at line 626
\endcode \endcode
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
scale > 0 scale > 0
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void recursiveSecondDerivativeLi
ne)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void recursiveSecondDerivativeLine(SrcIterator is, SrcIterator isend, SrcAc cessor as, void recursiveSecondDerivativeLine(SrcIterator is, SrcIterator isend, SrcAc cessor as,
DestIterator id, DestAccessor ad, double scale) DestIterator id, DestAccessor ad, double scale)
{ {
vigra_precondition(scale > 0, vigra_precondition(scale > 0,
"recursiveSecondDerivativeLine(): scale must be > 0.\n"); "recursiveSecondDerivativeLine(): scale must be > 0.\n");
int w = isend -is; int w = isend -is;
skipping to change at line 704 skipping to change at line 712
// second order filter // second order filter
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveFilterX(SrcImageIterator supperleft, void recursiveFilterX(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as , SrcImageIterator slowerright, SrcAccessor as ,
DestImageIterator dupperleft, DestAccessor a d, DestImageIterator dupperleft, DestAccessor a d,
double b1, double b2); double b1, double b2);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
// first order filter // first order filter
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveFilterX( void recursiveFilterX(
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
double b, BorderTreatmentMode border); double b, BorderTreatmentMode border);
skipping to change at line 727 skipping to change at line 735
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveFilterX( void recursiveFilterX(
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
double b1, double b2); double b1, double b2);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="recursiveconvolution_8hxx-source.html">vigra /recursiveconvolution.hxx</a>"<br> <b>\#include</b> \<<a href="recursiveconvolution_8hxx-source.html">vigr a/recursiveconvolution.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
vigra::recursiveSmoothX(srcImageRange(src), destImage(dest), vigra::recursiveSmoothX(srcImageRange(src), destImage(dest),
0.5, BORDER_TREATMENT_REFLECT); 0.5, BORDER_TREATMENT_REFLECT);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void recursiveFilterX)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveFilterX(SrcImageIterator supperleft, void recursiveFilterX(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as, SrcImageIterator slowerright, SrcAccessor as,
DestImageIterator dupperleft, DestAccessor ad, DestImageIterator dupperleft, DestAccessor ad,
double b, BorderTreatmentMode border) double b, BorderTreatmentMode border)
{ {
int w = slowerright.x - supperleft.x; int w = slowerright.x - supperleft.x;
int h = slowerright.y - supperleft.y; int h = slowerright.y - supperleft.y;
skipping to change at line 840 skipping to change at line 850
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveSmoothX(SrcImageIterator supperleft, void recursiveSmoothX(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as, SrcImageIterator slowerright, SrcAccessor as,
DestImageIterator dupperleft, DestAccessor ad, DestImageIterator dupperleft, DestAccessor ad,
double scale) double scale)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveSmoothX( void recursiveSmoothX(
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
double scale) double scale)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="recursiveconvolution_8hxx-source.html">vigra /recursiveconvolution.hxx</a>"<br> <b>\#include</b> \<<a href="recursiveconvolution_8hxx-source.html">vigr a/recursiveconvolution.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
vigra::recursiveSmoothX(srcImageRange(src), destImage(dest), 3.0); vigra::recursiveSmoothX(srcImageRange(src), destImage(dest), 3.0);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void recursiveSmoothX)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveSmoothX(SrcImageIterator supperleft, void recursiveSmoothX(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as, SrcImageIterator slowerright, SrcAccessor as,
DestImageIterator dupperleft, DestAccessor ad, DestImageIterator dupperleft, DestAccessor ad,
double scale) double scale)
{ {
int w = slowerright.x - supperleft.x; int w = slowerright.x - supperleft.x;
int h = slowerright.y - supperleft.y; int h = slowerright.y - supperleft.y;
skipping to change at line 935 skipping to change at line 947
// second order filter // second order filter
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveFilterY(SrcImageIterator supperleft, void recursiveFilterY(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as , SrcImageIterator slowerright, SrcAccessor as ,
DestImageIterator dupperleft, DestAccessor a d, DestImageIterator dupperleft, DestAccessor a d,
double b1, double b2); double b1, double b2);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
// first order filter // first order filter
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveFilterY( void recursiveFilterY(
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
double b, BorderTreatmentMode border); double b, BorderTreatmentMode border);
skipping to change at line 958 skipping to change at line 970
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveFilterY( void recursiveFilterY(
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
double b1, double b2); double b1, double b2);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="recursiveconvolution_8hxx-source.html">vigra /recursiveconvolution.hxx</a>"<br> <b>\#include</b> \<<a href="recursiveconvolution_8hxx-source.html">vigr a/recursiveconvolution.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
vigra::recursiveFilterY(srcImageRange(src), destImage(dest), -0.6, -0.0 6); vigra::recursiveFilterY(srcImageRange(src), destImage(dest), -0.6, -0.0 6);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void recursiveFilterY)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveFilterY(SrcImageIterator supperleft, void recursiveFilterY(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as, SrcImageIterator slowerright, SrcAccessor as,
DestImageIterator dupperleft, DestAccessor ad, DestImageIterator dupperleft, DestAccessor ad,
double b, BorderTreatmentMode border) double b, BorderTreatmentMode border)
{ {
int w = slowerright.x - supperleft.x; int w = slowerright.x - supperleft.x;
int h = slowerright.y - supperleft.y; int h = slowerright.y - supperleft.y;
skipping to change at line 1070 skipping to change at line 1084
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveSmoothY(SrcImageIterator supperleft, void recursiveSmoothY(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as, SrcImageIterator slowerright, SrcAccessor as,
DestImageIterator dupperleft, DestAccessor ad, DestImageIterator dupperleft, DestAccessor ad,
double scale) double scale)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveSmoothY( void recursiveSmoothY(
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
double scale) double scale)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="recursiveconvolution_8hxx-source.html">vigra /recursiveconvolution.hxx</a>"<br> <b>\#include</b> \<<a href="recursiveconvolution_8hxx-source.html">vigr a/recursiveconvolution.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
vigra::recursiveSmoothY(srcImageRange(src), destImage(dest), 3.0); vigra::recursiveSmoothY(srcImageRange(src), destImage(dest), 3.0);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void recursiveSmoothY)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveSmoothY(SrcImageIterator supperleft, void recursiveSmoothY(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as, SrcImageIterator slowerright, SrcAccessor as,
DestImageIterator dupperleft, DestAccessor ad, DestImageIterator dupperleft, DestAccessor ad,
double scale) double scale)
{ {
int w = slowerright.x - supperleft.x; int w = slowerright.x - supperleft.x;
int h = slowerright.y - supperleft.y; int h = slowerright.y - supperleft.y;
skipping to change at line 1157 skipping to change at line 1173
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveFirstDerivativeX(SrcImageIterator supperleft, void recursiveFirstDerivativeX(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as, SrcImageIterator slowerright, SrcAccessor as,
DestImageIterator dupperleft, DestAccessor ad, DestImageIterator dupperleft, DestAccessor ad,
double scale) double scale)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveFirstDerivativeX( void recursiveFirstDerivativeX(
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
double scale) double scale)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="recursiveconvolution_8hxx-source.html">vigra /recursiveconvolution.hxx</a>"<br> <b>\#include</b> \<<a href="recursiveconvolution_8hxx-source.html">vigr a/recursiveconvolution.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
vigra::recursiveFirstDerivativeX(srcImageRange(src), destImage(dest), 3 .0); vigra::recursiveFirstDerivativeX(srcImageRange(src), destImage(dest), 3 .0);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void recursiveFirstDerivativeX)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveFirstDerivativeX(SrcImageIterator supperleft, void recursiveFirstDerivativeX(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as, SrcImageIterator slowerright, SrcAccessor as,
DestImageIterator dupperleft, DestAccessor ad, DestImageIterator dupperleft, DestAccessor ad,
double scale) double scale)
{ {
int w = slowerright.x - supperleft.x; int w = slowerright.x - supperleft.x;
int h = slowerright.y - supperleft.y; int h = slowerright.y - supperleft.y;
skipping to change at line 1244 skipping to change at line 1262
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveFirstDerivativeY(SrcImageIterator supperleft, void recursiveFirstDerivativeY(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as, SrcImageIterator slowerright, SrcAccessor as,
DestImageIterator dupperleft, DestAccessor ad, DestImageIterator dupperleft, DestAccessor ad,
double scale) double scale)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveFirstDerivativeY( void recursiveFirstDerivativeY(
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
double scale) double scale)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="recursiveconvolution_8hxx-source.html">vigra /recursiveconvolution.hxx</a>"<br> <b>\#include</b> \<<a href="recursiveconvolution_8hxx-source.html">vigr a/recursiveconvolution.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
vigra::recursiveFirstDerivativeY(srcImageRange(src), destImage(dest), 3 .0); vigra::recursiveFirstDerivativeY(srcImageRange(src), destImage(dest), 3 .0);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void recursiveFirstDerivativeY)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveFirstDerivativeY(SrcImageIterator supperleft, void recursiveFirstDerivativeY(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as, SrcImageIterator slowerright, SrcAccessor as,
DestImageIterator dupperleft, DestAccessor ad, DestImageIterator dupperleft, DestAccessor ad,
double scale) double scale)
{ {
int w = slowerright.x - supperleft.x; int w = slowerright.x - supperleft.x;
int h = slowerright.y - supperleft.y; int h = slowerright.y - supperleft.y;
skipping to change at line 1331 skipping to change at line 1351
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveSecondDerivativeX(SrcImageIterator supperleft, void recursiveSecondDerivativeX(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as, SrcImageIterator slowerright, SrcAccessor as,
DestImageIterator dupperleft, DestAccessor ad, DestImageIterator dupperleft, DestAccessor ad,
double scale) double scale)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveSecondDerivativeX( void recursiveSecondDerivativeX(
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
double scale) double scale)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="recursiveconvolution_8hxx-source.html">vigra /recursiveconvolution.hxx</a>"<br> <b>\#include</b> \<<a href="recursiveconvolution_8hxx-source.html">vigr a/recursiveconvolution.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
vigra::recursiveSecondDerivativeX(srcImageRange(src), destImage(dest), 3.0); vigra::recursiveSecondDerivativeX(srcImageRange(src), destImage(dest), 3.0);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void recursiveSecondDerivativeX)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveSecondDerivativeX(SrcImageIterator supperleft, void recursiveSecondDerivativeX(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as, SrcImageIterator slowerright, SrcAccessor as,
DestImageIterator dupperleft, DestAccessor ad, DestImageIterator dupperleft, DestAccessor ad,
double scale) double scale)
{ {
int w = slowerright.x - supperleft.x; int w = slowerright.x - supperleft.x;
int h = slowerright.y - supperleft.y; int h = slowerright.y - supperleft.y;
skipping to change at line 1418 skipping to change at line 1440
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveSecondDerivativeY(SrcImageIterator supperleft, void recursiveSecondDerivativeY(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as, SrcImageIterator slowerright, SrcAccessor as,
DestImageIterator dupperleft, DestAccessor ad, DestImageIterator dupperleft, DestAccessor ad,
double scale) double scale)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveSecondDerivativeY( void recursiveSecondDerivativeY(
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
double scale) double scale)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="recursiveconvolution_8hxx-source.html">vigra /recursiveconvolution.hxx</a>"<br> <b>\#include</b> \<<a href="recursiveconvolution_8hxx-source.html">vigr a/recursiveconvolution.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
vigra::recursiveSecondDerivativeY(srcImageRange(src), destImage(dest), 3.0); vigra::recursiveSecondDerivativeY(srcImageRange(src), destImage(dest), 3.0);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void recursiveSecondDerivativeY)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void recursiveSecondDerivativeY(SrcImageIterator supperleft, void recursiveSecondDerivativeY(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor as, SrcImageIterator slowerright, SrcAccessor as,
DestImageIterator dupperleft, DestAccessor ad, DestImageIterator dupperleft, DestAccessor ad,
double scale) double scale)
{ {
int w = slowerright.x - supperleft.x; int w = slowerright.x - supperleft.x;
int h = slowerright.y - supperleft.y; int h = slowerright.y - supperleft.y;
 End of changes. 37 change blocks. 
26 lines changed or deleted 52 lines changed or added


 resampling_convolution.hxx   resampling_convolution.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2004 by Ullrich Koethe */ /* Copyright 1998-2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 46 skipping to change at line 46
/************************************************************************/ /************************************************************************/
#ifndef VIGRA_RESAMPLING_CONVOLUTION_HXX #ifndef VIGRA_RESAMPLING_CONVOLUTION_HXX
#define VIGRA_RESAMPLING_CONVOLUTION_HXX #define VIGRA_RESAMPLING_CONVOLUTION_HXX
#include <cmath> #include <cmath>
#include "stdimage.hxx" #include "stdimage.hxx"
#include "array_vector.hxx" #include "array_vector.hxx"
#include "rational.hxx" #include "rational.hxx"
#include "functortraits.hxx" #include "functortraits.hxx"
#include "functorexpression.hxx"
#include "transformimage.hxx"
#include "imagecontainer.hxx"
namespace vigra { namespace vigra {
namespace resampling_detail namespace resampling_detail
{ {
struct MapTargetToSourceCoordinate struct MapTargetToSourceCoordinate
{ {
MapTargetToSourceCoordinate(Rational<int> const & samplingRatio, MapTargetToSourceCoordinate(Rational<int> const & samplingRatio,
Rational<int> const & offset) Rational<int> const & offset)
: a(samplingRatio.denominator()*offset.denominator()), : a(samplingRatio.denominator()*offset.denominator()),
b(samplingRatio.numerator()*offset.numerator()), b(samplingRatio.numerator()*offset.numerator()),
c(samplingRatio.numerator()*offset.denominator()) c(samplingRatio.numerator()*offset.denominator())
{} {}
// the following funcions are more efficient realizations of: // the following functions are more efficient realizations of:
// rational_cast<T>(i / samplingRatio + offset); // rational_cast<T>(i / samplingRatio + offset);
// we need efficiency because this may be called in the inner loop // we need efficiency because this may be called in the inner loop
int operator()(int i) const int operator()(int i) const
{ {
return (i * a + b) / c; return (i * a + b) / c;
} }
double toDouble(int i) const double toDouble(int i) const
{ {
return double(i * a + b) / c; return double(i * a + b) / c;
} }
Rational<int> toRational(int i) const Rational<int> toRational(int i) const
{ {
return Rational<int>(i * a + b, c); return Rational<int>(i * a + b, c);
} }
bool isExpand2() const
{
return a == 1 && b == 0 && c == 2;
}
bool isReduce2() const
{
return a == 2 && b == 0 && c == 1;
}
int a, b, c; int a, b, c;
}; };
} // namespace resampling_detail } // namespace resampling_detail
template <> template <>
class FunctorTraits<resampling_detail::MapTargetToSourceCoordinate> class FunctorTraits<resampling_detail::MapTargetToSourceCoordinate>
: public FunctorTraitsBase<resampling_detail::MapTargetToSourceCoordinate> : public FunctorTraitsBase<resampling_detail::MapTargetToSourceCoordinate>
{ {
public: public:
typedef VigraTrueType isUnaryFunctor; typedef VigraTrueType isUnaryFunctor;
}; };
template <class SrcIter, class SrcAcc, template <class SrcIter, class SrcAcc,
class DestIter, class DestAcc, class DestIter, class DestAcc,
class KernelArray>
void
resamplingExpandLine2(SrcIter s, SrcIter send, SrcAcc src,
DestIter d, DestIter dend, DestAcc dest,
KernelArray const & kernels)
{
typedef typename KernelArray::value_type Kernel;
typedef typename KernelArray::const_reference KernelRef;
typedef typename Kernel::const_iterator KernelIter;
typedef typename
PromoteTraits<typename SrcAcc::value_type, typename Kernel::value_t
ype>::Promote
TmpType;
int wo = send - s;
int wn = dend - d;
int wo2 = 2*wo - 2;
int ileft = std::max(kernels[0].right(), kernels[1].right());
int iright = wo + std::min(kernels[0].left(), kernels[1].left()) - 1;
for(int i = 0; i < wn; ++i, ++d)
{
int is = i / 2;
KernelRef kernel = kernels[i & 1];
KernelIter k = kernel.center() + kernel.right();
TmpType sum = NumericTraits<TmpType>::zero();
if(is < ileft)
{
for(int m=is-kernel.right(); m <= is-kernel.left(); ++m, --k)
{
int mm = (m < 0)
? -m
: m;
sum += *k * src(s, mm);
}
}
else if(is > iright)
{
for(int m=is-kernel.right(); m <= is-kernel.left(); ++m, --k)
{
int mm = (m >= wo)
? wo2 - m
: m;
sum += *k * src(s, mm);
}
}
else
{
SrcIter ss = s + is - kernel.right();
for(int m = 0; m < kernel.size(); ++m, --k, ++ss)
{
sum += *k * src(ss);
}
}
dest.set(sum, d);
}
}
template <class SrcIter, class SrcAcc,
class DestIter, class DestAcc,
class KernelArray>
void
resamplingReduceLine2(SrcIter s, SrcIter send, SrcAcc src,
DestIter d, DestIter dend, DestAcc dest,
KernelArray const & kernels)
{
typedef typename KernelArray::value_type Kernel;
typedef typename KernelArray::const_reference KernelRef;
typedef typename Kernel::const_iterator KernelIter;
KernelRef kernel = kernels[0];
KernelIter kbegin = kernel.center() + kernel.right();
typedef typename
PromoteTraits<typename SrcAcc::value_type, typename Kernel::value_t
ype>::Promote
TmpType;
int wo = send - s;
int wn = dend - d;
int wo2 = 2*wo - 2;
int ileft = kernel.right();
int iright = wo + kernel.left() - 1;
for(int i = 0; i < wn; ++i, ++d)
{
int is = 2 * i;
KernelIter k = kbegin;
TmpType sum = NumericTraits<TmpType>::zero();
if(is < ileft)
{
for(int m=is-kernel.right(); m <= is-kernel.left(); ++m, --k)
{
int mm = (m < 0)
? -m
: m;
sum += *k * src(s, mm);
}
}
else if(is > iright)
{
for(int m=is-kernel.right(); m <= is-kernel.left(); ++m, --k)
{
int mm = (m >= wo)
? wo2 - m
: m;
sum += *k * src(s, mm);
}
}
else
{
SrcIter ss = s + is - kernel.right();
for(int m = 0; m < kernel.size(); ++m, --k, ++ss)
{
sum += *k * src(ss);
}
}
dest.set(sum, d);
}
}
/** \addtogroup ResamplingConvolutionFilters Resampling Convolution Filters
These functions implement the convolution operation when the source and
target images
have different sizes. This is realized by accessing a continous kernel
at the
appropriate non-integer positions. The technique is, for example, descr
ibed in
D. Schumacher: <i>General Filtered Image Rescaling</i>, in: Graphics Ge
ms III,
Academic Press, 1992.
*/
//@{
/********************************************************/
/* */
/* resamplingConvolveLine */
/* */
/********************************************************/
/** \brief Performs a 1-dimensional resampling convolution of the source si
gnal using the given
set of kernels.
This function is mainly used internally: It is called for each dimensio
n of a
higher dimensional array in order to perform a separable resize operati
on.
<b> Declaration:</b>
<b>\#include</b> \<<a href="resampling__convolution_8hxx-source.html">v
igra/resampling_convolution.hxx</a>\>
\code
namespace vigra {
template <class SrcIter, class SrcAcc,
class DestIter, class DestAcc,
class KernelArray,
class Functor>
void
resamplingConvolveLine(SrcIter s, SrcIter send, SrcAcc src,
DestIter d, DestIter dend, DestAcc dest,
KernelArray const & kernels,
Functor mapTargetToSourceCoordinate)
}
\endcode
*/
doxygen_overloaded_function(template <...> void resamplingConvolveLine)
template <class SrcIter, class SrcAcc,
class DestIter, class DestAcc,
class KernelArray, class KernelArray,
class Functor> class Functor>
void void
resamplingConvolveLine(SrcIter s, SrcIter send, SrcAcc src, resamplingConvolveLine(SrcIter s, SrcIter send, SrcAcc src,
DestIter d, DestIter dend, DestAcc dest, DestIter d, DestIter dend, DestAcc dest,
KernelArray const & kernels, KernelArray const & kernels,
Functor mapTargetToSourceCoordinate) Functor mapTargetToSourceCoordinate)
{ {
if(mapTargetToSourceCoordinate.isExpand2())
{
resamplingExpandLine2(s, send, src, d, dend, dest, kernels);
return;
}
if(mapTargetToSourceCoordinate.isReduce2())
{
resamplingReduceLine2(s, send, src, d, dend, dest, kernels);
return;
}
typedef typename typedef typename
NumericTraits<typename SrcAcc::value_type>::RealPromote NumericTraits<typename SrcAcc::value_type>::RealPromote
TmpType; TmpType;
typedef typename KernelArray::value_type Kernel; typedef typename KernelArray::value_type Kernel;
typedef typename Kernel::const_iterator KernelIter; typedef typename Kernel::const_iterator KernelIter;
int wo = send - s; int wo = send - s;
int wn = dend - d; int wn = dend - d;
int wo2 = 2*wo - 2; int wo2 = 2*wo - 2;
skipping to change at line 181 skipping to change at line 370
int right = int(floor(radius - offset)); int right = int(floor(radius - offset));
kernels[idest].initExplicitly(left, right); kernels[idest].initExplicitly(left, right);
double x = left + offset; double x = left + offset;
for(int i = left; i <= right; ++i, ++x) for(int i = left; i <= right; ++i, ++x)
kernels[idest][i] = kernel(x); kernels[idest][i] = kernel(x);
kernels[idest].normalize(1.0, kernel.derivativeOrder(), offset); kernels[idest].normalize(1.0, kernel.derivativeOrder(), offset);
} }
} }
/** \addtogroup ResamplingConvolutionFilters Resampling Convolution Filters
These functions implement the convolution operation when the source and
target images
have different sizes. This is realized by accessing a continous kernel
at the
appropriate non-integer positions. The technique is, for example, descr
ibed in
D. Schumacher: <i>General Filtered Image Rescaling</i>, in: Graphics Ge
ms III,
Academic Press, 1992.
*/
//@{
/********************************************************/
/* */
/* resamplingConvolveX */
/* */
/********************************************************/
/** \brief Apply a resampling filter in the x-direction. /** \brief Apply a resampling filter in the x-direction.
This function implements a convolution operation in x-direction This function implements a convolution operation in x-direction
(i.e. applies a 1D filter to every row) where the width of the source (i.e. applies a 1D filter to every row) where the width of the source
and destination images differ. This is typically used to avoid aliasing if and destination images differ. This is typically used to avoid aliasing if
the image is scaled down, or to interpolate smoothly if the image is sc aled up. the image is scaled down, or to interpolate smoothly if the image is sc aled up.
The target coordinates are transformed into source coordinates by The target coordinates are transformed into source coordinates by
\code \code
xsource = (xtarget - offset) / samplingRatio xsource = (xtarget - offset) / samplingRatio
skipping to change at line 237 skipping to change at line 410
class DestIter, class DestAcc, class DestIter, class DestAcc,
class Kernel> class Kernel>
void void
resamplingConvolveX(SrcIter sul, SrcIter slr, SrcAcc src, resamplingConvolveX(SrcIter sul, SrcIter slr, SrcAcc src,
DestIter dul, DestIter dlr, DestAcc dest, DestIter dul, DestIter dlr, DestAcc dest,
Kernel const & kernel, Kernel const & kernel,
Rational<int> const & samplingRatio, Rational<i nt> const & offset); Rational<int> const & samplingRatio, Rational<i nt> const & offset);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIter, class SrcAcc, template <class SrcIter, class SrcAcc,
class DestIter, class DestAcc, class DestIter, class DestAcc,
class Kernel> class Kernel>
void void
resamplingConvolveX(triple<SrcIter, SrcIter, SrcAcc> src, resamplingConvolveX(triple<SrcIter, SrcIter, SrcAcc> src,
triple<DestIter, DestIter, DestAcc> dest, triple<DestIter, DestIter, DestAcc> dest,
Kernel const & kernel, Kernel const & kernel,
Rational<int> const & samplingRatio, Rational<i nt> const & offset); Rational<int> const & samplingRatio, Rational<i nt> const & offset);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="resampling__convolution_8hxx-source.html">vi gra/resampling_convolution.hxx</a>" <b>\#include</b> \<<a href="resampling__convolution_8hxx-source.html">v igra/resampling_convolution.hxx</a>\>
\code \code
Rational<int> ratio(2), offset(0); Rational<int> ratio(2), offset(0);
FImage src(w,h), FImage src(w,h),
dest(rational_cast<int>(ratio*w), h); dest(rational_cast<int>(ratio*w), h);
float sigma = 2.0; float sigma = 2.0;
Gaussian<float> smooth(sigma); Gaussian<float> smooth(sigma);
... ...
skipping to change at line 279 skipping to change at line 452
<b> Required Interface:</b> <b> Required Interface:</b>
\code \code
Kernel kernel; Kernel kernel;
int kernelRadius = kernel.radius(); int kernelRadius = kernel.radius();
double x = ...; // must be <= radius() double x = ...; // must be <= radius()
double value = kernel(x); double value = kernel(x);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void resamplingConvolveX)
template <class SrcIter, class SrcAcc, template <class SrcIter, class SrcAcc,
class DestIter, class DestAcc, class DestIter, class DestAcc,
class Kernel> class Kernel>
void void
resamplingConvolveX(SrcIter sul, SrcIter slr, SrcAcc src, resamplingConvolveX(SrcIter sul, SrcIter slr, SrcAcc src,
DestIter dul, DestIter dlr, DestAcc dest, DestIter dul, DestIter dlr, DestAcc dest,
Kernel const & kernel, Kernel const & kernel,
Rational<int> const & samplingRatio, Rational<int> cons t & offset) Rational<int> const & samplingRatio, Rational<int> cons t & offset)
{ {
int wold = slr.x - sul.x; int wold = slr.x - sul.x;
skipping to change at line 372 skipping to change at line 547
class DestIter, class DestAcc, class DestIter, class DestAcc,
class Kernel> class Kernel>
void void
resamplingConvolveY(SrcIter sul, SrcIter slr, SrcAcc src, resamplingConvolveY(SrcIter sul, SrcIter slr, SrcAcc src,
DestIter dul, DestIter dlr, DestAcc dest, DestIter dul, DestIter dlr, DestAcc dest,
Kernel const & kernel, Kernel const & kernel,
Rational<int> const & samplingRatio, Rational<i nt> const & offset); Rational<int> const & samplingRatio, Rational<i nt> const & offset);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIter, class SrcAcc, template <class SrcIter, class SrcAcc,
class DestIter, class DestAcc, class DestIter, class DestAcc,
class Kernel> class Kernel>
void void
resamplingConvolveY(triple<SrcIter, SrcIter, SrcAcc> src, resamplingConvolveY(triple<SrcIter, SrcIter, SrcAcc> src,
triple<DestIter, DestIter, DestAcc> dest, triple<DestIter, DestIter, DestAcc> dest,
Kernel const & kernel, Kernel const & kernel,
Rational<int> const & samplingRatio, Rational<i nt> const & offset); Rational<int> const & samplingRatio, Rational<i nt> const & offset);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="resampling__convolution_8hxx-source.html">vi gra/resampling_convolution.hxx</a>" <b>\#include</b> \<<a href="resampling__convolution_8hxx-source.html">v igra/resampling_convolution.hxx</a>\>
\code \code
Rational<int> ratio(2), offset(0); Rational<int> ratio(2), offset(0);
FImage src(w,h), FImage src(w,h),
dest(w, rational_cast<int>(ratio*h)); dest(w, rational_cast<int>(ratio*h));
float sigma = 2.0; float sigma = 2.0;
Gaussian<float> smooth(sigma); Gaussian<float> smooth(sigma);
... ...
skipping to change at line 414 skipping to change at line 589
<b> Required Interface:</b> <b> Required Interface:</b>
\code \code
Kernel kernel; Kernel kernel;
int kernelRadius = kernel.radius(); int kernelRadius = kernel.radius();
double y = ...; // must be <= radius() double y = ...; // must be <= radius()
double value = kernel(y); double value = kernel(y);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void resamplingConvolveY)
template <class SrcIter, class SrcAcc, template <class SrcIter, class SrcAcc,
class DestIter, class DestAcc, class DestIter, class DestAcc,
class Kernel> class Kernel>
void void
resamplingConvolveY(SrcIter sul, SrcIter slr, SrcAcc src, resamplingConvolveY(SrcIter sul, SrcIter slr, SrcAcc src,
DestIter dul, DestIter dlr, DestAcc dest, DestIter dul, DestIter dlr, DestAcc dest,
Kernel const & kernel, Kernel const & kernel,
Rational<int> const & samplingRatio, Rational<int> cons t & offset) Rational<int> const & samplingRatio, Rational<int> cons t & offset)
{ {
int hold = slr.y - sul.y; int hold = slr.y - sul.y;
skipping to change at line 472 skipping to change at line 649
/********************************************************/ /********************************************************/
/* */ /* */
/* resamplingConvolveImage */ /* resamplingConvolveImage */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Apply two separable resampling filters successively, the first i n x-direction, /** \brief Apply two separable resampling filters successively, the first i n x-direction,
the second in y-direction. the second in y-direction.
This function is a shorthand for the concatenation of a call to This function is a shorthand for the concatenation of a call to
\link ResamplingConvolutionFilters#resamplingConvolveX resamplingConvol \ref resamplingConvolveX() and \ref resamplingConvolveY()
veX\endlink()
and \link ResamplingConvolutionFilters#resamplingConvolveY resamplingCo
nvolveY\endlink()
with the given kernels. See there for detailed documentation. with the given kernels. See there for detailed documentation.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class KernelX, class KernelY> class KernelX, class KernelY>
void resamplingConvolveImage(SrcIterator sul,SrcIterator slr, SrcAc cessor src, void resamplingConvolveImage(SrcIterator sul,SrcIterator slr, SrcAc cessor src,
DestIterator dul, DestIterator dlr, DestAccessor dest, DestIterator dul, DestIterator dlr, DestAccessor dest,
KernelX const & kx, KernelX const & kx,
Rational<int> const & samplingRatioX, Rational<i nt> const & offsetX, Rational<int> const & samplingRatioX, Rational<i nt> const & offsetX,
KernelY const & ky, KernelY const & ky,
Rational<int> const & samplingRatioY, Rational<i nt> const & offsetY); Rational<int> const & samplingRatioY, Rational<i nt> const & offsetY);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class KernelX, class KernelY> class KernelX, class KernelY>
void void
resamplingConvolveImage(triple<SrcIterator, SrcIterator, SrcAccesso r> src, resamplingConvolveImage(triple<SrcIterator, SrcIterator, SrcAccesso r> src,
triple<DestIterator, DestIterator, DestAccessor> dest, triple<DestIterator, DestIterator, DestAccessor> dest,
KernelX const & kx, KernelX const & kx,
Rational<int> const & samplingRatioX, Rational<i nt> const & offsetX, Rational<int> const & samplingRatioX, Rational<i nt> const & offsetX,
KernelY const & ky, KernelY const & ky,
Rational<int> const & samplingRatioY, Rational<i nt> const & offsetY); Rational<int> const & samplingRatioY, Rational<i nt> const & offsetY);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="resampling__convolution_8hxx-source.html">vi gra/resampling_convolution.hxx</a>" <b>\#include</b> \<<a href="resampling__convolution_8hxx-source.html">v igra/resampling_convolution.hxx</a>\>
\code \code
Rational<int> xratio(2), yratio(3), offset(0); Rational<int> xratio(2), yratio(3), offset(0);
FImage src(w,h), FImage src(w,h),
dest(rational_cast<int>(xratio*w), rational_cast<int>(yratio*h)) ; dest(rational_cast<int>(xratio*w), rational_cast<int>(yratio*h)) ;
float sigma = 2.0; float sigma = 2.0;
Gaussian<float> smooth(sigma); Gaussian<float> smooth(sigma);
... ...
// simpultaneously enlarge and smooth source image // simpultaneously enlarge and smooth source image
resamplingConvolveImage(srcImageRange(src), destImageRange(dest), resamplingConvolveImage(srcImageRange(src), destImageRange(dest),
smooth, xratio, offset, smooth, xratio, offset,
smooth, yratio, offset); smooth, yratio, offset);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void resamplingConvolveImage)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class KernelX, class KernelY> class KernelX, class KernelY>
void resamplingConvolveImage(SrcIterator sul,SrcIterator slr, SrcAccessor s rc, void resamplingConvolveImage(SrcIterator sul,SrcIterator slr, SrcAccessor s rc,
DestIterator dul, DestIterator dlr, DestAccessor dest, DestIterator dul, DestIterator dlr, DestAccessor dest,
KernelX const & kx, KernelX const & kx,
Rational<int> const & samplingRatioX, Rational<int> cons t & offsetX, Rational<int> const & samplingRatioX, Rational<int> cons t & offsetX,
KernelY const & ky, KernelY const & ky,
Rational<int> const & samplingRatioY, Rational<int> cons t & offsetY) Rational<int> const & samplingRatioY, Rational<int> cons t & offsetY)
{ {
skipping to change at line 572 skipping to change at line 750
Rational<int> const & samplingRatioX, Rational<int> cons t & offsetX, Rational<int> const & samplingRatioX, Rational<int> cons t & offsetX,
KernelY const & ky, KernelY const & ky,
Rational<int> const & samplingRatioY, Rational<int> cons t & offsetY) Rational<int> const & samplingRatioY, Rational<int> cons t & offsetY)
{ {
resamplingConvolveImage(src.first, src.second, src.third, resamplingConvolveImage(src.first, src.second, src.third,
dest.first, dest.second, dest.third, dest.first, dest.second, dest.third,
kx, samplingRatioX, offsetX, kx, samplingRatioX, offsetX,
ky, samplingRatioY, offsetY); ky, samplingRatioY, offsetY);
} }
/** \brief Two-fold down-sampling for image pyramid construction.
Sorry, no \ref detailedDocumentation() available yet.
<b> Declarations:</b>
<b>\#include</b> \<<a href="resampling__convolution_8hxx-source.html">v
igra/resampling_convolution.hxx</a>\><br>
Namespace: vigra
pass arguments explicitly:
\code
namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void pyramidReduceBurtFilter(SrcIterator sul, SrcIterator slr, SrcA
ccessor src,
DestIterator dul, DestIterator dlr, De
stAccessor dest,
double centerValue = 0.4);
}
\endcode
use argument objects in conjunction with \ref ArgumentObjectFactories :
\code
namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void pyramidReduceBurtFilter(triple<SrcIterator, SrcIterator, SrcAc
cessor> src,
triple<DestIterator, DestIterator, Des
tAccessor> dest,
double centerValue = 0.4);
}
\endcode
use a \ref vigra::ImagePyramid :
\code
namespace vigra {
template <class Image, class Alloc>
void pyramidReduceBurtFilter(ImagePyramid<Image, Alloc> & pyramid,
int fromLevel, int toLevel,
double centerValue = 0.4);
}
\endcode
*/
doxygen_overloaded_function(template <...> void pyramidReduceBurtFilter)
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void pyramidReduceBurtFilter(SrcIterator sul, SrcIterator slr, SrcAccessor
src,
DestIterator dul, DestIterator dlr, DestAccess
or dest,
double centerValue = 0.4)
{
vigra_precondition(0.25 <= centerValue && centerValue <= 0.5,
"pyramidReduceBurtFilter(): centerValue must be between 0.25 a
nd 0.5.");
int wold = slr.x - sul.x;
int wnew = dlr.x - dul.x;
int hold = slr.y - sul.y;
int hnew = dlr.y - dul.y;
Rational<int> samplingRatio(1,2), offset(0);
resampling_detail::MapTargetToSourceCoordinate mapCoordinate(samplingRa
tio, offset);
ArrayVector<Kernel1D<double> > kernels(1);
kernels[0].initExplicitly(-2, 2) = 0.25 - centerValue / 2.0, 0.25, cent
erValue, 0.25, 0.25 - centerValue / 2.0;
typedef typename
NumericTraits<typename SrcAccessor::value_type>::RealPromote
TmpType;
typedef BasicImage<TmpType> TmpImage;
typedef typename TmpImage::traverser TmpIterator;
BasicImage<TmpType> tmp(wnew, hold);
TmpIterator tul = tmp.upperLeft();
for(; sul.y < slr.y; ++sul.y, ++tul.y)
{
typename SrcIterator::row_iterator sr = sul.rowIterator();
typename TmpIterator::row_iterator tr = tul.rowIterator();
// FIXME: replace with reduceLineBurtFilter()
resamplingConvolveLine(sr, sr+wold, src, tr, tr+wnew, tmp.accessor(
),
kernels, mapCoordinate);
}
tul = tmp.upperLeft();
for(; dul.x < dlr.x; ++dul.x, ++tul.x)
{
typename DestIterator::column_iterator dc = dul.columnIterator();
typename TmpIterator::column_iterator tc = tul.columnIterator();
resamplingConvolveLine(tc, tc+hold, tmp.accessor(), dc, dc+hnew, de
st,
kernels, mapCoordinate);
}
}
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
inline
void pyramidReduceBurtFilter(triple<SrcIterator, SrcIterator, SrcAccessor>
src,
triple<DestIterator, DestIterator, DestAccesso
r> dest,
double centerValue = 0.4)
{
pyramidReduceBurtFilter(src.first, src.second, src.third,
dest.first, dest.second, dest.third, centerValu
e);
}
template <class Image, class Alloc>
inline
void pyramidReduceBurtFilter(ImagePyramid<Image, Alloc> & pyramid, int from
Level, int toLevel,
double centerValue = 0.4)
{
vigra_precondition(fromLevel < toLevel,
"pyramidReduceBurtFilter(): fromLevel must be smaller than toLevel."
);
vigra_precondition(pyramid.lowestLevel() <= fromLevel && toLevel <= pyr
amid.highestLevel(),
"pyramidReduceBurtFilter(): fromLevel and toLevel must be between th
e lowest and highest pyramid levels (inclusive).");
for(int i=fromLevel+1; i <= toLevel; ++i)
pyramidReduceBurtFilter(srcImageRange(pyramid[i-1]), destImageRange
(pyramid[i]), centerValue);
}
/** \brief Two-fold up-sampling for image pyramid reconstruction.
Sorry, no \ref detailedDocumentation() available yet.
<b> Declarations:</b>
<b>\#include</b> \<<a href="resampling__convolution_8hxx-source.html">v
igra/resampling_convolution.hxx</a>\><br>
Namespace: vigra
pass arguments explicitly:
\code
namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void pyramidExpandBurtFilter(SrcIterator sul, SrcIterator slr, SrcA
ccessor src,
DestIterator dul, DestIterator dlr, De
stAccessor dest,
double centerValue = 0.4);
}
\endcode
use argument objects in conjunction with \ref ArgumentObjectFactories :
\code
namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void pyramidExpandBurtFilter(triple<SrcIterator, SrcIterator, SrcAc
cessor> src,
triple<DestIterator, DestIterator, Des
tAccessor> dest,
double centerValue = 0.4);
}
\endcode
use a \ref vigra::ImagePyramid :
\code
namespace vigra {
template <class Image, class Alloc>
void pyramidExpandBurtFilter(ImagePyramid<Image, Alloc> & pyramid,
int fromLevel, int toLevel,
double centerValue = 0.4);
}
\endcode
*/
doxygen_overloaded_function(template <...> void pyramidExpandBurtFilter)
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void pyramidExpandBurtFilter(SrcIterator sul, SrcIterator slr, SrcAccessor
src,
DestIterator dul, DestIterator dlr, DestAccess
or dest,
double centerValue = 0.4)
{
vigra_precondition(0.25 <= centerValue && centerValue <= 0.5,
"pyramidExpandBurtFilter(): centerValue must be between 0.25 a
nd 0.5.");
int wold = slr.x - sul.x;
int wnew = dlr.x - dul.x;
int hold = slr.y - sul.y;
int hnew = dlr.y - dul.y;
Rational<int> samplingRatio(2), offset(0);
resampling_detail::MapTargetToSourceCoordinate mapCoordinate(samplingRa
tio, offset);
ArrayVector<Kernel1D<double> > kernels(2);
kernels[0].initExplicitly(-1, 1) = 0.5 - centerValue, 2.0*centerValue,
0.5 - centerValue;
kernels[1].initExplicitly(-1, 0) = 0.5, 0.5;
typedef typename
NumericTraits<typename SrcAccessor::value_type>::RealPromote
TmpType;
typedef BasicImage<TmpType> TmpImage;
typedef typename TmpImage::traverser TmpIterator;
BasicImage<TmpType> tmp(wnew, hold);
TmpIterator tul = tmp.upperLeft();
for(; sul.y < slr.y; ++sul.y, ++tul.y)
{
typename SrcIterator::row_iterator sr = sul.rowIterator();
typename TmpIterator::row_iterator tr = tul.rowIterator();
// FIXME: replace with expandLineBurtFilter()
resamplingConvolveLine(sr, sr+wold, src, tr, tr+wnew, tmp.accessor(
),
kernels, mapCoordinate);
}
tul = tmp.upperLeft();
for(; dul.x < dlr.x; ++dul.x, ++tul.x)
{
typename DestIterator::column_iterator dc = dul.columnIterator();
typename TmpIterator::column_iterator tc = tul.columnIterator();
resamplingConvolveLine(tc, tc+hold, tmp.accessor(), dc, dc+hnew, de
st,
kernels, mapCoordinate);
}
}
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
inline
void pyramidExpandBurtFilter(triple<SrcIterator, SrcIterator, SrcAccessor>
src,
triple<DestIterator, DestIterator, DestAccesso
r> dest,
double centerValue = 0.4)
{
pyramidExpandBurtFilter(src.first, src.second, src.third,
dest.first, dest.second, dest.third, centerValu
e);
}
template <class Image, class Alloc>
inline
void pyramidExpandBurtFilter(ImagePyramid<Image, Alloc> & pyramid, int from
Level, int toLevel,
double centerValue = 0.4)
{
vigra_precondition(fromLevel > toLevel,
"pyramidExpandBurtFilter(): fromLevel must be larger than toLevel.")
;
vigra_precondition(pyramid.lowestLevel() <= toLevel && fromLevel <= pyr
amid.highestLevel(),
"pyramidExpandBurtFilter(): fromLevel and toLevel must be between th
e lowest and highest pyramid levels (inclusive).");
for(int i=fromLevel-1; i >= toLevel; --i)
pyramidExpandBurtFilter(srcImageRange(pyramid[i+1]), destImageRange
(pyramid[i]), centerValue);
}
/** \brief Create a Laplacian pyramid.
Sorry, no \ref detailedDocumentation() available yet.
<b>\#include</b> \<<a href="resampling__convolution_8hxx-source.html">v
igra/resampling_convolution.hxx</a>\><br>
Namespace: vigra
*/
template <class Image, class Alloc>
inline
void pyramidReduceBurtLaplacian(ImagePyramid<Image, Alloc> & pyramid, int f
romLevel, int toLevel,
double centerValue = 0.4)
{
using namespace functor;
pyramidReduceBurtFilter(pyramid, fromLevel, toLevel, centerValue);
for(int i=fromLevel; i < toLevel; ++i)
{
typename ImagePyramid<Image, Alloc>::value_type tmpImage(pyramid[i]
.size());
pyramidExpandBurtFilter(srcImageRange(pyramid[i+1]), destImageRange
(tmpImage), centerValue);
combineTwoImages(srcImageRange(tmpImage), srcImage(pyramid[i]), des
tImage(pyramid[i]),
Arg1() - Arg2());
}
}
/** \brief Reconstruct a Laplacian pyramid.
Sorry, no \ref detailedDocumentation() available yet.
<b>\#include</b> \<<a href="resampling__convolution_8hxx-source.html">v
igra/resampling_convolution.hxx</a>\><br>
Namespace: vigra
*/
template <class Image, class Alloc>
inline
void pyramidExpandBurtLaplacian(ImagePyramid<Image, Alloc> & pyramid, int f
romLevel, int toLevel,
double centerValue = 0.4)
{
using namespace functor;
vigra_precondition(fromLevel > toLevel,
"pyramidExpandBurtLaplacian(): fromLevel must be larger than toLevel
.");
vigra_precondition(pyramid.lowestLevel() <= toLevel && fromLevel <= pyr
amid.highestLevel(),
"pyramidExpandBurtLaplacian(): fromLevel and toLevel must be between
the lowest and highest pyramid levels (inclusive).");
for(int i=fromLevel-1; i >= toLevel; --i)
{
typename ImagePyramid<Image, Alloc>::value_type tmpImage(pyramid[i]
.size());
pyramidExpandBurtFilter(srcImageRange(pyramid[i+1]), destImageRange
(tmpImage), centerValue);
combineTwoImages(srcImageRange(tmpImage), srcImage(pyramid[i]), des
tImage(pyramid[i]),
Arg1() - Arg2());
}
}
//@}
} // namespace vigra } // namespace vigra
#endif /* VIGRA_RESAMPLING_CONVOLUTION_HXX */ #endif /* VIGRA_RESAMPLING_CONVOLUTION_HXX */
 End of changes. 19 change blocks. 
34 lines changed or deleted 560 lines changed or added


 resizeimage.hxx   resizeimage.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2004 by Ullrich Koethe */ /* Copyright 1998-2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 64 skipping to change at line 64
/* CoscotFunction */ /* CoscotFunction */
/* */ /* */
/*****************************************************************/ /*****************************************************************/
/*! The Coscot interpolation function. /*! The Coscot interpolation function.
Implements the Coscot interpolation function proposed by Maria Magnusso n Seger Implements the Coscot interpolation function proposed by Maria Magnusso n Seger
(maria@isy.liu.se) in the context of tomographic reconstruction. It pro vides a fast (maria@isy.liu.se) in the context of tomographic reconstruction. It pro vides a fast
transition between the pass- and stop-bands and minimal ripple outside the transition transition between the pass- and stop-bands and minimal ripple outside the transition
region. Both properties are important for this application and can be t uned by the parameters region. Both properties are important for this application and can be t uned by the parameters
<i>m</i> and </i>h</i> (with defaults 3 and 0.5). The function is defin ed by <i>m</i> and <i>h</i> (with defaults 3 and 0.5). The function is define d by
\f[ f_{m,h}(x) = \left\{ \begin{array}{ll} \f[ f_{m,h}(x) = \left\{ \begin{array}{ll}
\frac{1}{2m}\sin(\pi x)\cot(\pi x / (2 m ))(h + (1-h)\cos(\pi x/m)) & |x| \leq m \\ \frac{1}{2m}\sin(\pi x)\cot(\pi x / (2 m ))(h + (1-h)\cos(\pi x/m)) & |x| \leq m \\
0 & \mbox{otherwise} 0 & \mbox{otherwise}
\end{array}\right. \end{array}\right.
\f] \f]
It can be used as a functor, and as a kernel for It can be used as a functor, and as a kernel for
\ref resamplingConvolveImage() to create a differentiable interpolant \ref resamplingConvolveImage() to create a differentiable interpolant
of an image. of an image.
<b>\#include</b> "<a href="resizeimage_8hxx-source.html">vigra/resizeim age.hxx</a>"<br> <b>\#include</b> \<<a href="resizeimage_8hxx-source.html">vigra/resizei mage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\ingroup MathFunctions \ingroup MathFunctions
*/ */
template <class T> template <class T>
class CoscotFunction class CoscotFunction
{ {
public: public:
/** the kernel's value type /** the kernel's value type
skipping to change at line 147 skipping to change at line 147
protected: protected:
unsigned int m_; unsigned int m_;
double h_; double h_;
}; };
/** \addtogroup GeometricTransformations Geometric Transformations /** \addtogroup GeometricTransformations Geometric Transformations
Zoom up and down by repeating pixels, or using various interpolation sc hemes. Zoom up and down by repeating pixels, or using various interpolation sc hemes.
See also: \ref resamplingConvolveImage(), \ref resampleImage() See also: \ref resamplingConvolveImage(), \ref resampleImage(), \ref re sizeMultiArraySplineInterpolation()
<b>\#include</b> "<a href="stdimagefunctions_8hxx-source.html">vigra/st dimagefunctions.hxx</a>"<br> <b>\#include</b> \<<a href="stdimagefunctions_8hxx-source.html">vigra/s tdimagefunctions.hxx</a>\><br>
<b>or</b><br> <b>or</b><br>
<b>\#include</b> "<a href="resizeimage_8hxx-source.html">vigra/resizeim age.hxx</a>"<br> <b>\#include</b> \<<a href="resizeimage_8hxx-source.html">vigra/resizei mage.hxx</a>\><br>
*/ */
//@{ //@{
/********************************************************/ /********************************************************/
/* */ /* */
/* resizeLineNoInterpolation */ /* resizeLineNoInterpolation */
/* */ /* */
/********************************************************/ /********************************************************/
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
skipping to change at line 218 skipping to change at line 218
pixels are directly copied from the appropriate source pixels. pixels are directly copied from the appropriate source pixels.
The function uses accessors. The function uses accessors.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void void
resizeImageNoInterpolation( resizeImageNoInterpolation(
SrcImageIterator is, SrcImageIterator iend, SrcAccessor sa, SrcImageIterator is, SrcImageIterator iend, SrcAccessor sa,
DestImageIterator id, DestImageIterator idend, DestAccessor da) DestImageIterator id, DestImageIterator idend, DestAccessor d a)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void void
resizeImageNoInterpolation( resizeImageNoInterpolation(
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
triple<DestImageIterator, DestImageIterator, DestAccessor> dest) triple<DestImageIterator, DestImageIterator, DestAccessor> de st)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="resizeimage_8hxx-source.html">vigra/resi zeimage.hxx</a>"<br> <b>\#include</b> \<<a href="resizeimage_8hxx-source.html">vigra/res izeimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::resizeImageNoInterpolation( vigra::resizeImageNoInterpolation(
src.upperLeft(), src.lowerRight(), src.accessor(), src.upperLeft(), src.lowerRight(), src.accessor(),
dest.upperLeft(), dest.lowerRight(), dest.accessor()); dest.upperLeft(), dest.lowerRight(), dest.accessor());
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
skipping to change at line 273 skipping to change at line 273
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
src_lowerright.x - src_upperleft.x > 1 src_lowerright.x - src_upperleft.x > 1
src_lowerright.y - src_upperleft.y > 1 src_lowerright.y - src_upperleft.y > 1
dest_lowerright.x - dest_upperleft.x > 1 dest_lowerright.x - dest_upperleft.x > 1
dest_lowerright.y - dest_upperleft.y > 1 dest_lowerright.y - dest_upperleft.y > 1
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void resizeImageNoInterpolation)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
resizeImageNoInterpolation(SrcIterator is, SrcIterator iend, SrcAccessor sa , resizeImageNoInterpolation(SrcIterator is, SrcIterator iend, SrcAccessor sa ,
DestIterator id, DestIterator idend, DestAccessor da) DestIterator id, DestIterator idend, DestAccessor da)
{ {
int w = iend.x - is.x; int w = iend.x - is.x;
int h = iend.y - is.y; int h = iend.y - is.y;
int wnew = idend.x - id.x; int wnew = idend.x - id.x;
skipping to change at line 399 skipping to change at line 401
be a linear space, i.e. it must support addition, multiplication be a linear space, i.e. it must support addition, multiplication
with a scalar real number and \ref NumericTraits "NumericTraits". with a scalar real number and \ref NumericTraits "NumericTraits".
The function uses accessors. The function uses accessors.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void void
resizeImageLinearInterpolation( resizeImageLinearInterpolation(
SrcImageIterator is, SrcImageIterator iend, SrcAccessor sa, SrcImageIterator is, SrcImageIterator iend, SrcAccessor sa,
DestImageIterator id, DestImageIterator idend, DestAccessor da) DestImageIterator id, DestImageIterator idend, DestAccessor d a)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor> class DestImageIterator, class DestAccessor>
void void
resizeImageLinearInterpolation( resizeImageLinearInterpolation(
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
triple<DestImageIterator, DestImageIterator, DestAccessor> dest) triple<DestImageIterator, DestImageIterator, DestAccessor> de st)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="resizeimage_8hxx-source.html">vigra/resi zeimage.hxx</a>"<br> <b>\#include</b> \<<a href="resizeimage_8hxx-source.html">vigra/res izeimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::resizeImageLinearInterpolation( vigra::resizeImageLinearInterpolation(
src.upperLeft(), src.lowerRight(), src.accessor(), src.upperLeft(), src.lowerRight(), src.accessor(),
dest.upperLeft(), dest.lowerRight(), dest.accessor()); dest.upperLeft(), dest.lowerRight(), dest.accessor());
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
skipping to change at line 464 skipping to change at line 466
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
src_lowerright.x - src_upperleft.x > 1 src_lowerright.x - src_upperleft.x > 1
src_lowerright.y - src_upperleft.y > 1 src_lowerright.y - src_upperleft.y > 1
dest_lowerright.x - dest_upperleft.x > 1 dest_lowerright.x - dest_upperleft.x > 1
dest_lowerright.y - dest_upperleft.y > 1 dest_lowerright.y - dest_upperleft.y > 1
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void resizeImageLinearInterpolat
ion)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
resizeImageLinearInterpolation(SrcIterator is, SrcIterator iend, SrcAccesso r sa, resizeImageLinearInterpolation(SrcIterator is, SrcIterator iend, SrcAccesso r sa,
DestIterator id, DestIterator idend, DestAccessor da) DestIterator id, DestIterator idend, DestAccessor da)
{ {
int w = iend.x - is.x; int w = iend.x - is.x;
int h = iend.y - is.y; int h = iend.y - is.y;
int wnew = idend.x - id.x; int wnew = idend.x - id.x;
skipping to change at line 567 skipping to change at line 571
/** \brief Resize image using B-spline interpolation. /** \brief Resize image using B-spline interpolation.
The function implements separable spline interpolation algorithm descri bed in The function implements separable spline interpolation algorithm descri bed in
M. Unser, A. Aldroubi, M. Eden, <i>"B-Spline Signal Processing"</i> M. Unser, A. Aldroubi, M. Eden, <i>"B-Spline Signal Processing"</i>
IEEE Transactions on Signal Processing, vol. 41, no. 2, pp. 821-833 (pa rt I), IEEE Transactions on Signal Processing, vol. 41, no. 2, pp. 821-833 (pa rt I),
pp. 834-848 (part II), 1993. pp. 834-848 (part II), 1993.
to obtain optimal interpolation quality and speed. You may pass the fun cion to obtain optimal interpolation quality and speed. You may pass the fun cion
a spline of arbitrary order (e.g. <TT>BSpline&lt;ORDER, double&gt;</tt> a spline of arbitrary order (e.g. <TT>BSpline<ORDER, double></tt> or
or <TT>CatmullRomSpline<double></tt>). The default is a third order spline
<TT>CatmullRomSpline&lt;double&gt;</tt>). The default is a third order
spline
which gives a twice continuously differentiable interpolant. which gives a twice continuously differentiable interpolant.
The implementation ensures that image values are interpolated rather The implementation ensures that image values are interpolated rather
than smoothed by first calling a recursive (sharpening) prefilter as than smoothed by first calling a recursive (sharpening) prefilter as
described in the above paper. Then the actual interpolation is done described in the above paper. Then the actual interpolation is done
using \ref resamplingConvolveLine(). using \ref resamplingConvolveLine().
The range of both the input and output images (resp. regions) The range of both the input and output images (resp. regions)
must be given. The input image must have a size of at must be given. The input image must have a size of at
least 4x4, the destination of at least 2x2. The scaling factors are the n calculated least 4x4, the destination of at least 2x2. The scaling factors are the n calculated
accordingly. If the source image is larger than the destination, it accordingly. If the source image is larger than the destination, it
skipping to change at line 592 skipping to change at line 596
and multiplication (+, -, *), multiplication with a scalar and multiplication (+, -, *), multiplication with a scalar
real number and \ref NumericTraits "NumericTraits". real number and \ref NumericTraits "NumericTraits".
The function uses accessors. The function uses accessors.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class SPLINE> class SPLINE>
void void
resizeImageSplineInterpolation( resizeImageSplineInterpolation(
SrcImageIterator is, SrcImageIterator iend, SrcAccessor sa, SrcImageIterator is, SrcImageIterator iend, SrcAccessor sa,
DestImageIterator id, DestImageIterator idend, DestAccessor da, DestImageIterator id, DestImageIterator idend, DestAccessor d
SPLINE spline = BSpline<3, double>()) a,
SPLINE spline = BSpline<3, double>())
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class SPLINE> class SPLINE>
void void
resizeImageSplineInterpolation( resizeImageSplineInterpolation(
triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
triple<DestImageIterator, DestImageIterator, DestAccessor> de st, triple<DestImageIterator, DestImageIterator, DestAccessor> de st,
SPLINE spline = BSpline<3, double>()) SPLINE spline = BSpline<3, double>())
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="resizeimage_8hxx-source.html">vigra/resi zeimage.hxx</a>"<br> <b>\#include</b> \<<a href="resizeimage_8hxx-source.html">vigra/res izeimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::resizeImageSplineInterpolation( vigra::resizeImageSplineInterpolation(
src.upperLeft(), src.lowerRight(), src.accessor(), src.upperLeft(), src.lowerRight(), src.accessor(),
dest.upperLeft(), dest.lowerRight(), dest.accessor()); dest.upperLeft(), dest.lowerRight(), dest.accessor());
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
skipping to change at line 665 skipping to change at line 669
<b> Preconditions:</b> <b> Preconditions:</b>
\code \code
src_lowerright.x - src_upperleft.x > 3 src_lowerright.x - src_upperleft.x > 3
src_lowerright.y - src_upperleft.y > 3 src_lowerright.y - src_upperleft.y > 3
dest_lowerright.x - dest_upperleft.x > 1 dest_lowerright.x - dest_upperleft.x > 1
dest_lowerright.y - dest_upperleft.y > 1 dest_lowerright.y - dest_upperleft.y > 1
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void resizeImageSplineInterpolat
ion)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class SPLINE> class SPLINE>
void void
resizeImageSplineInterpolation( resizeImageSplineInterpolation(
SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc, SrcIterator src_iter, SrcIterator src_iter_end, SrcAccessor src_acc,
DestIterator dest_iter, DestIterator dest_iter_end, DestAccessor dest_a cc, DestIterator dest_iter, DestIterator dest_iter_end, DestAccessor dest_a cc,
SPLINE const & spline) SPLINE const & spline)
{ {
skipping to change at line 874 skipping to change at line 880
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
resizeImageCatmullRomInterpolation(SrcIterator src_iter, SrcIterato r src_iter_end, SrcAccessor src_acc, resizeImageCatmullRomInterpolation(SrcIterator src_iter, SrcIterato r src_iter_end, SrcAccessor src_acc,
DestIterator dest_iter, DestIterator dest_ite r_end, DestAccessor dest_acc); DestIterator dest_iter, DestIterator dest_ite r_end, DestAccessor dest_acc);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
resizeImageCatmullRomInterpolation(triple<SrcIterator, SrcIterator, SrcAccessor> src, resizeImageCatmullRomInterpolation(triple<SrcIterator, SrcIterator, SrcAccessor> src,
triple<DestIterator, DestIterator, DestAccess or> dest); triple<DestIterator, DestIterator, DestAccess or> dest);
} }
\endcode \endcode
<b>\#include</b> "<a href="resizeimage_8hxx-source.html">vigra/resizeim age.hxx</a>"<br> <b>\#include</b> \<<a href="resizeimage_8hxx-source.html">vigra/resizei mage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
doxygen_overloaded_function(template <...> void resizeImageCatmullRomInterp
olation)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void inline void
resizeImageCatmullRomInterpolation(SrcIterator src_iter, SrcIterator src_it er_end, SrcAccessor src_acc, resizeImageCatmullRomInterpolation(SrcIterator src_iter, SrcIterator src_it er_end, SrcAccessor src_acc,
DestIterator dest_iter, DestIterator dest_iter_end, D estAccessor dest_acc) DestIterator dest_iter, DestIterator dest_iter_end, D estAccessor dest_acc)
{ {
resizeImageSplineInterpolation(src_iter, src_iter_end, src_acc, dest_it er, dest_iter_end, dest_acc, resizeImageSplineInterpolation(src_iter, src_iter_end, src_acc, dest_it er, dest_iter_end, dest_acc,
CatmullRomSpline<double>()); CatmullRomSpline<double>());
} }
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline inline
skipping to change at line 924 skipping to change at line 932
/* */ /* */
/*****************************************************************/ /*****************************************************************/
/** \brief Resize image using the cardinal B-spline interpolation function. /** \brief Resize image using the cardinal B-spline interpolation function.
The function calls like \ref resizeImageSplineInterpolation() with The function calls like \ref resizeImageSplineInterpolation() with
\ref vigra::BSpline<3, double> and prefiltering as an interpolation ker nel. \ref vigra::BSpline<3, double> and prefiltering as an interpolation ker nel.
The interpolated function has two continuous derivatives. The interpolated function has two continuous derivatives.
(See \ref resizeImageSplineInterpolation() for more documentation) (See \ref resizeImageSplineInterpolation() for more documentation)
<b>\#include</b> "<a href="resizeimage_8hxx-source.html">vigra/resizeim age.hxx</a>"<br> <b>\#include</b> \<<a href="resizeimage_8hxx-source.html">vigra/resizei mage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
resizeImageCubicInterpolation(SrcIterator src_iter, SrcIterator src_iter_en d, SrcAccessor src_acc, resizeImageCubicInterpolation(SrcIterator src_iter, SrcIterator src_iter_en d, SrcAccessor src_acc,
DestIterator dest_iter, DestIterator dest_iter_end, D estAccessor dest_acc) DestIterator dest_iter, DestIterator dest_iter_end, D estAccessor dest_acc)
{ {
resizeImageSplineInterpolation(src_iter, src_iter_end, src_acc, dest_it er, dest_iter_end, dest_acc, resizeImageSplineInterpolation(src_iter, src_iter_end, src_acc, dest_it er, dest_iter_end, dest_acc,
skipping to change at line 976 skipping to change at line 984
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
resizeImageCoscotInterpolation(SrcIterator src_iter, SrcIterator sr c_iter_end, SrcAccessor src_acc, resizeImageCoscotInterpolation(SrcIterator src_iter, SrcIterator sr c_iter_end, SrcAccessor src_acc,
DestIterator dest_iter, DestIterator dest_ite r_end, DestAccessor dest_acc); DestIterator dest_iter, DestIterator dest_ite r_end, DestAccessor dest_acc);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
resizeImageCoscotInterpolation(triple<SrcIterator, SrcIterator, Src Accessor> src, resizeImageCoscotInterpolation(triple<SrcIterator, SrcIterator, Src Accessor> src,
triple<DestIterator, DestIterator, DestAccess or> dest); triple<DestIterator, DestIterator, DestAccess or> dest);
} }
\endcode \endcode
<b>\#include</b> "<a href="resizeimage_8hxx-source.html">vigra/resizeim age.hxx</a>"<br> <b>\#include</b> \<<a href="resizeimage_8hxx-source.html">vigra/resizei mage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
doxygen_overloaded_function(template <...> void resizeImageCoscotInterpolat
ion)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
resizeImageCoscotInterpolation(SrcIterator src_iter, SrcIterator src_iter_e nd, SrcAccessor src_acc, resizeImageCoscotInterpolation(SrcIterator src_iter, SrcIterator src_iter_e nd, SrcAccessor src_acc,
DestIterator dest_iter, DestIterator dest_iter_end, D estAccessor dest_acc) DestIterator dest_iter, DestIterator dest_iter_end, D estAccessor dest_acc)
{ {
resizeImageSplineInterpolation(src_iter, src_iter_end, src_acc, dest_it er, dest_iter_end, dest_acc, resizeImageSplineInterpolation(src_iter, src_iter_end, src_acc, dest_it er, dest_iter_end, dest_acc,
CoscotFunction<double>()); CoscotFunction<double>());
} }
 End of changes. 36 change blocks. 
38 lines changed or deleted 51 lines changed or added


 rfftw.hxx   rfftw.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
 End of changes. 2 change blocks. 
3 lines changed or deleted 3 lines changed or added


 rgbvalue.hxx   rgbvalue.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 116 skipping to change at line 116
\ref blue()), index operator (operator[](dx), where the <tt>rgb[RED_IDX ]</tt> \ref blue()), index operator (operator[](dx), where the <tt>rgb[RED_IDX ]</tt>
returns red etc.) and iterator (STL-compatible random access returns red etc.) and iterator (STL-compatible random access
iterator that references the three colors in turn). The latter two iterator that references the three colors in turn). The latter two
methods, together with the necessary embedded typedefs, ensure methods, together with the necessary embedded typedefs, ensure
compatibility of a RGBValue with a STL vector. compatibility of a RGBValue with a STL vector.
\ref RGBValueOperators "Arithmetic operations" are defined as component -wise applications of these \ref RGBValueOperators "Arithmetic operations" are defined as component -wise applications of these
operations. Addition, subtraction, and multiplication of two RGBValues operations. Addition, subtraction, and multiplication of two RGBValues
(+=, -=, *=, +, -, *, unary -), multiplication and division of an (+=, -=, *=, +, -, *, unary -), multiplication and division of an
RGBValue with a double, and NumericTraits/PromoteTraits are defined, RGBValue with a double, and NumericTraits/PromoteTraits are defined,
so that RGBValue fulfills the requirements of a \ref LinearAlgebra. so that RGBValue fulfills the requirements of a \ref LinearAlgebraConce pt "Linear Algebra".
A number of \ref RGBValueAccessors "accessors" are provided A number of \ref RGBValueAccessors "accessors" are provided
that support access to RGBValues as a whole, to a selected that support access to RGBValues as a whole, to a selected
color component, or to the luminance value. color component, or to the luminance value.
<b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hx x</a>"<br> <b>\#include</b> \<<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class VALUETYPE, unsigned int RED_IDX = 0, unsigned int GREEN_IDX = 1, unsigned int BLUE_IDX = 2> template <class VALUETYPE, unsigned int RED_IDX = 0, unsigned int GREEN_IDX = 1, unsigned int BLUE_IDX = 2>
class RGBValue class RGBValue
: public TinyVector<VALUETYPE, 3> : public TinyVector<VALUETYPE, 3>
{ {
typedef TinyVector<VALUETYPE, 3> Base; typedef TinyVector<VALUETYPE, 3> Base;
// inverse mapping from index to color // inverse mapping from index to color
enum { enum {
skipping to change at line 336 skipping to change at line 336
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* RGBValue Comparison */ /* RGBValue Comparison */
/* */ /* */
/********************************************************/ /********************************************************/
/** \addtogroup RGBValueOperators Functions for RGBValue /** \addtogroup RGBValueOperators Functions for RGBValue
\brief <b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbv alue.hxx</a> \brief Implement basic arithmetic and equality for RGBValue.
These functions fulfill the requirements of a Linear Algebra. These functions fulfill the requirements of a Linear Algebra.
Return types are determined according to \ref RGBValueTraits. Return types are determined according to \ref RGBValueTraits.
<b>\#include</b> \<<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.h xx</a>\><br>
Namespace: vigra Namespace: vigra
<p> <p>
*/ */
//@{ //@{
/// component-wise equal /// component-wise equal
template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BI DX1, template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BI DX1,
class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BI DX2> class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BI DX2>
inline inline
bool bool
skipping to change at line 432 skipping to change at line 433
typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> P romote; typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> P romote;
}; };
template <class T, unsigned int R, unsigned int G, unsigned int B> template <class T, unsigned int R, unsigned int G, unsigned int B>
struct PromoteTraits<double, RGBValue<T, R, G, B> > struct PromoteTraits<double, RGBValue<T, R, G, B> >
{ {
typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> P romote; typedef RGBValue<typename NumericTraits<T>::RealPromote, R, G, B> P romote;
}; };
\endcode \endcode
<b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hx x</a>"<br> <b>\#include</b> \<<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
#if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION) #if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION)
template <class T, unsigned int R, unsigned int G, unsigned int B> template <class T, unsigned int R, unsigned int G, unsigned int B>
struct NumericTraits<RGBValue<T, R, G, B> > struct NumericTraits<RGBValue<T, R, G, B> >
{ {
typedef RGBValue<T, R, G, B> Type; typedef RGBValue<T, R, G, B> Type;
skipping to change at line 662 skipping to change at line 663
operator-=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l, operator-=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r) RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
{ {
l.red() -= r.red(); l.red() -= r.red();
l.green() -= r.green(); l.green() -= r.green();
l.blue() -= r.blue(); l.blue() -= r.blue();
return l; return l;
} }
/// componentwise multiply-assignment /// componentwise multiply-assignment
template <class V1, unsigned int RIDX1, unsigned int BIDX1, unsigned int GI template <class V1, unsigned int RIDX1, unsigned int GIDX1, unsigned int BI
DX1, class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BIDX2> DX1,
class V2, unsigned int RIDX2, unsigned int GIDX2, unsigned int BI
DX2>
inline inline
RGBValue<V1, RIDX1, GIDX1, BIDX1> & RGBValue<V1, RIDX1, GIDX1, BIDX1> &
operator*=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l, operator*=(RGBValue<V1, RIDX1, GIDX1, BIDX1> & l,
RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r) RGBValue<V2, RIDX2, GIDX2, BIDX2> const & r)
{ {
l.red() *= r.red(); l.red() *= r.red();
l.green() *= r.green(); l.green() *= r.green();
l.blue() *= r.blue(); l.blue() *= r.blue();
return l; return l;
} }
skipping to change at line 867 skipping to change at line 869
/* */ /* */
/********************************************************/ /********************************************************/
/** \addtogroup DataAccessors /** \addtogroup DataAccessors
*/ */
//@{ //@{
/** \defgroup RGBValueAccessors Accessors for RGBValue */ /** \defgroup RGBValueAccessors Accessors for RGBValue */
//@{ //@{
/** Encapsulate access to rgb values. /** Encapsulate access to rgb values.
<b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hx x</a>"<br> <b>\#include</b> \<<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class RGBVALUE> template <class RGBVALUE>
class RGBAccessor class RGBAccessor
: public VectorAccessor<RGBVALUE> : public VectorAccessor<RGBVALUE>
{ {
public: public:
typedef typename RGBVALUE::value_type component_type; typedef typename RGBVALUE::value_type component_type;
skipping to change at line 996 skipping to change at line 998
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* RedAccessor */ /* RedAccessor */
/* */ /* */
/********************************************************/ /********************************************************/
/** Encapsulate access to red band of an rgb value. /** Encapsulate access to red band of an rgb value.
<b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hx x</a>"<br> <b>\#include</b> \<<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class RGBVALUE> template <class RGBVALUE>
class RedAccessor class RedAccessor
{ {
public: public:
typedef typename RGBVALUE::value_type value_type; typedef typename RGBVALUE::value_type value_type;
/** Get value of the red component /** Get value of the red component
*/ */
skipping to change at line 1046 skipping to change at line 1048
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* GreenAccessor */ /* GreenAccessor */
/* */ /* */
/********************************************************/ /********************************************************/
/** Encapsulate access to green band of an rgb value. /** Encapsulate access to green band of an rgb value.
<b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hx x</a>"<br> <b>\#include</b> \<<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class RGBVALUE> template <class RGBVALUE>
class GreenAccessor class GreenAccessor
{ {
public: public:
typedef typename RGBVALUE::value_type value_type; typedef typename RGBVALUE::value_type value_type;
/** Get value of the green component /** Get value of the green component
*/ */
skipping to change at line 1096 skipping to change at line 1098
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* BlueAccessor */ /* BlueAccessor */
/* */ /* */
/********************************************************/ /********************************************************/
/** Encapsulate access to blue band of an rgb value. /** Encapsulate access to blue band of an rgb value.
<b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hx x</a>"<br> <b>\#include</b> \<<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class RGBVALUE> template <class RGBVALUE>
class BlueAccessor class BlueAccessor
{ {
public: public:
typedef typename RGBVALUE::value_type value_type; typedef typename RGBVALUE::value_type value_type;
/** Get value of the blue component /** Get value of the blue component
*/ */
skipping to change at line 1146 skipping to change at line 1148
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* RGBToGrayAccessor */ /* RGBToGrayAccessor */
/* */ /* */
/********************************************************/ /********************************************************/
/** Encapsulate access to luminance of an rgb value. /** Encapsulate access to luminance of an rgb value.
<b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hx x</a>"<br> <b>\#include</b> \<<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class RGBVALUE> template <class RGBVALUE>
class RGBToGrayAccessor class RGBToGrayAccessor
{ {
public: public:
typedef typename RGBVALUE::value_type value_type; typedef typename RGBVALUE::value_type value_type;
/** Get value of the luminance /** Get value of the luminance
*/ */
skipping to change at line 1179 skipping to change at line 1181
/********************************************************/ /********************************************************/
/* */ /* */
/* GrayToRGBAccessor */ /* GrayToRGBAccessor */
/* */ /* */
/********************************************************/ /********************************************************/
/** Create an RGB view for a grayscale image by making all three channe ls /** Create an RGB view for a grayscale image by making all three channe ls
equal. equal.
<b>\#include</b> "<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.hx x</a>"<br> <b>\#include</b> \<<a href="rgbvalue_8hxx-source.html">vigra/rgbvalue.h xx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class VALUETYPE> template <class VALUETYPE>
class GrayToRGBAccessor class GrayToRGBAccessor
{ {
public: public:
typedef typename vigra::RGBValue<VALUETYPE> value_type; typedef typename vigra::RGBValue<VALUETYPE> value_type;
/** Get RGB value for the given pixel. /** Get RGB value for the given pixel.
*/ */
 End of changes. 14 change blocks. 
15 lines changed or deleted 18 lines changed or added


 seededregiongrowing.hxx   seededregiongrowing.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2003 by Ullrich Koethe, Hans Meine */ /* Copyright 1998-2003 by Ullrich Koethe, Hans Meine */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 185 skipping to change at line 185
/********************************************************/ /********************************************************/
/** \brief Region Segmentation by means of Seeded Region Growing. /** \brief Region Segmentation by means of Seeded Region Growing.
This algorithm implements seeded region growing as described in This algorithm implements seeded region growing as described in
R. Adams, L. Bischof: "<em> Seeded Region Growing</em>", IEEE Trans. on Pattern R. Adams, L. Bischof: "<em> Seeded Region Growing</em>", IEEE Trans. on Pattern
Analysis and Maschine Intelligence, vol 16, no 6, 1994, and Analysis and Maschine Intelligence, vol 16, no 6, 1994, and
Ullrich K&ouml;the: Ullrich K&ouml;the:
<em> "<a href="http://kogs-www.informatik.uni-hamburg.de/~koethe/papers /#primary">Primary Image Segmentation</a>"</em>, <em><a href="http://kogs-www.informatik.uni-hamburg.de/~koethe/papers/# primary">Primary Image Segmentation</a></em>,
in: G. Sagerer, S. in: G. Sagerer, S.
Posch, F. Kummert (eds.): Mustererkennung 1995, Proc. 17. DAGM-Symposiu m, Posch, F. Kummert (eds.): Mustererkennung 1995, Proc. 17. DAGM-Symposiu m,
Springer 1995 Springer 1995
The seed image is a partly segmented image which contains uniquely The seed image is a partly segmented image which contains uniquely
labeled regions (the seeds) and unlabeled pixels (the candidates, label 0). labeled regions (the seeds) and unlabeled pixels (the candidates, label 0).
Seed regions can be as large as you wish and as small as one pixel. If Seed regions can be as large as you wish and as small as one pixel. If
there are no candidates, the algorithm will simply copy the seed image there are no candidates, the algorithm will simply copy the seed image
into the output image. Otherwise it will aggregate the candidates into into the output image. Otherwise it will aggregate the candidates into
the existing regions so that a cost function is minimized. This the existing regions so that a cost function is minimized. This
skipping to change at line 270 skipping to change at line 270
class RegionStatisticsArray> class RegionStatisticsArray>
void seededRegionGrowing(SrcImageIterator srcul, void seededRegionGrowing(SrcImageIterator srcul,
SrcImageIterator srclr, SrcAccessor as, SrcImageIterator srclr, SrcAccessor as,
SeedImageIterator seedsul, SeedAccessor as eeds, SeedImageIterator seedsul, SeedAccessor as eeds,
DestImageIterator destul, DestAccessor ad, DestImageIterator destul, DestAccessor ad,
RegionStatisticsArray & stats, RegionStatisticsArray & stats,
SRGType srgType = CompleteGrow); SRGType srgType = CompleteGrow);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class SeedImageIterator, class SeedAccessor, class SeedImageIterator, class SeedAccessor,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class RegionStatisticsArray> class RegionStatisticsArray>
inline void void
seededRegionGrowing(triple<SrcImageIterator, SrcImageIterator, SrcA ccessor> img1, seededRegionGrowing(triple<SrcImageIterator, SrcImageIterator, SrcA ccessor> img1,
pair<SeedImageIterator, SeedAccessor> img3, pair<SeedImageIterator, SeedAccessor> img3,
pair<DestImageIterator, DestAccessor> img4, pair<DestImageIterator, DestAccessor> img4,
RegionStatisticsArray & stats, RegionStatisticsArray & stats,
SRGType srgType = CompleteGrow); SRGType srgType = CompleteGrow);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="seededregiongrowing_8hxx-source.html">vigra/ seededregiongrowing.hxx</a>"<br> <b>\#include</b> \<<a href="seededregiongrowing_8hxx-source.html">vigra /seededregiongrowing.hxx</a>\><br>
Namespace: vigra Namespace: vigra
Example: implementation of the voronoi tesselation Example: implementation of the voronoi tesselation
\code \code
vigra::BImage points(w,h); vigra::BImage points(w,h);
vigra::FImage dist(x,y); vigra::FImage dist(x,y);
// empty edge image // empty edge image
points = 0; points = 0;
skipping to change at line 348 skipping to change at line 348
// update statistics // update statistics
stats[seed_accessor(seed_upperleft)](src_accessor(src_upperleft)); stats[seed_accessor(seed_upperleft)](src_accessor(src_upperleft));
// set result // set result
dest_accessor.set(seed_accessor(seed_upperleft), dest_upperleft); dest_accessor.set(seed_accessor(seed_upperleft), dest_upperleft);
\endcode \endcode
Further requirements are determined by the <TT>RegionStatisticsArray</T T>. Further requirements are determined by the <TT>RegionStatisticsArray</T T>.
*/ */
doxygen_overloaded_function(template <...> void seededRegionGrowing)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class SeedImageIterator, class SeedAccessor, class SeedImageIterator, class SeedAccessor,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class RegionStatisticsArray> class RegionStatisticsArray>
void seededRegionGrowing(SrcImageIterator srcul, void seededRegionGrowing(SrcImageIterator srcul,
SrcImageIterator srclr, SrcAccessor as, SrcImageIterator srclr, SrcAccessor as,
SeedImageIterator seedsul, SeedAccessor aseeds, SeedImageIterator seedsul, SeedAccessor aseeds,
DestImageIterator destul, DestAccessor ad, DestImageIterator destul, DestAccessor ad,
RegionStatisticsArray & stats, RegionStatisticsArray & stats,
const SRGType srgType) const SRGType srgType)
skipping to change at line 538 skipping to change at line 540
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Statistics functor to be used for seeded region growing. /** \brief Statistics functor to be used for seeded region growing.
This functor can be used if the cost of a candidate during This functor can be used if the cost of a candidate during
\ref seededRegionGrowing() is equal to the feature value of that \ref seededRegionGrowing() is equal to the feature value of that
candidate and does not depend on properties of the region it is going t o candidate and does not depend on properties of the region it is going t o
be merged with. be merged with.
<b>\#include</b> "<a href="seededregiongrowing_8hxx-source.html">vigra/ seededregiongrowing.hxx</a>"<br> <b>\#include</b> \<<a href="seededregiongrowing_8hxx-source.html">vigra /seededregiongrowing.hxx</a>\><br>
Namespace: vigra Namespace: vigra
<b> Required Interface:</b> <b> Required Interface:</b>
no requirements no requirements
*/ */
template <class Value> template <class Value>
class SeedRgDirectValueFunctor class SeedRgDirectValueFunctor
{ {
public: public:
 End of changes. 8 change blocks. 
8 lines changed or deleted 10 lines changed or added


 separableconvolution.hxx   separableconvolution.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 416 skipping to change at line 416
Perform 1D convolution and separable filtering in 2 dimensions. Perform 1D convolution and separable filtering in 2 dimensions.
These generic convolution functions implement These generic convolution functions implement
the standard convolution operation for a wide range of images and the standard convolution operation for a wide range of images and
signals that fit into the required interface. They need a suitable signals that fit into the required interface. They need a suitable
kernel to operate. kernel to operate.
*/ */
//@{ //@{
/** \brief Performs a 1 dimensional convolution of the source signal using the given /** \brief Performs a 1-dimensional convolution of the source signal using the given
kernel. kernel.
The KernelIterator must point to the center iterator, and The KernelIterator must point to the center iterator, and
the kernel's size is given by its left (kleft <= 0) and right the kernel's size is given by its left (kleft <= 0) and right
(kright >= 0) borders. The signal must always be larger than the kernel . (kright >= 0) borders. The signal must always be larger than the kernel .
At those positions where the kernel does not completely fit At those positions where the kernel does not completely fit
into the signal's range, the specified \ref BorderTreatmentMode is into the signal's range, the specified \ref BorderTreatmentMode is
applied. applied.
The signal's value_type (SrcAccessor::value_type) must be a The signal's value_type (SrcAccessor::value_type) must be a
skipping to change at line 449 skipping to change at line 449
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
void convolveLine(SrcIterator is, SrcIterator isend, SrcAccessor sa , void convolveLine(SrcIterator is, SrcIterator isend, SrcAccessor sa ,
DestIterator id, DestAccessor da, DestIterator id, DestAccessor da,
KernelIterator ik, KernelAccessor ka, KernelIterator ik, KernelAccessor ka,
int kleft, int kright, BorderTreatmentMode border ) int kleft, int kright, BorderTreatmentMode border )
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
void convolveLine(triple<SrcIterator, SrcIterator, SrcAccessor> src , void convolveLine(triple<SrcIterator, SrcIterator, SrcAccessor> src ,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
tuple5<KernelIterator, KernelAccessor, tuple5<KernelIterator, KernelAccessor,
int, int, BorderTreatmentMode> kernel) int, int, BorderTreatmentMode> kernel)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="separableconvolution_8hxx-source.html">vigra /separableconvolution.hxx</a>" <b>\#include</b> \<<a href="separableconvolution_8hxx-source.html">vigr a/separableconvolution.hxx</a>\>
\code \code
std::vector<float> src, dest; std::vector<float> src, dest;
... ...
// define binomial filter of size 5 // define binomial filter of size 5
static float kernel[] = static float kernel[] =
{ 1.0/16.0, 4.0/16.0, 6.0/16.0, 4.0/16.0, 1.0/16.0}; { 1.0/16.0, 4.0/16.0, 6.0/16.0, 4.0/16.0, 1.0/16.0};
typedef vigra::StandardAccessor<float> FAccessor; typedef vigra::StandardAccessor<float> FAccessor;
skipping to change at line 528 skipping to change at line 528
\code \code
kleft <= 0 kleft <= 0
kright >= 0 kright >= 0
iend - is >= kright + kleft + 1 iend - is >= kright + kleft + 1
\endcode \endcode
If border == BORDER_TREATMENT_CLIP: Sum of kernel elements must be If border == BORDER_TREATMENT_CLIP: Sum of kernel elements must be
!= 0. != 0.
*/ */
doxygen_overloaded_function(template <...> void convolveLine)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
void convolveLine(SrcIterator is, SrcIterator iend, SrcAccessor sa, void convolveLine(SrcIterator is, SrcIterator iend, SrcAccessor sa,
DestIterator id, DestAccessor da, DestIterator id, DestAccessor da,
KernelIterator ik, KernelAccessor ka, KernelIterator ik, KernelAccessor ka,
int kleft, int kright, BorderTreatmentMode border) int kleft, int kright, BorderTreatmentMode border)
{ {
typedef typename KernelAccessor::value_type KernelValue; typedef typename KernelAccessor::value_type KernelValue;
skipping to change at line 617 skipping to change at line 619
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* separableConvolveX */ /* separableConvolveX */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Performs a 1 dimensional convolution in x direction. /** \brief Performs a 1 dimensional convolution in x direction.
It calls \link SeparableConvolution#convolveLine convolveLine\endlink() It calls \ref convolveLine() for every row of the image. See \ref convo
for every row of the lveLine()
image. See \link SeparableConvolution#convolveLine convolveLine\endlink for more information about required interfaces and vigra_preconditions.
() for more information about required interfaces
and vigra_preconditions.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
void separableConvolveX(SrcImageIterator supperleft, void separableConvolveX(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor s a, SrcImageIterator slowerright, SrcAccessor s a,
DestImageIterator dupperleft, DestAccessor da, DestImageIterator dupperleft, DestAccessor da,
KernelIterator ik, KernelAccessor ka, KernelIterator ik, KernelAccessor ka,
int kleft, int kright, BorderTreatmentMode border) int kleft, int kright, BorderTreatmentMode border)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
void separableConvolveX(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, void separableConvolveX(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
tuple5<KernelIterator, KernelAccessor, tuple5<KernelIterator, KernelAccessor,
int, int, BorderTreatmentMode> kernel) int, int, BorderTreatmentMode> kernel)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="separableconvolution_8hxx-source.html">vigra /separableconvolution.hxx</a>" <b>\#include</b> \<<a href="separableconvolution_8hxx-source.html">vigr a/separableconvolution.hxx</a>\>
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
// define Gaussian kernel with std. deviation 3.0 // define Gaussian kernel with std. deviation 3.0
vigra::Kernel1D<double> kernel; vigra::Kernel1D<double> kernel;
kernel.initGaussian(3.0); kernel.initGaussian(3.0);
vigra::separableConvolveX(srcImageRange(src), destImage(dest), kernel1d (kernel)); vigra::separableConvolveX(srcImageRange(src), destImage(dest), kernel1d (kernel));
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void separableConvolveX)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
void separableConvolveX(SrcIterator supperleft, void separableConvolveX(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor sa, SrcIterator slowerright, SrcAccessor sa,
DestIterator dupperleft, DestAccessor da, DestIterator dupperleft, DestAccessor da,
KernelIterator ik, KernelAccessor ka, KernelIterator ik, KernelAccessor ka,
int kleft, int kright, BorderTreatmentMode border) int kleft, int kright, BorderTreatmentMode border)
{ {
typedef typename KernelAccessor::value_type KernelValue; typedef typename KernelAccessor::value_type KernelValue;
skipping to change at line 724 skipping to change at line 727
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* separableConvolveY */ /* separableConvolveY */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Performs a 1 dimensional convolution in y direction. /** \brief Performs a 1 dimensional convolution in y direction.
It calls \link SeparableConvolution#convolveLine convolveLine\endlink() It calls \ref convolveLine() for every column of the image. See \ref co
for every column of the nvolveLine()
image. See \link SeparableConvolution#convolveLine convolveLine\endlink for more information about required interfaces and vigra_preconditions.
() for more information about required interfaces
and vigra_preconditions.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
void separableConvolveY(SrcImageIterator supperleft, void separableConvolveY(SrcImageIterator supperleft,
SrcImageIterator slowerright, SrcAccessor s a, SrcImageIterator slowerright, SrcAccessor s a,
DestImageIterator dupperleft, DestAccessor da, DestImageIterator dupperleft, DestAccessor da,
KernelIterator ik, KernelAccessor ka, KernelIterator ik, KernelAccessor ka,
int kleft, int kright, BorderTreatmentMode border) int kleft, int kright, BorderTreatmentMode border)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
void separableConvolveY(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src, void separableConvolveY(triple<SrcImageIterator, SrcImageIterator, SrcAccessor> src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
tuple5<KernelIterator, KernelAccessor, tuple5<KernelIterator, KernelAccessor,
int, int, BorderTreatmentMode> kernel) int, int, BorderTreatmentMode> kernel)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="separableconvolution_8hxx-source.html">vigra /separableconvolution.hxx</a>" <b>\#include</b> \<<a href="separableconvolution_8hxx-source.html">vigr a/separableconvolution.hxx</a>\>
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
// define Gaussian kernel with std. deviation 3.0 // define Gaussian kernel with std. deviation 3.0
vigra::Kernel1D kernel; vigra::Kernel1D kernel;
kernel.initGaussian(3.0); kernel.initGaussian(3.0);
vigra::separableConvolveY(srcImageRange(src), destImage(dest), kernel1d (kernel)); vigra::separableConvolveY(srcImageRange(src), destImage(dest), kernel1d (kernel));
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void separableConvolveY)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
void separableConvolveY(SrcIterator supperleft, void separableConvolveY(SrcIterator supperleft,
SrcIterator slowerright, SrcAccessor sa, SrcIterator slowerright, SrcAccessor sa,
DestIterator dupperleft, DestAccessor da, DestIterator dupperleft, DestAccessor da,
KernelIterator ik, KernelAccessor ka, KernelIterator ik, KernelAccessor ka,
int kleft, int kright, BorderTreatmentMode border) int kleft, int kright, BorderTreatmentMode border)
{ {
typedef typename KernelAccessor::value_type KernelValue; typedef typename KernelAccessor::value_type KernelValue;
skipping to change at line 851 skipping to change at line 855
The different init functions create a kernel with the specified The different init functions create a kernel with the specified
properties. The kernel's value_type must be a linear space, i.e. it properties. The kernel's value_type must be a linear space, i.e. it
must define multiplication with doubles and NumericTraits. must define multiplication with doubles and NumericTraits.
The kernel defines a factory function kernel1d() to create an argument object The kernel defines a factory function kernel1d() to create an argument object
(see \ref KernelArgumentObjectFactories). (see \ref KernelArgumentObjectFactories).
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="stdconvolution_8hxx-source.html">vigra/stdco nvolution.hxx</a>" <b>\#include</b> \<<a href="stdconvolution_8hxx-source.html">vigra/stdc onvolution.hxx</a>\>
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
// define Gaussian kernel with std. deviation 3.0 // define Gaussian kernel with std. deviation 3.0
vigra::Kernel1D kernel; vigra::Kernel1D kernel;
kernel.initGaussian(3.0); kernel.initGaussian(3.0);
vigra::separableConvolveX(srcImageRange(src), destImage(dest), kernel1d (kernel)); vigra::separableConvolveX(srcImageRange(src), destImage(dest), kernel1d (kernel));
skipping to change at line 925 skipping to change at line 929
InitProxy(Iterator i, int count, value_type & norm) InitProxy(Iterator i, int count, value_type & norm)
: iter_(i), base_(i), : iter_(i), base_(i),
count_(count), sum_(count), count_(count), sum_(count),
norm_(norm) norm_(norm)
{} {}
~InitProxy() ~InitProxy()
{ {
vigra_precondition(count_ == 1 || count_ == sum_, vigra_precondition(count_ == 1 || count_ == sum_,
"Kernel1D::initExplicitly(): " "Kernel1D::initExplicitly(): "
"Too few init values."); "Wrong number of init values.");
} }
InitProxy & operator,(value_type const & v) InitProxy & operator,(value_type const & v)
{ {
if(sum_ == count_) norm_ = *iter_; if(sum_ == count_)
norm_ = *iter_;
norm_ += v; norm_ += v;
--count_; --count_;
vigra_precondition(count_ > 0,
"Kernel1D::initExplicitly(): "
"Too many init values.");
++iter_; if(count_ > 0)
*iter_ = v; {
++iter_;
*iter_ = v;
}
return *this; return *this;
} }
Iterator iter_, base_; Iterator iter_, base_;
int count_, sum_; int count_, sum_;
value_type & norm_; value_type & norm_;
}; };
static value_type one() { return NumericTraits<value_type>::one(); } static value_type one() { return NumericTraits<value_type>::one(); }
/** Default constructor. /** Default constructor.
Creates a kernel of size 1 which would copy the signal Creates a kernel of size 1 which would copy the signal
unchanged. unchanged.
*/ */
Kernel1D() Kernel1D()
: kernel_(), : kernel_(),
left_(0), left_(0),
right_(0), right_(0),
border_treatment_(BORDER_TREATMENT_CLIP), border_treatment_(BORDER_TREATMENT_REFLECT),
norm_(one()) norm_(one())
{ {
kernel_.push_back(norm_); kernel_.push_back(norm_);
} }
/** Copy constructor. /** Copy constructor.
*/ */
Kernel1D(Kernel1D const & k) Kernel1D(Kernel1D const & k)
: kernel_(k.kernel_), : kernel_(k.kernel_),
left_(k.left_), left_(k.left_),
skipping to change at line 1039 skipping to change at line 1044
Precondition: Precondition:
\code \code
std_dev >= 0.0 std_dev >= 0.0
\endcode \endcode
Postconditions: Postconditions:
\code \code
1. left() == -(int)(3.0*std_dev + 0.5) 1. left() == -(int)(3.0*std_dev + 0.5)
2. right() == (int)(3.0*std_dev + 0.5) 2. right() == (int)(3.0*std_dev + 0.5)
3. borderTreatment() == BORDER_TREATMENT_CLIP 3. borderTreatment() == BORDER_TREATMENT_REFLECT
4. norm() == norm 4. norm() == norm
\endcode \endcode
*/ */
void initGaussian(double std_dev, value_type norm); void initGaussian(double std_dev, value_type norm);
/** Init as a Gaussian function with norm 1. /** Init as a Gaussian function with norm 1.
*/ */
void initGaussian(double std_dev) void initGaussian(double std_dev)
{ {
initGaussian(std_dev, one()); initGaussian(std_dev, one());
skipping to change at line 1071 skipping to change at line 1076
Postconditions: Postconditions:
\code \code
1. left() == -(int)(3.0*std_dev + 0.5) 1. left() == -(int)(3.0*std_dev + 0.5)
2. right() == (int)(3.0*std_dev + 0.5) 2. right() == (int)(3.0*std_dev + 0.5)
3. borderTreatment() == BORDER_TREATMENT_REFLECT 3. borderTreatment() == BORDER_TREATMENT_REFLECT
4. norm() == norm 4. norm() == norm
\endcode \endcode
*/ */
void initDiscreteGaussian(double std_dev, value_type norm); void initDiscreteGaussian(double std_dev, value_type norm);
/** Init as a LOineberg's discrete analog of the Gaussian function /** Init as a Lindeberg's discrete analog of the Gaussian function
with norm 1. with norm 1.
*/ */
void initDiscreteGaussian(double std_dev) void initDiscreteGaussian(double std_dev)
{ {
initDiscreteGaussian(std_dev, one()); initDiscreteGaussian(std_dev, one());
} }
/** /**
Init as a Gaussian derivative of order '<tt>order</tt>'. Init as a Gaussian derivative of order '<tt>order</tt>'.
The radius of the kernel is always <tt>3*std_dev + 0.5*order</t t>. The radius of the kernel is always <tt>3*std_dev + 0.5*order</t t>.
skipping to change at line 1105 skipping to change at line 1110
Preconditions: Preconditions:
\code \code
1. std_dev >= 0.0 1. std_dev >= 0.0
2. order >= 1 2. order >= 1
\endcode \endcode
Postconditions: Postconditions:
\code \code
1. left() == -(int)(3.0*std_dev + 0.5*order + 0.5) 1. left() == -(int)(3.0*std_dev + 0.5*order + 0.5)
2. right() == (int)(3.0*std_dev + 0.5*order + 0.5) 2. right() == (int)(3.0*std_dev + 0.5*order + 0.5)
3. borderTreatment() == BORDER_TREATMENT_REPEAT 3. borderTreatment() == BORDER_TREATMENT_REFLECT
4. norm() == norm 4. norm() == norm
\endcode \endcode
*/ */
void initGaussianDerivative(double std_dev, int order, value_type norm) ; void initGaussianDerivative(double std_dev, int order, value_type norm) ;
/** Init as a Gaussian derivative with norm 1. /** Init as a Gaussian derivative with norm 1.
*/ */
void initGaussianDerivative(double std_dev, int order) void initGaussianDerivative(double std_dev, int order)
{ {
initGaussianDerivative(std_dev, order, one()); initGaussianDerivative(std_dev, order, one());
} }
/** /**
Init an optimal 3-tap smoothing filter.
The filter values are
\code
[0.216, 0.568, 0.216]
\endcode
These values are optimal in the sense that the 3x3 filter obtai
ned by separable application
of this filter is the best possible 3x3 approximation to a Gaus
sian filter.
The equivalent Gaussian has sigma = 0.680.
Postconditions:
\code
1. left() == -1
2. right() == 1
3. borderTreatment() == BORDER_TREATMENT_REFLECT
4. norm() == 1.0
\endcode
*/
void initOptimalSmoothing3()
{
this->initExplicitly(-1, 1) = 0.216, 0.568, 0.216;
this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
}
/**
Init an optimal 3-tap smoothing filter to be used in the contex
t of first derivative computation.
This filter must be used in conjunction with the symmetric diff
erence filter (see initSymmetricDifference()),
such that the difference filter is applied along one dimension,
and the smoothing filter along the other.
The filter values are
\code
[0.224365, 0.55127, 0.224365]
\endcode
These values are optimal in the sense that the 3x3 filter obtai
ned by combining
this filter with the symmetric difference is the best possible
3x3 approximation to a
Gaussian first derivative filter. The equivalent Gaussian has s
igma = 0.675.
Postconditions:
\code
1. left() == -1
2. right() == 1
3. borderTreatment() == BORDER_TREATMENT_REFLECT
4. norm() == 1.0
\endcode
*/
void initOptimalFirstDerivativeSmoothing3()
{
this->initExplicitly(-1, 1) = 0.224365, 0.55127, 0.224365;
this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
}
/**
Init an optimal 3-tap smoothing filter to be used in the contex
t of second derivative computation.
This filter must be used in conjunction with the 3-tap second d
ifference filter (see initSecondDifference3()),
such that the difference filter is applied along one dimension,
and the smoothing filter along the other.
The filter values are
\code
[0.13, 0.74, 0.13]
\endcode
These values are optimal in the sense that the 3x3 filter obtai
ned by combining
this filter with the 3-tap second difference is the best possib
le 3x3 approximation to a
Gaussian second derivative filter. The equivalent Gaussian has
sigma = 0.433.
Postconditions:
\code
1. left() == -1
2. right() == 1
3. borderTreatment() == BORDER_TREATMENT_REFLECT
4. norm() == 1.0
\endcode
*/
void initOptimalSecondDerivativeSmoothing3()
{
this->initExplicitly(-1, 1) = 0.13, 0.74, 0.13;
this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
}
/**
Init an optimal 5-tap smoothing filter.
The filter values are
\code
[0.03134, 0.24, 0.45732, 0.24, 0.03134]
\endcode
These values are optimal in the sense that the 5x5 filter obtai
ned by separable application
of this filter is the best possible 5x5 approximation to a Gaus
sian filter.
The equivalent Gaussian has sigma = 0.867.
Postconditions:
\code
1. left() == -2
2. right() == 2
3. borderTreatment() == BORDER_TREATMENT_REFLECT
4. norm() == 1.0
\endcode
*/
void initOptimalSmoothing5()
{
this->initExplicitly(-2, 2) = 0.03134, 0.24, 0.45732, 0.24, 0.03134
;
this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
}
/**
Init an optimal 5-tap smoothing filter to be used in the contex
t of first derivative computation.
This filter must be used in conjunction with the optimal 5-tap f
irst derivative filter
(see initOptimalFirstDerivative5()), such that the derivative f
ilter is applied along one dimension,
and the smoothing filter along the other. The filter values are
\code
[0.04255, 0.241, 0.4329, 0.241, 0.04255]
\endcode
These values are optimal in the sense that the 5x5 filter obtai
ned by combining
this filter with the optimal 5-tap first derivative is the best
possible 5x5 approximation to a
Gaussian first derivative filter. The equivalent Gaussian has s
igma = 0.906.
Postconditions:
\code
1. left() == -2
2. right() == 2
3. borderTreatment() == BORDER_TREATMENT_REFLECT
4. norm() == 1.0
\endcode
*/
void initOptimalFirstDerivativeSmoothing5()
{
this->initExplicitly(-2, 2) = 0.04255, 0.241, 0.4329, 0.241, 0.0425
5;
this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
}
/**
Init an optimal 5-tap smoothing filter to be used in the contex
t of second derivative computation.
This filter must be used in conjunction with the optimal 5-tap s
econd derivative filter
(see initOptimalSecondDerivative5()), such that the derivative f
ilter is applied along one dimension,
and the smoothing filter along the other. The filter values are
\code
[0.0243, 0.23556, 0.48028, 0.23556, 0.0243]
\endcode
These values are optimal in the sense that the 5x5 filter obtai
ned by combining
this filter with the optimal 5-tap second derivative is the bes
t possible 5x5 approximation to a
Gaussian second derivative filter. The equivalent Gaussian has
sigma = 0.817.
Postconditions:
\code
1. left() == -2
2. right() == 2
3. borderTreatment() == BORDER_TREATMENT_REFLECT
4. norm() == 1.0
\endcode
*/
void initOptimalSecondDerivativeSmoothing5()
{
this->initExplicitly(-2, 2) = 0.0243, 0.23556, 0.48028, 0.23556, 0.
0243;
this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
}
/**
Init a 5-tap filter as defined by Peter Burt in the context of
pyramid creation.
The filter values are
\code
[a, 0.25, 0.5-2*a, 0.25, a]
\endcode
The default <tt>a = 0.04785</tt> is optimal in the sense that i
t minimizes the difference
to a true Gaussian filter (which would have sigma = 0.975). For
other values of <tt>a</tt>, the scale
of the most similar Gaussian can be approximated by
\code
sigma = 5.1 * a + 0.731
\endcode
Preconditions:
\code
0 <= a <= 0.125
\endcode
Postconditions:
\code
1. left() == -2
2. right() == 2
3. borderTreatment() == BORDER_TREATMENT_REFLECT
4. norm() == 1.0
\endcode
*/
void initBurtFilter(double a = 0.04785)
{
vigra_precondition(a >= 0.0 && a <= 0.125,
"Kernel1D::initBurtFilter(): 0 <= a <= 0.125 required.");
this->initExplicitly(-2, 2) = a, 0.25, 0.5 - 2.0*a, 0.25, a;
this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
}
/**
Init as a Binomial filter. 'norm' denotes the sum of all bins Init as a Binomial filter. 'norm' denotes the sum of all bins
of the kernel. of the kernel.
Precondition: Precondition:
\code \code
radius >= 0 radius >= 0
\endcode \endcode
Postconditions: Postconditions:
\code \code
skipping to change at line 1163 skipping to change at line 1369
Postconditions: Postconditions:
\code \code
1. left() == -radius 1. left() == -radius
2. right() == radius 2. right() == radius
3. borderTreatment() == BORDER_TREATMENT_CLIP 3. borderTreatment() == BORDER_TREATMENT_CLIP
4. norm() == norm 4. norm() == norm
\endcode \endcode
*/ */
void initAveraging(int radius, value_type norm); void initAveraging(int radius, value_type norm);
/** Init as a Averaging filter with norm 1. /** Init as an Averaging filter with norm 1.
*/ */
void initAveraging(int radius) void initAveraging(int radius)
{ {
initAveraging(radius, one()); initAveraging(radius, one());
} }
/** /**
Init as a symmetric gradient filter of the form Init as a symmetric gradient filter of the form
<TT>[ 0.5 * norm, 0.0 * norm, -0.5 * norm]</TT> <TT>[ 0.5 * norm, 0.0 * norm, -0.5 * norm]</TT>
<b>Deprecated</b>. Use initSymmetricDifference() instead.
Postconditions: Postconditions:
\code \code
1. left() == -1 1. left() == -1
2. right() == 1 2. right() == 1
3. borderTreatment() == BORDER_TREATMENT_REPEAT 3. borderTreatment() == BORDER_TREATMENT_REPEAT
4. norm() == norm 4. norm() == norm
\endcode \endcode
*/ */
void void
initSymmetricGradient(value_type norm ); initSymmetricGradient(value_type norm )
{
initSymmetricDifference(norm);
setBorderTreatment(BORDER_TREATMENT_REPEAT);
}
/** Init as a symmetric gradient filter with norm 1. /** Init as a symmetric gradient filter with norm 1.
<b>Deprecated</b>. Use initSymmetricDifference() instead.
*/ */
void initSymmetricGradient() void initSymmetricGradient()
{ {
initSymmetricGradient(one()); initSymmetricGradient(one());
} }
void
initSymmetricDifference(value_type norm );
/** Init as the 3-tap symmetric difference filter
The filter values are
\code
[0.5, 0, -0.5]
\endcode
Postconditions:
\code
1. left() == -1
2. right() == 1
3. borderTreatment() == BORDER_TREATMENT_REFLECT
4. norm() == 1.0
\endcode
*/
void initSymmetricDifference()
{
initSymmetricDifference(one());
}
/**
Init the 3-tap second difference filter.
The filter values are
\code
[1, -2, 1]
\endcode
Postconditions:
\code
1. left() == -1
2. right() == 1
3. borderTreatment() == BORDER_TREATMENT_REFLECT
4. norm() == 1
\endcode
*/
void
initSecondDifference3()
{
this->initExplicitly(-1, 1) = 1.0, -2.0, 1.0;
this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
}
/**
Init an optimal 5-tap first derivative filter.
This filter must be used in conjunction with the corresponding 5
-tap smoothing filter
(see initOptimalFirstDerivativeSmoothing5()), such that the deri
vative filter is applied along one dimension,
and the smoothing filter along the other.
The filter values are
\code
[0.1, 0.3, 0.0, -0.3, -0.1]
\endcode
These values are optimal in the sense that the 5x5 filter obtai
ned by combining
this filter with the corresponding 5-tap smoothing filter is th
e best possible 5x5 approximation to a
Gaussian first derivative filter. The equivalent Gaussian has s
igma = 0.906.
If the filter is instead separably combined with itself, an alm
ost optimal approximation of the
mixed second Gaussian derivative at scale sigma = 0.899 results
.
Postconditions:
\code
1. left() == -2
2. right() == 2
3. borderTreatment() == BORDER_TREATMENT_REFLECT
4. norm() == 1.0
\endcode
*/
void initOptimalFirstDerivative5()
{
this->initExplicitly(-2, 2) = 0.1, 0.3, 0.0, -0.3, -0.1;
this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
}
/**
Init an optimal 5-tap second derivative filter.
This filter must be used in conjunction with the corresponding 5
-tap smoothing filter
(see initOptimalSecondDerivativeSmoothing5()), such that the der
ivative filter is applied along one dimension,
and the smoothing filter along the other.
The filter values are
\code
[0.22075, 0.117, -0.6755, 0.117, 0.22075]
\endcode
These values are optimal in the sense that the 5x5 filter obtai
ned by combining
this filter with the corresponding 5-tap smoothing filter is th
e best possible 5x5 approximation to a
Gaussian second derivative filter. The equivalent Gaussian has
sigma = 0.817.
Postconditions:
\code
1. left() == -2
2. right() == 2
3. borderTreatment() == BORDER_TREATMENT_REFLECT
4. norm() == 1.0
\endcode
*/
void initOptimalSecondDerivative5()
{
this->initExplicitly(-2, 2) = 0.22075, 0.117, -0.6755, 0.117, 0.220
75;
this->setBorderTreatment(BORDER_TREATMENT_REFLECT);
}
/** Init the kernel by an explicit initializer list. /** Init the kernel by an explicit initializer list.
The left and right boundaries of the kernel must be passed. The left and right boundaries of the kernel must be passed.
A comma-separated initializer list is given after the assignmen t A comma-separated initializer list is given after the assignmen t
operator. This function is used like this: operator. This function is used like this:
\code \code
// define horizontal Roberts filter // define horizontal Roberts filter
vigra::Kernel1D<float> roberts_gradient_x; vigra::Kernel1D<float> roberts_gradient_x;
roberts_gradient_x.initExplicitly(0, 1) = 1.0, -1.0; roberts_gradient_x.initExplicitly(0, 1) = 1.0, -1.0;
skipping to change at line 1231 skipping to change at line 1552
2. right >= 0 2. right >= 0
3. the number of values in the initializer list 3. the number of values in the initializer list
is 1 or equals the size of the kernel. is 1 or equals the size of the kernel.
\endcode \endcode
*/ */
Kernel1D & initExplicitly(int left, int right) Kernel1D & initExplicitly(int left, int right)
{ {
vigra_precondition(left <= 0, vigra_precondition(left <= 0,
"Kernel1D::initExplicitly(): left border must be <= 0. "); "Kernel1D::initExplicitly(): left border must be <= 0. ");
vigra_precondition(right >= 0, vigra_precondition(right >= 0,
"Kernel1D::initExplicitly(): right border must be <= 0 ."); "Kernel1D::initExplicitly(): right border must be >= 0 .");
right_ = right; right_ = right;
left_ = left; left_ = left;
kernel_.resize(right - left + 1); kernel_.resize(right - left + 1);
return *this; return *this;
} }
/** Get iterator to center of kernel /** Get iterator to center of kernel
skipping to change at line 1304 skipping to change at line 1625
/** Set border treatment mode. /** Set border treatment mode.
*/ */
void setBorderTreatment( BorderTreatmentMode new_mode) void setBorderTreatment( BorderTreatmentMode new_mode)
{ border_treatment_ = new_mode; } { border_treatment_ = new_mode; }
/** norm of kernel /** norm of kernel
*/ */
value_type norm() const { return norm_; } value_type norm() const { return norm_; }
/** set a new norm and normalize kernel, use the normalization form ula /** set a new norm and normalize kernel, use the normalization form ula
for the given </tt>derivativeOrder</tt>. for the given <tt>derivativeOrder</tt>.
*/ */
void void
normalize(value_type norm, unsigned int derivativeOrder = 0, double off set = 0.0); normalize(value_type norm, unsigned int derivativeOrder = 0, double off set = 0.0);
/** normalize kernel to norm 1. /** normalize kernel to norm 1.
*/ */
void void
normalize() normalize()
{ {
normalize(one()); normalize(one());
skipping to change at line 1417 skipping to change at line 1738
kernel_.push_back(1.0); kernel_.push_back(1.0);
left_ = 0; left_ = 0;
right_ = 0; right_ = 0;
} }
if(norm != 0.0) if(norm != 0.0)
normalize(norm); normalize(norm);
else else
norm_ = 1.0; norm_ = 1.0;
// best border treatment for Gaussians is BORDER_TREATMENT_CLIP // best border treatment for Gaussians is BORDER_TREATMENT_REFLECT
border_treatment_ = BORDER_TREATMENT_CLIP; border_treatment_ = BORDER_TREATMENT_REFLECT;
} }
/***********************************************************************/ /***********************************************************************/
template <class ARITHTYPE> template <class ARITHTYPE>
void Kernel1D<ARITHTYPE>::initDiscreteGaussian(double std_dev, void Kernel1D<ARITHTYPE>::initDiscreteGaussian(double std_dev,
value_type norm) value_type norm)
{ {
vigra_precondition(std_dev >= 0.0, vigra_precondition(std_dev >= 0.0,
"Kernel1D::initDiscreteGaussian(): Standard deviation must be >= 0."); "Kernel1D::initDiscreteGaussian(): Standard deviation must be >= 0.");
skipping to change at line 1524 skipping to change at line 1845
// first calculate required kernel sizes // first calculate required kernel sizes
int radius = (int)(3.0 * std_dev + 0.5 * order + 0.5); int radius = (int)(3.0 * std_dev + 0.5 * order + 0.5);
if(radius == 0) if(radius == 0)
radius = 1; radius = 1;
// allocate the kernels // allocate the kernels
kernel_.clear(); kernel_.clear();
kernel_.reserve(radius*2+1); kernel_.reserve(radius*2+1);
// fill the kernel and calculate the DC component // fill the kernel and calculate the DC component
// introduced by truncation of the Geussian // introduced by truncation of the Gaussian
ARITHTYPE dc = 0.0; ARITHTYPE dc = 0.0;
for(ARITHTYPE x = -radius; x <= radius; ++x) for(ARITHTYPE x = -radius; x <= radius; ++x)
{ {
kernel_.push_back(gauss(x)); kernel_.push_back(gauss(x));
dc += kernel_[kernel_.size()-1]; dc += kernel_[kernel_.size()-1];
} }
dc /= (2.0*radius + 1.0); dc /= (2.0*radius + 1.0);
// remove DC, but only if kernel correction is permitted by a non-zero // remove DC, but only if kernel correction is permitted by a non-zero
// value for norm // value for norm
skipping to change at line 1552 skipping to change at line 1873
left_ = -radius; left_ = -radius;
right_ = radius; right_ = radius;
if(norm != 0.0) if(norm != 0.0)
normalize(norm, order); normalize(norm, order);
else else
norm_ = 1.0; norm_ = 1.0;
// best border treatment for Gaussian derivatives is // best border treatment for Gaussian derivatives is
// BORDER_TREATMENT_REPEAT // BORDER_TREATMENT_REFLECT
border_treatment_ = BORDER_TREATMENT_REPEAT; border_treatment_ = BORDER_TREATMENT_REFLECT;
} }
/***********************************************************************/ /***********************************************************************/
template <class ARITHTYPE> template <class ARITHTYPE>
void void
Kernel1D<ARITHTYPE>::initBinomial(int radius, Kernel1D<ARITHTYPE>::initBinomial(int radius,
value_type norm) value_type norm)
{ {
vigra_precondition(radius > 0, vigra_precondition(radius > 0,
skipping to change at line 1635 skipping to change at line 1956
norm_ = norm; norm_ = norm;
// best border treatment for Averaging is BORDER_TREATMENT_CLIP // best border treatment for Averaging is BORDER_TREATMENT_CLIP
border_treatment_ = BORDER_TREATMENT_CLIP; border_treatment_ = BORDER_TREATMENT_CLIP;
} }
/***********************************************************************/ /***********************************************************************/
template <class ARITHTYPE> template <class ARITHTYPE>
void void
Kernel1D<ARITHTYPE>::initSymmetricGradient(value_type norm) Kernel1D<ARITHTYPE>::initSymmetricDifference(value_type norm)
{ {
kernel_.erase(kernel_.begin(), kernel_.end()); kernel_.erase(kernel_.begin(), kernel_.end());
kernel_.reserve(3); kernel_.reserve(3);
kernel_.push_back(0.5 * norm); kernel_.push_back(0.5 * norm);
kernel_.push_back(0.0 * norm); kernel_.push_back(0.0 * norm);
kernel_.push_back(-0.5 * norm); kernel_.push_back(-0.5 * norm);
left_ = -1; left_ = -1;
right_ = 1; right_ = 1;
norm_ = norm; norm_ = norm;
// best border treatment for SymmetricGradient is // best border treatment for symmetric difference is
// BORDER_TREATMENT_REPEAT // BORDER_TREATMENT_REFLECT
border_treatment_ = BORDER_TREATMENT_REPEAT; border_treatment_ = BORDER_TREATMENT_REFLECT;
} }
/**************************************************************/ /**************************************************************/
/* */ /* */
/* Argument object factories for Kernel1D */ /* Argument object factories for Kernel1D */
/* */ /* */
/* (documentation: see vigra/convolution.hxx) */ /* (documentation: see vigra/convolution.hxx) */
/* */ /* */
/**************************************************************/ /**************************************************************/
 End of changes. 37 change blocks. 
46 lines changed or deleted 412 lines changed or added


 sized_int.hxx   sized_int.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
 End of changes. 2 change blocks. 
3 lines changed or deleted 3 lines changed or added


 slanted_edge_mtf.hxx   slanted_edge_mtf.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2006 by Ullrich Koethe */ /* Copyright 1998-2006 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 78 skipping to change at line 78
/** \brief Pass options to one of the \ref slantedEdgeMTF() functions. /** \brief Pass options to one of the \ref slantedEdgeMTF() functions.
<tt>SlantedEdgeMTFOptions</tt> is an argument objects that holds vario us optional <tt>SlantedEdgeMTFOptions</tt> is an argument objects that holds vario us optional
parameters used by the \ref slantedEdgeMTF() functions. If a parameter is not explicitly parameters used by the \ref slantedEdgeMTF() functions. If a parameter is not explicitly
set, a suitable default will be used. Changing the defaults is only nec essary if you can't set, a suitable default will be used. Changing the defaults is only nec essary if you can't
obtain good input data, but absolutely need an MTF estimate. obtain good input data, but absolutely need an MTF estimate.
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="slanted__edge__mtf_8hxx-source.html">vig ra/slanted_edge_mtf.hxx</a>"<br> <b>\#include</b> \<<a href="slanted__edge__mtf_8hxx-source.html">vi gra/slanted_edge_mtf.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h); vigra::BImage src(w,h);
std::vector<vigra::TinyVector<double, 2> > mtf; std::vector<vigra::TinyVector<double, 2> > mtf;
... ...
vigra::slantedEdgeMTF(srcImageRange(src), mtf, vigra::slantedEdgeMTF(srcImageRange(src), mtf,
vigra::SlantedEdgeMTFOptions().mtfSmoothingScale( 1.0)); vigra::SlantedEdgeMTFOptions().mtfSmoothingScale( 1.0));
skipping to change at line 550 skipping to change at line 550
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, class BackInsertabl e> template <class SrcIterator, class SrcAccessor, class BackInsertabl e>
void void
slantedEdgeMTF(SrcIterator sul, SrcIterator slr, SrcAccessor src, B ackInsertable & mtf, slantedEdgeMTF(SrcIterator sul, SrcIterator slr, SrcAccessor src, B ackInsertable & mtf,
SlantedEdgeMTFOptions const & options = SlantedEdgeMTFO ptions()); SlantedEdgeMTFOptions const & options = SlantedEdgeMTFO ptions());
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, class BackInsertabl e> template <class SrcIterator, class SrcAccessor, class BackInsertabl e>
void void
slantedEdgeMTF(triple<SrcIterator, SrcIterator, SrcAccessor> src, B ackInsertable & mtf, slantedEdgeMTF(triple<SrcIterator, SrcIterator, SrcAccessor> src, B ackInsertable & mtf,
SlantedEdgeMTFOptions const & options = SlantedEdgeM TFOptions()) SlantedEdgeMTFOptions const & options = SlantedEdgeM TFOptions())
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="slanted__edge__mtf_8hxx-source.html">vig ra/slanted_edge_mtf.hxx</a>"<br> <b>\#include</b> \<<a href="slanted__edge__mtf_8hxx-source.html">vi gra/slanted_edge_mtf.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h); vigra::BImage src(w,h);
std::vector<vigra::TinyVector<double, 2> > mtf; std::vector<vigra::TinyVector<double, 2> > mtf;
... ...
vigra::slantedEdgeMTF(srcImageRange(src), mtf); vigra::slantedEdgeMTF(srcImageRange(src), mtf);
// print the frequency / attenuation pairs found // print the frequency / attenuation pairs found
skipping to change at line 595 skipping to change at line 595
assert(isScalar::asBool == true); assert(isScalar::asBool == true);
double value = src(uperleft); double value = src(uperleft);
BackInsertable result; BackInsertable result;
typedef BackInsertable::value_type ResultType; typedef BackInsertable::value_type ResultType;
double intensity, variance; double intensity, variance;
result.push_back(ResultType(intensity, variance)); result.push_back(ResultType(intensity, variance));
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void slantedEdgeMTF)
template <class SrcIterator, class SrcAccessor, class BackInsertable> template <class SrcIterator, class SrcAccessor, class BackInsertable>
void void
slantedEdgeMTF(SrcIterator sul, SrcIterator slr, SrcAccessor src, BackInser table & mtf, slantedEdgeMTF(SrcIterator sul, SrcIterator slr, SrcAccessor src, BackInser table & mtf,
SlantedEdgeMTFOptions const & options = SlantedEdgeMTFOption s()) SlantedEdgeMTFOptions const & options = SlantedEdgeMTFOption s())
{ {
DImage preparedInput; DImage preparedInput;
unsigned int edgeWidth = detail::prepareSlantedEdgeInput(sul, slr, src, preparedInput, options); unsigned int edgeWidth = detail::prepareSlantedEdgeInput(sul, slr, src, preparedInput, options);
detail::slantedEdgeShadingCorrection(preparedInput, edgeWidth); detail::slantedEdgeShadingCorrection(preparedInput, edgeWidth);
ArrayVector<double> centers; ArrayVector<double> centers;
skipping to change at line 648 skipping to change at line 650
\code \code
namespace vigra { namespace vigra {
template <class Vector> template <class Vector>
double mtfFitGaussian(Vector const & mtf); double mtfFitGaussian(Vector const & mtf);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="slanted__edge__mtf_8hxx-source.html">vig ra/slanted_edge_mtf.hxx</a>"<br> <b>\#include</b> \<<a href="slanted__edge__mtf_8hxx-source.html">vi gra/slanted_edge_mtf.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h); vigra::BImage src(w,h);
std::vector<vigra::TinyVector<double, 2> > mtf; std::vector<vigra::TinyVector<double, 2> > mtf;
... ...
vigra::slantedEdgeMTF(srcImageRange(src), mtf); vigra::slantedEdgeMTF(srcImageRange(src), mtf);
double scale = vigra::mtfFitGaussian(mtf) double scale = vigra::mtfFitGaussian(mtf)
 End of changes. 7 change blocks. 
7 lines changed or deleted 9 lines changed or added


 splineimageview.hxx   splineimageview.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2004 by Ullrich Koethe */ /* Copyright 1998-2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 78 skipping to change at line 78
The <tt>SplineImageView</tt> template is explicitly specialized to make it as efficient as possible. The <tt>SplineImageView</tt> template is explicitly specialized to make it as efficient as possible.
In particular, unnecessary copying of the image is avoided when the ite rators passed In particular, unnecessary copying of the image is avoided when the ite rators passed
in the constructor originate from a \ref vigra::BasicImage. In addition , these specializations in the constructor originate from a \ref vigra::BasicImage. In addition , these specializations
provide function <tt>unchecked(...)</tt> that do not perform bounds che cking. If the original image provide function <tt>unchecked(...)</tt> that do not perform bounds che cking. If the original image
is not a variant of \ref vigra::BasicImage, one can customize the inter nal representation by is not a variant of \ref vigra::BasicImage, one can customize the inter nal representation by
using \ref vigra::SplineImageView0 or \ref vigra::SplineImageView1. using \ref vigra::SplineImageView0 or \ref vigra::SplineImageView1.
<b>Usage:</b> <b>Usage:</b>
<b>\#include</b> "<a href="splineimageview_8hxx-source.html">vigra/spli neimageview.hxx</a>"<br> <b>\#include</b> \<<a href="splineimageview_8hxx-source.html">vigra/spl ineimageview.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
BImage img(w,h); BImage img(w,h);
... // fill img ... // fill img
// construct spline view for quadratic interpolation // construct spline view for quadratic interpolation
SplineImageView<2, double> spi2(img); SplineImageView<2, double> spi2(srcImageRange(img));
double x = ..., y = ...; double x = ..., y = ...;
double v2 = spi2(x, y); double v2 = spi2(x, y);
// construct spline view for linear interpolation // construct spline view for linear interpolation
SplineImageView<1, UInt32> spi1(img); SplineImageView<1, UInt32> spi1(srcImageRange(img));
UInt32 v1 = spi1(x, y); UInt32 v1 = spi1(x, y);
FixedPoint<16, 15> fx(...), fy(...); FixedPoint<16, 15> fx(...), fy(...);
UInt32 vf = spi1.unchecked(fx, fy); UInt32 vf = spi1.unchecked(fx, fy); // caller is sure that (fx, fy) are valid coordinates
\endcode \endcode
*/ */
template <int ORDER, class VALUETYPE> template <int ORDER, class VALUETYPE>
class SplineImageView class SplineImageView
{ {
typedef typename NumericTraits<VALUETYPE>::RealPromote InternalValue; typedef typename NumericTraits<VALUETYPE>::RealPromote InternalValue;
public: public:
/** The view's value type (return type of access and derivative fun ctions). /** The view's value type (return type of access and derivative fun ctions).
skipping to change at line 375 skipping to change at line 375
value_type g2xy(difference_type const & d) const value_type g2xy(difference_type const & d) const
{ return g2xy(d[0], d[1]); } { return g2xy(d[0], d[1]); }
/** Access 2nd derivative in y-direction of gradient squared magnit ude /** Access 2nd derivative in y-direction of gradient squared magnit ude
at real-valued coordinate <tt>d</tt>. at real-valued coordinate <tt>d</tt>.
*/ */
value_type g2yy(difference_type const & d) const value_type g2yy(difference_type const & d) const
{ return g2yy(d[0], d[1]); } { return g2yy(d[0], d[1]); }
/** The width of the image. /** The width of the image.
<tt>0 <= x &lt;= width()-1</tt> is required for all access f unctions. <tt>0 <= x <= width()-1</tt> is required for all access functio ns.
*/ */
unsigned int width() const unsigned int width() const
{ return w_; } { return w_; }
/** The height of the image. /** The height of the image.
<tt>0 <= y &lt;= height()-1</tt> is required for all access functions. <tt>0 <= y <= height()-1</tt> is required for all access functi ons.
*/ */
unsigned int height() const unsigned int height() const
{ return h_; } { return h_; }
/** The size of the image. /** The size of the image.
<tt>0 <= x &lt;= size().x-1</tt> and <tt>0 &lt;= y &lt;= siz e().y-1</tt> <tt>0 <= x <= size().x-1</tt> and <tt>0 <= y <= size().y-1</tt>
are required for all access functions. are required for all access functions.
*/ */
size_type size() const size_type size() const
{ return size_type(w_, h_); } { return size_type(w_, h_); }
/** The internal image holding the spline coefficients. /** The internal image holding the spline coefficients.
*/ */
InternalImage const & image() const InternalImage const & image() const
{ {
return image_; return image_;
skipping to change at line 440 skipping to change at line 440
for(int nx = 0; nx < ORDER + 1; ++nx) for(int nx = 0; nx < ORDER + 1; ++nx)
f_x_y += pow(dx, nx) * pow(dy, ny) * coefficients(nx, n y); f_x_y += pow(dx, nx) * pow(dy, ny) * coefficients(nx, n y);
assert(abs(f_x_y - view(x, y)) < 1e-6); assert(abs(f_x_y - view(x, y)) < 1e-6);
\endcode \endcode
*/ */
template <class Array> template <class Array>
void coefficientArray(double x, double y, Array & res) const; void coefficientArray(double x, double y, Array & res) const;
/** Check if x is in the original image range. /** Check if x is in the original image range.
Equivalent to <tt>0 <= x &lt;= width()-1</tt>. Equivalent to <tt>0 <= x &lt;= width()-1</tt>.
*/ */
bool isInsideX(double x) const bool isInsideX(double x) const
{ {
return x >= 0.0 && x <= width()-1.0; return x >= 0.0 && x <= width()-1.0;
} }
/** Check if y is in the original image range. /** Check if y is in the original image range.
Equivalent to <tt>0 <= y &lt;= height()-1</tt>. Equivalent to <tt>0 <= y &lt;= height()-1</tt>.
*/ */
bool isInsideY(double y) const bool isInsideY(double y) const
{ {
return y >= 0.0 && y <= height()-1.0; return y >= 0.0 && y <= height()-1.0;
} }
/** Check if x and y are in the original image range. /** Check if x and y are in the original image range.
Equivalent to <tt>0 <= x &lt;= width()-1</tt> and <tt>0 &lt; = y &lt;= height()-1</tt>. Equivalent to <tt>0 <= x <= width()-1</tt> and <tt>0 <= y <= he ight()-1</tt>.
*/ */
bool isInside(double x, double y) const bool isInside(double x, double y) const
{ {
return isInsideX(x) && isInsideY(y); return isInsideX(x) && isInsideY(y);
} }
/** Check if x and y are in the valid range. Points outside the ori ginal image range are computed /** Check if x and y are in the valid range. Points outside the ori ginal image range are computed
by reflcective boundary conditions, but only within the first r eflection. by reflcective boundary conditions, but only within the first r eflection.
Equivalent to <tt>-width() + ORDER/2 + 2 &lt; x &lt; 2*width() Equivalent to <tt>-width() + ORDER/2 + 2 < x < 2*width() - ORDE
- ORDER/2 - 2</tt> and R/2 - 2</tt> and
<tt>-height() + ORDER/2 + 2 &lt; y &lt; 2*height() - ORDER/2 - <tt>-height() + ORDER/2 + 2 < y < 2*height() - ORDER/2 - 2</tt>
2</tt>. .
*/ */
bool isValid(double x, double y) const bool isValid(double x, double y) const
{ {
return x < w1_ + x1_ && x > -x1_ && y < h1_ + y1_ && y > -y1_; return x < w1_ + x1_ && x > -x1_ && y < h1_ + y1_ && y > -y1_;
} }
/** Check whether the points <tt>(x0, y0)</tt> and <tt>(x1, y1)</tt > are in /** Check whether the points <tt>(x0, y0)</tt> and <tt>(x1, y1)</tt > are in
the same spline facet. For odd order splines, facets span the r ange the same spline facet. For odd order splines, facets span the r ange
<tt>(floor(x), floor(x)+1) x (floor(y), floor(y)+1)</tt> (i.e. we have <tt>(floor(x), floor(x)+1) x (floor(y), floor(y)+1)</tt> (i.e. we have
integer facet borders), whereas even order splines have facet b etween integer facet borders), whereas even order splines have facet b etween
 End of changes. 13 change blocks. 
17 lines changed or deleted 17 lines changed or added


 splines.hxx   splines.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2004 by Ullrich Koethe */ /* Copyright 1998-2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 55 skipping to change at line 55
#include "array_vector.hxx" #include "array_vector.hxx"
#include "fixedpoint.hxx" #include "fixedpoint.hxx"
namespace vigra { namespace vigra {
/** \addtogroup MathFunctions Mathematical Functions /** \addtogroup MathFunctions Mathematical Functions
*/ */
//@{ //@{
/* B-Splines of arbitrary order and interpolating Catmull/Rom splines. /* B-Splines of arbitrary order and interpolating Catmull/Rom splines.
<b>\#include</b> "<a href="splines_8hxx-source.html">vigra/splines.hxx< /a>"<br> <b>\#include</b> \<<a href="splines_8hxx-source.html">vigra/splines.hxx </a>\><br>
Namespace: vigra Namespace: vigra
*/ */
#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION #ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
/** Basic interface of the spline functors. /** Basic interface of the spline functors.
Implements the spline functions defined by the recursion Implements the spline functions defined by the recursion
\f[ B_0(x) = \left\{ \begin{array}{ll} \f[ B_0(x) = \left\{ \begin{array}{ll}
1 & -\frac{1}{2} \leq x < \frac{1}{2} \\ 1 & -\frac{1}{2} \leq x < \frac{1}{2} \\
skipping to change at line 81 skipping to change at line 81
\f[ B_n(x) = B_0(x) * B_{n-1}(x) \f[ B_n(x) = B_0(x) * B_{n-1}(x)
\f] \f]
where * denotes convolution, and <i>n</i> is the spline order given by the where * denotes convolution, and <i>n</i> is the spline order given by the
template parameter <tt>ORDER</tt>. These spline classes can be used as template parameter <tt>ORDER</tt>. These spline classes can be used as
unary and binary functors, as kernels for \ref resamplingConvolveImage( ), unary and binary functors, as kernels for \ref resamplingConvolveImage( ),
and as arguments for \ref vigra::SplineImageView. Note that the spline order and as arguments for \ref vigra::SplineImageView. Note that the spline order
is given as a template argument. is given as a template argument.
<b>\#include</b> "<a href="splines_8hxx-source.html">vigra/splines.hxx< /a>"<br> <b>\#include</b> \<<a href="splines_8hxx-source.html">vigra/splines.hxx </a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <int ORDER, class T = double> template <int ORDER, class T = double>
class BSplineBase class BSplineBase
{ {
public: public:
/** the value type if used as a kernel in \ref resamplingConvolveIm age(). /** the value type if used as a kernel in \ref resamplingConvolveIm age().
*/ */
typedef T value_type; typedef T value_type;
skipping to change at line 154 skipping to change at line 154
{ return (ORDER + 1) * 0.5; } { return (ORDER + 1) * 0.5; }
/** Get the derivative order of the Gaussian. /** Get the derivative order of the Gaussian.
*/ */
unsigned int derivativeOrder() const unsigned int derivativeOrder() const
{ return s1_.derivativeOrder(); } { return s1_.derivativeOrder(); }
/** Get the prefilter coefficients required for interpolation. /** Get the prefilter coefficients required for interpolation.
To interpolate with a B-spline, \ref resamplingConvolveImage() To interpolate with a B-spline, \ref resamplingConvolveImage()
can be used. However, the image to be interpolated must be can be used. However, the image to be interpolated must be
pre-filtered using \ref recursiveFilterImage() with the filter pre-filtered using \ref recursiveFilterX() and \ref recursiveFi
coefficients given by this function. The length of the array lterY()
corresponds to the number of times \ref recursiveFilterImage() with the filter coefficients given by this function. The length
of the array
corresponds to how many times the above recursive filtering
has to be applied (zero length means no prefiltering necessary) . has to be applied (zero length means no prefiltering necessary) .
*/ */
ArrayVector<double> const & prefilterCoefficients() const ArrayVector<double> const & prefilterCoefficients() const
{ {
static ArrayVector<double> const & b = calculatePrefilterCoefficien ts(); static ArrayVector<double> const & b = calculatePrefilterCoefficien ts();
return b; return b;
} }
static ArrayVector<double> const & calculatePrefilterCoefficients(); static ArrayVector<double> const & calculatePrefilterCoefficients();
skipping to change at line 234 skipping to change at line 234
template <int ORDER, class T> template <int ORDER, class T>
typename BSplineBase<ORDER, T>::WeightMatrix & typename BSplineBase<ORDER, T>::WeightMatrix &
BSplineBase<ORDER, T>::calculateWeightMatrix() BSplineBase<ORDER, T>::calculateWeightMatrix()
{ {
static WeightMatrix b; static WeightMatrix b;
double faculty = 1.0; double faculty = 1.0;
for(int d = 0; d <= ORDER; ++d) for(int d = 0; d <= ORDER; ++d)
{ {
if(d > 1) if(d > 1)
faculty *= d; faculty *= d;
double x = ORDER / 2; double x = ORDER / 2; // (note: integer division)
BSplineBase spline; BSplineBase spline;
for(int i = 0; i <= ORDER; ++i, --x) for(int i = 0; i <= ORDER; ++i, --x)
b[d][i] = spline(x, d) / faculty; b[d][i] = spline(x, d) / faculty;
} }
return b; return b;
} }
/********************************************************/ /********************************************************/
/* */ /* */
/* BSpline<N, T> */ /* BSpline<N, T> */
skipping to change at line 491 skipping to change at line 491
: v < THREE_HALVES : v < THREE_HALVES
? Value((int)(sq((unsigned)(THREE_HALVES-v) >> PREMULTIPLY_SHIFT1) >> (POSTMULTIPLY_SHIFT1 + 1)), FPNoShift) ? Value((int)(sq((unsigned)(THREE_HALVES-v) >> PREMULTIPLY_SHIFT1) >> (POSTMULTIPLY_SHIFT1 + 1)), FPNoShift)
: Value(0, FPNoShift); : Value(0, FPNoShift);
} }
result_type operator()(first_argument_type x, second_argument_type deri vative_order) const result_type operator()(first_argument_type x, second_argument_type deri vative_order) const
{ {
return exec(x, derivativeOrder_ + derivative_order); return exec(x, derivativeOrder_ + derivative_order);
} }
result_type dx(argument_type x) const
{ return operator()(x, 1); }
value_type operator[](value_type x) const value_type operator[](value_type x) const
{ return operator()(x); } { return operator()(x); }
double radius() const double radius() const
{ return 1.5; } { return 1.5; }
unsigned int derivativeOrder() const unsigned int derivativeOrder() const
{ return derivativeOrder_; } { return derivativeOrder_; }
ArrayVector<double> const & prefilterCoefficients() const ArrayVector<double> const & prefilterCoefficients() const
skipping to change at line 719 skipping to change at line 722
} }
default: default:
return 0.0; return 0.0;
} }
} }
typedef BSpline<3, double> CubicBSplineKernel; typedef BSpline<3, double> CubicBSplineKernel;
/********************************************************/ /********************************************************/
/* */ /* */
/* BSpline<4, T> */
/* */
/********************************************************/
template <class T>
class BSpline<4, T>
{
public:
typedef T value_type;
typedef T argument_type;
typedef T first_argument_type;
typedef unsigned int second_argument_type;
typedef T result_type;
enum StaticOrder { order = 4 };
explicit BSpline(unsigned int derivativeOrder = 0)
: derivativeOrder_(derivativeOrder)
{}
result_type operator()(argument_type x) const
{
return exec(x, derivativeOrder_);
}
result_type operator()(first_argument_type x, second_argument_type deri
vative_order) const
{
return exec(x, derivativeOrder_ + derivative_order);
}
result_type dx(argument_type x) const
{ return operator()(x, 1); }
result_type dxx(argument_type x) const
{ return operator()(x, 2); }
result_type dx3(argument_type x) const
{ return operator()(x, 3); }
value_type operator[](value_type x) const
{ return operator()(x); }
double radius() const
{ return 2.5; }
unsigned int derivativeOrder() const
{ return derivativeOrder_; }
ArrayVector<double> const & prefilterCoefficients() const
{
static ArrayVector<double> const & b = initPrefilterCoefficients();
return b;
}
static ArrayVector<double> const & initPrefilterCoefficients()
{
static ArrayVector<double> b(2);
// -19 + 4*sqrt(19) + 2*sqrt(2*(83 - 19*sqrt(19)))
b[0] = -0.361341225900220177092212841325;
// -19 - 4*sqrt(19) + 2*sqrt(2*(83 + 19*sqrt(19)))
b[1] = -0.013725429297339121360331226939;
return b;
}
typedef T WeightMatrix[5][5];
static WeightMatrix & weights()
{
static T b[5][5] = {{ 1.0/384.0, 19.0/96.0, 115.0/192.0, 19.0/96.0,
1.0/384.0},
{-1.0/48.0, -11.0/24.0, 0.0, 11.0/24.0, 1.0/48.
0},
{ 1.0/16.0, 1.0/4.0, -5.0/8.0, 1.0/4.0, 1.0/16.
0},
{-1.0/12.0, 1.0/6.0, 0.0, -1.0/6.0, 1.0/12.0},
{ 1.0/24.0, -1.0/6.0, 0.25, -1.0/6.0, 1.0/24.0}
};
return b;
}
protected:
result_type exec(first_argument_type x, second_argument_type derivative
_order) const;
unsigned int derivativeOrder_;
};
template <class T>
typename BSpline<4, T>::result_type
BSpline<4, T>::exec(first_argument_type x, second_argument_type derivative_
order) const
{
switch(derivative_order)
{
case 0:
{
x = VIGRA_CSTD::fabs(x);
if(x <= 0.5)
{
return 115.0/192.0 + x*x*(-0.625 + x*x*0.25);
}
else if(x < 1.5)
{
return (55.0/16.0 + x*(1.25 + x*(-7.5 + x*(5.0 - x)))) / 6.
0;
}
else if(x < 2.5)
{
x = 2.5 - x;
return sq(x*x) / 24.0;
}
else
return 0.0;
}
case 1:
{
double s = x < 0.0 ?
-1.0 :
1.0;
x = VIGRA_CSTD::fabs(x);
if(x <= 0.5)
{
return s*x*(-1.25 + x*x);
}
else if(x < 1.5)
{
return s*(5.0 + x*(-60.0 + x*(60.0 - 16.0*x))) / 24.0;
}
else if(x < 2.5)
{
x = 2.5 - x;
return s*x*x*x / -6.0;
}
else
return 0.0;
}
case 2:
{
x = VIGRA_CSTD::fabs(x);
if(x <= 0.5)
{
return -1.25 + 3.0*x*x;
}
else if(x < 1.5)
{
return -2.5 + x*(5.0 - 2.0*x);
}
else if(x < 2.5)
{
x = 2.5 - x;
return x*x / 2.0;
}
else
return 0.0;
}
case 3:
{
double s = x < 0.0 ?
-1.0 :
1.0;
x = VIGRA_CSTD::fabs(x);
if(x <= 0.5)
{
return s*x*6.0;
}
else if(x < 1.5)
{
return s*(5.0 - 4.0*x);
}
else if(x < 2.5)
{
return s*(x - 2.5);
}
else
return 0.0;
}
case 4:
{
return x < 0.0
? x < -2.5
? 0.0
: x < -1.5
? 1.0
: x < -0.5
? -4.0
: 6.0
: x < 0.5
? 6.0
: x < 1.5
? -4.0
: x < 2.5
? 1.0
: 0.0;
}
default:
return 0.0;
}
}
typedef BSpline<4, double> QuarticBSplineKernel;
/********************************************************/
/* */
/* BSpline<5, T> */ /* BSpline<5, T> */
/* */ /* */
/********************************************************/ /********************************************************/
template <class T> template <class T>
class BSpline<5, T> class BSpline<5, T>
{ {
public: public:
typedef T value_type; typedef T value_type;
skipping to change at line 779 skipping to change at line 977
ArrayVector<double> const & prefilterCoefficients() const ArrayVector<double> const & prefilterCoefficients() const
{ {
static ArrayVector<double> const & b = initPrefilterCoefficients(); static ArrayVector<double> const & b = initPrefilterCoefficients();
return b; return b;
} }
static ArrayVector<double> const & initPrefilterCoefficients() static ArrayVector<double> const & initPrefilterCoefficients()
{ {
static ArrayVector<double> b(2); static ArrayVector<double> b(2);
b[0] = -0.43057534709997114; // -(13/2) + sqrt(105)/2 + sqrt(1/2*((135 - 13*sqrt(105))))
b[1] = -0.043096288203264652; b[0] = -0.430575347099973791851434783493;
// (1/2)*((-13) - sqrt(105) + sqrt(2*((135 + 13*sqrt(105)))))
b[1] = -0.043096288203264653822712376822;
return b; return b;
} }
typedef T WeightMatrix[6][6]; typedef T WeightMatrix[6][6];
static WeightMatrix & weights() static WeightMatrix & weights()
{ {
static T b[6][6] = {{ 1.0/120.0, 13.0/60.0, 11.0/20.0, 13.0/60.0, 1 .0/120.0, 0.0}, static T b[6][6] = {{ 1.0/120.0, 13.0/60.0, 11.0/20.0, 13.0/60.0, 1 .0/120.0, 0.0},
{-1.0/24.0, -5.0/12.0, 0.0, 5.0/12.0, 1.0/24.0, 0.0}, {-1.0/24.0, -5.0/12.0, 0.0, 5.0/12.0, 1.0/24.0, 0.0},
{ 1.0/12.0, 1.0/6.0, -0.5, 1.0/6.0, 1.0/12.0, 0 .0}, { 1.0/12.0, 1.0/6.0, -0.5, 1.0/6.0, 1.0/12.0, 0 .0},
{-1.0/12.0, 1.0/6.0, 0.0, -1.0/6.0, 1.0/12.0, 0 .0}, {-1.0/12.0, 1.0/6.0, 0.0, -1.0/6.0, 1.0/12.0, 0 .0},
skipping to change at line 958 skipping to change at line 1158
0 & \mbox{otherwise} 0 & \mbox{otherwise}
\end{array}\right. \end{array}\right.
\f] \f]
It can be used as a functor, and as a kernel for It can be used as a functor, and as a kernel for
\ref resamplingConvolveImage() to create a differentiable interpolant \ref resamplingConvolveImage() to create a differentiable interpolant
of an image. However, it should be noted that a twice differentiable of an image. However, it should be noted that a twice differentiable
interpolant can be created with only slightly more effort by recursive interpolant can be created with only slightly more effort by recursive
prefiltering followed by convolution with a 3rd order B-spline. prefiltering followed by convolution with a 3rd order B-spline.
<b>\#include</b> "<a href="splines_8hxx-source.html">vigra/splines.hxx< /a>"<br> <b>\#include</b> \<<a href="splines_8hxx-source.html">vigra/splines.hxx </a>\><br>
Namespace: vigra Namespace: vigra
*/ */
template <class T = double> template <class T = double>
class CatmullRomSpline class CatmullRomSpline
{ {
public: public:
/** the kernel's value type /** the kernel's value type
*/ */
typedef T value_type; typedef T value_type;
/** the unary functor's argument type /** the unary functor's argument type
 End of changes. 10 change blocks. 
12 lines changed or deleted 222 lines changed or added


 static_assert.hxx   static_assert.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2004-2005 by Ullrich Koethe */ /* Copyright 2004-2005 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
 End of changes. 2 change blocks. 
3 lines changed or deleted 3 lines changed or added


 stdconvolution.hxx   stdconvolution.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 371 skipping to change at line 371
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
void convolveImage(SrcIterator src_ul, SrcIterator src_lr, SrcAcces sor src_acc, void convolveImage(SrcIterator src_ul, SrcIterator src_lr, SrcAcces sor src_acc,
DestIterator dest_ul, DestAccessor dest_acc, DestIterator dest_ul, DestAccessor dest_acc,
KernelIterator ki, KernelAccessor ak, KernelIterator ki, KernelAccessor ak,
Diff2D kul, Diff2D klr, BorderTreatmentMode bord er); Diff2D kul, Diff2D klr, BorderTreatmentMode bord er);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
void convolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> sr c, void convolveImage(triple<SrcIterator, SrcIterator, SrcAccessor> sr c,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
tuple5<KernelIterator, KernelAccessor, Diff2D, D iff2D, tuple5<KernelIterator, KernelAccessor, Diff2D, D iff2D,
BorderTreatmentMode> kernel); BorderTreatmentMode> kernel);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="stdconvolution_8hxx-source.html">vigra/stdco nvolution.hxx</a>"<br> <b>\#include</b> \<<a href="stdconvolution_8hxx-source.html">vigra/stdc onvolution.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
// define horizontal Sobel filter // define horizontal Sobel filter
vigra::Kernel2D<float> sobel; vigra::Kernel2D<float> sobel;
sobel.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) = // upper left and l ower right sobel.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) = // upper left and l ower right
0.125, 0.0, -0.125, 0.125, 0.0, -0.125,
0.25, 0.0, -0.25, 0.25, 0.0, -0.25,
0.125, 0.0, -0.125; 0.125, 0.0, -0.125;
sobel.setBorderTreatment(vigra::BORDER_TREATMENT_REFLECT);
vigra::convolveImage(srcImageRange(src), destImage(dest), kernel2d(sobe l)); vigra::convolveImage(srcImageRange(src), destImage(dest), kernel2d(sobe l));
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
\code \code
ImageIterator src_ul, src_lr; ImageIterator src_ul, src_lr;
ImageIterator dest_ul; ImageIterator dest_ul;
ImageIterator ik; ImageIterator ik;
skipping to change at line 721 skipping to change at line 722
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
void void
normalizedConvolveImage(SrcIterator src_ul, SrcIterator src_lr, Src Accessor src_acc, normalizedConvolveImage(SrcIterator src_ul, SrcIterator src_lr, Src Accessor src_acc,
MaskIterator mul, MaskAccessor am, MaskIterator mul, MaskAccessor am,
DestIterator dest_ul, DestAccessor dest_acc , DestIterator dest_ul, DestAccessor dest_acc ,
KernelIterator ki, KernelAccessor ak, KernelIterator ki, KernelAccessor ak,
Diff2D kul, Diff2D klr, BorderTreatmentMode border); Diff2D kul, Diff2D klr, BorderTreatmentMode border);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
inline
void normalizedConvolveImage(triple<SrcIterator, SrcIterator, SrcAc cessor> src, void normalizedConvolveImage(triple<SrcIterator, SrcIterator, SrcAc cessor> src,
pair<MaskIterator, MaskAccessor> mask, pair<MaskIterator, MaskAccessor> mask,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
tuple5<KernelIterator, KernelAccessor, Diff2D, Diff2D, tuple5<KernelIterator, KernelAccessor, Diff2D, Diff2D,
BorderTreatmentMode> kernel); BorderTreatmentMode> kernel);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="stdconvolution_8hxx-source.html">vigra/stdco nvolution.hxx</a>"<br> <b>\#include</b> \<<a href="stdconvolution_8hxx-source.html">vigra/stdc onvolution.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
vigra::CImage mask(w,h); vigra::CImage mask(w,h);
... ...
// define 3x3 binomial filter // define 3x3 binomial filter
vigra::Kernel2D<float> binom; vigra::Kernel2D<float> binom;
skipping to change at line 805 skipping to change at line 805
klr.x >= 0 klr.x >= 0
klr.y >= 0 klr.y >= 0
src_lr.x - src_ul.x >= klr.x + kul.x + 1 src_lr.x - src_ul.x >= klr.x + kul.x + 1
src_lr.y - src_ul.y >= klr.y + kul.y + 1 src_lr.y - src_ul.y >= klr.y + kul.y + 1
border == BORDER_TREATMENT_CLIP || border == BORDER_TREATMENT_AVOID border == BORDER_TREATMENT_CLIP || border == BORDER_TREATMENT_AVOID
\endcode \endcode
Sum of kernel elements must be != 0. Sum of kernel elements must be != 0.
*/ */
doxygen_overloaded_function(template <...> void normalizedConvolveImage)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
void void
normalizedConvolveImage(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc, normalizedConvolveImage(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor src_acc,
MaskIterator mul, MaskAccessor am, MaskIterator mul, MaskAccessor am,
DestIterator dest_ul, DestAccessor dest_acc, DestIterator dest_ul, DestAccessor dest_acc,
KernelIterator ki, KernelAccessor ak, KernelIterator ki, KernelAccessor ak,
Diff2D kul, Diff2D klr, BorderTreatmentMode border) Diff2D kul, Diff2D klr, BorderTreatmentMode border)
skipping to change at line 901 skipping to change at line 903
int xx, kernel_width, kernel_height; int xx, kernel_width, kernel_height;
kernel_width = x1 - x0 + 1; kernel_width = x1 - x0 + 1;
kernel_height = y1 - y0 + 1; kernel_height = y1 - y0 + 1;
for(yy=0; yy<kernel_height; ++yy, ++yys.y, --yk.y, ++yym.y) for(yy=0; yy<kernel_height; ++yy, ++yys.y, --yk.y, ++yym.y)
{ {
typename SrcIterator::row_iterator xxs = yys.rowIterator(); typename SrcIterator::row_iterator xxs = yys.rowIterator();
typename SrcIterator::row_iterator xxend = xxs + kernel_wid th; typename SrcIterator::row_iterator xxend = xxs + kernel_wid th;
typename MaskIterator::row_iterator xxm = yym.rowIterator() ; typename MaskIterator::row_iterator xxm = yym.rowIterator() ;
typename KernelIterator::row_iterator xk = yk.rowIterator( ); typename KernelIterator::row_iterator xk = yk.rowIterator( );
for(xx=0; xxs < xxend; ++xxs.x, --xk.x, ++xxm.x) for(xx=0; xxs < xxend; ++xxs, --xk, ++xxm)
{ {
if(!am(xxm)) continue; if(!am(xxm)) continue;
if(first) if(first)
{ {
sum = ak(xk) * src_acc(xxs); sum = ak(xk) * src_acc(xxs);
ksum = ak(xk); ksum = ak(xk);
first = false; first = false;
} }
else else
skipping to change at line 969 skipping to change at line 971
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
void void
convolveImageWithMask(SrcIterator src_ul, SrcIterator src_lr, SrcAc cessor src_acc, convolveImageWithMask(SrcIterator src_ul, SrcIterator src_lr, SrcAc cessor src_acc,
MaskIterator mul, MaskAccessor am, MaskIterator mul, MaskAccessor am,
DestIterator dest_ul, DestAccessor dest_acc, DestIterator dest_ul, DestAccessor dest_acc,
KernelIterator ki, KernelAccessor ak, KernelIterator ki, KernelAccessor ak,
Diff2D kul, Diff2D klr, BorderTreatmentMode b order); Diff2D kul, Diff2D klr, BorderTreatmentMode b order);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
inline
void convolveImageWithMask(triple<SrcIterator, SrcIterator, SrcAcce ssor> src, void convolveImageWithMask(triple<SrcIterator, SrcIterator, SrcAcce ssor> src,
pair<MaskIterator, MaskAccessor> mask, pair<MaskIterator, MaskAccessor> mask,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
tuple5<KernelIterator, KernelAccessor, D iff2D, Diff2D, tuple5<KernelIterator, KernelAccessor, D iff2D, Diff2D,
BorderTreatmentMode> kernel); BorderTreatmentMode> kernel);
} }
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void convolveImageWithMask)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class MaskIterator, class MaskAccessor, class MaskIterator, class MaskAccessor,
class KernelIterator, class KernelAccessor> class KernelIterator, class KernelAccessor>
inline void inline void
convolveImageWithMask(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor s rc_acc, convolveImageWithMask(SrcIterator src_ul, SrcIterator src_lr, SrcAccessor s rc_acc,
MaskIterator mul, MaskAccessor am, MaskIterator mul, MaskAccessor am,
DestIterator dest_ul, DestAccessor dest_acc, DestIterator dest_ul, DestAccessor dest_acc,
KernelIterator ki, KernelAccessor ak, KernelIterator ki, KernelAccessor ak,
Diff2D kul, Diff2D klr, BorderTreatmentMode border) Diff2D kul, Diff2D klr, BorderTreatmentMode border)
skipping to change at line 1051 skipping to change at line 1054
The different init functions create a kernel with the specified The different init functions create a kernel with the specified
properties. The requirements for the kernel's value_type depend properties. The requirements for the kernel's value_type depend
on the init function used. At least NumericTraits must be defined. on the init function used. At least NumericTraits must be defined.
The kernel defines a factory function kernel2d() to create an argument object The kernel defines a factory function kernel2d() to create an argument object
(see \ref KernelArgumentObjectFactories). (see \ref KernelArgumentObjectFactories).
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="stdconvolution_8hxx-source.html">vigra/stdco nvolution.hxx</a>"<br> <b>\#include</b> \<<a href="stdconvolution_8hxx-source.html">vigra/stdc onvolution.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::FImage src(w,h), dest(w,h); vigra::FImage src(w,h), dest(w,h);
... ...
// define horizontal Sobel filter // define horizontal Sobel filter
vigra::Kernel2D<float> sobel; vigra::Kernel2D<float> sobel;
sobel.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) = // upper left and l ower right sobel.initExplicitly(Diff2D(-1,-1), Diff2D(1,1)) = // upper left and l ower right
 End of changes. 14 change blocks. 
12 lines changed or deleted 15 lines changed or added


 stdimage.hxx   stdimage.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 60 skipping to change at line 60
/** \addtogroup StandardImageTypes Standard Image Types /** \addtogroup StandardImageTypes Standard Image Types
\brief The most common instantiations of the \ref vigra::BasicImage tem plate \brief The most common instantiations of the \ref vigra::BasicImage tem plate
*/ */
//@{ //@{
/** Byte (8-bit unsigned) image. /** Byte (8-bit unsigned) image.
It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<UInt8> BImage; typedef BasicImage<UInt8> BImage;
/** Byte (8-bit unsigned) image. /** Byte (8-bit unsigned) image.
It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<UInt8> UInt8Image; typedef BasicImage<UInt8> UInt8Image;
/** Signed byte (8-bit signed) image. /** Signed byte (8-bit signed) image.
It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<Int8> Int8Image; typedef BasicImage<Int8> Int8Image;
/** Short integer (16-bit signed) image. /** Short integer (16-bit signed) image.
It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<Int16> SImage; typedef BasicImage<Int16> SImage;
/** Short integer (16-bit unsigned) image. /** Short integer (16-bit unsigned) image.
It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<UInt16> UInt16Image; typedef BasicImage<UInt16> UInt16Image;
/** Short integer (16-bit signed) image. /** Short integer (16-bit signed) image.
It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<Int16> Int16Image; typedef BasicImage<Int16> Int16Image;
/** Integer (32-bit signed) image. /** Integer (32-bit signed) image.
It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<Int32> IImage; typedef BasicImage<Int32> IImage;
/** Integer (32-bit unsigned) image. /** Integer (32-bit unsigned) image.
It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<UInt32> UInt32Image; typedef BasicImage<UInt32> UInt32Image;
/** Integer (32-bit signed) image. /** Integer (32-bit signed) image.
It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<Int32> Int32Image; typedef BasicImage<Int32> Int32Image;
/** Float (float) image. /** Float (float) image.
It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<float> FImage; typedef BasicImage<float> FImage;
/** Double (double) image. /** Double (double) image.
It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and It uses \ref vigra::BasicImageIterator and \ref vigra::StandardAcce ssor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimage .hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<double> DImage; typedef BasicImage<double> DImage;
/** Byte (3x 8-bit unsigned) RGB image. /** Byte (3x 8-bit unsigned) RGB image.
The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::UInt 8>". The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::UInt 8>".
It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<RGBValue<UInt8> > BRGBImage; typedef BasicImage<RGBValue<UInt8> > BRGBImage;
/** Byte (3x 8-bit unsigned) RGB image. /** Byte (3x 8-bit unsigned) RGB image.
The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::UInt 8>". The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::UInt 8>".
It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<RGBValue<UInt8> > UInt8RGBImage; typedef BasicImage<RGBValue<UInt8> > UInt8RGBImage;
/** Byte (3x 8-bit signed) RGB image. /** Byte (3x 8-bit signed) RGB image.
The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::UInt 8>". The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::UInt 8>".
It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<RGBValue<Int8> > Int8RGBImage; typedef BasicImage<RGBValue<Int8> > Int8RGBImage;
/** Short (3x 16-bit signed) RGB image. /** Short (3x 16-bit signed) RGB image.
The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int1 6>". The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int1 6>".
It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<RGBValue<Int16> > SRGBImage; typedef BasicImage<RGBValue<Int16> > SRGBImage;
/** Short (3x 16-bit unsigned) RGB image. /** Short (3x 16-bit unsigned) RGB image.
The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int1 6>". The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int1 6>".
It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<RGBValue<UInt16> > UInt16RGBImage; typedef BasicImage<RGBValue<UInt16> > UInt16RGBImage;
/** Short (3x 16-bit signed) RGB image. /** Short (3x 16-bit signed) RGB image.
The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int1 6>". The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int1 6>".
It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<RGBValue<Int16> > Int16RGBImage; typedef BasicImage<RGBValue<Int16> > Int16RGBImage;
/** Integer (3x 32-bit signed) RGB image. /** Integer (3x 32-bit signed) RGB image.
The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int3 2>". The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int3 2>".
It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<RGBValue<Int32> > IRGBImage; typedef BasicImage<RGBValue<Int32> > IRGBImage;
/** Integer (3x 32-bit unsigned) RGB image. /** Integer (3x 32-bit unsigned) RGB image.
The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int3 2>". The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int3 2>".
It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<RGBValue<UInt32> > UInt32RGBImage; typedef BasicImage<RGBValue<UInt32> > UInt32RGBImage;
/** Integer (3x 32-bit signed) RGB image. /** Integer (3x 32-bit signed) RGB image.
The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int3 2>". The pixel type is \ref vigra::RGBValue "vigra::RGBValue<vigra::Int3 2>".
It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<RGBValue<Int32> > Int32RGBImage; typedef BasicImage<RGBValue<Int32> > Int32RGBImage;
/** Floating-point (3x float) RGB image. /** Floating-point (3x float) RGB image.
The pixel type is \ref vigra::RGBValue "vigra::RGBValue<float>". The pixel type is \ref vigra::RGBValue "vigra::RGBValue<float>".
It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<RGBValue<float> > FRGBImage; typedef BasicImage<RGBValue<float> > FRGBImage;
/** Double-precision floating-point (3x double) RGB image. /** Double-precision floating-point (3x double) RGB image.
The pixel type is \ref vigra::RGBValue "vigra::RGBValue<double>". The pixel type is \ref vigra::RGBValue "vigra::RGBValue<double>".
It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and It uses \ref vigra::BasicImageIterator and \ref vigra::RGBAccessor and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<RGBValue<double> > DRGBImage; typedef BasicImage<RGBValue<double> > DRGBImage;
/** Floating-point TinyVector image. /** Floating-point TinyVector image.
The pixel type is \ref vigra::TinyVector "vigra::TinyVector<float, 2>". The pixel type is \ref vigra::TinyVector "vigra::TinyVector<float, 2>".
It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess or and It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess or and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<TinyVector<float, 2> > FVector2Image; typedef BasicImage<TinyVector<float, 2> > FVector2Image;
/** Floating-point TinyVector image. /** Floating-point TinyVector image.
The pixel type is \ref vigra::TinyVector "vigra::TinyVector<float, 3>". The pixel type is \ref vigra::TinyVector "vigra::TinyVector<float, 3>".
It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess or and It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess or and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<TinyVector<float, 3> > FVector3Image; typedef BasicImage<TinyVector<float, 3> > FVector3Image;
/** Floating-point TinyVector image. /** Floating-point TinyVector image.
The pixel type is \ref vigra::TinyVector "vigra::TinyVector<float, 4>". The pixel type is \ref vigra::TinyVector "vigra::TinyVector<float, 4>".
It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess or and It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess or and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<TinyVector<float, 4> > FVector4Image; typedef BasicImage<TinyVector<float, 4> > FVector4Image;
/** Floating-point TinyVector image. /** Floating-point TinyVector image.
The pixel type is \ref vigra::TinyVector "vigra::TinyVector<double, 2>". The pixel type is \ref vigra::TinyVector "vigra::TinyVector<double, 2>".
It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess or and It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess or and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<TinyVector<double, 2> > DVector2Image; typedef BasicImage<TinyVector<double, 2> > DVector2Image;
/** Floating-point TinyVector image. /** Floating-point TinyVector image.
The pixel type is \ref vigra::TinyVector "vigra::TinyVector<double, 3>". The pixel type is \ref vigra::TinyVector "vigra::TinyVector<double, 3>".
It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess or and It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess or and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
//typedef BasicImage<TinyVector<double, 3> > DVector3Image; //typedef BasicImage<TinyVector<double, 3> > DVector3Image;
typedef BasicImage<TinyVector<double, 3> > DVector3Image; typedef BasicImage<TinyVector<double, 3> > DVector3Image;
/** Floating-point TinyVector image. /** Floating-point TinyVector image.
The pixel type is \ref vigra::TinyVector "vigra::TinyVector<double, 4>". The pixel type is \ref vigra::TinyVector "vigra::TinyVector<double, 4>".
It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess or and It uses \ref vigra::BasicImageIterator and \ref vigra::VectorAccess or and
their const counterparts to access the data. their const counterparts to access the data.
<b>\#include</b> "<a href="stdimage_8hxx-source.html">vigra/stdimag e.hxx</a>"<br> <b>\#include</b> \<<a href="stdimage_8hxx-source.html">vigra/stdima ge.hxx</a>\><br>
Namespace: vigra Namespace: vigra
*/ */
typedef BasicImage<TinyVector<double, 4> > DVector4Image; typedef BasicImage<TinyVector<double, 4> > DVector4Image;
//@} //@}
} // namespace vigra } // namespace vigra
#endif // VIGRA_STDIMAGE_HXX #endif // VIGRA_STDIMAGE_HXX
 End of changes. 30 change blocks. 
31 lines changed or deleted 31 lines changed or added


 stdimagefunctions.hxx   stdimagefunctions.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 43 skipping to change at line 43
/* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */ /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
/* OTHER DEALINGS IN THE SOFTWARE. */ /* OTHER DEALINGS IN THE SOFTWARE. */
/* */ /* */
/************************************************************************/ /************************************************************************/
#ifndef VIGRA_STDIMAGEFUNCTIONS_HXX #ifndef VIGRA_STDIMAGEFUNCTIONS_HXX
#define VIGRA_STDIMAGEFUNCTIONS_HXX #define VIGRA_STDIMAGEFUNCTIONS_HXX
/** \page PointOperators Point Operators /** \page PointOperators Point Operators
<DL> <UL style="list-style-image:url(documents/bullet.gif)">
<DT> <LI> \ref InitAlgo
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <BR>&nbsp;&nbsp;&nbsp; <em>init images or image borders </em>
\ref InitAlgo <LI> \ref InspectAlgo
<DD><em>init images or image borders </em> <BR>&nbsp;&nbsp;&nbsp; <em>Apply read-only functor to every pixel<
<DT> /em>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref InspectFunctor
\ref InspectAlgo <BR>&nbsp;&nbsp;&nbsp; <em>Functors which report image statistics<
<DD> <em>Apply read-only functor to every pixel</em> /em>
<DT> <LI> \ref CopyAlgo
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <BR>&nbsp;&nbsp;&nbsp; <em>Copy images or regions</em>
\ref InspectFunctor <LI> \ref TransformAlgo
<DD><em>Functors which report image statistics</em> <BR>&nbsp;&nbsp;&nbsp; <em>apply functor to calculate a pixelwise
<DT> transformation of one image</em>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref TransformFunctor
\ref CopyAlgo <BR>&nbsp;&nbsp;&nbsp; <em>frequently used unary transformation fu
<DD> <em>Copy images or regions</em> nctors</em>
<DT> <LI> \ref CombineAlgo
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <BR>&nbsp;&nbsp;&nbsp; <em>apply functor to calculate a pixelwise
\ref TransformAlgo transformation from several image</em>
<DD><em>apply functor to calculate a pixelwise transformation of on <LI> \ref CombineFunctor
e image</em> <BR>&nbsp;&nbsp;&nbsp; <em>frequently used binary transformations
<DT> functors</em>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref MultiPointoperators
\ref TransformFunctor <BR>&nbsp;&nbsp;&nbsp; <em>Point operators on multi-dimensional ar
<DD> <em>frequently used unary transformation functors</em> rays</em>
<DT> </UL>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref CombineAlgo
<DD><em>apply functor to calculate a pixelwise transformation from
several image</em>
<DT>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref CombineFunctor
<DD> <em>frequently used binary transformations functors</em>
<DT>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref MultiPointoperators
<DD> <em>Point operators on multi-dimensional arrays</em>
</DL>
<b>\#include</b> "<a href="stdimagefunctions_8hxx-source.html">vigra/st dimagefunctions.hxx</a>"<br> <b>\#include</b> \<<a href="stdimagefunctions_8hxx-source.html">vigra/s tdimagefunctions.hxx</a>\><br>
Namespace: vigra Namespace: vigra
see also: \ref FunctorExpressions "Automatic Functor Creation" see also: \ref FunctorExpressions "Automatic Functor Creation"
*/ */
#include "initimage.hxx" #include "initimage.hxx"
#include "inspectimage.hxx" #include "inspectimage.hxx"
#include "copyimage.hxx" #include "copyimage.hxx"
#include "transformimage.hxx" #include "transformimage.hxx"
#include "combineimages.hxx" #include "combineimages.hxx"
 End of changes. 4 change blocks. 
44 lines changed or deleted 31 lines changed or added


 symmetry.hxx   symmetry.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 78 skipping to change at line 78
at <tt>0.25*scale</TT> (these values are recommendations from the paper ). at <tt>0.25*scale</TT> (these values are recommendations from the paper ).
Loy and Zelinsky additionally propose to add the operator response from several Loy and Zelinsky additionally propose to add the operator response from several
scales (see usage example below). scales (see usage example below).
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
radialSymmetryTransform(SrcIterator sul, SrcIterator slr, SrcAccess or as, radialSymmetryTransform(SrcIterator sul, SrcIterator slr, SrcAccess or as,
DestIterator dul, DestAccessor ad, DestIterator dul, DestAccessor a
double scale) d,
double scale)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
inline inline
void radialSymmetryTransform( void radialSymmetryTransform(
triple<SrcIterator, SrcIterator, SrcAccessor> src, triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
double scale) double scale)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="symmetry_8hxx-source.html">vigra/symmetr y.hxx</a>"<br> <b>\#include</b> \<<a href="symmetry_8hxx-source.html">vigra/symmet ry.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(w,h), centers(w,h); vigra::BImage src(w,h), centers(w,h);
vigra::FImage symmetry(w,h); vigra::FImage symmetry(w,h);
// empty result image // empty result image
centers.init(128); centers.init(128);
symmetry.init(0.0); symmetry.init(0.0);
skipping to change at line 143 skipping to change at line 143
SrcAccessor src_accessor; SrcAccessor src_accessor;
DestAccessor dest_accessor; DestAccessor dest_accessor;
// SrcAccessor::value_type must be a built-in type // SrcAccessor::value_type must be a built-in type
SrcAccessor::value_type u = src_accessor(src_upperleft); SrcAccessor::value_type u = src_accessor(src_upperleft);
dest_accessor.set(u, dest_upperleft); dest_accessor.set(u, dest_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void radialSymmetryTransform)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void void
radialSymmetryTransform(SrcIterator sul, SrcIterator slr, SrcAccessor as, radialSymmetryTransform(SrcIterator sul, SrcIterator slr, SrcAccessor as,
DestIterator dul, DestAccessor ad, DestIterator dul, DestAccessor ad,
double scale) double scale)
{ {
vigra_precondition(scale > 0.0, vigra_precondition(scale > 0.0,
"radialSymmetryTransform(): Scale must be > 0"); "radialSymmetryTransform(): Scale must be > 0");
 End of changes. 8 change blocks. 
9 lines changed or deleted 12 lines changed or added


 tensorutilities.hxx   tensorutilities.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 2002-2004 by Ullrich Koethe */ /* Copyright 2002-2004 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 76 skipping to change at line 76
e.g. a gradient filter, because <tt>y</tt> runs from top to bottom) e.g. a gradient filter, because <tt>y</tt> runs from top to bottom)
into a right handed tensor (as is required by all tensor function in VI GRA). This into a right handed tensor (as is required by all tensor function in VI GRA). This
behavior can be switched off by setting <tt>negateComponent2 = false</t t>. behavior can be switched off by setting <tt>negateComponent2 = false</t t>.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void vectorToTensor(SrcIterator sul, SrcIterator slr, SrcAccessor s rc, void vectorToTensor(SrcIterator sul, SrcIterator slr, SrcAccessor s rc,
DestIterator dul, DestAccessor dest, DestIterator dul, DestAccessor dest,
bool negateComponent2 = true); bool negateComponent2 = true);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void vectorToTensor(triple<SrcIterator, SrcIterator, SrcAccessor> s , void vectorToTensor(triple<SrcIterator, SrcIterator, SrcAccessor> s ,
pair<DestIterator, DestAccessor> d, pair<DestIterator, DestAccessor> d,
bool negateComponent2 = true); bool negateComponent2 = true);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="tensorutilities_8hxx-source.html">vigra/tens orutilities.hxx</a>" <b>\#include</b> \<<a href="tensorutilities_8hxx-source.html">vigra/ten sorutilities.hxx</a>\>
\code \code
FImage img(w,h); FImage img(w,h);
FVector2Image gradient(w,h); FVector2Image gradient(w,h);
FVector3Image tensor(w,h); FVector3Image tensor(w,h);
gaussianGradient(srcImageRange(img), destImage(gradient), 2.0); gaussianGradient(srcImageRange(img), destImage(gradient), 2.0);
vectorToTensor(srcImageRange(gradient), destImage(tensor)); vectorToTensor(srcImageRange(gradient), destImage(tensor));
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void vectorToTensor)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void vectorToTensor(SrcIterator sul, SrcIterator slr, SrcAccessor src, void vectorToTensor(SrcIterator sul, SrcIterator slr, SrcAccessor src,
DestIterator dul, DestAccessor dest, DestIterator dul, DestAccessor dest,
bool negateComponent2) bool negateComponent2)
{ {
vigra_precondition(src.size(sul) == 2, vigra_precondition(src.size(sul) == 2,
"vectorToTensor(): input image must have 2 bands."); "vectorToTensor(): input image must have 2 bands.");
vigra_precondition(dest.size(dul) == 3, vigra_precondition(dest.size(dul) == 3,
"vectorToTensor(): output image must have 3 bands.") ; "vectorToTensor(): output image must have 3 bands.") ;
skipping to change at line 187 skipping to change at line 189
/********************************************************/ /********************************************************/
/* */ /* */
/* tensorEigenRepresentation */ /* tensorEigenRepresentation */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Calculate eigen representation of a symmetric 2x2 tensor. /** \brief Calculate eigen representation of a symmetric 2x2 tensor.
This function turns a 3-band image representing the tensor components This function turns a 3-band image representing the tensor components
t11, t12 (== t21 due to symmetry), t22 into the a 3-band image holding the eigen t11, t12 (== t21 due to symmetry), t22 into the a 3-band image holding the eigen
representation e1, e2, and angle, where e1 &gt; e2. The original tensor must be representation e1, e2, and angle, where e1 \> e2. The original tensor m ust be
defined in a right-handed coordinate system, and the angle of the tenso r will defined in a right-handed coordinate system, and the angle of the tenso r will
then be given in mathematical positive (counter-clockwise) orientation, starting then be given in mathematical positive (counter-clockwise) orientation, starting
at the x-axis. at the x-axis.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void tensorEigenRepresentation(SrcIterator sul, SrcIterator slr, Sr cAccessor src, void tensorEigenRepresentation(SrcIterator sul, SrcIterator slr, Sr cAccessor src,
DestIterator dul, DestAccessor dest) ; DestIterator dul, DestAccessor dest) ;
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void tensorEigenRepresentation(triple<SrcIterator, SrcIterator, Src Accessor> s, void tensorEigenRepresentation(triple<SrcIterator, SrcIterator, Src Accessor> s,
pair<DestIterator, DestAccessor> d); pair<DestIterator, DestAccessor> d);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="tensorutilities_8hxx-source.html">vigra/tens orutilities.hxx</a>" <b>\#include</b> \<<a href="tensorutilities_8hxx-source.html">vigra/ten sorutilities.hxx</a>\>
\code \code
FVector3Image tensor(w,h); FVector3Image tensor(w,h);
FVector3Image eigen(w,h); FVector3Image eigen(w,h);
tensorEigenRepresentation(srcImageRange(tensor), destImage(eigen)); tensorEigenRepresentation(srcImageRange(tensor), destImage(eigen));
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void tensorEigenRepresentation)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void tensorEigenRepresentation(SrcIterator sul, SrcIterator slr, SrcAccesso r src, void tensorEigenRepresentation(SrcIterator sul, SrcIterator slr, SrcAccesso r src,
DestIterator dul, DestAccessor dest) DestIterator dul, DestAccessor dest)
{ {
vigra_precondition(src.size(sul) == 3, vigra_precondition(src.size(sul) == 3,
"tensorEigenRepresentation(): input image must have 3 bands."); "tensorEigenRepresentation(): input image must have 3 bands.");
vigra_precondition(dest.size(dul) == 3, vigra_precondition(dest.size(dul) == 3,
"tensorEigenRepresentation(): output image must have 3 bands."); "tensorEigenRepresentation(): output image must have 3 bands.");
skipping to change at line 294 skipping to change at line 298
This function turns a 3-band image representing the tensor components This function turns a 3-band image representing the tensor components
t11, t12 (== t21 due to symmetry), t22 into the a 1-band image holding the t11, t12 (== t21 due to symmetry), t22 into the a 1-band image holding the
tensor trace t11 + t22. tensor trace t11 + t22.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void tensorTrace(SrcIterator sul, SrcIterator slr, SrcAccessor src, void tensorTrace(SrcIterator sul, SrcIterator slr, SrcAccessor src,
DestIterator dul, DestAccessor dest); DestIterator dul, DestAccessor dest);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void tensorTrace(triple<SrcIterator, SrcIterator, SrcAccessor> s, void tensorTrace(triple<SrcIterator, SrcIterator, SrcAccessor> s,
pair<DestIterator, DestAccessor> d); pair<DestIterator, DestAccessor> d);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="tensorutilities_8hxx-source.html">vigra/tens orutilities.hxx</a>" <b>\#include</b> \<<a href="tensorutilities_8hxx-source.html">vigra/ten sorutilities.hxx</a>\>
\code \code
FVector3Image tensor(w,h); FVector3Image tensor(w,h);
FImage trace(w,h); FImage trace(w,h);
tensorTrace(srcImageRange(tensor), destImage(trace)); tensorTrace(srcImageRange(tensor), destImage(trace));
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void tensorTrace)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor> class DestIterator, class DestAccessor>
void tensorTrace(SrcIterator sul, SrcIterator slr, SrcAccessor src, void tensorTrace(SrcIterator sul, SrcIterator slr, SrcAccessor src,
DestIterator dul, DestAccessor dest) DestIterator dul, DestAccessor dest)
{ {
vigra_precondition(src.size(sul) == 3, vigra_precondition(src.size(sul) == 3,
"tensorTrace(): input image must have 3 bands."); "tensorTrace(): input image must have 3 bands.");
int w = slr.x - sul.x; int w = slr.x - sul.x;
int h = slr.y - sul.y; int h = slr.y - sul.y;
skipping to change at line 384 skipping to change at line 390
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator1, class DestAccessor1, class DestIterator1, class DestAccessor1,
class DestIterator2, class DestAccessor2> class DestIterator2, class DestAccessor2>
void tensorToEdgeCorner(SrcIterator sul, SrcIterator slr, SrcAccess or src, void tensorToEdgeCorner(SrcIterator sul, SrcIterator slr, SrcAccess or src,
DestIterator1 edgeul, DestAccessor1 edge, DestIterator1 edgeul, DestAccessor1 edge,
DestIterator2 cornerul, DestAccessor2 corne r); DestIterator2 cornerul, DestAccessor2 corne r);
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator1, class DestAccessor1, class DestIterator1, class DestAccessor1,
class DestIterator2, class DestAccessor2> class DestIterator2, class DestAccessor2>
void tensorToEdgeCorner(triple<SrcIterator, SrcIterator, SrcAccesso r> s, void tensorToEdgeCorner(triple<SrcIterator, SrcIterator, SrcAccesso r> s,
pair<DestIterator1, DestAccessor1> edge, pair<DestIterator1, DestAccessor1> edge,
pair<DestIterator2, DestAccessor2> corner); pair<DestIterator2, DestAccessor2> corner);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="tensorutilities_8hxx-source.html">vigra/tens orutilities.hxx</a>" <b>\#include</b> \<<a href="tensorutilities_8hxx-source.html">vigra/ten sorutilities.hxx</a>\>
\code \code
FVector3Image tensor(w,h); FVector3Image tensor(w,h);
FVector2Image edgePart(w,h); FVector2Image edgePart(w,h);
FImage cornerPart(w,h); FImage cornerPart(w,h);
tensorTrace(srcImageRange(tensor), destImage(edgePart), destImage(corne rPart)); tensorTrace(srcImageRange(tensor), destImage(edgePart), destImage(corne rPart));
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void tensorToEdgeCorner)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator1, class DestAccessor1, class DestIterator1, class DestAccessor1,
class DestIterator2, class DestAccessor2> class DestIterator2, class DestAccessor2>
void tensorToEdgeCorner(SrcIterator sul, SrcIterator slr, SrcAccessor src, void tensorToEdgeCorner(SrcIterator sul, SrcIterator slr, SrcAccessor src,
DestIterator1 edgeul, DestAccessor1 edge, DestIterator1 edgeul, DestAccessor1 edge,
DestIterator2 cornerul, DestAccessor2 corner) DestIterator2 cornerul, DestAccessor2 corner)
{ {
vigra_precondition(src.size(sul) == 3, vigra_precondition(src.size(sul) == 3,
"tensorToEdgeCorner(): input image must have 3 bands ."); "tensorToEdgeCorner(): input image must have 3 bands .");
vigra_precondition(edge.size(edgeul) == 2, vigra_precondition(edge.size(edgeul) == 2,
 End of changes. 21 change blocks. 
18 lines changed or deleted 26 lines changed or added


 tiff.hxx   tiff.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 93 skipping to change at line 93
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
void void
importTiffImage(TiffImage * tiff, ImageIterator iter, Accessor a) importTiffImage(TiffImage * tiff, ImageIterator iter, Accessor a)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
void void
importTiffImage(TiffImage * tiff, pair<ImageIterator, Accessor> des t) importTiffImage(TiffImage * tiff, pair<ImageIterator, Accessor> des t)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>" <b>\#include</b> \<<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>\>
\code \code
uint32 w, h; uint32 w, h;
TiffImage * tiff = TIFFOpen("tiffimage.tiff", "r"); TiffImage * tiff = TIFFOpen("tiffimage.tiff", "r");
TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h); TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
vigra::BImage img(w,h); vigra::BImage img(w,h);
vigra::importTiffImage(tiff, destImage(img)); vigra::importTiffImage(tiff, destImage(img));
skipping to change at line 128 skipping to change at line 128
<b> Required Interface:</b> <b> Required Interface:</b>
see \ref tiffToScalarImage() and \ref tiffToRGBImage() see \ref tiffToScalarImage() and \ref tiffToRGBImage()
<b> Preconditions:</b> <b> Preconditions:</b>
see \ref tiffToScalarImage() and \ref tiffToRGBImage() see \ref tiffToScalarImage() and \ref tiffToRGBImage()
*/ */
doxygen_overloaded_function(template <...> void importTiffImage)
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
inline void inline void
importTiffImage(TiffImage * tiff, ImageIterator iter, Accessor a) importTiffImage(TiffImage * tiff, ImageIterator iter, Accessor a)
{ {
typedef typename typedef typename
NumericTraits<typename Accessor::value_type>::isScalar NumericTraits<typename Accessor::value_type>::isScalar
isScalar; isScalar;
importTiffImage(tiff, iter, a, isScalar()); importTiffImage(tiff, iter, a, isScalar());
} }
skipping to change at line 180 skipping to change at line 182
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
void void
tiffToScalarImage(TiffImage * tiff, ImageIterator iter, Accessor a) tiffToScalarImage(TiffImage * tiff, ImageIterator iter, Accessor a)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
void void
tiffToScalarImage(TiffImage * tiff, pair<ImageIterator, Accessor> d est) tiffToScalarImage(TiffImage * tiff, pair<ImageIterator, Accessor> d est)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>" <b>\#include</b> \<<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>\>
\code \code
uint32 w, h; uint32 w, h;
uint16 photometric uint16 photometric
TiffImage * tiff = TIFFOpen("tiffimage.tiff", "r"); TiffImage * tiff = TIFFOpen("tiffimage.tiff", "r");
TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h); TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
TIFFGetField(tiff_, TIFFTAG_PHOTOMETRIC, &photometric); TIFFGetField(tiff_, TIFFTAG_PHOTOMETRIC, &photometric);
if(photometric != PHOTOMETRIC_MINISWHITE && if(photometric != PHOTOMETRIC_MINISWHITE &&
skipping to change at line 250 skipping to change at line 252
photometric == PHOTOMETRIC_MINISBLACK photometric == PHOTOMETRIC_MINISBLACK
bitsPerSample == 1 || bitsPerSample == 1 ||
bitsPerSample == 8 || bitsPerSample == 8 ||
bitsPerSample == 16 || bitsPerSample == 16 ||
bitsPerSample == 32 || bitsPerSample == 32 ||
bitsPerSample == 64 bitsPerSample == 64
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void tiffToScalarImage)
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
void void
tiffToScalarImage(TiffImage * tiff, ImageIterator iter, Accessor a) tiffToScalarImage(TiffImage * tiff, ImageIterator iter, Accessor a)
{ {
vigra_precondition(tiff != 0, vigra_precondition(tiff != 0,
"tiffToScalarImage(TiffImage *, ScalarImageIterator): " "tiffToScalarImage(TiffImage *, ScalarImageIterator): "
"NULL pointer to input data."); "NULL pointer to input data.");
uint16 sampleFormat = 1, bitsPerSample, uint16 sampleFormat = 1, bitsPerSample,
fillorder, samplesPerPixel, photometric; fillorder, samplesPerPixel, photometric;
skipping to change at line 538 skipping to change at line 542
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class RGBImageIterator, class RGBAccessor> template <class RGBImageIterator, class RGBAccessor>
void void
tiffToRGBImage(TiffImage * tiff, RGBImageIterator iter, RGBAccessor a) tiffToRGBImage(TiffImage * tiff, RGBImageIterator iter, RGBAccessor a)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class RGBImageIterator, class RGBAccessor> template <class RGBImageIterator, class RGBAccessor>
void void
tiffToRGBImage(TiffImage * tiff, pair<RGBImageIterator, RGBAccessor > dest) tiffToRGBImage(TiffImage * tiff, pair<RGBImageIterator, RGBAccessor > dest)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>" <b>\#include</b> \<<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>\>
\code \code
uint32 w, h; uint32 w, h;
uint16 photometric uint16 photometric
TiffImage * tiff = TIFFOpen("tiffimage.tiff", "r"); TiffImage * tiff = TIFFOpen("tiffimage.tiff", "r");
TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &w);
TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h); TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &h);
TIFFGetField(tiff_, TIFFTAG_PHOTOMETRIC, &photometric); TIFFGetField(tiff_, TIFFTAG_PHOTOMETRIC, &photometric);
if(photometric != PHOTOMETRIC_RGB && if(photometric != PHOTOMETRIC_RGB &&
skipping to change at line 609 skipping to change at line 613
photometric == PHOTOMETRIC_RGB || photometric == PHOTOMETRIC_RGB ||
photometric == PHOTOMETRIC_PALETTE photometric == PHOTOMETRIC_PALETTE
bitsPerSample == 1 || bitsPerSample == 1 ||
bitsPerSample == 8 || bitsPerSample == 8 ||
bitsPerSample == 16 || bitsPerSample == 16 ||
bitsPerSample == 32 || bitsPerSample == 32 ||
bitsPerSample == 64 bitsPerSample == 64
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void tiffToRGBImage)
template <class RGBImageIterator, class RGBAccessor> template <class RGBImageIterator, class RGBAccessor>
void void
tiffToRGBImage(TiffImage * tiff, RGBImageIterator iter, RGBAccessor a) tiffToRGBImage(TiffImage * tiff, RGBImageIterator iter, RGBAccessor a)
{ {
vigra_precondition(tiff != 0, vigra_precondition(tiff != 0,
"tiffToRGBImage(TiffImage *, RGBImageIterator): " "tiffToRGBImage(TiffImage *, RGBImageIterator): "
"NULL pointer to input data."); "NULL pointer to input data.");
uint16 sampleFormat = 1, bitsPerSample, uint16 sampleFormat = 1, bitsPerSample,
samplesPerPixel, planarConfig, photometric; samplesPerPixel, planarConfig, photometric;
skipping to change at line 1021 skipping to change at line 1027
Currently, the function can create scalar images and RGB images of type Currently, the function can create scalar images and RGB images of type
unsigned char, short, int, float, and double. unsigned char, short, int, float, and double.
This function uses accessors to read the data. This function uses accessors to read the data.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
inline TiffImage * TiffImage *
createTiffImage(ImageIterator upperleft, ImageIterator lowerright, createTiffImage(ImageIterator upperleft, ImageIterator lowerright,
Accessor a) Accessor a)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
inline TiffImage * TiffImage *
createTiffImage(triple<ImageIterator, ImageIterator, Accessor> src) createTiffImage(triple<ImageIterator, ImageIterator, Accessor> src)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>" <b>\#include</b> \<<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>\>
\code \code
vigra::BImage img(width, height); vigra::BImage img(width, height);
... ...
TiffImage * tiff = TIFFOpen(("tiffimage.tiff", "w"); TiffImage * tiff = TIFFOpen(("tiffimage.tiff", "w");
vigra::createTiffImage(srcImageRange(img), tiff); vigra::createTiffImage(srcImageRange(img), tiff);
skipping to change at line 1062 skipping to change at line 1068
<b> Required Interface:</b> <b> Required Interface:</b>
\code \code
ImageIterator upperleft; ImageIterator upperleft;
Accessor accessor; Accessor accessor;
accessor(upperleft); // result written into TiffImage accessor(upperleft); // result written into TiffImage
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void createTiffImage)
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
inline void inline void
createTiffImage(ImageIterator upperleft, ImageIterator lowerright, createTiffImage(ImageIterator upperleft, ImageIterator lowerright,
Accessor a, TiffImage * tiff) Accessor a, TiffImage * tiff)
{ {
CreateTiffImage<typename Accessor::value_type>:: CreateTiffImage<typename Accessor::value_type>::
exec(upperleft, lowerright, a, tiff); exec(upperleft, lowerright, a, tiff);
} }
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
skipping to change at line 1096 skipping to change at line 1104
Type and size of the TiffImage are determined by the input image Type and size of the TiffImage are determined by the input image
(may be one of unsigned char, short, int, float, or double). (may be one of unsigned char, short, int, float, or double).
This function uses accessors to read the data. This function uses accessors to read the data.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
inline TiffImage * TiffImage *
createScalarTiffImage(ImageIterator upperleft, ImageIterator lowerr ight, createScalarTiffImage(ImageIterator upperleft, ImageIterator lowerr ight,
Accessor a) Accessor a)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
inline TiffImage * TiffImage *
createScalarTiffImage(triple<ImageIterator, ImageIterator, Accessor > src) createScalarTiffImage(triple<ImageIterator, ImageIterator, Accessor > src)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>" <b>\#include</b> \<<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>\>
\code \code
vigra::BImage img(width, height); vigra::BImage img(width, height);
... ...
TiffImage * tiff = TIFFOpen(("tiffimage.tiff", "w"); TiffImage * tiff = TIFFOpen(("tiffimage.tiff", "w");
vigra::createScalarTiffImage(srcImageRange(img), tiff); vigra::createScalarTiffImage(srcImageRange(img), tiff);
skipping to change at line 1137 skipping to change at line 1145
<b> Required Interface:</b> <b> Required Interface:</b>
\code \code
ImageIterator upperleft; ImageIterator upperleft;
Accessor accessor; Accessor accessor;
accessor(upperleft); // result written into TiffImage accessor(upperleft); // result written into TiffImage
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void createScalarTiffImage)
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
inline void inline void
createScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright, createScalarTiffImage(ImageIterator upperleft, ImageIterator lowerright,
Accessor a, TiffImage * tiff) Accessor a, TiffImage * tiff)
{ {
CreateTiffImage<typename Accessor::value_type>:: CreateTiffImage<typename Accessor::value_type>::
exec(upperleft, lowerright, a, tiff); exec(upperleft, lowerright, a, tiff);
} }
template <class ImageIterator, class Accessor> template <class ImageIterator, class Accessor>
skipping to change at line 1454 skipping to change at line 1464
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class RGBImageIterator, class RGBAccessor> template <class RGBImageIterator, class RGBAccessor>
TiffImage * TiffImage *
createRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator low erright, createRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator low erright,
RGBAccessor a) RGBAccessor a)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class RGBImageIterator, class RGBAccessor> template <class RGBImageIterator, class RGBAccessor>
inline TiffImage * TiffImage *
createRGBTiffImage(triple<RGBImageIterator, RGBImageIterator, RGBAc cessor> src) createRGBTiffImage(triple<RGBImageIterator, RGBImageIterator, RGBAc cessor> src)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>" <b>\#include</b> \<<a href="tiff_8hxx-source.html">vigra/tiff.hxx</a>\>
\code \code
vigra::BRGBImage img(width, height); vigra::BRGBImage img(width, height);
... ...
TiffImage * tiff = TIFFOpen(("tiffimage.tiff", "w"); TiffImage * tiff = TIFFOpen(("tiffimage.tiff", "w");
vigra::createRGBTiffImage(srcImageRange(img), tiff); vigra::createRGBTiffImage(srcImageRange(img), tiff);
skipping to change at line 1491 skipping to change at line 1501
\code \code
ImageIterator upperleft; ImageIterator upperleft;
RGBAccessor accessor; RGBAccessor accessor;
accessor.red(upperleft); // result written into TiffImage accessor.red(upperleft); // result written into TiffImage
accessor.green(upperleft); // result written into TiffImage accessor.green(upperleft); // result written into TiffImage
accessor.blue(upperleft); // result written into TiffImage accessor.blue(upperleft); // result written into TiffImage
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void createRGBTiffImage)
template <class RGBImageIterator, class RGBAccessor> template <class RGBImageIterator, class RGBAccessor>
inline void inline void
createRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright, createRGBTiffImage(RGBImageIterator upperleft, RGBImageIterator lowerright,
RGBAccessor a, TiffImage * tiff) RGBAccessor a, TiffImage * tiff)
{ {
CreateTiffImage<typename RGBAccessor::value_type>:: CreateTiffImage<typename RGBAccessor::value_type>::
exec(upperleft, lowerright, a, tiff); exec(upperleft, lowerright, a, tiff);
} }
template <class RGBImageIterator, class RGBAccessor> template <class RGBImageIterator, class RGBAccessor>
 End of changes. 25 change blocks. 
20 lines changed or deleted 32 lines changed or added


 tinyvector.hxx   tinyvector.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 365 skipping to change at line 365
/* TinyVectorBase */ /* TinyVectorBase */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Base class for fixed size vectors. /** \brief Base class for fixed size vectors.
This class contains functionality shared by This class contains functionality shared by
\ref TinyVector and \ref TinyVectorView, and enables these classes \ref TinyVector and \ref TinyVectorView, and enables these classes
to be freely mixed within expressions. It is typically not used directl y. to be freely mixed within expressions. It is typically not used directl y.
<b>\#include</b> "<a href="tinyvector_8hxx-source.html">vigra/tinyvecto r.hxx</a>"<br> <b>\#include</b> \<<a href="tinyvector_8hxx-source.html">vigra/tinyvect or.hxx</a>\><br>
Namespace: vigra Namespace: vigra
**/ **/
template <class VALUETYPE, int SIZE, class DATA, class DERIVED> template <class VALUETYPE, int SIZE, class DATA, class DERIVED>
class TinyVectorBase class TinyVectorBase
{ {
TinyVectorBase(TinyVectorBase const &); // do not use TinyVectorBase(TinyVectorBase const &); // do not use
TinyVectorBase & operator=(TinyVectorBase const & other); // do not use TinyVectorBase & operator=(TinyVectorBase const & other); // do not use
protected: protected:
skipping to change at line 549 skipping to change at line 549
This class contains an array of size SIZE of the specified VALUETYPE. This class contains an array of size SIZE of the specified VALUETYPE.
The interface conforms to STL vector, except that there are no function s The interface conforms to STL vector, except that there are no function s
that change the size of a TinyVector. that change the size of a TinyVector.
\ref TinyVectorOperators "Arithmetic operations" \ref TinyVectorOperators "Arithmetic operations"
on TinyVectors are defined as component-wise applications of these on TinyVectors are defined as component-wise applications of these
operations. Addition and subtraction of two TinyVectors operations. Addition and subtraction of two TinyVectors
(+=, -=, +, -, unary -), multiplication and division of an (+=, -=, +, -, unary -), multiplication and division of an
TinyVector with a double, and NumericTraits/PromoteTraits are defined, TinyVector with a double, and NumericTraits/PromoteTraits are defined,
so that TinyVector fulfills the requirements of \ref LinearAlgebra. so that TinyVector fulfills the requirements of \ref LinearAlgebraConce pt "Linear Algebra".
VIGRA algorithms typically use \ref vigra::VectorAccessor to access VIGRA algorithms typically use \ref vigra::VectorAccessor to access
TinyVectors as a whole, or specific components of them. TinyVectors as a whole, or specific components of them.
See also:<br> See also:<br>
<DL> <UL style="list-style-image:url(documents/bullet.gif)">
<DT> <LI> \ref vigra::TinyVectorBase
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref vigra::TinyVectorView
\ref vigra::TinyVectorBase <LI> \ref TinyVectorTraits
<DD> <LI> \ref TinyVectorOperators
<DT> </UL>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref vigra::TinyVectorView
<DD>
<DT>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref TinyVectorTraits
<DD>
<DT>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref TinyVectorOperators
<DD>
</DL>
<b>\#include</b> "<a href="tinyvector_8hxx-source.html">vigra/tinyvecto r.hxx</a>"<br> <b>\#include</b> \<<a href="tinyvector_8hxx-source.html">vigra/tinyvect or.hxx</a>\><br>
Namespace: vigra Namespace: vigra
**/ **/
template <class T, int SIZE> template <class T, int SIZE>
class TinyVector class TinyVector
: public TinyVectorBase<T, SIZE, T[SIZE], TinyVector<T, SIZE> > : public TinyVectorBase<T, SIZE, T[SIZE], TinyVector<T, SIZE> >
{ {
typedef TinyVectorBase<T, SIZE, T[SIZE], TinyVector<T, SIZE> > BaseType ; typedef TinyVectorBase<T, SIZE, T[SIZE], TinyVector<T, SIZE> > BaseType ;
typedef typename BaseType::Loop Loop; typedef typename BaseType::Loop Loop;
public: public:
skipping to change at line 709 skipping to change at line 697
Thus, the array can be accessed with an interface similar to Thus, the array can be accessed with an interface similar to
that of std::vector (except that there are no functions that of std::vector (except that there are no functions
that change the size of a TinyVectorView). The TinyVectorView that change the size of a TinyVectorView). The TinyVectorView
does <em>not</em> assume ownership of the given memory. does <em>not</em> assume ownership of the given memory.
\ref TinyVectorOperators "Arithmetic operations" \ref TinyVectorOperators "Arithmetic operations"
on TinyVectorViews are defined as component-wise applications of these on TinyVectorViews are defined as component-wise applications of these
operations. Addition and subtraction of two TinyVectorViews operations. Addition and subtraction of two TinyVectorViews
(+=, -=, +, -, unary -), multiplication and division of an (+=, -=, +, -, unary -), multiplication and division of an
TinyVectorViews with a double, and NumericTraits/PromoteTraits are defi ned, TinyVectorViews with a double, and NumericTraits/PromoteTraits are defi ned,
so that TinyVectorView fulfills the requirements of \ref LinearAlgebra. so that TinyVectorView fulfills the requirements of \ref LinearAlgebraC oncept "Linear Algebra".
VIGRA algorithms typically use \ref vigra::VectorAccessor to access VIGRA algorithms typically use \ref vigra::VectorAccessor to access
TinyVectorViews as a whole, or specific components of them. TinyVectorViews as a whole, or specific components of them.
<b>See also:</b> <b>See also:</b>
<ul> <ul>
<li> \ref vigra::TinyVectorBase <li> \ref vigra::TinyVectorBase
<li> \ref vigra::TinyVector <li> \ref vigra::TinyVector
<li> \ref TinyVectorTraits <li> \ref TinyVectorTraits
<li> \ref TinyVectorOperators <li> \ref TinyVectorOperators
</ul> </ul>
<b>\#include</b> "<a href="tinyvector_8hxx-source.html">vigra/tinyvecto r.hxx</a>"<br> <b>\#include</b> \<<a href="tinyvector_8hxx-source.html">vigra/tinyvect or.hxx</a>\><br>
Namespace: vigra Namespace: vigra
**/ **/
template <class T, int SIZE> template <class T, int SIZE>
class TinyVectorView class TinyVectorView
: public TinyVectorBase<T, SIZE, T *, TinyVectorView<T, SIZE> > : public TinyVectorBase<T, SIZE, T *, TinyVectorView<T, SIZE> >
{ {
typedef TinyVectorBase<T, SIZE, T *, TinyVectorView<T, SIZE> > BaseType ; typedef TinyVectorBase<T, SIZE, T *, TinyVectorView<T, SIZE> > BaseType ;
typedef typename BaseType::Loop Loop; typedef typename BaseType::Loop Loop;
public: public:
skipping to change at line 807 skipping to change at line 795
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* TinyVector Comparison */ /* TinyVector Comparison */
/* */ /* */
/********************************************************/ /********************************************************/
/** \addtogroup TinyVectorOperators Functions for TinyVector /** \addtogroup TinyVectorOperators Functions for TinyVector
\brief <b>\#include</b> "<a href="tinyvector_8hxx-source.html">vigra/ti nyvector.hxx</a> \brief Implement basic arithmetic and equality for TinyVector.
These functions fulfill the requirements of a Linear Space (vector spac e). These functions fulfill the requirements of a Linear Space (vector spac e).
Return types are determined according to \ref TinyVectorTraits. Return types are determined according to \ref TinyVectorTraits.
<b>\#include</b> \<<a href="tinyvector_8hxx-source.html">vigra/tinyvect or.hxx</a>\><br>
Namespace: vigra Namespace: vigra
<p> */
*/
//@{ //@{
/// component-wise equal /// component-wise equal
template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4> template <class V1, int SIZE, class D1, class D2, class V2, class D3, class D4>
inline bool inline bool
operator==(TinyVectorBase<V1, SIZE, D1, D2> const & l, operator==(TinyVectorBase<V1, SIZE, D1, D2> const & l,
TinyVectorBase<V2, SIZE, D3, D4> const & r) TinyVectorBase<V2, SIZE, D3, D4> const & r)
{ {
return !(l != r); return !(l != r);
} }
skipping to change at line 898 skipping to change at line 885
typedef typename Type::NormType NormType; typedef typename Type::NormType NormType;
}; };
template <class T1, class T2, SIZE> template <class T1, class T2, SIZE>
struct PromoteTraits<TinyVector<T1, SIZE>, TinyVector<T2, SIZE> > struct PromoteTraits<TinyVector<T1, SIZE>, TinyVector<T2, SIZE> >
{ {
typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> P romote; typedef TinyVector<typename PromoteTraits<T1, T2>::Promote, SIZE> P romote;
}; };
\endcode \endcode
<b>\#include</b> "<a href="tinyvector_8hxx-source.html">vigra/tinyvecto r.hxx</a>"<br> <b>\#include</b> \<<a href="tinyvector_8hxx-source.html">vigra/tinyvect or.hxx</a>\><br>
Namespace: vigra Namespace: vigra
On compilers that don't support pertial template specialization (e.g. On compilers that don't support pertial template specialization (e.g.
MS VisualC++), the traits classes are explicitly specialized for MS VisualC++), the traits classes are explicitly specialized for
<TT>TinyVector<VALUETYPE, SIZE></TT> with <TT>TinyVector<VALUETYPE, SIZE></TT> with
<TT>VALUETYPE = unsigned char | int | float | double</TT> and <TT>SIZE = 2 | 3 | 4</TT>. <TT>VALUETYPE = unsigned char | int | float | double</TT> and <TT>SIZE = 2 | 3 | 4</TT>.
*/ */
#if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION) #if !defined(NO_PARTIAL_TEMPLATE_SPECIALIZATION)
 End of changes. 12 change blocks. 
31 lines changed or deleted 18 lines changed or added


 transformimage.hxx   transformimage.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 110 skipping to change at line 110
Note that the unary functors of the STL can be used in addition to Note that the unary functors of the STL can be used in addition to
the functors specifically defined in \ref TransformFunctor. the functors specifically defined in \ref TransformFunctor.
Creation of new functors is easiest by using \ref FunctorExpressions. Creation of new functors is easiest by using \ref FunctorExpressions.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor, class Functor> class DestImageIterator, class DestAccessor, class Functo r>
void void
transformImage(SrcImageIterator src_upperleft, transformImage(SrcImageIterator src_upperleft,
SrcImageIterator src_lowerright, SrcAccessor sa, SrcImageIterator src_lowerright, SrcAccessor sa,
DestImageIterator dest_upperleft, DestAccessor da, DestImageIterator dest_upperleft, DestAccessor da,
Functor const & f) Functor const & f)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor, class Functor> class DestImageIterator, class DestAccessor, class Functo r>
void void
transformImage(triple<SrcImageIterator, SrcImageIterator, SrcAccess or> src, transformImage(triple<SrcImageIterator, SrcImageIterator, SrcAccess or> src,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
Functor const & f) Functor const & f)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/trans formimage.hxx</a>"<br> <b>\#include</b> \<<a href="transformimage_8hxx-source.html">vigra/tran sformimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
#include <cmath> // for sqrt() #include <cmath> // for sqrt()
vigra::transformImage(srcImageRange(src), vigra::transformImage(srcImageRange(src),
destImage(dest), destImage(dest),
(double(*)(double))&std::sqrt ); (double(*)(double))&std::sqrt );
skipping to change at line 164 skipping to change at line 164
SrcAccessor src_accessor; SrcAccessor src_accessor;
DestAccessor dest_accessor; DestAccessor dest_accessor;
Functor functor; Functor functor;
dest_accessor.set(functor(src_accessor(sx)), dx); dest_accessor.set(functor(src_accessor(sx)), dx);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void transformImage)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor, class Functor> class DestImageIterator, class DestAccessor, class Functor>
void void
transformImage(SrcImageIterator src_upperleft, transformImage(SrcImageIterator src_upperleft,
SrcImageIterator src_lowerright, SrcAccessor sa, SrcImageIterator src_lowerright, SrcAccessor sa,
DestImageIterator dest_upperleft, DestAccessor da, DestImageIterator dest_upperleft, DestAccessor da,
Functor const & f) Functor const & f)
{ {
int w = src_lowerright.x - src_upperleft.x; int w = src_lowerright.x - src_upperleft.x;
skipping to change at line 218 skipping to change at line 220
Note that the unary functors of the STL can be used in addition to Note that the unary functors of the STL can be used in addition to
the functors specifically defined in \ref TransformFunctor. the functors specifically defined in \ref TransformFunctor.
Creation of new functors is easiest by using \ref FunctorExpressions. Creation of new functors is easiest by using \ref FunctorExpressions.
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class MaskImageIterator, class MaskAccessor, class MaskImageIterator, class MaskAccessor,
class DestImageIterator, clas DestAccessor, class DestImageIterator, clas DestAccessor,
class Functor> class Functor>
void void
transformImageIf(SrcImageIterator src_upperleft, transformImageIf(SrcImageIterator src_upperleft,
SrcImageIterator src_lowerright, SrcAccessor sa, SrcImageIterator src_lowerright, SrcAccessor sa,
MaskImageIterator mask_upperleft, MaskAccessor ma, MaskImageIterator mask_upperleft, MaskAccessor ma,
DestImageIterator dest_upperleft, DestAccessor da, DestImageIterator dest_upperleft, DestAccessor da,
Functor const & f) Functor const & f)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class MaskImageIterator, class MaskAccessor, class MaskImageIterator, class MaskAccessor,
class DestImageIterator, clas DestAccessor, class DestImageIterator, clas DestAccessor,
class Functor> class Functor>
void void
transformImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAcce ssor> src, transformImageIf(triple<SrcImageIterator, SrcImageIterator, SrcAcce ssor> src,
pair<MaskImageIterator, MaskAccessor> mask, pair<MaskImageIterator, MaskAccessor> mask,
pair<DestImageIterator, DestAccessor> dest, pair<DestImageIterator, DestAccessor> dest,
Functor const & f) Functor const & f)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/t ransformimage.hxx</a>"<br> <b>\#include</b> \<<a href="transformimage_8hxx-source.html">vigra/ transformimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
#include <cmath> // for sqrt() #include <cmath> // for sqrt()
vigra::transformImageIf(srcImageRange(src), vigra::transformImageIf(srcImageRange(src),
maskImage(mask), maskImage(mask),
destImage(dest), destImage(dest),
(double(*)(double))&std::sqrt ); (double(*)(double))&std::sqrt );
skipping to change at line 281 skipping to change at line 283
DestAccessor dest_accessor; DestAccessor dest_accessor;
MaskAccessor mask_accessor; MaskAccessor mask_accessor;
Functor functor; Functor functor;
if(mask_accessor(mx)) if(mask_accessor(mx))
dest_accessor.set(functor(src_accessor(sx)), dx); dest_accessor.set(functor(src_accessor(sx)), dx);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void transformImageIf)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class MaskImageIterator, class MaskAccessor, class MaskImageIterator, class MaskAccessor,
class DestImageIterator, class DestAccessor, class DestImageIterator, class DestAccessor,
class Functor> class Functor>
void void
transformImageIf(SrcImageIterator src_upperleft, transformImageIf(SrcImageIterator src_upperleft,
SrcImageIterator src_lowerright, SrcAccessor sa, SrcImageIterator src_lowerright, SrcAccessor sa,
MaskImageIterator mask_upperleft, MaskAccessor ma, MaskImageIterator mask_upperleft, MaskAccessor ma,
DestImageIterator dest_upperleft, DestAccessor da, DestImageIterator dest_upperleft, DestAccessor da,
Functor const & f) Functor const & f)
skipping to change at line 345 skipping to change at line 349
<b> Declarations:</b> <b> Declarations:</b>
pass arguments explicitly: pass arguments explicitly:
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor, class Functo r> class DestImageIterator, class DestAccessor, class Functo r>
void void
gradientBasedTransform(SrcImageIterator srcul, SrcImageIterator src lr, SrcAccessor sa, gradientBasedTransform(SrcImageIterator srcul, SrcImageIterator src lr, SrcAccessor sa,
DestImageIterator destul, DestAccessor da, Functor co nst & f) DestImageIterator destul, DestAccessor da, F unctor const & f)
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor, class Functo r> class DestImageIterator, class DestAccessor, class Functo r>
void void
gradientBasedTransform(triple<SrcImageIterator, SrcImageIterator, S rcAccessor> src, gradientBasedTransform(triple<SrcImageIterator, SrcImageIterator, S rcAccessor> src,
pair<DestImageIterator, DestAccessor> dest, Functor const & const & f) pair<DestImageIterator, DestAccessor> dest, Functor const & const & f)
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/trans formimage.hxx</a>" <b>\#include</b> \<<a href="transformimage_8hxx-source.html">vigra/tran sformimage.hxx</a>\>
\code \code
vigra::FImage src(w,h), magnitude(w,h); vigra::FImage src(w,h), magnitude(w,h);
... ...
gradientBasedTransform(srcImageRange(src), destImage(magnitude), gradientBasedTransform(srcImageRange(src), destImage(magnitude),
vigra::MagnitudeFunctor<float>()); vigra::MagnitudeFunctor<float>());
\endcode \endcode
<b> Required Interface:</b> <b> Required Interface:</b>
skipping to change at line 394 skipping to change at line 398
diffx = src_accessor(is, Diff2D(-1,0)) - src_accessor(is, Diff2D(1,0)); diffx = src_accessor(is, Diff2D(-1,0)) - src_accessor(is, Diff2D(1,0));
diffy = src_accessor(is, Diff2D(0,-1)) - src_accessor(is, Diff2D(0,1)); diffy = src_accessor(is, Diff2D(0,-1)) - src_accessor(is, Diff2D(0,1));
Functor f; Functor f;
dest_accessor.set(f(diffx, diffy), id); dest_accessor.set(f(diffx, diffy), id);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> void gradientBasedTransform)
template <class SrcImageIterator, class SrcAccessor, template <class SrcImageIterator, class SrcAccessor,
class DestImageIterator, class DestAccessor, class Functor> class DestImageIterator, class DestAccessor, class Functor>
void void
gradientBasedTransform(SrcImageIterator srcul, SrcImageIterator srclr, SrcA ccessor sa, gradientBasedTransform(SrcImageIterator srcul, SrcImageIterator srclr, SrcA ccessor sa,
DestImageIterator destul, DestAccessor da, Functor c onst & grad) DestImageIterator destul, DestAccessor da, Functor c onst & grad)
{ {
int w = srclr.x - srcul.x; int w = srclr.x - srcul.x;
int h = srclr.y - srcul.y; int h = srclr.y - srcul.y;
int x,y; int x,y;
skipping to change at line 619 skipping to change at line 624
This can, for example, be used to transform images into the visible This can, for example, be used to transform images into the visible
range 0...255 or to invert an image. range 0...255 or to invert an image.
If you leave out the second parameter / offset, you will get an If you leave out the second parameter / offset, you will get an
optimized version of the functor which only scales by the given optimized version of the functor which only scales by the given
factor, however you have to make the template parameter (pixel factor, however you have to make the template parameter (pixel
type) explicit then. type) explicit then.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
<b> Declaration:</b> <b> Declaration:</b>
\code \code
namespace vigra { namespace vigra {
template <class Multiplier, class DestValueType> template <class Multiplier, class DestValueType>
LinearIntensityTransform<DestValueType, Multiplier> LinearIntensityTransform<DestValueType, Multiplier>
linearIntensityTransform(Multiplier scale, DestValueType offset); linearIntensityTransform(Multiplier scale, DestValueType offset);
template <class DestValueType, class Multiplier> template <class DestValueType, class Multiplier>
ScalarIntensityTransform<DestValueType, Multiplier> ScalarIntensityTransform<DestValueType, Multiplier>
linearIntensityTransform(Multiplier scale); linearIntensityTransform(Multiplier scale);
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/t ransformimage.hxx</a>"<br> <b>\#include</b> \<<a href="transformimage_8hxx-source.html">vigra/ transformimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::IImage src(width, height); vigra::IImage src(width, height);
vigra::BImage dest(width, height); vigra::BImage dest(width, height);
... ...
vigra::FindMinMax<IImage::PixelType> minmax; // functor to find range vigra::FindMinMax<IImage::PixelType> minmax; // functor to find range
vigra::inspectImage(srcImageRange(src), minmax); // find original range vigra::inspectImage(srcImageRange(src), minmax); // find original range
skipping to change at line 714 skipping to change at line 719
namespace vigra { namespace vigra {
template <class SrcValueType, class DestValueType> template <class SrcValueType, class DestValueType>
LinearIntensityTransform<DestValueType, typename NumericTraits<Dest ValueType>::RealPromote> LinearIntensityTransform<DestValueType, typename NumericTraits<Dest ValueType>::RealPromote>
linearRangeMapping(SrcValueType src_min, SrcValueType src_max, linearRangeMapping(SrcValueType src_min, SrcValueType src_max,
DestValueType dest_min, DestValueType dest_max ) ; DestValueType dest_min, DestValueType dest_max ) ;
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/t ransformimage.hxx</a>"<br> <b>\#include</b> \<<a href="transformimage_8hxx-source.html">vigra/ transformimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::IImage src(width, height); vigra::IImage src(width, height);
vigra::BImage dest(width, height); vigra::BImage dest(width, height);
... ...
vigra::FindMinMax<IImage::PixelType> minmax; // functor to find range vigra::FindMinMax<IImage::PixelType> minmax; // functor to find range
vigra::inspectImage(srcImageRange(src), minmax); // find original range vigra::inspectImage(srcImageRange(src), minmax); // find original range
skipping to change at line 799 skipping to change at line 804
/** \brief Threshold an image. /** \brief Threshold an image.
If a source pixel is above or equal the lower and below If a source pixel is above or equal the lower and below
or equal the higher threshold (i.e. within the closed interval or equal the higher threshold (i.e. within the closed interval
[lower, heigher]) the destination pixel is set to 'yesresult', [lower, heigher]) the destination pixel is set to 'yesresult',
otherwise to 'noresult'. otherwise to 'noresult'.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/t ransformimage.hxx</a>"<br> <b>\#include</b> \<<a href="transformimage_8hxx-source.html">vigra/ transformimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage src(width, height), dest(width, height); vigra::BImage src(width, height), dest(width, height);
... ...
vigra::transformImage(src.upperLeft(), src.lowerRight(), src.accessor() , vigra::transformImage(src.upperLeft(), src.lowerRight(), src.accessor() ,
dest.upperLeft(), dest.accessor(), dest.upperLeft(), dest.accessor(),
vigra::Threshold< vigra::Threshold<
vigra::BImage::PixelType, vigra::BImage::PixelType>(10, 100, 0, 2 55)); vigra::BImage::PixelType, vigra::BImage::PixelType>(10, 100, 0, 2 55));
skipping to change at line 879 skipping to change at line 884
/********************************************************/ /********************************************************/
/* */ /* */
/* BrightnessContrastFunctor */ /* BrightnessContrastFunctor */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief Adjust brightness and contrast of an image. /** \brief Adjust brightness and contrast of an image.
This functor applies a gamma correction to each pixel in order to This functor applies a gamma correction to each pixel in order to
modify the brightness of the image. To the result of the gamma correcti modify the brightness of the image. To the result of the gamma
on, correction, another transform is applied that modifies the
another transform is applied that modifies the contrast. The brightness contrast. The brightness and contrast parameters must be
and positive. Values greater than 1 will increase image brightness or
contrast parameters must be positive. Values greater than 1 will increa contrast respectively, values smaller than 1 decrease them. A
se image value of exactly 1 will have no effect. If contrast is set to 1,
brightness and contrast, values smaller than 1 decrease them. A value = the result is equivalent to that of the GammaFunctor with gamma =
1 will 1./brightness.
have no effect.
For \ref RGBValue "RGBValue's", the transforms are applied component-wi For \ref RGBValue "RGBValue's", the transforms are applied
se. The pixel component-wise. The pixel values are assumed to lie between the
values are assumed to lie between the given minimum and maximum given minimum and maximum values (in case of RGB, this is again
values. In case of RGB, this is again understood component-wise. In cas understood component-wise). In case of <TT>unsigned char</TT>, min
e and max default to 0 and 255 respectively. Precisely, the
of <TT>unsigned char</TT>, min and max default to 0 and 255 respectivel following transform is applied to each <em> PixelValue</em>:
y.
Precisely, the following transform is applied to each <em> PixelValue</
em>:
\f[ \f[
\begin{array}{rcl} \begin{array}{rcl}
V_1 & = & \frac{PixelValue - min}{max - min} \\ V_1 & = & \frac{PixelValue - min}{max - min} \\
V_2 & = & V_1^\frac{1}{brightness} \\ V_2 & = & V_1^\frac{1}{brightness} \\
V_3 & = & 2 V_2 - 1 \\ V_3 & = & 2 V_2 - 1 \\
V_4 & = & \left\lbrace V_4 & = & \left\lbrace
\begin{array}{l} \begin{array}{l}
V_3^\frac{1}{contrast} \mbox{\rm \quad if } V_3 \ge 0 \\ V_3^\frac{1}{contrast} \mbox{\rm \quad if } V_3 \ge 0 \\
- (-V_3)^\frac{1}{contrast} \mbox{\rm \quad otherwise} - (-V_3)^\frac{1}{contrast} \mbox{\rm \quad otherwise}
\end{array} \right. \\ \end{array} \right. \\
Result & = & \frac{V_4 + 1}{2} (max - min) + min Result & = & \frac{V_4 + 1}{2} (max - min) + min
\end{array} \end{array}
\f] \f]
If the <TT>PixelType</TT> is <TT>unsigned char</TT>, a look-up-table is used If the <TT>PixelType</TT> is <TT>unsigned char</TT>, a look-up-table is used
for faster computation. for faster computation.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/t ransformimage.hxx</a>"<br> <b>\#include</b> \<<a href="transformimage_8hxx-source.html">vigra/ transformimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
vigra::BImage bimage(width, height); vigra::BImage bimage(width, height);
double brightness, contrast; double brightness, contrast;
... ...
vigra::transformImage(srcImageRange(bimage), destImage(bimage), vigra::transformImage(srcImageRange(bimage), destImage(bimage),
vigra::BrightnessContrastFunctor<unsigned char>(brightness, contrast )); vigra::BrightnessContrastFunctor<unsigned char>(brightness, contrast ));
vigra::FImage fimage(width, height); vigra::FImage fimage(width, height);
skipping to change at line 1137 skipping to change at line 1147
value_type operator()(value_type const & v) const value_type operator()(value_type const & v) const
{ {
return value_type(red(v.red()), green(v.green()), blue(v.blue())); return value_type(red(v.red()), green(v.green()), blue(v.blue()));
} }
}; };
/********************************************************/ /********************************************************/
/* */ /* */
/* GammaFunctor */
/* */
/********************************************************/
/** \brief Perform gamma correction of an image.
This functor applies a gamma correction to each pixel in order to
modify the brightness of the image. Gamma values smaller than 1
will increase image brightness, whereas values greater than 1
decrease it. A value of gamma = 1 will have no effect. (See also
BrightnessContrastFunctor, which additionally changes the
contrast.)
For \ref RGBValue "RGBValue's", the transforms are applied
component-wise. For ease of use, the pixel values are assumed to
lie between the given minimum and maximum values (in case of RGB,
this is again understood component-wise). In case of <TT>unsigned
char</TT>, min and max default to 0 and 255 respectively.
Precisely, the following transform is applied to each <em>
PixelValue</em>:
\f[
\begin{array}{rcl}
V_1 & = & \frac{PixelValue - min}{max - min} \\
V_2 & = & V_1^{gamma} \\
Result & = & V_2 (max - min) + min
\end{array}
\f]
If the <TT>PixelType</TT> is <TT>unsigned char</TT>, a
look-up-table is used for faster computation.
<b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
<b> Usage:</b>
<b>\#include</b> \<<a href="transformimage_8hxx-source.html">vigra/
transformimage.hxx</a>\><br>
Namespace: vigra
\code
vigra::BImage bimage(width, height);
double gamma;
...
vigra::transformImage(srcImageRange(bimage), destImage(bimage),
vigra::GammaFunctor<unsigned char>(gamma));
vigra::FImage fimage(width, height);
...
vigra::FindMinmax<float> minmax;
vigra::inspectImage(srcImageRange(fimage), minmax);
vigra::transformImage(srcImageRange(fimage), destImage(fimage),
vigra::GammaFunctor<float>(gamma, minmax.min, minmax.max));
\endcode
<b> Required Interface:</b>
Scalar types: must be a linear algebra (+, - *, NumericTraits),
strict weakly ordered (<), and <TT>pow()</TT> must be defined.
RGB values: the component type must meet the above requirements.
*/
template <class PixelType>
class GammaFunctor
{
typedef typename
NumericTraits<PixelType>::RealPromote promote_type;
public:
/** the functor's argument type
*/
typedef PixelType argument_type;
/** the functor's result type
*/
typedef PixelType result_type;
/** \deprecated use argument_type and result_type
*/
typedef PixelType value_type;
/** Init functor for argument range <TT>[min, max]</TT>.
<TT>gamma</TT> values < 1 will increase brightness, > 1
will decrease it (gamma == 1 means no change).
*/
GammaFunctor(promote_type gamma,
argument_type const & min, argument_type const & max)
: gamma_(gamma),
min_(min),
diff_(max - min),
zero_(NumericTraits<promote_type>::zero()),
one_(NumericTraits<promote_type>::one())
{}
/** Calculate modified gray or color value
*/
result_type operator()(argument_type const & v) const
{
promote_type v1 = (v - min_) / diff_;
promote_type brighter = VIGRA_CSTD::pow(v1, gamma_);
return result_type(diff_ * brighter + min_);
}
private:
promote_type gamma_;
argument_type min_;
promote_type diff_, zero_, one_;
};
template <>
class GammaFunctor<unsigned char>
{
typedef NumericTraits<unsigned char>::RealPromote promote_type;
unsigned char lut[256];
public:
typedef unsigned char value_type;
GammaFunctor(promote_type gamma,
value_type const & min = 0, value_type const & max = 255)
{
GammaFunctor<promote_type> f(gamma, min, max);
for(int i = min; i <= max; ++i)
{
lut[i] = static_cast<unsigned char>(f(i)+0.5);
}
}
value_type operator()(value_type const & v) const
{
return lut[v];
}
};
#ifndef NO_PARTIAL_TEMPLATE_SPECIALIZATION
template <class ComponentType>
class GammaFunctor<RGBValue<ComponentType> >
{
typedef typename
NumericTraits<ComponentType>::RealPromote promote_type;
GammaFunctor<ComponentType> red, green, blue;
public:
typedef RGBValue<ComponentType> value_type;
GammaFunctor(promote_type gamma,
value_type const & min, value_type const & max)
: red(gamma, min.red(), max.red()),
green(gamma, min.green(), max.green()),
blue(gamma, min.blue(), max.blue())
{}
value_type operator()(value_type const & v) const
{
return value_type(red(v.red()), green(v.green()), blue(v.blue()));
}
};
#else // NO_PARTIAL_TEMPLATE_SPECIALIZATION
template <>
class GammaFunctor<RGBValue<int> >
{
typedef NumericTraits<int>::RealPromote promote_type;
GammaFunctor<int> red, green, blue;
public:
typedef RGBValue<int> value_type;
GammaFunctor(promote_type gamma,
value_type const & min, value_type const & max)
: red(gamma, min.red(), max.red()),
green(gamma, min.green(), max.green()),
blue(gamma, min.blue(), max.blue())
{}
value_type operator()(value_type const & v) const
{
return value_type(red(v.red()), green(v.green()), blue(v.blue()));
}
};
template <>
class GammaFunctor<RGBValue<float> >
{
typedef NumericTraits<float>::RealPromote promote_type;
GammaFunctor<float> red, green, blue;
public:
typedef RGBValue<float> value_type;
GammaFunctor(promote_type gamma,
value_type const & min, value_type const & max)
: red(gamma, min.red(), max.red()),
green(gamma, min.green(), max.green()),
blue(gamma, min.blue(), max.blue())
{}
value_type operator()(value_type const & v) const
{
return value_type(red(v.red()), green(v.green()), blue(v.blue()));
}
};
template <class PixelType>
class FunctorTraits<GammaFunctor<PixelType> >
: public FunctorTraitsBase<GammaFunctor<PixelType> >
{
public:
typedef VigraTrueType isUnaryFunctor;
};
#endif // NO_PARTIAL_TEMPLATE_SPECIALIZATION
template <>
class GammaFunctor<RGBValue<unsigned char> >
{
typedef NumericTraits<unsigned char>::RealPromote promote_type;
GammaFunctor<unsigned char> red, green, blue;
public:
typedef RGBValue<unsigned char> value_type;
GammaFunctor(promote_type gamma,
value_type const & min = value_type(0,0,0),
value_type const & max = value_type(255, 255, 255))
: red(gamma, min.red(), max.red()),
green(gamma, min.green(), max.green()),
blue(gamma, min.blue(), max.blue())
{}
value_type operator()(value_type const & v) const
{
return value_type(red(v.red()), green(v.green()), blue(v.blue()));
}
};
/********************************************************/
/* */
/* VectorNormFunctor */ /* VectorNormFunctor */
/* */ /* */
/********************************************************/ /********************************************************/
/** \brief A functor for computing the vector norm /** \brief A functor for computing the vector norm
Calculate the magnitude or norm from a given vector-valued Calculate the magnitude or norm from a given vector-valued
entity. The vector type will typically be some sort of entity. The vector type will typically be some sort of
ref vigra::TinyVector. If the vector is represented by a pair of ref vigra::TinyVector. If the vector is represented by a pair of
scalar-valued images, use \ref vigra::MagnitudeFunctor instead. scalar-valued images, use \ref vigra::MagnitudeFunctor instead.
At least, the vector type is required to have a function At least, the vector type is required to have a function
'<em>result</em><TT> = dot(v,v)</TT>'. '<em>result</em><TT> = dot(v,v)</TT>'.
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="transformimage_8hxx-source.html">vigra/t ransformimage.hxx</a>"<br> <b>\#include</b> \<<a href="transformimage_8hxx-source.html">vigra/ transformimage.hxx</a>\><br>
Namespace: vigra Namespace: vigra
\code \code
typedef vigra::TinyVector<float, 2> Vector; typedef vigra::TinyVector<float, 2> Vector;
vigra::BasicImage<Vector> grad(width, height); vigra::BasicImage<Vector> grad(width, height);
vigra::FImage magn(width,height); vigra::FImage magn(width,height);
... ...
vigra::transformImage(srcImageRange(grad), destImage(magn), vigra::transformImage(srcImageRange(grad), destImage(magn),
VectorNormFunctor<float>() VectorNormFunctor<float>()
); );
skipping to change at line 1213 skipping to change at line 1474
vector-valued entity. The vector type will typically be some vector-valued entity. The vector type will typically be some
sort of TinyVector. sort of TinyVector.
At least, the vector type is required to have a function At least, the vector type is required to have a function
'<em>result</em><TT> = dot(v,v)</TT>'. '<em>result</em><TT> = dot(v,v)</TT>'.
For an example of its usage see VectorNormFunctor For an example of its usage see VectorNormFunctor
<b> Traits defined:</b> <b> Traits defined:</b>
<tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType<tt>) <tt>FunctorTraits::isUnaryFunctor</tt> is true (<tt>VigraTrueType</tt>)
\see TinyVector, dot() \see TinyVector, dot()
*/ */
template <class ValueType> template <class ValueType>
class VectorNormSqFunctor class VectorNormSqFunctor
{ {
public: public:
/** the functor's argument type /** the functor's argument type
*/ */
typedef ValueType argument_type; typedef ValueType argument_type;
 End of changes. 31 change blocks. 
54 lines changed or deleted 308 lines changed or added


 tuple.hxx   tuple.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 49 skipping to change at line 49
#define VIGRA_TUPLE_HXX #define VIGRA_TUPLE_HXX
#include <utility> // for pair #include <utility> // for pair
namespace vigra { namespace vigra {
/*! \page TupleTypes Tuple Types /*! \page TupleTypes Tuple Types
pair, triple, tuple4, tuple5 pair, triple, tuple4, tuple5
<b>\#include</b> "<a href="utilities_8hxx-source.html">vigra/utilities. hxx</a>"<br> <b>\#include</b> \<<a href="utilities_8hxx-source.html">vigra/utilities .hxx</a>\><br>
Namespace: vigra Namespace: vigra
VIGRA defines tuple types \p vigra::triple, \p vigra::tuple4, \p vigra: :tuple5. VIGRA defines tuple types \p vigra::triple, \p vigra::tuple4, \p vigra: :tuple5.
In addition, \p std::pair is imported into namespace vigra from the C++ standard In addition, \p std::pair is imported into namespace vigra from the C++ standard
library. All these types are defined similarly: library. All these types are defined similarly:
<ul> <ul>
<li> They are parameterized by the respective number of types. For each tuple, <li> They are parameterized by the respective number of types. For each tuple,
a constructor is defined that takes that many arguments, e.g.: a constructor is defined that takes that many arguments, e.g.:
 End of changes. 3 change blocks. 
4 lines changed or deleted 4 lines changed or added


 utilities.hxx   utilities.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2002 by Ullrich Koethe */ /* Copyright 1998-2002 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 51 skipping to change at line 51
#include "config.hxx" #include "config.hxx"
#include "error.hxx" #include "error.hxx"
#include "metaprogramming.hxx" #include "metaprogramming.hxx"
#include "tuple.hxx" #include "tuple.hxx"
#include "diff2d.hxx" #include "diff2d.hxx"
#include "mathutil.hxx" #include "mathutil.hxx"
/*! \page Utilities Utilities /*! \page Utilities Utilities
Basic helper functionality needed throughout. Basic helper functionality needed throughout.
<DL> <UL style="list-style-image:url(documents/bullet.gif)">
<DT> <LI> \ref vigra::ArrayVector
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <BR>&nbsp;&nbsp;&nbsp;<em>replacement for std::vector</em>
\ref vigra::ArrayVector <LI> \ref RangesAndPoints
<DD><em>replacement for std::vector</em> <BR>&nbsp;&nbsp;&nbsp;<em>2-dimensional positions, extents, and re
<DT> ctangles</em>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref PixelNeighborhood
\ref RangesAndPoints <BR>&nbsp;&nbsp;&nbsp;<em>4- and 8-neighborhood definitions and ci
<DD><em>2-dimensional positions, extents, and rectangles</em> rculators</em>
<DT> <LI> \ref vigra::IteratorAdaptor
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <BR>&nbsp;&nbsp;&nbsp;<em>Quickly create STL-compatible 1D iterato
\ref PixelNeighborhood r adaptors</em>
<DD><em>4- and 8-neighborhood definitions and circulators</em> <LI> \ref TupleTypes
<DT> <BR>&nbsp;&nbsp;&nbsp;<em>pair, triple, tuple4, tuple5</em>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> <LI> \ref MathConstants
\ref vigra::IteratorAdaptor <BR>&nbsp;&nbsp;&nbsp;<em>M_PI, M_SQRT2</em>
<DD><em>Quickly create STL-compatible 1D iterator adaptors</em> </UL>
<DT>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref TupleTypes
<DD><em>pair, triple, tuple4, tuple5</em>
<DT>
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif">
\ref MathConstants
<DD><em>M_PI, M_SQRT2</em>
</DL>
*/ */
#endif // VIGRA_BASICS_HXX #endif // VIGRA_BASICS_HXX
 End of changes. 3 change blocks. 
29 lines changed or deleted 20 lines changed or added


 watersheds.hxx   watersheds.hxx 
/************************************************************************/ /************************************************************************/
/* */ /* */
/* Copyright 1998-2005 by Ullrich Koethe */ /* Copyright 1998-2005 by Ullrich Koethe */
/* Cognitive Systems Group, University of Hamburg, Germany */ /* Cognitive Systems Group, University of Hamburg, Germany */
/* */ /* */
/* This file is part of the VIGRA computer vision library. */ /* This file is part of the VIGRA computer vision library. */
/* ( Version 1.5.0, Dec 07 2006 ) */ /* ( Version 1.6.0, Aug 13 2008 ) */
/* The VIGRA Website is */ /* The VIGRA Website is */
/* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */ /* http://kogs-www.informatik.uni-hamburg.de/~koethe/vigra/ */
/* Please direct questions, bug reports, and contributions to */ /* Please direct questions, bug reports, and contributions to */
/* koethe@informatik.uni-hamburg.de or */ /* ullrich.koethe@iwr.uni-heidelberg.de or */
/* vigra@kogs1.informatik.uni-hamburg.de */ /* vigra@informatik.uni-hamburg.de */
/* */ /* */
/* Permission is hereby granted, free of charge, to any person */ /* Permission is hereby granted, free of charge, to any person */
/* obtaining a copy of this software and associated documentation */ /* obtaining a copy of this software and associated documentation */
/* files (the "Software"), to deal in the Software without */ /* files (the "Software"), to deal in the Software without */
/* restriction, including without limitation the rights to use, */ /* restriction, including without limitation the rights to use, */
/* copy, modify, merge, publish, distribute, sublicense, and/or */ /* copy, modify, merge, publish, distribute, sublicense, and/or */
/* sell copies of the Software, and to permit persons to whom the */ /* sell copies of the Software, and to permit persons to whom the */
/* Software is furnished to do so, subject to the following */ /* Software is furnished to do so, subject to the following */
/* conditions: */ /* conditions: */
/* */ /* */
skipping to change at line 370 skipping to change at line 370
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class Neighborhood = EightNeighborCode> class Neighborhood = EightNeighborCode>
unsigned int unsigned int
watersheds(SrcIterator upperlefts, SrcIterator lowerrights, SrcAcce ssor sa, watersheds(SrcIterator upperlefts, SrcIterator lowerrights, SrcAcce ssor sa,
DestIterator upperleftd, DestAccessor da, DestIterator upperleftd, DestAccessor da,
Neighborhood neighborhood = EightNeighborCode()) Neighborhood neighborhood = EightNeighborCode())
} }
\endcode \endcode
use argument objects in conjunction with \ref ArgumentObjectFactories: use argument objects in conjunction with \ref ArgumentObjectFactories :
\code \code
namespace vigra { namespace vigra {
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class Neighborhood = EightNeighborCode> class Neighborhood = EightNeighborCode>
unsigned int unsigned int
watersheds(triple<SrcIterator, SrcIterator, SrcAccessor> src, watersheds(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest, pair<DestIterator, DestAccessor> dest,
Neighborhood neighborhood = EightNeighborCode()) Neighborhood neighborhood = EightNeighborCode())
} }
\endcode \endcode
<b> Usage:</b> <b> Usage:</b>
<b>\#include</b> "<a href="watersheds_8hxx-source.html">vigra/watershed s.hxx</a>"<br> <b>\#include</b> \<<a href="watersheds_8hxx-source.html">vigra/watershe ds.hxx</a>\><br>
Namespace: vigra Namespace: vigra
Example: watersheds of the gradient magnitude. Example: watersheds of the gradient magnitude.
\code \code
vigra::BImage in(w,h); vigra::BImage in(w,h);
... // read input data ... // read input data
vigra::FImage gradx(x,y), grady(x,y), gradMag(x,y); vigra::FImage gradx(x,y), grady(x,y), gradMag(x,y);
gaussianGradient(srcImageRange(src), destImage(gradx), destImage(grady) , 3.0); gaussianGradient(srcImageRange(src), destImage(gradx), destImage(grady) , 3.0);
skipping to change at line 423 skipping to change at line 423
DestAccessor dest_accessor; DestAccessor dest_accessor;
// compare src values // compare src values
src_accessor(src_upperleft) <= src_accessor(src_upperleft) src_accessor(src_upperleft) <= src_accessor(src_upperleft)
// set result // set result
int label; int label;
dest_accessor.set(label, dest_upperleft); dest_accessor.set(label, dest_upperleft);
\endcode \endcode
*/ */
doxygen_overloaded_function(template <...> unsigned int watersheds)
template <class SrcIterator, class SrcAccessor, template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor, class DestIterator, class DestAccessor,
class Neighborhood> class Neighborhood>
unsigned int unsigned int
watersheds(SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa, watersheds(SrcIterator upperlefts, SrcIterator lowerrights, SrcAccessor sa,
DestIterator upperleftd, DestAccessor da, Neighborhood neighborh ood) DestIterator upperleftd, DestAccessor da, Neighborhood neighborh ood)
{ {
SImage orientationImage(lowerrights - upperlefts); SImage orientationImage(lowerrights - upperlefts);
SImage::traverser yo = orientationImage.upperLeft(); SImage::traverser yo = orientationImage.upperLeft();
 End of changes. 5 change blocks. 
5 lines changed or deleted 7 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/