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

## Function Documentation

template<... >
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 arguments explicitly:

        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>

        FImage img(w,h);
        FVector3Image bt(w,h);
        ...
        boundaryTensor(srcImageRange(img), destImage(bt), 2.0);

template<... >
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>

pass arguments explicitly:

        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);
        }

template<... >
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 arguments explicitly:

        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>

        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);

template<... >
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 accross 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 arguments explicitly:

        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>

        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()

template<... >
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 imput 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: By default, this function negates the second component of the vector in order to turn a left handed vector (the usual resul of convolution, e.g. a gradient filter, because `y` runs from top to bottom) into a right handed tensor (as is required by all tensor function in VIGRA). This behavior can be switched off by setting `negateComponent2 = false`.

Declarations:

pass arguments explicitly:

        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 = true);
        }

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 = true);
        }

Usage:

#include <vigra/tensorutilities.hxx>

        FImage img(w,h);
        FVector2Image gradient(w,h);
        FVector3Image tensor(w,h);

        gaussianGradient(srcImageRange(img), destImage(gradient), 2.0);
        vectorToTensor(srcImageRange(gradient), destImage(tensor));

template<... >
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. The original tensor must be defined in a right-handed coordinate system, and the angle of the tensor will then be given in mathematical positive (counter-clockwise) orientation, starting at the x-axis.

Declarations:

pass arguments explicitly:

        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>

        FVector3Image tensor(w,h);
        FVector3Image eigen(w,h);

        tensorEigenRepresentation(srcImageRange(tensor), destImage(eigen));

template<... >
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 arguments explicitly:

        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>

        FVector3Image tensor(w,h);
        FImage trace(w,h);

        tensorTrace(srcImageRange(tensor), destImage(trace));

template<... >
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 arguments explicitly:

        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>

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

        tensorTrace(srcImageRange(tensor), destImage(edgePart), destImage(cornerPart));

© 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.6.0 (13 Aug 2008)