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) |
This module collects functions related to Gabor filtering.
| #define ONEPERIOD 100.0 |
The length in voxels of a period that represents Fourier frequency of 1.
The default value is 100.0 .
| 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.
| [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 |
| 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.
| [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 |
| 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.
| [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 |
| 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.
| [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 |
| 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.
| 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.
| 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.
| [in,out] | spec | Gabor filter specification to be adjusted |
| 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.
| [in,out] | spec | Gabor filter specification to be adjusted |
| 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.
| [in] | spec | Gabor filter specification |
| [out] | filter | separable filter structure to be filled |
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).| 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.
| [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.
| 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...
| 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).
| [out] | res | output image with correct/expected impulse response |
| [in] | f | Gabor filter specs |
| [in] | impulse | the impulse's value |
| 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.
| [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.
| 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.
| [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.
| 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().
| 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:
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.
| [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 |
float or double. The function is explicitly instantiated only with these types.| 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.
| [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 |
float or double. The function is explicitly instantiated only with these types.| 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.
| [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.
float or double. The function is explicitly instantiated only with these types.| 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:
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:
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)).
| [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 |
| 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:
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:
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)).
| [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 |
| 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:
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.
| [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 |
| 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:
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.
| [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 |
| 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.
| [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 |
| 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.
| [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 |
| 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.
| [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 |
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.
| 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:
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.
| [in] | in | input image |
| [out] | out | the energy output image |
| [in] | f | parameter of the Gabor filter to be applied on the image |
float or double. The function is explicitly instantiated only with these types.Literature: A. Spinei, D. Pellerin and J. Herault. Spatiotemporal energy-based method for velocity estimation. In Signal processing 65. Pages 347-362. 1998.
| 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.
| [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 |
float and double types of 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.
| [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 |
float and double types of 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.
| [in,out] | im | modified image |
| [in] | limit | the threshold value representing interval < -limit,limit > |
float and double types of VOXEL.| 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.
| [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 |
float and double types of 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...
| [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 |
float and double types of 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().
| [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 |
float and double types of 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.
| [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.
float and double types of 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.
| [out] | out | a result, an image with Fourier energies over different sine-waves |
| [in] | f | an input Gabor filter |
float and double types of 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().
| [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.
float and double types of 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.
| [out] | out | a result, an image with Fourier energies over different sine-waves |
| [in] | f | an input Gabor filter |
float and double types of FLOAT.
1.7.1