36 #ifndef VIGRA_TENSORUTILITIES_HXX 
   37 #define VIGRA_TENSORUTILITIES_HXX 
   41 #include "mathutil.hxx" 
   42 #include "multi_shape.hxx" 
  134 template <
class SrcIterator, 
class SrcAccessor,
 
  135           class DestIterator, 
class DestAccessor>
 
  136 void vectorToTensor(SrcIterator sul, SrcIterator slr, SrcAccessor src,
 
  137                     DestIterator dul, DestAccessor dest,
 
  138                     bool negateComponent2)
 
  140     vigra_precondition(src.size(sul) == 2,
 
  141                        "vectorToTensor(): input image must have 2 bands.");
 
  142     vigra_precondition(dest.size(dul) == 3,
 
  143                        "vectorToTensor(): output image must have 3 bands.");
 
  145     int w = slr.x - sul.x;
 
  146     int h = slr.y - sul.y;
 
  148     for(
int y=0; y<h; ++y, ++sul.y, ++dul.y)
 
  150         typename SrcIterator::row_iterator s = sul.rowIterator();
 
  151         typename SrcIterator::row_iterator send = s + w;
 
  152         typename DestIterator::row_iterator d = dul.rowIterator();
 
  155             for(; s < send; ++s, ++d)
 
  157                 dest.setComponent(
sq(src.getComponent(s, 0)), d, 0);
 
  158                 dest.setComponent(-src.getComponent(s, 0)*src.getComponent(s, 1), d, 1);
 
  160                 dest.setComponent(
sq(src.getComponent(s, 1)), d, 2);
 
  165             for(; s < send; ++s, ++d)
 
  167                 dest.setComponent(
sq(src.getComponent(s, 0)), d, 0);
 
  168                 dest.setComponent(src.getComponent(s, 0)*src.getComponent(s, 1), d, 1);
 
  169                 dest.setComponent(
sq(src.getComponent(s, 1)), d, 2);
 
  175 template <
class SrcIterator, 
class SrcAccessor,
 
  176           class DestIterator, 
class DestAccessor>
 
  178 void vectorToTensor(SrcIterator sul, SrcIterator slr, SrcAccessor src,
 
  179                     DestIterator dul, DestAccessor dest)
 
  184 template <
class SrcIterator, 
class SrcAccessor,
 
  185           class DestIterator, 
class DestAccessor>
 
  188                pair<DestIterator, DestAccessor> d,
 
  189                bool negateComponent2)
 
  191     vectorToTensor(s.first, s.second, s.third, d.first, d.second, negateComponent2);
 
  194 template <
class SrcIterator, 
class SrcAccessor,
 
  195           class DestIterator, 
class DestAccessor>
 
  198                pair<DestIterator, DestAccessor> d)
 
  200     vectorToTensor(s.first, s.second, s.third, d.first, d.second, 
false);
 
  203 template <
class T1, 
class S1,
 
  207                MultiArrayView<2, T2, S2> dest,
 
  208                bool negateComponent2 = 
false)
 
  210     vigra_precondition(src.shape() == dest.shape(),
 
  211         "vectorToTensor(): shape mismatch between input and output.");
 
  212     vectorToTensor(srcImageRange(src), destImage(dest), negateComponent2);
 
  287 template <
class SrcIterator, 
class SrcAccessor,
 
  288           class DestIterator, 
class DestAccessor>
 
  290                                DestIterator dul, DestAccessor dest)
 
  292     vigra_precondition(src.size(sul) == 3,
 
  293                        "tensorEigenRepresentation(): input image must have 3 bands.");
 
  294     vigra_precondition(dest.size(dul) == 3,
 
  295                        "tensorEigenRepresentation(): output image must have 3 bands.");
 
  297     int w = slr.x - sul.x;
 
  298     int h = slr.y - sul.y;
 
  300     for(
int y=0; y<h; ++y, ++sul.y, ++dul.y)
 
  302         typename SrcIterator::row_iterator s = sul.rowIterator();
 
  303         typename SrcIterator::row_iterator send = s + w;
 
  304         typename DestIterator::row_iterator d = dul.rowIterator();
 
  305         for(; s < send; ++s, ++d)
 
  308                NumericTraits<typename SrcAccessor::component_type>::RealPromote TmpType;
 
  309             TmpType d1 = src.getComponent(s,0) + src.getComponent(s,2);
 
  310             TmpType d2 = src.getComponent(s,0) - src.getComponent(s,2);
 
  311             TmpType d3 = TmpType(2.0) * src.getComponent(s,1);
 
  312             TmpType d4 = (TmpType)
hypot(d2, d3);
 
  314             dest.setComponent(0.5 * (d1 + d4), d, 0); 
 
  315             dest.setComponent(0.5 * (d1 - d4), d, 1); 
 
  316             if(d2==0.0 && d3==0.0)
 
  318                 dest.setComponent(0, d, 2); 
 
  328 template <
class SrcIterator, 
class SrcAccessor,
 
  329           class DestIterator, 
class DestAccessor>
 
  332                           pair<DestIterator, DestAccessor> dest)
 
  337 template <
class T1, 
class S1,
 
  341                           MultiArrayView<2, T2, S2> dest)
 
  343     vigra_precondition(src.shape() == dest.shape(),
 
  344         "tensorEigenRepresentation(): shape mismatch between input and output.");
 
  417 template <
class SrcIterator, 
class SrcAccessor,
 
  418           class DestIterator, 
class DestAccessor>
 
  419 void tensorTrace(SrcIterator sul, SrcIterator slr, SrcAccessor src,
 
  420                  DestIterator dul, DestAccessor dest)
 
  422     vigra_precondition(src.size(sul) == 3,
 
  423                        "tensorTrace(): input image must have 3 bands.");
 
  425     int w = slr.x - sul.x;
 
  426     int h = slr.y - sul.y;
 
  428     for(
int y=0; y<h; ++y, ++sul.y, ++dul.y)
 
  430         typename SrcIterator::row_iterator s = sul.rowIterator();
 
  431         typename SrcIterator::row_iterator send = s + w;
 
  432         typename DestIterator::row_iterator d = dul.rowIterator();
 
  433         for(; s < send; ++s, ++d)
 
  435             dest.set(src.getComponent(s,0) + src.getComponent(s,2), d);
 
  440 template <
class SrcIterator, 
class SrcAccessor,
 
  441           class DestIterator, 
class DestAccessor>
 
  443 tensorTrace(triple<SrcIterator, SrcIterator, SrcAccessor> src,
 
  444             pair<DestIterator, DestAccessor> dest)
 
  446     tensorTrace(src.first, src.second, src.third, dest.first, dest.second);
 
  449 template <
class T1, 
class S1,
 
  453             MultiArrayView<2, T2, S2> dest)
 
  455     vigra_precondition(src.shape() == dest.shape(),
 
  456         "tensorTrace(): shape mismatch between input and output.");
 
  542 template <
class SrcIterator, 
class SrcAccessor,
 
  543           class DestIterator1, 
class DestAccessor1,
 
  544           class DestIterator2, 
class DestAccessor2>
 
  546                         DestIterator1 edgeul, DestAccessor1 
edge,
 
  547                         DestIterator2 cornerul, DestAccessor2 corner)
 
  549     vigra_precondition(src.size(sul) == 3,
 
  550                        "tensorToEdgeCorner(): input image must have 3 bands.");
 
  551     vigra_precondition(edge.size(edgeul) == 2,
 
  552                        "tensorToEdgeCorner(): edge image must have 2 bands.");
 
  554     int w = slr.x - sul.x;
 
  555     int h = slr.y - sul.y;
 
  557     for(
int y=0; y<h; ++y, ++sul.y, ++edgeul.y, ++cornerul.y)
 
  559         typename SrcIterator::row_iterator s = sul.rowIterator();
 
  560         typename SrcIterator::row_iterator send = s + w;
 
  561         typename DestIterator1::row_iterator e = edgeul.rowIterator();
 
  562         typename DestIterator2::row_iterator c = cornerul.rowIterator();
 
  563         for(; s < send; ++s, ++e, ++c)
 
  566                NumericTraits<typename SrcAccessor::component_type>::RealPromote TmpType;
 
  567             TmpType d1 = src.getComponent(s,0) + src.getComponent(s,2);
 
  568             TmpType d2 = src.getComponent(s,0) - src.getComponent(s,2);
 
  569             TmpType d3 = 2.0 * src.getComponent(s,1);
 
  570             TmpType d4 = (TmpType)
hypot(d2, d3);
 
  572             edge.setComponent(d4, e, 0); 
 
  573             if(d2 == 0.0 && d3 == 0.0)
 
  575                 edge.setComponent(0.0, e, 1); 
 
  581             corner.set(d1 - d4, c); 
 
  586 template <
class SrcIterator, 
class SrcAccessor,
 
  587           class DestIterator1, 
class DestAccessor1,
 
  588           class DestIterator2, 
class DestAccessor2>
 
  591                    pair<DestIterator1, DestAccessor1> edge,
 
  592                    pair<DestIterator2, DestAccessor2> corner)
 
  595                        edge.first, edge.second, corner.first, corner.second);
 
  598 template <
class T1, 
class S1,
 
  599           class T21, 
class S21,
 
  600           class T22, 
class S22>
 
  603                    MultiArrayView<2, T21, S21> edge,
 
  604                    MultiArrayView<2, T22, S22> corner)
 
  606     vigra_precondition(src.shape() == edge.shape(),
 
  607         "tensorToEdgeCorner(): shape mismatch between input and output.");
 
  609                        destImage(edge), destImage(corner));
 
FixedPoint16< 2, OverflowHandling > atan2(FixedPoint16< IntBits, OverflowHandling > y, FixedPoint16< IntBits, OverflowHandling > x)
Arctangent. Accuracy better than 1/3 degree (9 significant bits). 
Definition: fixedpoint.hxx:1654
void tensorEigenRepresentation(...)
Calculate eigen representation of a symmetric 2x2 tensor. 
void vectorToTensor(...)
Calculate the tensor (outer) product of a 2D vector with itself. 
FixedPoint16< IntBits, OverflowHandling > hypot(FixedPoint16< IntBits, OverflowHandling > v1, FixedPoint16< IntBits, OverflowHandling > v2)
Length of hypotenuse. 
Definition: fixedpoint.hxx:1640
NumericTraits< T >::Promote sq(T t)
The square function. 
Definition: mathutil.hxx:382
void tensorToEdgeCorner(...)
Decompose a symmetric 2x2 tensor into its edge and corner parts. 
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays. 
std::pair< typename vigra::GridGraph< N, DirectedTag >::edge_descriptor, bool > edge(typename vigra::GridGraph< N, DirectedTag >::vertex_descriptor const &u, typename vigra::GridGraph< N, DirectedTag >::vertex_descriptor const &v, vigra::GridGraph< N, DirectedTag > const &g)
Return the pair (edge_descriptor, true) when an edge between vertices u and v exists, or (lemon::INVALID, false) otherwise (API: boost). 
Definition: multi_gridgraph.hxx:2990
void tensorTrace(...)
Calculate the trace of a 2x2 tensor.