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></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öthe: <a href="http://kogs-www.informatik.uni-hamburg.de/~koet he/papers/abstracts/polarfilters.html"> | U. Kö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> <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> <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> <em>Resampling convolution filters</em> | |||
Array etc.)</em> | <LI> \ref StandardConvolution | |||
<DT> | <BR> <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> <em>Generic 2-dimensional discrete convoluti | |||
<DT> | on kernel </em> | |||
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> | <LI> \ref SeparableConvolution | |||
\ref StandardConvolution | <BR> <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> <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> <em>Recursive filters (1st and 2nd order)</e | |||
<DT> | m> | |||
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> | <LI> \ref NonLinearDiffusion | |||
\ref SeparableConvolution | <BR> <em>Edge-preserving smoothing </em> | |||
<DD> <em>1D convolution and separable filters in 2 dimensions </em> | <LI> \ref BorderTreatmentMode | |||
<DT> | <BR> <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> <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örstner: <em> "A feature based correspondence algorithms for image | [W. Fö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ängigen | according to [K. Rohr: <em>"Untersuchung von grauwertabhä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ür Nachrichtensysteme, Univ. Karlsruhe, 198 7, see also | Diploma thesis, Inst. fü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>::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>::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>::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>::reference</tt></td> | <td><tt>IteratorTraits<ImageIterator>::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>::index_reference</tt></td> | <td><tt>IteratorTraits<ImageIterator>::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>::pointer</tt></td> | <td><tt>IteratorTraits<ImageIterator>::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>::difference_type</tt></td> | <td><tt>IteratorTraits<ImageIterator>::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>::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>::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>::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>::DefaultAccessor</tt></td> | <td><tt>IteratorTraits<ImageIterator>::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>::default_accessor</tt></td> | <td><tt>IteratorTraits<ImageIterator>::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>::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<int>::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 ,...></tt> | /** Number of rows of a matrix represented as a <tt>MultiArrayView<2, . ..></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,...></tt> | /** Number of columns of a matrix represented as a <tt>MultiArrayView<2 , ...></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 ></tt>. | <tt>RGBValue<T></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> <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> <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> <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, ..></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></TT>)</td> | <td>the iterator's multi-dimensional difference type (<TT>TinyVector<Mu ltiArrayIndex, N></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, ...></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>::</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<FUNCTOR>::</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<FUNCTOR>::</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<FUNCTOR>::</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<FUNCTOR>::</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> <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> <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> <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> <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>::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ö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, ///< | NotAtBorder = 0, ///< | |||
RightBorder = 1, ///< | RightBorder = 1, ///< | |||
LeftBorder = 2, ///< | LeftBorder = 2, ///< | |||
TopBorder = 4, ///< | TopBorder = 4, ///< | |||
BottomBorder = 8, ///< | BottomBorder = 8, ///< | |||
TopRightBorder = TopBorder | RightBorder, ///< | FrontBorder = 16, ///< | |||
TopLeftBorder = TopBorder | LeftBorder, ///< | RearBorder = 32, | |||
BottomLeftBorder = BottomBorder | LeftBorder, ///< | TopRightBorder = TopBorder | RightBorder, //5 | |||
BottomRightBorder = BottomBorder | RightBorder ///< | 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, ///< | Error = -1, ///< | |||
East = 0, ///< | East = 0, ///< | |||
North, ///< | North, ///< | |||
West, ///< | West, ///< | |||
South, ///< | South, ///< | |||
DirectionCount, ///< | DirectionCount, ///< | |||
CausalFirst = North, ///< | CausalFirst = North, ///< | |||
CausalLast = West, ///< | CausalLast = West, ///< | |||
AntiCausalFirst = South, ///< | AntiCausalFirst = South, ///< | |||
AntiCausalLast = East ///< | AntiCausalLast = East, ///< | |||
}; | ||||
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, ///< | Error = -1, ///< | |||
skipping to change at line 395 | skipping to change at line 425 | |||
North, ///< | North, ///< | |||
NorthWest, ///< | NorthWest, ///< | |||
West, ///< | West, ///< | |||
SouthWest, ///< | SouthWest, ///< | |||
South, ///< | South, ///< | |||
SouthEast, ///< | SouthEast, ///< | |||
DirectionCount, ///< | DirectionCount, ///< | |||
CausalFirst = NorthEast, ///< | CausalFirst = NorthEast, ///< | |||
CausalLast = West, ///< | CausalLast = West, ///< | |||
AntiCausalFirst = SouthWest, ///< | AntiCausalFirst = SouthWest, ///< | |||
AntiCausalLast = East ///< | AntiCausalLast = East, ///< | |||
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<ORDER, double></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<double></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öthe: | Ullrich Kö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 <= 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 <= 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 <= size().x-1</tt> and <tt>0 <= y <= 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 <= width()-1</tt>. | Equivalent to <tt>0 <= x <= 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 <= height()-1</tt>. | Equivalent to <tt>0 <= y <= 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 <= width()-1</tt> and <tt>0 < = y <= 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 < x < 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 < y < 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> <em>init images or image borders </em> | |||
\ref InitAlgo | <LI> \ref InspectAlgo | |||
<DD><em>init images or image borders </em> | <BR> <em>Apply read-only functor to every pixel< | |||
<DT> | /em> | |||
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> | <LI> \ref InspectFunctor | |||
\ref InspectAlgo | <BR> <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> <em>Copy images or regions</em> | |||
\ref InspectFunctor | <LI> \ref TransformAlgo | |||
<DD><em>Functors which report image statistics</em> | <BR> <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> <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> <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> <em>frequently used binary transformations | |||
<DT> | functors</em> | |||
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> | <LI> \ref MultiPointoperators | |||
\ref TransformFunctor | <BR> <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 > 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> <em>replacement for std::vector</em> | |||
\ref vigra::ArrayVector | <LI> \ref RangesAndPoints | |||
<DD><em>replacement for std::vector</em> | <BR> <em>2-dimensional positions, extents, and re | |||
<DT> | ctangles</em> | |||
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> | <LI> \ref PixelNeighborhood | |||
\ref RangesAndPoints | <BR> <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> <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> <em>pair, triple, tuple4, tuple5</em> | |||
<IMG BORDER=0 ALT="-" SRC="documents/bullet.gif"> | <LI> \ref MathConstants | |||
\ref vigra::IteratorAdaptor | <BR> <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 | |||