vigra - Tensor Image Processing

[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

| Tensor Image Processing |

## Functions
template<... >
void | boundaryTensor (...)
| Calculate the boundary tensor for a scalar valued image. More...
template<... >
void | boundaryTensor1 (...)
| Boundary tensor variant. More...
template<... >
void | gradientEnergyTensor (...)
| Calculate the gradient energy tensor for a scalar valued image. More...
template<... >
void | hourGlassFilter (...)
| Anisotropic tensor smoothing with the hourglass filter. More...
template<... >
void | tensorEigenRepresentation (...)
| Calculate eigen representation of a symmetric 2x2 tensor. More...
template<... >
void | tensorToEdgeCorner (...)
| Decompose a symmetric 2x2 tensor into its edge and corner parts. More...
template<... >
void | tensorTrace (...)
| Calculate the trace of a 2x2 tensor. More...
template<... >
void | vectorToTensor (...)
| Calculate the tensor (outer) product of a 2D vector with itself. More...

## Detailed Description

## Function Documentation

void vigra::boundaryTensor | ( |  | ... | ) |

Calculate the boundary tensor for a scalar valued image.

These functions calculate a spatial domain approximation of the boundary tensor as described in

U. Köthe: "Integrated Edge and Junction Detection with the Boundary Tensor", in: ICCV 03, Proc. of 9th Intl. Conf. on Computer Vision, Nice 2003, vol. 1, pp. 424-431, Los Alamitos: IEEE Computer Society, 2003

with the Laplacian of Gaussian as the underlying bandpass filter (see rieszTransformOfLOG()). The output image must have 3 bands which will hold the tensor components in the order t11, t12 (== t21), t22. The function boundaryTensor1() with the same interface implements a variant of the boundary tensor where the 0th-order Riesz transform has been dropped, so that the tensor is no longer sensitive to blobs.

Declarations:

pass 2D array views:

namespace vigra {
template <class T1, class S1,
class T2, class S2>
void
boundaryTensor(MultiArrayView<2, T1, S1> const & src,
MultiArrayView<2, T2, S2> dest,
double scale);
}

show deprecated declarations

pass Image Iterators and Data Accessors :
namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void boundaryTensor(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
DestIterator dupperleft, DestAccessor dest,
double scale);
}

use argument objects in conjunction with Argument Object Factories :

namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void boundaryTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest,
double scale);
}

Usage:

#include <vigra/boundarytensor.hxx>
Namespace: vigra

MultiArray<2, float> img(w,h);
MultiArray<2, TinyVector<float, 3> bt(w,h);
...
boundaryTensor(img, bt, 2.0);

Examples:
  boundarytensor.cxx.

void vigra::boundaryTensor1 | ( |  | ... | ) |

Boundary tensor variant.

This function implements a variant of the boundary tensor where the 0th-order Riesz transform has been dropped, so that the tensor is no longer sensitive to blobs. See boundaryTensor() for more detailed documentation.

Declarations:

#include <vigra/boundarytensor.hxx>
Namespace: vigra

pass 2D array views:

namespace vigra {
template <class T1, class S1,
class T2, class S2>
void
boundaryTensor1(MultiArrayView<2, T1, S1> const & src,
MultiArrayView<2, T2, S2> dest,
double scale);
}

show deprecated declarations

pass Image Iterators and Data Accessors :
namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void boundaryTensor1(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
DestIterator dupperleft, DestAccessor dest,
double scale);
}

use argument objects in conjunction with Argument Object Factories :

namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void boundaryTensor1(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest,
double scale);
}

void vigra::gradientEnergyTensor | ( |  | ... | ) |

Calculate the gradient energy tensor for a scalar valued image.

These function calculates the gradient energy tensor (GET operator) as described in

M. Felsberg, U. Köthe: "GET: The Connection Between Monogenic Scale-Space and Gaussian Derivatives", in: R. Kimmel, N. Sochen, J. Weickert (Eds.): Scale Space and PDE Methods in Computer Vision, Proc. of Scale-Space 2005, Lecture Notes in Computer Science 3459, pp. 192-203, Heidelberg: Springer, 2005.

U. Köthe, M. Felsberg: "Riesz-Transforms Versus Derivatives: On the Relationship Between the Boundary Tensor and the Energy Tensor", in: ditto, pp. 179-191.

with the given filters: The derivative filter derivKernel is applied to the appropriate image dimensions in turn (see the papers above for details), and the other dimension is smoothed with smoothKernel. The kernels can be as small as 3x1, e.g. [0.5, 0, -0.5] and [3.0/16.0, 10.0/16.0, 3.0/16.0] respectively. The output image must have 3 bands which will hold the tensor components in the order t11, t12 (== t21), t22. The signs of the output are adjusted for a right-handed coordinate system. Thus, orientations derived from the tensor will be in counter-clockwise (mathematically positive) order, with the x-axis at zero degrees (this is the standard in all VIGRA functions that deal with orientation).

Declarations:

pass 2D array views:

namespace vigra {
template <class T1, class S1,
class T2, class S2>
void
gradientEnergyTensor(MultiArrayView<2, T1, S1> const & src,
MultiArrayView<2, T2, S2> dest,
Kernel1D<double> const & derivKernel, Kernel1D<double> const & smoothKernel);
}

show deprecated declarations

pass Image Iterators and Data Accessors :
namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void gradientEnergyTensor(SrcIterator supperleft, SrcIterator slowerright, SrcAccessor src,
DestIterator dupperleft, DestAccessor dest,
Kernel1D<double> const & derivKernel, Kernel1D<double> const & smoothKernel);
}

use argument objects in conjunction with Argument Object Factories :

namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void gradientEnergyTensor(triple<SrcIterator, SrcIterator, SrcAccessor> src,
pair<DestIterator, DestAccessor> dest,
Kernel1D<double> const & derivKernel, Kernel1D<double> const & smoothKernel);
}

Usage:

#include <vigra/gradient_energy_tensor.hxx>
Namespace: vigra

MultiArray<2, float> img(w,h);
MultiArray<2, TinyVector<float, 3> > get(w,h);
Kernel1D<double> grad, smooth;
grad.initGaussianDerivative(0.7, 1);
smooth.initGaussian(0.7);
...
gradientEnergyTensor(img, get, grad, smooth);

show deprecated examples

FImage img(w,h);
FVector3Image get(w,h);
Kernel1D<double> grad, smooth;
grad.initGaussianDerivative(0.7, 1);
smooth.initGaussian(0.7);
...
gradientEnergyTensor(srcImageRange(img), destImage(get), grad, smooth);

void vigra::hourGlassFilter | ( |  | ... | ) |

Anisotropic tensor smoothing with the hourglass filter.

This function implements anisotropic tensor smoothing by an hourglass-shaped filters as described in

U. Köthe: "Edge and Junction Detection with an Improved Structure Tensor", in: Proc. of 25th DAGM Symposium, Magdeburg 2003, Lecture Notes in Computer Science 2781, pp. 25-32, Heidelberg: Springer, 2003

It is closely related to the structure tensor (see structureTensor()), but replaces the linear tensor smoothing with a smoothing along edges only. Smoothing across edges is largely suppressed. This means that the image structure is preserved much better because nearby features such as parallel edges are not blended into each other.

The hourglass filter is typically applied to a gradient tensor, i.e. the Euclidean product of the gradient with itself, which can be obtained by a gradient operator followed with vectorToTensor(), see example below. The hourglass shape of the filter can be interpreted as indicating the likely continuations of a local edge element. The parameter `sigma` determines the radius of the hourglass (i.e. how far the influence of the edge element reaches), and `rho` controls its opening angle (i.e. how narrow the edge orientation os followed). Recommended values are `sigma = 1.4` (or, more generally, two to three times the scale of the gradient operator used in the first step), and `rho = 0.4` which corresponds to an opening angle of 22.5 degrees to either side of the edge.

Declarations:

pass 2D array views:

namespace vigra {
template <class T1, class S1,
class T2, class S2>
void
hourGlassFilter(MultiArrayView<2, T1, S1> const & src,
MultiArrayView<2, T2, S2> dest,
double sigma, double rho);
}

show deprecated declarations

pass Image Iterators and Data Accessors :
namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void hourGlassFilter(SrcIterator sul, SrcIterator slr, SrcAccessor src,
DestIterator dul, DestAccessor dest,
double sigma, double rho);
}

use argument objects in conjunction with Argument Object Factories :

namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
inline
void hourGlassFilter(triple<SrcIterator, SrcIterator, SrcAccessor> s,
pair<DestIterator, DestAccessor> d,
double sigma, double rho);
}

Usage:

#include <vigra/orientedtensorfilters.hxx>
Namespace: vigra

MultiArray<2, float> img(w,h);
MultiArray<2, TinyVector<float, 2> > gradient(w,h);
MultiArray<2, TinyVector<float, 3> > tensor(w,h), smoothedTensor(w,h);
gaussianGradient(img, gradient, 1.0);
vectorToTensor(gradient, tensor);
hourGlassFilter(tensor, smoothedTensor, 2.0, 0.4);

show deprecated examples

FImage img(w,h);
FVector2Image gradient(w,h);
FVector3Image tensor(w,h), smoothedTensor(w,h);
gaussianGradient(srcImageRange(img), destImage(gradient), 1.0);
vectorToTensor(srcImageRange(gradient), destImage(tensor));
hourGlassFilter(srcImageRange(tensor), destImage(smoothedTensor), 2.0, 0.4);

See Also
  vectorToTensor()

void vigra::vectorToTensor | ( |  | ... | ) |

Calculate the tensor (outer) product of a 2D vector with itself.

This function is useful to transform vector images into a tensor representation that can be used as input to tensor based processing and analysis functions (e.g. tensor smoothing). The input pixel type must be vectors of length 2, whereas the output must contain vectors of length 3 which will represent the tensor components in the order t11, t12 (== t21 due to symmetry), t22.

Note: In order to account for the left-handedness of the image coordinate system, the second tensor component (t12) can be negated by setting `negateComponent2 = false`. Angles will then be interpreted counter-clockwise rather than clockwise. By default, this behavior is switched off.

Declarations:

pass 2D array views:

namespace vigra {
template <class T1, class S1,
class T2, class S2>
void
vectorToTensor(MultiArrayView<2, T1, S1> const & src,
MultiArrayView<2, T2, S2> dest,
bool negateComponent2 = false);
}

show deprecated declarations

pass Image Iterators and Data Accessors :
namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void vectorToTensor(SrcIterator sul, SrcIterator slr, SrcAccessor src,
DestIterator dul, DestAccessor dest,
bool negateComponent2 = false);
}

use argument objects in conjunction with Argument Object Factories :

namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void vectorToTensor(triple<SrcIterator, SrcIterator, SrcAccessor> s,
pair<DestIterator, DestAccessor> d,
bool negateComponent2 = false);
}

Usage:

#include <vigra/tensorutilities.hxx>
Namespace: vigra

MultiArray<2, float> img(w,h);
MultiArray<2, TinyVector<float, 2> > gradient(w,h);
MultiArray<2, TinyVector<float, 3> > tensor(w,h);
...
gaussianGradient(img, gradient, 2.0);
vectorToTensor(gradient, tensor);

show deprecated examples

FImage img(w,h);
FVector2Image gradient(w,h);
FVector3Image tensor(w,h);
gaussianGradient(srcImageRange(img), destImage(gradient), 2.0);
vectorToTensor(srcImageRange(gradient), destImage(tensor));

void vigra::tensorEigenRepresentation | ( |  | ... | ) |

Calculate eigen representation of a symmetric 2x2 tensor.

This function turns a 3-band image representing the tensor components t11, t12 (== t21 due to symmetry), t22 into the a 3-band image holding the eigen representation e1, e2, and angle, where e1 > e2. When the tensor is defined in a left-handed coordinate system (the default on images), the angle will then be given in clockwise orientation, starting at the x-axis. Otherwise, it will be given in counter-clockwise orientation.

Declarations:

pass 2D array views:

namespace vigra {
template <class T1, class S1,
class T2, class S2>
void
tensorEigenRepresentation(MultiArrayView<2, T1, S1> const & src,
MultiArrayView<2, T2, S2> dest);
}

show deprecated declarations

pass Image Iterators and Data Accessors :
namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void tensorEigenRepresentation(SrcIterator sul, SrcIterator slr, SrcAccessor src,
DestIterator dul, DestAccessor dest);
}

use argument objects in conjunction with Argument Object Factories :

namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void tensorEigenRepresentation(triple<SrcIterator, SrcIterator, SrcAccessor> s,
pair<DestIterator, DestAccessor> d);
}

Usage:

#include <vigra/tensorutilities.hxx>
Namespace: vigra

MultiArray<2, TinyVector<float, 3> > tensor(w,h),
eigen(w,h);
tensorEigenRepresentation(tensor, eigen);

show deprecated examples

FVector3Image tensor(w,h);
FVector3Image eigen(w,h);
tensorEigenRepresentation(srcImageRange(tensor), destImage(eigen));

void vigra::tensorTrace | ( |  | ... | ) |

Calculate the trace of a 2x2 tensor.

This function turns a 3-band image representing the tensor components t11, t12 (== t21 due to symmetry), t22 into the a 1-band image holding the tensor trace t11 + t22.

Declarations:

pass 2D array views:

namespace vigra {
template <class T1, class S1,
class T2, class S2>
void
tensorTrace(MultiArrayView<2, T1, S1> const & src,
MultiArrayView<2, T2, S2> dest);
}

show deprecated declarations

pass Image Iterators and Data Accessors :
namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void tensorTrace(SrcIterator sul, SrcIterator slr, SrcAccessor src,
DestIterator dul, DestAccessor dest);
}

use argument objects in conjunction with Argument Object Factories :

namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator, class DestAccessor>
void tensorTrace(triple<SrcIterator, SrcIterator, SrcAccessor> s,
pair<DestIterator, DestAccessor> d);
}

Usage:

#include <vigra/tensorutilities.hxx>
Namespace: vigra

MultiArray<2, TinyVector<float, 3> > tensor(w,h);
MultiArray<2, float> trace(w,h);
tensorTrace(tensor, trace);

show deprecated examples

FVector3Image tensor(w,h);
FImage trace(w,h);
tensorTrace(srcImageRange(tensor), destImage(trace));

Examples:
  boundarytensor.cxx.

void vigra::tensorToEdgeCorner | ( |  | ... | ) |

Decompose a symmetric 2x2 tensor into its edge and corner parts.

This function turns a 3-band image representing the tensor components t11, t12 (== t21 due to symmetry), t22 into the a 2-band image holding the tensor's edgeness (difference of the tensor's eigenvalues) and orientation, and a 1-band image representing its corner part (equal to the twice the small eigen value). The original tensor must be positive definite and defined in a right-handed coordinate system (e.g. the tensor resulting from boundaryTensor()).

Declarations:

pass 2D array views:

namespace vigra {
template <class T1, class S1,
class T21, class S21,
class T22, class S22>
void
tensorToEdgeCorner(MultiArrayView<2, T1, S1> const & src,
MultiArrayView<2, T21, S21> edge,
MultiArrayView<2, T22, S22> corner);
}

show deprecated declarations

pass Image Iterators and Data Accessors :
namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator1, class DestAccessor1,
class DestIterator2, class DestAccessor2>
void tensorToEdgeCorner(SrcIterator sul, SrcIterator slr, SrcAccessor src,
DestIterator1 edgeul, DestAccessor1 edge,
DestIterator2 cornerul, DestAccessor2 corner);
}

use argument objects in conjunction with Argument Object Factories :

namespace vigra {
template <class SrcIterator, class SrcAccessor,
class DestIterator1, class DestAccessor1,
class DestIterator2, class DestAccessor2>
void tensorToEdgeCorner(triple<SrcIterator, SrcIterator, SrcAccessor> s,
pair<DestIterator1, DestAccessor1> edge,
pair<DestIterator2, DestAccessor2> corner);
}

Usage:

#include <vigra/tensorutilities.hxx>
Namespace: vigra

MultiArray<2, TinyVector<float, 3> > tensor(w,h);
MultiArray<2, TinyVector<float, 2> > edgePart(w,h);
MultiArray<2, float> cornerPart(w,h);
...
tensorTrace(tensor, edgePart, cornerPart);

show deprecated examples

FVector3Image tensor(w,h);
FVector2Image edgePart(w,h);
FImage cornerPart(w,h);
tensorTrace(srcImageRange(tensor), destImage(edgePart), destImage(cornerPart));

Examples:
  boundarytensor.cxx.

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.11.1 (Fri May 19 2017)