36#ifndef VIGRA_TENSORUTILITIES_HXX
37#define VIGRA_TENSORUTILITIES_HXX
41#include "mathutil.hxx"
42#include "multi_shape.hxx"
141 "vectorToTensor(): input image must have 2 bands.");
143 "vectorToTensor(): output image must have 3 bands.");
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);
175template <
class SrcIterator,
class SrcAccessor,
176 class DestIterator,
class DestAccessor>
178void vectorToTensor(SrcIterator sul, SrcIterator slr, SrcAccessor src,
179 DestIterator dul, DestAccessor dest)
184template <
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);
194template <
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);
203template <
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);
293 "tensorEigenRepresentation(): input image must have 3 bands.");
295 "tensorEigenRepresentation(): output image must have 3 bands.");
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;
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);
322 dest.setComponent(0.5 * VIGRA_CSTD::atan2(
d3,
d2), d, 2);
328template <
class SrcIterator,
class SrcAccessor,
329 class DestIterator,
class DestAccessor>
332 pair<DestIterator, DestAccessor> dest)
337template <
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.");
423 "tensorTrace(): input image must have 3 bands.");
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);
440template <
class SrcIterator,
class SrcAccessor,
441 class DestIterator,
class DestAccessor>
443tensorTrace(triple<SrcIterator, SrcIterator, SrcAccessor> src,
444 pair<DestIterator, DestAccessor> dest)
446 tensorTrace(src.first, src.second, src.third, dest.first, dest.second);
449template <
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.");
550 "tensorToEdgeCorner(): input image must have 3 bands.");
551 vigra_precondition(edge.size(
edgeul) == 2,
552 "tensorToEdgeCorner(): edge image must have 2 bands.");
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;
572 edge.setComponent(
d4, e, 0);
573 if(
d2 == 0.0 &&
d3 == 0.0)
575 edge.setComponent(0.0, e, 1);
579 edge.setComponent(0.5 * VIGRA_CSTD::atan2(
d3,
d2), e, 1);
586template <
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);
598template <
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));
Class for a single RGB value.
Definition rgbvalue.hxx:128
size_type size() const
Definition tinyvector.hxx:913
void vectorToTensor(...)
Calculate the tensor (outer) product of a 2D vector with itself.
void tensorTrace(...)
Calculate the trace of a 2x2 tensor.
void tensorToEdgeCorner(...)
Decompose a symmetric 2x2 tensor into its edge and corner parts.
void tensorEigenRepresentation(...)
Calculate eigen representation of a symmetric 2x2 tensor.
FixedPoint16< IntBits, OverflowHandling > hypot(FixedPoint16< IntBits, OverflowHandling > v1, FixedPoint16< IntBits, OverflowHandling > v2)
Length of hypotenuse.
Definition fixedpoint.hxx:1640