| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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_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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|
| 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 | |
|