Classes | Modules | Defines | Functions

Gabor Filters
[Linear Filters]

This module collects functions related to Gabor filtering. More...

Classes

struct  GaborFilter< FLOAT >
 This is a user-friendlier controlling structure for Gabor filtering. More...
struct  GaborFilter3D< FLOAT >
 This is a controlling structure for 3D (2D+t) Gabor filtering. More...
struct  GaborFilter4D< FLOAT >
 This is a controlling structure for 4D (3D+t) Gabor filtering. More...
struct  GaborConvolution3D
 This structure defines arbitrary 3D Gabor filter from a computational point of view. More...

Modules

 oriented Gabor Filters and support
 optical flow closely related filtering and support

Defines

#define ONEPERIOD   100.0

Functions

template<typename FLOAT >
void RotateBBox (int &x, int &y, const FLOAT phi)
template<typename FLOAT >
void RotateBBox (FLOAT &x, FLOAT &y, const FLOAT phi)
template<typename FLOAT >
void RotateBBox (int &x, int &y, int &z, const FLOAT phi, const FLOAT psi)
template<typename FLOAT >
void RotateBBox (FLOAT &x, FLOAT &y, FLOAT &z, const FLOAT phi, const FLOAT psi)
template<typename FLOAT >
FLOAT GetFrequency (const FLOAT period)
template<typename FLOAT >
FLOAT GetPeriod (const FLOAT frequency)
template<typename FLOAT >
int SuggestFilterLengths (struct GaborFilter3D< FLOAT > &spec)
template<typename FLOAT >
int AlignGaussianPartToXYT (struct GaborFilter3D< FLOAT > &spec)
template<class VOXEL , typename FLOAT >
int CreateSeparableGaborFilter (struct GaborFilter3D< FLOAT > const &spec, struct Separable3DFilter< VOXEL > &filter)
template<class VOXEL , typename FLOAT >
int SeparableGaborFiltering (Image3d< VOXEL > const &in, Image3d< VOXEL > &out, struct GaborFilter3D< FLOAT > const &filter)
template<class VOXEL , typename FLOAT >
int RotatedGaborFiltering (Image3d< VOXEL > const &in, Image3d< VOXEL > &out, struct GaborFilter3D< FLOAT > const &filter)
template<class VOXEL , class FLOAT >
int GetGaborImpulseResponse (Image3d< VOXEL > &res, const VOXEL impulse, struct GaborFilter3D< FLOAT > const &f)
template<class VOXEL , typename FLOAT >
int FullGaborFiltering (Image3d< VOXEL > const &in, Image3d< VOXEL > &out, struct GaborFilter3D< FLOAT > const &f)
template<class VOXEL , typename FLOAT >
int FullGaborFilteringExtended (Image3d< VOXEL > const &in, Image3d< VOXEL > &out, struct GaborFilter3D< FLOAT > const &f)
template<class VOXEL , typename FLOAT >
int FullGaborFilteringAligned (Image3d< VOXEL > const &in, Image3d< VOXEL > &out, struct GaborFilter3D< FLOAT > const &f)
template<class VOXEL , typename FLOAT >
int StagedGaborFiltering (Image3d< VOXEL > const &in, Image3d< VOXEL > &outRe, Image3d< VOXEL > &outIm, struct GaborFilter3D< FLOAT > const &f, const char method='U')
template<class VOXEL , typename FLOAT >
int IIRedGaborFiltering (Image3d< VOXEL > const &in, Image3d< VOXEL > &outRe, Image3d< VOXEL > &outIm, struct GaborFilter3D< FLOAT > const &f)
template<class VOXEL , typename FLOAT >
int IIRedGaborFilteringZeroDC (Image3d< VOXEL > const &in, Image3d< VOXEL > &outRe, Image3d< VOXEL > &outIm, struct GaborFilter3D< FLOAT > const &f)
template<class VOXEL , typename FLOAT >
int Staged2GaborFiltering (Image3d< VOXEL > const &In, Image3d< VOXEL > *OutRe[2], Image3d< VOXEL > *OutIm[2], struct GaborFilter3D< FLOAT > const &f)
template<class VOXEL , typename FLOAT >
int Staged4GaborFiltering (Image3d< VOXEL > const &In, Image3d< VOXEL > *OutRe[4], Image3d< VOXEL > *OutIm[4], struct GaborFilter3D< FLOAT > const &f)
template<class VOXEL , typename FLOAT >
int ApplyGaborBank (Image3d< VOXEL > const &In, Image3d< VOXEL > **OutRe, Image3d< VOXEL > **OutIm, struct GaborFilter3D< FLOAT > const &f, const int no)
template<typename FLOAT >
int PrepareGaborBank (struct GaborFilter3D< FLOAT > const &f, const int no, struct GaborConvolution3D **convs)
template<class VOXEL >
int ApplyGaborBank (Image3d< VOXEL > const &In, Image3d< VOXEL > **OutRe, Image3d< VOXEL > **OutIm, struct GaborConvolution3D const *convs)
template<class VOXEL >
int ApplyGaborBank2 (Image3d< VOXEL > const &In, Image3d< VOXEL > **OutRe, Image3d< VOXEL > **OutIm, struct GaborConvolution3D const *convs)
template<class VOXEL >
int ApplyGaborBank2_DC (Image3d< VOXEL > const &In, Image3d< VOXEL > **OutRe, Image3d< VOXEL > **OutIm, struct GaborConvolution3D const *convs)
template<class VOXEL , typename FLOAT >
int StagedGaborEnergy (Image3d< VOXEL > const &in, Image3d< VOXEL > &out, struct GaborFilter3D< FLOAT > const &f)
template<class VOXEL >
int GaborEnergy (Image3d< VOXEL > const &inRe, Image3d< VOXEL > const &inIm, Image3d< VOXEL > &out)
template<class VOXEL >
int GaborPhase (Image3d< VOXEL > const &inRe, Image3d< VOXEL > const &inIm, Image3d< VOXEL > &out)
template<class VOXEL >
void PurgeSmallVoxels (Image3d< VOXEL > &im, const VOXEL limit=0.0001)
template<typename FLOAT >
int GetGaborEnergyImage (Image3d< FLOAT > &out, struct GaborFilter3D< FLOAT > const &f, const int wxF, const int wyF, const int wtF, const int wxT, const int wyT, const int wtT)
template<typename FLOAT >
int GetGaborEnergyImage (Image3d< FLOAT > &out, struct GaborFilter3D< FLOAT > const &f)
template<typename FLOAT >
int GetGaborEnergyExtImage (Image3d< FLOAT > &out, struct GaborFilter3D< FLOAT > const &f)
template<typename FLOAT >
int GaborOnSineEnergyImage (Image3d< FLOAT > &out, struct GaborFilter3D< FLOAT > const &f, const int wxF, const int wyF, const int wtF, const int wxT, const int wyT, const int wtT)
template<typename FLOAT >
int GaborOnSineEnergyImage (Image3d< FLOAT > &out, struct GaborFilter3D< FLOAT > const &f)
template<typename FLOAT >
int GaborQOnSineEnergyImage (Image3d< FLOAT > &out, struct GaborFilter3D< FLOAT > const &f, const int wxF, const int wyF, const int wtF, const int wxT, const int wyT, const int wtT)
template<typename FLOAT >
int GaborQOnSineEnergyImage (Image3d< FLOAT > &out, struct GaborFilter3D< FLOAT > const &f)

Detailed Description

This module collects functions related to Gabor filtering.


Define Documentation

#define ONEPERIOD   100.0

The length in voxels of a period that represents Fourier frequency of 1.

The default value is 100.0 .


Function Documentation

template<typename FLOAT >
void RotateBBox ( int &  x,
int &  y,
const FLOAT  phi 
)

An AB-axes-aligned rectangular box, given by x and y along some arbitrary axis A and B, respectively, is rotated by angle phi.

A bounding box which itself is AB-axes-aligned again and wraps the original one before and after the rotation is computed and returned in the x and y parameters.

Parameters:
[in,out] x the A-axis dimension of a bounding box
[in,out] y the B-axis dimension of a bounding box
[in] phi rotation angle in radians
Note:
This function is not officially visible outside the library at the moment (= it is not manifested in the header file). However, anyone can access this function after explicitly specifying its declaration in his/her source code.
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<typename FLOAT >
void RotateBBox ( FLOAT &  x,
FLOAT &  y,
const FLOAT  phi 
)

An AB-axes-aligned rectangular box, given by x and y along some arbitrary axis A and B, respectively, is rotated by angle phi.

A bounding box which itself is AB-axes-aligned again and wraps the original one before and after the rotation is computed and returned in the x and y parameters.

Parameters:
[in,out] x the A-axis dimension of a bounding box
[in,out] y the B-axis dimension of a bounding box
[in] phi rotation angle in radians
Note:
This function is not officially visible outside the library at the moment (= it is not manifested in the header file). However, anyone can access this function after explicitly specifying its declaration in his/her source code.
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<typename FLOAT >
void RotateBBox ( int &  x,
int &  y,
int &  z,
const FLOAT  phi,
const FLOAT  psi 
)

An ABC-axes-aligned rectangular box, given by x, y and z along some arbitrary axes A, B and C, respectively, is rotated by angle phi in the AB-plane and then by angle psi in the AC plane.

A bounding box which itself is ABC-axes-aligned again and wraps the original one before and after the rotation is computed and returned in the x, y and z parameters.

Parameters:
[in,out] x the A-axis dimension of a bounding box
[in,out] y the B-axis dimension of a bounding box
[in,out] z the C-axis dimension of a bounding box
[in] phi first rotation angle in radians
[in] psi second rotation angle in radians
Note:
This is a helper function to the RotatedGaborFiltering(). It is not officially visible outside the library at the moment (= it is not manifested in the header file). However, anyone can access this function after explicitly specifying its declaration in his/her source code.
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<typename FLOAT >
void RotateBBox ( FLOAT &  x,
FLOAT &  y,
FLOAT &  z,
const FLOAT  phi,
const FLOAT  psi 
)

An ABC-axes-aligned rectangular box, given by x, y and z along some arbitrary axes A, B and C, respectively, is rotated by angle phi in the AB-plane and then by angle psi in the AC plane.

A bounding box which itself is ABC-axes-aligned again and wraps the original one before and after the rotation is computed and returned in the x, y and z parameters.

Parameters:
[in,out] x the A-axis dimension of a bounding box
[in,out] y the B-axis dimension of a bounding box
[in,out] z the C-axis dimension of a bounding box
[in] phi first rotation angle in radians
[in] psi second rotation angle in radians
Note:
This is a helper function to the RotatedGaborFiltering(). It is not officially visible outside the library at the moment (= it is not manifested in the header file). However, anyone can access this function after explicitly specifying its declaration in his/her source code.
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<typename FLOAT >
FLOAT GetFrequency ( const FLOAT  period  )  [inline]

A tool to aid converting from spatial period to spatial frequency.

We adopted the notation that period of ONEPERIOD voxels amounts to frequency 1 in order to interconnect the Fourier world with discrete images we deal with.

Note:
Ask GetFrequency(1.0) to learn the actual value of ONEPERIOD.
Zero or negative input yields output 999999.
template<typename FLOAT >
FLOAT GetPeriod ( const FLOAT  frequency  )  [inline]

A tool to aid converting from spatial frequency to spatial period.

We adopted the notation that frequency of 1 amounts to ONEPERIOD voxels in order to interconnect the Fourier world with discrete images we deal with.

Note:
Ask GetPeriod(1.0) to learn the actual value of ONEPERIOD.
Zero or negative input yields output 999999.
template<typename FLOAT >
int SuggestFilterLengths ( struct GaborFilter3D< FLOAT > &  spec  ) 

This sets the paramaters spec,[xyt]Length according to Sigmas in spec.

The rule of six sigma is applied. This is an initial setting which reflects our sense for support size of an "ideal" xyz-aligned (when the both spec.xyPhiG and spec.xtPhiG are 0deg) Gabor filter.

In case when some Gabor filtering routine can't handle generally oriented Gabors (and hence generally oriented Gaussians), what happens when spec.xyPhiG or spec.xtPhiG is not multiple of PI/2 (which is most of the time), the "physical" lengths of the filter and Sigmas need some adjustment. Both Sigmas and lengths (real proportions of the filter) can be adjusted with the function AlignGaussianPartToXYT() in such cases.

Parameters:
[in,out] spec Gabor filter specification to be adjusted
Returns:
  • 0 on success
  • 1 on wrong input parameters
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<typename FLOAT >
int AlignGaussianPartToXYT ( struct GaborFilter3D< FLOAT > &  spec  ) 

This re-adjusts the Gaussian part of the Gabor filter.

Notably, values of spec,[xyt]Sigma, spec,[xyt]Length, spec.xyPhiG and spec.xtPhiG parameters are changed.

Gabor filter consists of a Sine wave component, which acts as a selected frequency detector, and an Gaussian envelope, which attenuates this Sine wave. It may be the case that this envelope is of elliptical shape with its main axis in the direction of the movement to be detected. The direction of movement may be well arbitrary -- notably, not aligned with Cartesian axes.

Some Gabor filtering routines can work properly only with xyz-axes aligned (Cartesian-aligned) elliptical (Gaussian) envelopes. This function aims to find such xyz-aligned elliptical approximation of the original envelope. In fact, it resolves xyz coordinates of (xLength,0,0), (0,yLength,0) and (0,0,tLength) and changes [xyt]Lengths to the absolute element-wise maximum of the three xyz-coordinate vectors. The same happens with Sigmas. Afterwards, xyPhiG and xtPhiG are set to zero to indicate the alignment with xyz coordinate system.

Parameters:
[in,out] spec Gabor filter specification to be adjusted
Returns:
  • 0 always
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<class VOXEL , typename FLOAT >
int CreateSeparableGaborFilter ( struct GaborFilter3D< FLOAT > const &  spec,
struct Separable3DFilter< VOXEL > &  filter 
)

This fills the 3D separable filter structure filter with Gabor filter specified by the spec parameter.

The t-axis related parameters are used for the z-axis since the filter is a general structure for 3D convolutions with traditional x,y and z labels. This is a consequence of the 2D+t representation via 3D images.

The frequency, which is expected to be applied along the direction given by spec.xyPhiS and spec.xtPhiS, is split into three factors each aligned along basic Cartesian coordinate axis. These factors are then used for the generation of filter's convolution's values.

The certain filter's convolution axis is not prepared if its [xyz]Length parameter is not set to some positive value. The structure spec should be prepared well and should readily tell the length of the filter along every Cartesian axis.

Parameters:
[in] spec Gabor filter specification
[out] filter separable filter structure to be filled
Note:
The filter is created mirrored since it should be directly used in the FIR convolution routines. We designed these routines not to flip the kernel image naturaly, instead just apply the kernel image, voxel-wise multiply and sum up.
A VOXEL type must be more general than FLOAT type because an implicit instatiation from FLOAT to VOXEL occurs in the code. For instance, int used for FLOAT and float used for VOXEL will work while it is impossible to convert it the other way around without loss of some information. This protects, on a syntax level, the user from creating, for example, char filter from double parameters. However, the function is currently instatiated only for float and double (and one from their mutual combinations).
Returns:
  • 1 on wrong input parameters
  • the returned value is the value returned from MultiplyFilters()
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<class VOXEL , typename FLOAT >
int SeparableGaborFiltering ( Image3d< VOXEL > const &  in,
Image3d< VOXEL > &  out,
struct GaborFilter3D< FLOAT > const &  filter 
)

This is a Gabor filtering routine good for separable Gabors (Gabors of special shape). It can handle 2D+t images stored in the 3D sequence image.

Parameters:
[in] in input image
[out] out output image
[in] filter parameters of the Gabor filter to be applied on the image

Technically, this performs the convolution axis by axis, separably. This is achieved owing to the trigonometric addition formulas, namely: sin(x+y)=sin(x).cos(y) + sin(y).cos(x). The essense of every 3D Gabor filter is the argument (f_x.x + f_y.y + f_t.t) of Sine function. The addition formula enabled us to expand this Sine into several simple Sine functions, each of just one argument respecting the Cartesian axes. These are then executed one by one, i.e. separable.

By computing the total number of MADDs (multiply and add) instructions for both cases, it can be shown that the expansion is more economical and thus faster. Precisely, this implementation saves 60% multiplications and 64% additions versus classical convolution scheme. Drawback: During the computation, it requires 3 additional temporary images to be saved in the memory, in addition to the two images for the input and output.

Note:
This is not just a plain wrapper of single call of separable convolution function. It utilizes a complex scheme of convolution calls.
The restriction to template types holds as in the CreateSeparableGaborFilter() which is called from this function.
Returns:
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<class VOXEL , typename FLOAT >
int RotatedGaborFiltering ( Image3d< VOXEL > const &  in,
Image3d< VOXEL > &  out,
struct GaborFilter3D< FLOAT > const &  filter 
)

Performs separable convolution of some Gabor filter on a rotated input image.

It rotates the image in in the 3D (2D+t) space so that the filter's coordinate system given by its main direction will align with the one used in image. The given Gabor filter is separable very rarely due to its Gaussian. If the input image is rotated appropriately then the separability may be utilized.

The routine is really not an example of the fastest code. It is considered a "non-perspective" branch anyway. We used this function to test the hyphothesis whether it is better to first rotate image, do axis-aligned Gabor filtering and rotate the result back. We found this approach to be rather slow and, the most significantly, inaccurate. Hence left alone...

Returns:
  • 0 on success
  • 1 on memory allocation error
  • the returned value is the value returned from MultiplyFilters()
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<class VOXEL , class FLOAT >
int GetGaborImpulseResponse ( Image3d< VOXEL > &  res,
const VOXEL  impulse,
struct GaborFilter3D< FLOAT > const &  f 
)

Compute a sample impulse response image.

An output image of (f.xLength,f.yLength,f.tLength) will be created. A hypothetical 3D Gabor, given by this function's parameters, will be applied on the impulse of magnitude impulse. The Gabor formula will be multiplied by the impulse to simulate the real convolution. Results of such evaluation will be stored in the output image res. Note that no convolution will take place at all. Hence, one will usually get the result very fast.

If impulse is negative, then only the exponential term in the Gaussian component of Gabor will be computed, multiplied by -impulse and stored in the output image. This disables the normalization factor of the Gaussian component.

Obviously, f.xLength, f.yLength and f.zLength shall not be negative or zero. Moreover, each must be an odd number owing to the simulation of the convolution in which an input impulse is located directly in the centre of the convolved image. Computing the centre of even-sized image is somewhat troublesome. The output image will have set the resolution to (1,1,1) and the offset to (0,0,0).

Parameters:
[out] res output image with correct/expected impulse response
[in] f Gabor filter specs
[in] impulse the impulse's value
Note:
The function, according to its name, computes a sample response to a single impulse. However, if one changes the sign (typically, makes it negative) of filter.Frequency then a mirrored out image can be produced (partly owing to the Gaussian's symmetry). This can be used as a kernel to some convolution.
Returns:
  • 0 on success
  • 1 on wrong input parameters
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<class VOXEL , typename FLOAT >
int FullGaborFiltering ( Image3d< VOXEL > const &  in,
Image3d< VOXEL > &  out,
struct GaborFilter3D< FLOAT > const &  f 
)

This is a ``naive'' Gabor filtering routine.

It can handle 2D+t images stored in the 3D sequence image. The filtering parameters are defined through the structure in the second parameter. In this structure, the values for z-axis are ignored.

Parameters:
[in] in input image
[out] out output image
[in] f parameters of the Gabor filter to be applied on the image

Technically, this performs a classical full convolution. It creates a 3D image for the convolution kernel which is then used for the computation. It doesn't require more memory except for the convolution kernel image. It is the highest possible complexity solution. However, it is expected that it produces the most correct result. Hence, it is ment for the controlling purposes predominantly.

The input image is (virtually) extended with zeros.

Returns:
  • 0 on success
  • 1 on wrong input parameters
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<class VOXEL , typename FLOAT >
int FullGaborFilteringExtended ( Image3d< VOXEL > const &  in,
Image3d< VOXEL > &  out,
struct GaborFilter3D< FLOAT > const &  f 
)

This is a ``naive'' Gabor filtering routine.

It can handle 2D+t images stored in the 3D sequence image. The filtering parameters are defined through the structure in the second parameter. In this structure, the values for z-axis are ignored.

Parameters:
[in] in input image
[out] out output image
[in] f parameters of the Gabor filter to be applied on the image

Technically, this performs a classical full convolution. It creates a 3D image for the convolution kernel which is then used for the computation. An enlarged copy of input image is created too. It is extended with border values from the original input image. These two images are used for the convolution what ends up with another image of increased(!) size. The function thus requires memory for two temporary enlarged images in addition to the image of the convolution kernel and the input and output images in and out.

The convolution is the highest possible complexity solution. However, it is expected to produce the most correct result. Hence, it is ment for the controlling purposes predominantly.

The input image is extended with border values.

Returns:
  • 0 on success
  • 1 on wrong input parameters
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<class VOXEL , typename FLOAT >
int FullGaborFilteringAligned ( Image3d< VOXEL > const &  in,
Image3d< VOXEL > &  out,
struct GaborFilter3D< FLOAT > const &  f 
)

The same as the FullGaborFiltering().

Only the Gaussian envelope is aligned to main axes whereas in the FullGaborFiltering() it is aligned to the new coordinate system given by f.xyPhiG and f.xtPhiG. The alignment is done by the AlignGaussianPartToXYT().

Returns:
  • 0 on success
  • 1 on wrong input parameters
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<class VOXEL , typename FLOAT >
int StagedGaborFiltering ( Image3d< VOXEL > const &  in,
Image3d< VOXEL > &  outRe,
Image3d< VOXEL > &  outIm,
struct GaborFilter3D< FLOAT > const &  f,
const char  method = 'U' 
)

The staged Gabor filtering for 2D+t images.

Gabor filter convolution is staged/split into the three parts:

  • multiply the image with position-dependent complex constant, i.e. the goniometric part of Gabor (this results in two images),
  • filter both images (the real-part and complex-part images) with Gaussian,
  • multiply both images again with position-dependent "counter" complex constant.

The process starts with real-valued image in and ends with a complex-valued image, which is represented in the two real-valued images outRe and outIm. The shift towards the complex domain enabled to, sort of, exclude the goniometric part of Gabor filter from the convolution. Instead, two additional voxel-by-voxel image multiplications (position-dependent constant is treated as an constant image) had to be introduced in order to compensate for the exclusion.

The filtering part of the process is realized either by the ApplyANIGaussL() or the ApplyANIGaussU2() with the latter set as default. The selection is driven by the last parameter method:

The output images outRe and outIm hold Gabor filtered input image in using cos() and sin() components, respectively. In fact, a quadrature pair responses are returned. Unfortunatelly, the procedure does not allow for computing only a Gabor filtering with sin() component without actually computing the same with cos() component as well, and vice versa.

Parameters:
[in] in input image
[out] outRe real-part of output image
[out] outIm imaginary-part of output image
[in] f Gabor filter to be applied on the image
[in] method selection of Gaussian filtering method
Returns:
  • 0 on success
  • 2 on Gaussian convolution error
Note:
VOXEL and FLOAT should be the same types, apparently float or double. The function is explicitly instantiated only with these types.
Two extra copies of input image are allocated in the memory during the execution. The total memory consumption is then 5 times size of the input image (1x input image, 2x output image, 2x helper images).
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<class VOXEL , typename FLOAT >
int IIRedGaborFiltering ( Image3d< VOXEL > const &  in,
Image3d< VOXEL > &  outRe,
Image3d< VOXEL > &  outIm,
struct GaborFilter3D< FLOAT > const &  f 
)

The direct "IIRed" Gabor filtering for 2D+t images.

It is a frontend to the ApplyIIRGabors().

Gabor filter convolution is separated into six 1D Gabor convolutions and computed separately, similarily to the way it is in the function ApplyANIGaussU2(). Each convolution is realized via a IIR Gabor filter, namely with the function ApplyIIRGaborInteger1D().

The input real-valued image in is filtered into a complex-valued image, which is represented in the two real-valued images outRe and outIm. The output images outRe and outIm hold Gabor filtered input image in using cos() and sin() components, respectively. In fact, a quadrature pair responses are returned. Unfortunatelly, the procedure does not allow for computing only a Gabor filtering with sin() component without actually computing the same with cos() component as well, and vice versa.

Parameters:
[in] in input image
[out] outRe real-part of output image
[out] outIm imaginary-part of output image
[in] f Gabor filter to be applied on the image
Returns:
  • 0 on success
  • 1 on negative sigma in the filter's Gaussian part
  • 2 on some error when separating the filter
  • 3 on some error with convolutions themselves
Note:
VOXEL and FLOAT should be the same types, apparently float or double. The function is explicitly instantiated only with these types.
Two extra copies of input image are allocated in the memory during the execution.
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<class VOXEL , typename FLOAT >
int IIRedGaborFilteringZeroDC ( Image3d< VOXEL > const &  in,
Image3d< VOXEL > &  outRe,
Image3d< VOXEL > &  outIm,
struct GaborFilter3D< FLOAT > const &  f 
)

The direct "IIRed" Gabor filtering for 2D+t images with DC-offset removal.

It convolves with Gabor filter and corrects the real part of a result by subtracting a scaled Gaussian-filtered input image, according to [Bernardino06]. The function calls functions IIRedGaborFiltering(), ApplyANIGaussU2() and GaborDCRemovingConstantEmpiric(). In fact, it is an extension of the IIRedGaborFiltering() -- refer to its documentation for more details on Gabor filtering.

Parameters:
[in] in input image
[out] outRe real-part of output image
[out] outIm imaginary-part of output image
[in] f Gabor filter to be applied on the image

Literature: A. Bernardino and J. Santos-Victor. Fast IIR Isotropic 2-D Complex Gabor Filters With Boundary Initialization. In Transactions on image processing 15. Pages 3338-3348. 2006.

Returns:
Note:
The GaborDCRemovingConstantEmpiric() calls the ApplyANIGaussU2() anyway. So all the three called functions use the same 3D to 6D separation kernel, all failing or working at the same time...
VOXEL and FLOAT should be the same types, apparently float or double. The function is explicitly instantiated only with these types.
Two extra copies of input image are allocated in the memory during the execution.
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<class VOXEL , typename FLOAT >
int Staged2GaborFiltering ( Image3d< VOXEL > const &  In,
Image3d< VOXEL > *  OutRe[2],
Image3d< VOXEL > *  OutIm[2],
struct GaborFilter3D< FLOAT > const &  f 
)

This function applies pair of similar Gabor filters on the given image.

Basically, convolution of any Gabor filter with given image can be split into three parts: modulation, Gaussian filtering and demodulation with Gaussian filtering realized with the function ApplyANIGaussU2(). Exactly this scheme is applied in the function StagedGaborFiltering(), which allows for convolution with single Gabor filter.

We have observed that when the two filters are carefully selected, their Gaussians' and sine-waves' parameters are the same or "symmetric". This functions benefits from this observation allowing for efficient computation of the bank of filters.

The bank is defined via single filter f. Its shape is restricted for the purpose of image motion processing:

  • the direction (heading) of Gussian and sine-wave are the same, f.xyPhiG == f.xyPhiS
  • the tilt of Gaussian and sine-wave differs exactly by PI/2, abs(f.xyPhiG - f.xyPhiS) == PI/2

Moreover, both values of f.xyPhiG and f.xyPhiS must be within 0 rad and PI rad. The second filter is the same except for its f.xyPhiG and f.xyPhiS parameters, which can be computed as:

  • D) 2*PI - f.xyPhi[GS]

The input image In is filtered with the filter f and its clone, the results are complex images. These are returned in the array of pointers to images, OutRe[] and OutIm[] for the real and imaginary parts, respectively, of the result. Results of the filtering as is specified with f and the filter denoted D are returned in the array at indices 0 and 1, respectively.

The function also returns the number of operations it required in order to convolve the four filters on the given image. The lower the number is, the more convolutions it managed to share. Multiplication or addition between voxel value and some real number are both equally regarded as one operation. For instance, the IIR implementation of the ApplyIIRGauss3() function requires 7 multiplications and 6 additions, thus 13 operations, to evaluate final value of each voxel.

The returned number of operations changes for different inputs. It depends on the Gaussian's parameters, which in turn depends on the shape of the input Gabor filter, that realize the middle stage. The number of 328 ops/voxel is the worst case scenario, which is achieved when both filters are computed independently with StagedGaborFiltering(). Thus, an improvement in percents can be computed as 100% * (1.0 - (returned_value / 328)).

Parameters:
[in] In input image to be filtered
[out] OutRe output array of pointers to real-part images, each is a result of different filtering
[out] OutIm output array of pointers to imaginary-part images, each is a result of different filtering
[in] f input Gabor filter
Returns:
  • >0 - when OKay, the total number, summed over all four filters, of operations per pixel used
  • -1 - when wrong direction/heading of the Gaussian in the filter
  • -2 - when heading of the Gaussian and the Sine-wave is the same
  • -3 - when tilting of the Gaussian and the Sine-wave is not orthogonal
  • -4 - couldn't find Gaussian's approximation, try slighty re-adjust Sigmas
  • -5 - didn't find any suitable "first" base vector in the Gaussian's filtering cascade
Note:
One extra copy of complex image is allocated in the memory during the execution. The total memory consumption is then 7 times size of the input image (1x input image, 2x real output images, 2x imaginary output images, 2x helper images (real+imaginary)).
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<class VOXEL , typename FLOAT >
int Staged4GaborFiltering ( Image3d< VOXEL > const &  In,
Image3d< VOXEL > *  OutRe[4],
Image3d< VOXEL > *  OutIm[4],
struct GaborFilter3D< FLOAT > const &  f 
)

This function applies bank of four similar Gabor filters on the given image.

Basically, convolution of any Gabor filter with given image can be split into three parts: modulation, Gaussian filtering and demodulation with Gaussian filtering realized with the function ApplyANIGaussU2(). Exactly this scheme is applied in the function StagedGaborFiltering(), which allows for convolution with single Gabor filter.

We have observed that when the four filters are carefully selected, their Gaussians' and sine-waves' parameters are the same or "symmetric". This functions benefits from this observation allowing for efficient computation of the bank of filters.

The bank is defined via single filter f. Its shape is restricted for the purpose of image motion processing:

  • the direction (heading) of Gussian and sine-wave are the same, f.xyPhiG == f.xyPhiS
  • the tilt of Gaussian and sine-wave differs exactly by PI/2, abs(f.xyPhiG - f.xyPhiS) == PI/2

Moreover, both values of f.xyPhiG and f.xyPhiS must be within 0 rad and PI/2 rad. The other three filters are the same except for their f.xyPhiG and f.xyPhiS parameters, which can be computed as:

  • B) PI - f.xyPhi[GS]
  • C) PI + f.xyPhi[GS]
  • D) 2*PI - f.xyPhi[GS]

The input image In is filtered with the filter f and its clones, the results are complex images. These are returned in the array of pointers to images, OutRe[] and OutIm[] for the real and imaginary parts, respectively, of the result. Results of the filtering as is specified with f and the filters denoted B, C and D are returned in the array at indices 0, 1, 2 and 3, respectively.

The function also returns the number of operations it required in order to convolve the four filters on the given image. The lower the number is, the more convolutions it managed to share. Multiplication or addition between voxel value and some real number are both equally regarded as one operation. For instance, the IIR implementation of the ApplyIIRGauss3() function requires 7 multiplications and 6 additions, thus 13 operations, to evaluate final value of each voxel.

The returned number of operations changes for different inputs. It depends on the Gaussian's parameters, which in turn depends on the shape of the input Gabor filter, that realize the middle stage. The number of 656 ops/voxel is the worst case scenario, which is achieved when all four filters are computed independently with StagedGaborFiltering(). Thus, an improvement in percents can be computed as 100% * (1.0 - (returned_value / 656)).

Parameters:
[in] In input image to be filtered
[out] OutRe output array of pointers to real-part images, each is a result of different filtering
[out] OutIm output array of pointers to imaginary-part images, each is a result of different filtering
[in] f input Gabor filter
Returns:
  • >0 - when OKay, the total number, summed over all four filters, of operations per pixel used
  • -1 - when wrong direction/heading of the Gaussian in the filter
  • -2 - when heading of the Gaussian and the Sine-wave is the same
  • -3 - when tilting of the Gaussian and the Sine-wave is not orthogonal
  • -4 - couldn't find Gaussian's approximation, try slighty re-adjust Sigmas
  • -5 - didn't find suitable "first" base vector in the Gaussian's filtering cascade
  • -6 - didn't find any suitable "second and more" base vector in the Gaussian's filtering AD cascade
  • -7 - didn't find any suitable "second and more" base vector in the Gaussian's filtering BC cascade
Note:
One extra copy of complex image is allocated in the memory during the execution. The total memory consumption is then 11 times size of the input image (1x input image, 4x real output images, 4x imaginary output images, 2x helper images (real+imaginary)).
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<class VOXEL , typename FLOAT >
int ApplyGaborBank ( Image3d< VOXEL > const &  In,
Image3d< VOXEL > **  OutRe,
Image3d< VOXEL > **  OutIm,
struct GaborFilter3D< FLOAT > const &  f,
const int  no 
)

Applies the bank of no Gabor filters on the input image and no output images is then returned.

The output images are with real and imaginary parts expressing together the quadrature pair. They are addressed via two arrays of pointers. The length of both arrays is exactly 2+2*no ! This is a consequence of the shape of the filter bank.

The output arrays must be correctly prepared before this function is called, i.e. the 2+2*no "real" and the same number of "imaginary" image objects must be created and pointers to them must be correctly set up in both arrays. The output images themselves need not be properly sized as this function will resize them automatically.

The filter bank consists of the same filters as the input filter f except for the heading of the filter -- the azimuth angles in the xy-plane given in f.xyPhiG and f.xyPhiS. The headings of filters are stepped by A=90/(n+1) degrees as follows:

  • [ filter's index in the output array) nominal azimuth angle, comments ]
  • 0) 0deg, filter is oriented along the x-axis
  • 1) Adeg, the second filter in the bank, the first closest to the x-axis
  • 2) 2Adeg, the third filter in the bank, the second closest to the x-axis
  • ...
  • n) nAdeg, the (n+1)th filter in the bank, the furtherst to the x-axis in the I. quadrant of the xy plane
  • n+1) 90deg, filter oriented along the y-axis
  • n+2) (90+A)deg, the first closest to the y-axis in the II. quadrant of the xy plane
  • n+3) (90+2A)deg, the second closest to the y-axis in the II. quadrant of the xy plane
  • ...
  • n+n+1) (180-A)deg, the last filter in the bank, the furtherst to the y-axis in the II. quadrant of the xy plane

In other words, the bank contains always the filters along x- and y-axes. This is when no = 0. The parameter no then tells how many filters should be equally spaced between the two in the I. quadrant of the xy plane. The headings to the II. quadrant associated with the second half of filters in the bank are then mirrored to those no in the I. quadrant. The order of filter indices in the bank, and of filtering results in the output arrays as well, corresponds to the linear order of their azimuth angles from the smallest one.

Hence, the values of f.xyPhiG and f.xyPhiS are ignored in the input structure. The above mentioned values are used instead. Especially note that, we had put f.xyPhiG equal to f.xyPhiS, i.e. the spatial direction of the main axis and the secondary main axis are the same, see docs of the structure GaborFilter3D .

This function is merelly a wrapper to the StagedGaborFiltering(), Staged2GaborFiltering() and Staged4GaborFiltering(). The latter two introduces another constraint on the tilting of the main direction and secondary main direction. The tilting of Gaussian and Sine-wave must be mutually perpendicular.

Parameters:
[in] In input image
[out] OutRe array of pointers on images holding the real part of the convolution results
[out] OutIm array of pointers on images holding the imaginary part of the convolution results
[in] f sample input filter upon which the content of the filtering bank is derived
[in] no gives the number 2+2*no of filters in the bank
Returns:
  • 0 when the filtering was succesful
  • 1 when negative number of filters in the bank was given
  • 2 when couldn't do 0deg or 90deg Gauss
  • 10-19 the error states of Staged4GaborFiltering()
  • 20-29 the error states of Staged2GaborFiltering()
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<typename FLOAT >
int PrepareGaborBank ( struct GaborFilter3D< FLOAT > const &  f,
const int  no,
struct GaborConvolution3D **  convs 
)

Precomputes computational parameters of the bank of no Gabor filters.

The result is stored in a chain of structures GaborConvolution3D. The principles used are the same as in the function ApplyGaborBank().

The pointer to the head of convolutions chain is returned in the parameter convs. In other words, the GaborConvolution3D structures are allocated and chained. The caller of this routine must, when he/she decides, free memory with these structures.

The filter bank consists of the same filters as the input filter f except for the heading of the filter -- the azimuth angles in the xy-plane given in f.xyPhiG and f.xyPhiS. The headings of filters are stepped by A=90/(n+1) degrees as follows:

  • [ filter's index in the output array) nominal azimuth angle, comments ]
  • 0) 0deg, filter is oriented along the x-axis
  • 1) Adeg, the second filter in the bank, the first closest to the x-axis
  • 2) 2Adeg, the third filter in the bank, the second closest to the x-axis
  • ...
  • n) nAdeg, the (n+1)th filter in the bank, the furtherst to the x-axis in the I. quadrant of the xy plane
  • n+1) 90deg, filter oriented along the y-axis
  • n+2) (90+A)deg, the first closest to the y-axis in the II. quadrant of the xy plane
  • n+3) (90+2A)deg, the second closest to the y-axis in the II. quadrant of the xy plane
  • ...
  • n+n+1) (180-A)deg, the last filter in the bank, the furtherst to the y-axis in the II. quadrant of the xy plane The indices in the output structure GaborConvolution3D follow this scheme.

In other words, the bank contains always the filters along x- and y-axes. This is when no = 0. The parameter no then tells how many filters should be equally spaced between the two in the I. quadrant of the xy plane. The headings to the II. quadrant associated with the second half of filters in the bank are then mirrored to those no in the I. quadrant. The order of filter indices in the bank corresponds to the linear order of their azimuth angles from the smallest one. However, the order of filters derived from the order of convolutions in the chain convs need not, and will probably not, follow the described order of azimuth angles.

The values of f.xyPhiG and f.xyPhiS are, therefore, ignored in the input structure. The above mentioned values are used instead. Especially note that, we had put f.xyPhiG equal to f.xyPhiS, i.e. the spatial direction of the main axis and the secondary main axis are the same, see docs of the structure GaborFilter3D .

Above mentioned filter index is the value stored in GaborConvolution3D::index property. When the structure describes more than one filter, more index values are encoded in this property according to the scheme described there.

There is a constraint on the tilting of the main direction and secondary main direction: the tilting of Gaussian and Sine-wave must be mutually perpendicular.

Parameters:
[in] f sample input filter upon which the content of the filtering bank is derived
[in] no gives the number 2+2*no of filters in the bank
[out] convs the pointer to the first GaborConvolution3D structure
Returns:
  • 0 when the parameters were precomputed/established
  • 1 when negative number of filters in the bank was given
  • 2 when couldn't do 0deg or 90deg Gauss
  • 3 when memory allocation error (when allocating for some next GaborConvolution3D structure)
  • 4 when even a filter pair can't be convolved with simultaneously, no improvement can be achieved then
  • nG+10 when couldn't do nG-th Gauss, shall stay within <1+10,no+10>
Note:
The function is targeted to prepare parameters for _effective_ convolutions with the filtering bank, by which we understand that the convolution will require less operations per voxel (will run faster) compared to the (plain naive) filtering with filter by filter. Thus, at least two filters must be somehow convolvable at once -- simultaneously. The return value 4 indicates that there exists a filter in the bank for which we were not able to find at least one other filter to be convolved with. Since this would damage the efficiency, we decided to return with error value even thought the convolution with this filtering bank is possible, but not effectively.
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<class VOXEL >
int ApplyGaborBank ( Image3d< VOXEL > const &  In,
Image3d< VOXEL > **  OutRe,
Image3d< VOXEL > **  OutIm,
struct GaborConvolution3D const *  convs 
)

Applies Gabor filters bank given by a GaborConvolution3D "receipt".

A Gabor filtering bank must be first constructed by PrepareGaborBank() or otherwise following the suggestion of the GaborConvolution3D structure. This creates something like a receipt which results eventually in a Gabor bank filtering. Such receipt is fed into this function in the last parameter convs. The structure convs will mostly contain pointers to other such structures (GaborConvolution3D::next). They together create a chain of convolutions, a filtering chain.

The function applies these convolutions on the input image In and returns complex images, encoded with an array of real parts in OutRe and an array of imaginary parts in OutIm. The Image3d<FLOAT> objects must be created and pointers to them must be correclty stored in both arrays prior the call of this function. The length of the arrays must be at least the highest number encoded in the convs.index, see GaborConvolution3D::index. The output images themselves need not be properly sized as this function will resize them automatically.

The function employs an extra knowledge on how to proceed with convolutions when some structure of the chain convs describes two or four filters. More information on this can be compiled from documentations of ApplyGaborBank(), PrepareGaborBank() and GaborConvolution3D.

Parameters:
[in] In input image
[out] OutRe array of pointers on images holding the real part of the convolution results
[out] OutIm array of pointers on images holding the imaginary part of the convolution results
[in] convs the receipt for Gabor filter convolutions
Note:
When some of GaborConvolution3D structures describes filtering with four filters, the GaborConvolution3D::vecs must start with the base vector (0,0,1) -- since this is the vector with which every convolutions with filter quadruple start with and the routine counts on it (and does not test it!).
Returns:
  • 0 when everything went just fine
  • 1 when some error happened during the first convolution of filter quadruple
  • 2 when input image is too small (should be at least 8px along all axes)
Note:
This is a staged Gabor filtering version. It uses the approach of splitting the task into a modulating, Gaussian filtering and demodulating stages -- as opposite to using directly the IIR Gabor filtering, what is implemented in the ApplyGaborBank2() function. The same ``extra knowledge'' on how to compute more filters at once is applied in both cases.
This function implementes the theoretically efficient method unlike its sibling ApplyGaborBank2() which uses the same principles to gain efficiency but with faster function ApplyIIRGaborInteger1D(). The latter is thus not that efficient from the theoretical point of view but is faster (the time consumption measured in seconds) in real life.
One extra copy of complex image is allocated in the memory during the execution. The total memory consumption is then 2n+3 times size of the input image (1 input image, n real output images, n imaginary output images, 2 helper images (real+imaginary)).
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<class VOXEL >
int ApplyGaborBank2 ( Image3d< VOXEL > const &  In,
Image3d< VOXEL > **  OutRe,
Image3d< VOXEL > **  OutIm,
struct GaborConvolution3D const *  convs 
)

Applies Gabor filters bank given by a GaborConvolution3D "receipt".

This is a sibbling to the ApplyGaborBank() based also on the GaborConvolution3D structure. It, similarily, needs a Gabor filtering bank constructed by PrepareGaborBank(), or otherwise following the suggestion of the GaborConvolution3D structure, beforehand. The interface and purpose is the same.

The function also employs an extra knowledge on how to proceed with convolutions when some structure of the chain convs describes two or four filters.

Parameters:
[in] In input image
[out] OutRe array of pointers on images holding the real part of the convolution results
[out] OutIm array of pointers on images holding the imaginary part of the convolution results
[in] convs the receipt for Gabor filter convolutions
Note:
When some of GaborConvolution3D structures describes filtering with four filters, the GaborConvolution3D::vecs must start with the base vector (0,0,1) -- since this is the vector with which every convolutions with filter quadruple start with and the routine counts on it (and does not test it!).
Returns:
  • 0 when everything went just fine
  • 1 when some error happened during the first convolution of filter quadruple
  • 2 when input image is too small (should be at least 8px along all axes)
Note:
This is not a staged Gabor filtering version. It uses directly the IIR Gabor filtering. The ``extra knowledge'' on how to compute more filters is, however, utilized too.
This function is faster in real life compared to its sibbling ApplyGaborBank() even though it does not implement the theoretically efficient method. That's life, sometimes... ;-)
One extra copy of complex image is allocated in the memory during the execution. The total memory consumption is then 2n+3 times size of the input image (1 input image, n real output images, n imaginary output images, 2 helper images (real+imaginary)).
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<class VOXEL >
int ApplyGaborBank2_DC ( Image3d< VOXEL > const &  In,
Image3d< VOXEL > **  OutRe,
Image3d< VOXEL > **  OutIm,
struct GaborConvolution3D const *  convs 
)

Applies Gabor filters bank given by a GaborConvolution3D "receipt" including the DC-offset removing.

This is in fact the ApplyGaborBank2() with the only exception that this one immediately subtracts from filtering results in order to remove the DC-offset. This implements the idea of [Bernardino06]: an input image is filtered with Gaussian, the envelope of given Gabor filter, and subtracted. The Gaussian filtering is optimized as well, it also uses the concept of base-sharing like it is used for the Gabor filtering.

The function also employs an extra knowledge on how to proceed with convolutions when some structure of the chain convs describes two or four filters.

Parameters:
[in] In input image
[out] OutRe array of pointers on images holding the real part of the convolution results
[out] OutIm array of pointers on images holding the imaginary part of the convolution results
[in] convs the receipt for Gabor filter convolutions
Note:
When some of GaborConvolution3D structures describes filtering with four filters, the GaborConvolution3D::vecs must start with the base vector (0,0,1) -- since this is the vector with which every convolution with filter quadruple starts with and the routine counts on it (and does not test it!).

Literature: A. Bernardino and J. Santos-Victor. Fast IIR Isotropic 2-D Complex Gabor Filters With Boundary Initialization. In Transactions on image processing 15. Pages 3338-3348. 2006.

Returns:
  • 0 when everything went just fine
  • 1 when some error happened during the first convolution of filter quadruple
  • 2 when input image is too small (should be at least 8px along all axes)
Note:
This is not a staged Gabor filtering version. It uses directly the IIR Gabor filtering. The ``extra knowledge'' on how to compute more filters is, however, utilized too.
This function is faster in real life compared to its sibbling ApplyGaborBank() even though it does not implement the theoretically efficient method. That's life, sometimes... ;-)
One extra copy of complex image and one (real) image are allocated in the memory during the execution. The total memory consumption is then 2n+4 times size of the input image (1 input image, n real output images, n imaginary output images, 3 helper images (real+imaginary to create a complex one and one just real)).
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2010
template<class VOXEL , typename FLOAT >
int StagedGaborEnergy ( Image3d< VOXEL > const &  in,
Image3d< VOXEL > &  out,
struct GaborFilter3D< FLOAT > const &  f 
)

The staged Gabor energy for 2D+t images.

Gabor energy, which is essentially complex Gabor filtering (see the StagedGaborFiltering()) plus voxel-wise computation of magnitudes (sum of squared real and imaginary parts of a complex number), is staged/split into the three parts:

  • multiply the image with position-dependent complex constant, i.e. the goniometric part of Gabor (this results in two images),
  • filter both images (the real-part and complex-part images) with Gaussian,
  • sum voxel-wise squares of both images (this gives an energy of the given Gabor filter f).

Note the difference in the last step when compared to the sibbling function StagedGaborFiltering(). We use the fact that the last multiplication of "counter" complex constant is needless as noted in [Spinei et al., 1998].

Also note that f.xzPhi and f.zSigma are ignored in the function as these are related to 3D+t filtering.

Parameters:
[in] in input image
[out] out the energy output image
[in] f parameter of the Gabor filter to be applied on the image
Note:
VOXEL and FLOAT should be the same types, apparently float or double. The function is explicitly instantiated only with these types.
Two extra copies of input image are allocated in the memory during the execution. The total memory consumption is then 4 times size of the input image (1x input image, 1x output image, 2x helper images).
Returns:
  • 0 on success
  • 2 on Gaussian convolution error

Literature: A. Spinei, D. Pellerin and J. Herault. Spatiotemporal energy-based method for velocity estimation. In Signal processing 65. Pages 347-362. 1998.

Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<class VOXEL >
int GaborEnergy ( Image3d< VOXEL > const &  inRe,
Image3d< VOXEL > const &  inIm,
Image3d< VOXEL > &  out 
)

Computes voxel-wise energy from two Gabor filtered images, preferrably both being mutually 90deg out of phase (also known as quadrature pair).

The output images from the StagedGaborFiltering() are nice adepts. However, if one is to compute the energy right from the beginning, i.e. without having intermediate Gabor filtered images at hand, we recommend to use the StagedGaborEnergy() function rather. It gives the same result but faster.

One may take voxel-wise square-root of values in out to see magnitudes of Gabor filtering responses.

Parameters:
[in] inRe real part of input Gabor filtered image (the cos() component)
[in] inIm imaginary part of input Gabor filtered image (the sin() component)
[out] out output energy image
Note:
The function is instantiated only for float and double types of VOXEL.
Returns:
  • 0 when energy was computed
  • 1 when input images were of different sizes
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<class VOXEL >
int GaborPhase ( Image3d< VOXEL > const &  inRe,
Image3d< VOXEL > const &  inIm,
Image3d< VOXEL > &  out 
)

Computes voxel-wise phase from two Gabor filtered images, necessarily both being mutually 90deg out of phase (also known as quadrature pair).

The output images from the StagedGaborFiltering() are nice adepts.

The function computes voxel-wise atan(inIm / inRe). Hence, the order of input parameters is very important. The values of phase in out are in radians.

Parameters:
[in] inRe real part of input Gabor filtered image (the cos() component)
[in] inIm imaginary part of input Gabor filtered image (the sin() component)
[out] out output energy image
Note:
The function is instantiated only for float and double types of VOXEL.
Returns:
  • 0 when phase was computed
  • 1 when input images were of different sizes
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<class VOXEL >
void PurgeSmallVoxels ( Image3d< VOXEL > &  im,
const VOXEL  limit = 0.0001 
)

Just sets to zero all voxels that are closer to zero than given limit.

Parameters:
[in,out] im modified image
[in] limit the threshold value representing interval < -limit,limit >
Note:
The function is instantiated only for float and double types of VOXEL.
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2008
template<typename FLOAT >
int GetGaborEnergyImage ( Image3d< FLOAT > &  out,
struct GaborFilter3D< FLOAT > const &  f,
const int  wxF,
const int  wyF,
const int  wtF,
const int  wxT,
const int  wyT,
const int  wtT 
)

Creates an Fourier energy image of the given filter f -- an energy of a result of the discrete Fourier transform of an impulse response of the filter.

Since we use the constant ONEPERIOD to give certain meaning to the frequency 1, the size of output image out will be set to (ONEPERIOD,ONEPERIOD,ONEPERIOD).

The output image is initiated with zeros prior the computation. The energy is evaluated only within input interval <wxF,wxT> x <wyF,wyT> x <wtF,wtT> . Any of the three input intervals need not span across the entire <0,ONEPERIOD-1>, though, it shall not expand over it.

Parameters:
[out] out a result, an image with Fourier energy of the given filter
[in] f an input Gabor filter whose energy is to be computed
[in] wxF begining of an x-axis interval of frequencies in which the energy is to evaluated
[in] wyF begining of an y-axis interval of frequencies in which the energy is to evaluated
[in] wtF begining of an t-axis interval of frequencies in which the energy is to evaluated
[in] wxT end of an x-axis interval of frequencies in which the energy is to evaluated
[in] wyT end of an y-axis interval of frequencies in which the energy is to evaluated
[in] wtT end of an t-axis interval of frequencies in which the energy is to evaluated
Note:
The negative Fourier frequencies are not evaluated nor imaged in the result.
Energy of a single filter, as opposed to a quadrature pair, is considered in this function.
The Fourier transform would return with some Re+j*Im (j is the imaginary unit), we compute the energy as Re*Re + Im*Im -- without the square root.
The function is instantiated only for float and double types of FLOAT.
Returns:
  • 0 when image was generated successfuly
  • 1 when some of w[xyt]F was higher than its "partner" w[xyt]T
  • 2 when some of w[xyt]F or w[xyt]T was out of the interval <0,ONEPERIOD-1>
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<typename FLOAT >
int GetGaborEnergyImage ( Image3d< FLOAT > &  out,
struct GaborFilter3D< FLOAT > const &  f 
)

Creates an Fourier energy image of the given filter f -- an energy of a result of the discrete Fourier transform of an impulse response of the filter.

This only calls the above GetGaborEnergyImage (out,f,"interval") with automatically guessed "interval". The "guessing" is driven by the rule of six sigmas...

Parameters:
[out] out a result, an image with Fourier energy of the given filter
[in] f an input Gabor filter whose energy is to be computed
Note:
The negative Fourier frequencies are not evaluated nor imaged in the result.
Energy of a single filter, as opposed to a quadrature pair, is considered in this function.
The Fourier transform would return with some Re+j*Im (j is the imaginary unit), we compute the energy as Re*Re + Im*Im -- without the square root.
The function is instantiated only for float and double types of FLOAT.
Returns:
  • 0 when image was generated successfuly
  • 1 when some of w[xyt]F was higher than its "partner" w[xyt]T
  • 3 when some of filter's sigma is negative
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<typename FLOAT >
int GetGaborEnergyExtImage ( Image3d< FLOAT > &  out,
struct GaborFilter3D< FLOAT > const &  f 
)

Creates an Fourier energy image of the given filter f -- an energy of a result of the discrete Fourier transform of an impulse response of the filter.

Since we use the constant ONEPERIOD to give certain meaning to the frequency 1, the size of output image out will be set to (2*ONEPERIOD,2*ONEPERIOD,2*ONEPERIOD) with the DC frequency positioned at [ONEPERIOD,ONEPERIOD,ONEPERIOD]. The "energy data generating" core of the function is a slightly modified copy from GetGaborEnergyImage().

Parameters:
[out] out a result, an image with Fourier energy of the given filter
[in] f an input Gabor filter whose energy is to be computed
Note:
The negative Fourier frequencies are evaluated and imaged in the result.
Energy of a single filter, as opposed to a quadrature pair, is considered in this function.
The Fourier transform would return with some Re+j*Im (j is the imaginary unit), we compute the energy as Re*Re + Im*Im -- without the square root.
The function is instantiated only for float and double types of FLOAT.
Returns:
  • 0 always
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<typename FLOAT >
int GaborOnSineEnergyImage ( Image3d< FLOAT > &  out,
struct GaborFilter3D< FLOAT > const &  f,
const int  wxF,
const int  wyF,
const int  wtF,
const int  wxT,
const int  wyT,
const int  wtT 
)

Creates an image with total Fourier energies of different sine waves convolved with given input Gabor filter.

The sum of squared outputs of a sine-wave convolved with a Gabor filter is equal, according to the Parseval's theorem, to the sum of Fourier energies from the Fourier transform of the convolution result. There can be derived an analytic expression for such energy of certain sine-wave convolved with given Gabor filter [Heeger88].

Energy related to the sine-wave of the shape sin((wx*x + wy*y + wt*t) / ONEPERIOD) will be stored in the image out at the position [wx - wxF,wy - wyF,wt - wtF] where wx, wy and wt range from <wxF,wxT>, <wyF,wyT> and <wtF,wtT>, respectively. Clearly, the range interval must be set reasonably: any of the three input intervals need not span across the entire <0,ONEPERIOD-1>, though, it shall not expand over it. The output image's size will be set to (ONEPERIOD,ONEPERIOD,ONEPERIOD).

Such an output image can give an insight into which sine-waves a given input filter f is the most sensitive to. This is a purpose of this function. Note that it does not compute total energy of a quadrature pair of Gabor filters for every sine-wave, use GaborQOnSineEnergyImage() for this purpose.

Parameters:
[out] out a result, an image with Fourier energies over different sine-waves
[in] f an input Gabor filter
[in] wxF begining of an x-axis interval of frequencies
[in] wyF begining of an y-axis interval of frequencies
[in] wtF begining of an t-axis interval of frequencies
[in] wxT end of an x-axis interval of frequencies
[in] wyT end of an y-axis interval of frequencies
[in] wtT end of an t-axis interval of frequencies

Literature: D. J. Heeger. Optical Flow Using Spatiotemporal Filters. In International Journal of Computer Vision. Pages 279-302. 1988.

Note:
The negative Fourier frequencies are not evaluated nor imaged in the result.
Energy of a single filter, as opposed to a quadrature pair, is considered in this function.
The Fourier transform would return with some Re+j*Im (j is the imaginary unit), we compute the energy as Re*Re + Im*Im -- without the square root.
The function is instantiated only for float and double types of FLOAT.
Returns:
  • 0 when image was generated successfuly
  • 1 when some of w[xyt]F was higher than its "partner" w[xyt]T
  • 2 when some of w[xyt]F or w[xyt]T was out of the interval <0,ONEPERIOD-1>
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<typename FLOAT >
int GaborOnSineEnergyImage ( Image3d< FLOAT > &  out,
struct GaborFilter3D< FLOAT > const &  f 
)

The same as the above function GaborOnSineEnergyImage() except it suggests proper frequency intervals automatically.

Parameters:
[out] out a result, an image with Fourier energies over different sine-waves
[in] f an input Gabor filter
Note:
The negative Fourier frequencies are not evaluated nor imaged in the result.
Energy of a single filter, as opposed to a quadrature pair, is considered in this function.
The Fourier transform would return with some Re+j*Im (j is the imaginary unit), we compute the energy as Re*Re + Im*Im -- without the square root.
The function is instantiated only for float and double types of FLOAT.
Returns:
  • 0 when image was generated successfuly
  • 1 when some of w[xyt]F was higher than its "partner" w[xyt]T
  • 3 when some of filter's sigma is negative
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<typename FLOAT >
int GaborQOnSineEnergyImage ( Image3d< FLOAT > &  out,
struct GaborFilter3D< FLOAT > const &  f,
const int  wxF,
const int  wyF,
const int  wtF,
const int  wxT,
const int  wyT,
const int  wtT 
)

Creates an image with total Fourier energies of different sine waves convolved with quadrature-pair Gabor filters.

The pair is given in the input parameter f. The quadrature-pair filters differs mutually only in the phase, a pair consists of a sine-phase and cosine-phase filters. However, it can be shown that the "initial" phase is irrelevant in the computation of total energy for any certain sine-wave [Heeger88]. Thus, in this case, the input filter describes the quadrature adequately (and the f.Phase is ignored).

The content of output image out and image's properties are similar to what has been explained in the function GaborQOnSineEnergyImage().

Parameters:
[out] out a result, an image with Fourier energies over different sine-waves
[in] f an input Gabor filter
[in] wxF begining of an x-axis interval of frequencies
[in] wyF begining of an y-axis interval of frequencies
[in] wtF begining of an t-axis interval of frequencies
[in] wxT end of an x-axis interval of frequencies
[in] wyT end of an y-axis interval of frequencies
[in] wtT end of an t-axis interval of frequencies

Literature: D. J. Heeger. Optical Flow Using Spatiotemporal Filters. In International Journal of Computer Vision. Pages 279-302. 1988.

Note:
The negative Fourier frequencies are not evaluated nor imaged in the result.
Energy of a quadrature pair, as opposed to a single filter, is considered in this function.
The Fourier transform would return with some Re+j*Im (j is the imaginary unit), we compute the energy as Re*Re + Im*Im -- without the square root.
The function is instantiated only for float and double types of FLOAT.
Returns:
  • 0 when image was generated successfuly
  • 1 when some of w[xyt]F was higher than its "partner" w[xyt]T
  • 2 when some of w[xyt]F or w[xyt]T was out of the interval <0,ONEPERIOD-1>
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009
template<typename FLOAT >
int GaborQOnSineEnergyImage ( Image3d< FLOAT > &  out,
struct GaborFilter3D< FLOAT > const &  f 
)

The same as the above function GaborQOnSineEnergyImage() except it suggests proper frequency intervals automatically.

Parameters:
[out] out a result, an image with Fourier energies over different sine-waves
[in] f an input Gabor filter
Note:
The negative Fourier frequencies are not evaluated nor imaged in the result.
Energy of a quadrature pair, as opposed to a single filter, is considered in this function.
The Fourier transform would return with some Re+j*Im (j is the imaginary unit), we compute the energy as Re*Re + Im*Im -- without the square root.
The function is instantiated only for float and double types of FLOAT.
Returns:
  • 0 when image was generated successfuly
  • 1 when some of w[xyt]F was higher than its "partner" w[xyt]T
  • 3 when some of filter's sigma is negative
Author:
Vladimír Ulman (xulman@fi.muni.cz)
Date:
2009