This module basicaly contains supporting functions to just two implementations of zero-mean 3D Gaussian filters. More...
Classes | |
| class | LibFilters_GaussianLUT |
Defines | |
| #define | ENUMERATED_BASES 48 |
Typedefs | |
| typedef const int | BASE [6][3] |
Functions | |
| int | ComputeLampertParams (const double phi, const double psi, const double sigmaX, const double sigmaY, const double sigmaZ, double &v12, double &v13, double &v23, double &d1, double &d2, double &d3) |
| int | ComputeLampertParams (const double phi, const double sigmaX, const double sigmaY, double &v12, double &d1, double &d2) |
| void | EnumerateBases (int MaxTwos, int bases[][6][3], int &HowMany) |
| void | EnumerateBases91 (int MaxTwos, int bases[][6][3], int &HowMany) |
| int | GetIDOfBase (int const (&vecs)[6][3]) |
| int | GetIDOfEquivalentBase (int const (&vecs)[6][3], int newIndex[6]) |
| int | GetBaseFromID (const int ID, int vecs[6][3]) |
| int | GetIDOfBase (int const (&vecs)[6][3], const BASE bases[], const int basesNo) |
| int | GetIDOfEquivalentBase (int const (&vecs)[6][3], const BASE bases[], const int basesNo, int newIndex[6]) |
| int | GetBaseFromID (const int ID, const BASE bases[], const int basesNo, int vecs[6][3]) |
| void | PrintBases (const BASE bases[], const int basesNo) |
| int | GetParamsANIGaussU (const double xyPhi, const double sigmaX, const double sigmaY, int vecs[3][2], double sigs[3]) |
| int | GetParamsANIGaussU (const double xyPhi, const double xzPsi, const double sigmaX, const double sigmaY, const double sigmaZ, int vecs[6][3], double sigs[6]) |
| int | GetParamsANIGaussUb (const double xyPhi, const double xzPsi, const double sigmaX, const double sigmaY, const double sigmaZ, const int vecs[6][3], double sigs[6]) |
| int | GetParamsANIGaussUb (const double xyPhi, const double xzPsi, const double sigmaX, const double sigmaY, const double sigmaZ, const int baseID, double sigs[6]) |
| int | GetParamsANIGaussUb (const double xyPhi, const double sigmaX, const double sigmaY, const int vecs[3][2], double sigs[3]) |
| int | GetParamsANIGaussU2 (const double xyPhi, const double xzPsi, const double sigmaX, const double sigmaY, const double sigmaZ, int vecs[6][3], double sigs[6]) |
| int | GetParamsANIGaussUBS (const double xyPhi, const double xzPsi, const double sigmaX, const double sigmaY, const double sigmaZ, int vecs[6][3], double sigs[6]) |
| void | EnumerateBasesBS (int bases[][6][3], int &HowMany) |
| template<class VOXEL > | |
| void | ChangeToBestOrder (const i3d::Image3d< VOXEL > &srcIm, const i3d::Image3d< VOXEL > &refIm, int vecs[6][3], double sigs[6], int newIndex[6]) |
| template<class VOXEL > | |
| void | ChangeToBestOrderForGaussian (const double xyPhi, const double xzPsi, const double sigmaX, const double sigmaY, const double sigmaZ, int vecs[6][3], double sigs[6], int newIndex[6]) |
| template<class VOXEL > | |
| void | ApplyBaseConvolutions (i3d::Image3d< VOXEL > const &in, i3d::Image3d< VOXEL > &out, const int vecs[3][2], const double sigs[3]) |
| template<class VOXEL > | |
| void | ApplyBaseConvolutions (i3d::Image3d< VOXEL > const &in, i3d::Image3d< VOXEL > &out, const int vecs[6][3], const double sigs[6]) |
| template<class VOXEL > | |
| void | ApplyBaseConvolutions2 (i3d::Image3d< VOXEL > const &in, i3d::Image3d< VOXEL > &out, const int vecs[6][3], const double sigs[6]) |
| template<class VOXEL > | |
| void | ApplyBaseConvolutions (i3d::Image3d< VOXEL > const &in, i3d::Image3d< VOXEL > &out, const int baseID, const double sigs[6]) |
| void | AdjustInputOrientation (double &xyphi, double &xzpsi, int &xDir, int &yDir, int &zDir) |
| void | AdjustInputOrientation (double &xyphi, int &xDir, int &yDir) |
| void | ApplyAlfaSymmetry (const double alfa, double &new_alfa, char &revert_info) |
| void | RevertAlfaSymmetry (int vecs[6][3], double sigs[6], const char revert_info) |
| int | DetermineGaussMatrixType (const double elems[6]) |
| void | LibFilters_GaussianLUT_LUTLoader (std::map< int, std::vector< int > > &lut) |
Variables | |
| class LibFilters_GaussianLUT | GaussVectorsLUT |
| static const BASE | basesType0 [2] |
| static const BASE | basesType1x [48] |
| static const BASE | basesType1y [38] |
| static const BASE | basesType1z [44] |
This module basicaly contains supporting functions to just two implementations of zero-mean 3D Gaussian filters.
The one is due to [Lampert and Wirjadi, 2006] and the second is an extension of [Lam and Shi, 2007] explained in [Ulman, 2008].
If one is aware of the principles of both approaches, some time consumption can be saved by using these helper functions cleverly.
Literature: Ch. H. Lampert and O. Wirjadi. An Optimal Nonorthogonal Separation of the Anisotropic Gaussian Convolution Filter. In IEEE Transactions on Image Processing 15, 11. Pages 3501-3513. 2006.
Literature: S. Y. M. Lam and B. E. Shi. Recursive Anisotropic 2-D Gaussian Filtering Based on a Triple-axis Decomposition. In IEEE Transactions on Image Processing 16, 7. Pages 1925-1930. 2007.
Literature: V. Ulman. Arbitrarily-Oriented Anisotropic 3D Gaussian Filtering Computed with 1D Convolutions without Interpolation. In Proceedings of 8th WSEAS International Conference on SIGNAL PROCESSING, COMPUTATIONAL GEOMETRY and ARTIFICIAL VISION. Pages 56-62. 2008. ISBN: 978-960-6766-95-4.
| #define ENUMERATED_BASES 48 |
This macro holds the number of bases plus one typically. One may allocate an array of this length that accomodates all bases enumerated by the EnumerateBases() function.
| typedef const int BASE[6][3] |
This is just a helper typedef to ease the reading of library C++ code.
It should wrap one base vectors, i.e. six 3D vectors, into a single type.
We'll use it intesively when addressing/working with certain initial base set.
| int ComputeLampertParams | ( | const double | phi, | |
| const double | psi, | |||
| const double | sigmaX, | |||
| const double | sigmaY, | |||
| const double | sigmaZ, | |||
| double & | v12, | |||
| double & | v13, | |||
| double & | v23, | |||
| double & | d1, | |||
| double & | d2, | |||
| double & | d3 | |||
| ) |
A parameter conversion routine. An arbitrarily oriented anisotropic 3D Gaussian filter is expressed in 3 direction-related parameters and 3 associated sigmas.
This is a helper routine to the main ApplyANIGaussL() function. It computes the parameters for a replacement of 3D Gaussian filtering with three 1D convolutions as suggested by [Lampert and Wirjadi, 2006]. The input anisotropic, given by sigmaX, sigmaY and sigmaZ, arbitrarily oriented, given by phi and psi, 3D Gauss filter will be replaced with the following three convolutions:
The order of convolutions is not important. Or at least, a change in the order shouldn't be noticeable in terms of accuracy and time consumption.
The main sigma sigmaX must be strictly greater than both minor sigmas sigmaY and sigmaZ.
| [in] | phi | orientation of filter's main axis, xyPlane steering (in radians) |
| [in] | psi | orientation of filter's main axis, tilting around y-axis (in radians) |
| [in] | sigmaX | sigma along main axis |
| [in] | sigmaY | sigma along axis perpendicular to the main axis in the xyPlane |
| [in] | sigmaZ | sigma along axis perpendicular to both previous axes |
| [out] | v12 | direction defining parameter |
| [out] | v13 | direction defining parameter |
| [out] | v23 | direction defining parameter |
| [out] | d1 | sigma of the 1. direction |
| [out] | d2 | sigma of the 2. direction |
| [out] | d3 | sigma of the 3. direction |
Literature: Ch. H. Lampert and O. Wirjadi. An Optimal Nonorthogonal Separation of the Anisotropic Gaussian Convolution Filter. In IEEE Transactions on Image Processing 15, 11. Pages 3501-3513. 2006.
| int ComputeLampertParams | ( | const double | phi, | |
| const double | sigmaX, | |||
| const double | sigmaY, | |||
| double & | v12, | |||
| double & | d1, | |||
| double & | d2 | |||
| ) |
A parameter conversion routine.
An arbitrarily oriented anisotropic 2D Gaussian filter is expressed in 2 direction-related parameters and 2 associated sigmas.
This is a helper routine to the main ApplyANIGaussL() function. It computes the parameters for a replacement of 2D Gaussian filtering with two 1D convolutions as suggested by [Lampert and Wirjadi, 2006]. The input anisotropic, given by sigmaX and sigmaY, arbitrarily oriented, given by phi, 2D Gauss filter will be replaced with the following two convolutions:
The order of convolutions is not important. Or at least, a change in the order shouldn't be noticeable in terms of accuracy and time demand.
The main sigma sigmaX must be strictly greater than minor sigma sigmaY.
| [in] | phi | orientation of filter's main axis, xyPlane steering (in radians) |
| [in] | sigmaX | sigma along main axis |
| [in] | sigmaY | sigma along axis perpendicular to the main axis in the xyPlane |
| [out] | v12 | direction defining parameter |
| [out] | d1 | sigma of the 1. direction |
| [out] | d2 | sigma of the 2. direction |
Literature: Ch. H. Lampert and O. Wirjadi. An Optimal Nonorthogonal Separation of the Anisotropic Gaussian Convolution Filter. In IEEE Transactions on Image Processing 15, 11. Pages 3501-3513. 2006.
| void EnumerateBases | ( | int | MaxTwos, | |
| int | bases[][6][3], | |||
| int & | HowMany | |||
| ) |
Interger-valued 3D vectors are listed/enumerated into the bases list by this function.
This function serves as a sort of official generator of official Look-Up-Table :-). Since we work with certain set of vector 6-tuples (we call each 6-tuple the base), it is convenient to reference each base by its ID. The ID is nothing else but the index under which given base can found in the array bases. This function fills this array in a uniform manner ensuring that given ID always points to the same base. To save time, the ID-to-base relation is returned in a Look-Up-Table bases.
The length of the output array bases is given in the parameter HowMany. The enumerating will stop (and complain to the std::cerr) at this number eventually to avoid stepping out of allocated memory. On return, the parameter HowMany tells the size of the Look-Up-Table, tells the total number of bases.
Different base sets can be created by changing the paramter MaxTwos. It defines how many vectors holding the number 2 as some of its element is allowed to be present in any base. For instance, by setting this parameter to zero, no vector of (x,y,2), (x,2,z) or (2,x,z), x,y,z
{0,1}, will be used. Thus, this parameter also controls the size of the created Look-Up-Table.
| [in] | MaxTwos | the number of "big" vectors is allowed in any base |
| [out] | bases | the filled Look-Up-Table |
| [in,out] | HowMany | the size of the array bases as input, the number of filled bases as output |
| void EnumerateBases91 | ( | int | MaxTwos, | |
| int | bases[][6][3], | |||
| int & | HowMany | |||
| ) |
Interger-valued 3D vectors are listed/enumerated into the bases list by this function.
This is exactly the same as the EnumerateBases() function with the only difference that it generates the older official initial base set of 91 bases.
| [in] | MaxTwos | the number of "big" vectors is allowed in any base |
| [out] | bases | the filled Look-Up-Table |
| [in,out] | HowMany | the size of the array bases as input, the number of filled bases as output |
| int GetIDOfBase | ( | int const (&) | vecs[6][3] | ) |
Find an ID of the input base.
This performs a reverse search in the Look-Up-Table (explained in the EnumerateBases() function). It searches for ID of the input base given with vecs. The base vecs must be exactly the same as some of reference bases in order to discover its ID. Use rather GetIDOfEquivalentBase() when the order is different. The EnumerateBases() is used for reference.
| [in] | vecs | six 3D base vectors |
| int GetIDOfEquivalentBase | ( | int const (&) | vecs[6][3], | |
| int | newIndex[6] | |||
| ) |
Find an ID of the permuted input base.
This performs a reverse search in the Look-Up-Table (explained in the EnumerateBases() function). It searches for ID of the input base given with vecs. Unlike in the function GetIDOfBase(), the input base vecs may have different order of its base vectors. In any case, the permutation of base vectors is described in the output parameter newIndex: if vecs is equivalent to base with ID then vecs[i] corresponds to base[ID][newIndex[i]]. The EnumerateBases() is used for reference.
| [in] | vecs | six 3D base vectors |
| [out] | newIndex | permutation of vecs with respect to the reference base |
| int GetBaseFromID | ( | const int | ID, | |
| int | vecs[6][3] | |||
| ) |
Find a base with the ID given.
This performs a search in the Look-Up-Table (explained in the EnumerateBases() function). It finds the base vectors of given input ID. The EnumerateBases() is used for reference. The base is stored in the parameter vecs.
This is just a "lazy-programmer" function when he/she doesn't want to explicitly handle the array of vectors. If one were to have such array, he/she would naturally pick the particular vector directly out of it. On the other hand, it makes a copy of the base vector given (in contrast to returning a reference).
| [in] | ID | ID of the base |
| [out] | vecs | six 3D base vectors |
| int GetIDOfBase | ( | int const (&) | vecs[6][3], | |
| const BASE | bases[], | |||
| const int | basesNo | |||
| ) |
Find an ID of the input base in the initial base set.
This performs a reverse search in the array of bases (aka initial base set, what is in fact the same as the Look-Up-Table, which is explained in the EnumerateBases() function). It searches for ID of the input base given with vecs within an initial base set given by bases. The base vecs must be exactly the same as some of reference bases in order to discover its ID. Use rather GetIDOfEquivalentBase() when the order is different.
| [in] | vecs | six 3D base vectors |
| [in] | bases | array of base vectors to search within |
| [in] | basesNo | length of the array |
| int GetIDOfEquivalentBase | ( | int const (&) | vecs[6][3], | |
| const BASE | bases[], | |||
| const int | basesNo, | |||
| int | newIndex[6] | |||
| ) |
Find an ID of the permuted input base.
This performs a reverse search in the array of bases (aka initial base set, what is in fact the same as the Look-Up-Table, which is explained in the EnumerateBases() function). It searches for ID of the input base given with vecs within an initial base set given by bases. Unlike in the function GetIDOfBase(), the input base vecs may have different order of its base vectors. In any case, the permutation of base vectors is described in the output parameter newIndex: if vecs is equivalent to base with ID then vecs[i] corresponds to base[ID][newIndex[i]].
| [in] | vecs | six 3D base vectors |
| [in] | bases | array of base vectors to search within |
| [in] | basesNo | length of the array |
| [out] | newIndex | permutation of vecs with respect to the reference base |
| int GetBaseFromID | ( | const int | ID, | |
| const BASE | bases[], | |||
| const int | basesNo, | |||
| int | vecs[6][3] | |||
| ) |
Find a base with the ID given.
This performs a reverse search in the array of bases (aka initial base set, what is in fact the same as the Look-Up-Table, which is explained in the EnumerateBases() function). It finds the base vectors of given input ID within an initial base set given by bases. The base is stored in the parameter vecs.
This is just a "lazy-programmer" function when he/she doesn't want to explicitly handle the array of vectors. If one were to have such array, he/she would naturally pick the particular vector directly out of it. On the other hand, it makes a copy of the base vector given (in contrast to returning a reference).
| [in] | ID | ID of the base |
| [in] | bases | array of base vectors to search within |
| [in] | basesNo | length of the array |
| [out] | vecs | six 3D base vectors |
| void PrintBases | ( | const BASE | bases[], | |
| const int | basesNo | |||
| ) |
Prints a list of initial base set.
One row per one base (six 3D vectors) which vectors and their elements visually separated by spaces.
| [in] | bases | array of base vectors to be listed |
| [in] | basesNo | length of the array |
| int GetParamsANIGaussU | ( | const double | xyPhi, | |
| const double | sigmaX, | |||
| const double | sigmaY, | |||
| int | vecs[3][2], | |||
| double | sigs[3] | |||
| ) |
A parameter conversion routine.
An arbitrary oriented anisotropic 2D Gaussian filter is expressed in 3 directional vectors and 3 associated sigmas.
This is a helper routine to the ApplyBaseConvolutions() function. It computes the parameters for a replacement of 2D Gaussian filtering with three 1D convolutions -- according to [Lam and Shi, 2007]. The speciality is that directional vectors consists only of integer elements. The input anisotropic, given by sigmaX and sigmaY, arbitrarily oriented, given by xyPhi, 2D Gauss filter will be replaced with the following three convolutions:
The order of convolutions is not important. Or at least, a change in the order shouldn't be noticeable in terms of accuracy and time consumption.
The main sigma sigmaX must be strictly greater than minor sigma sigmaY.
The i-th convolution shall be skipped whenever sigs[i] is zero.
| [in] | xyPhi | orientation of filter's main axis, xyPlane steering (in radians) |
| [in] | sigmaX | sigma along main axis |
| [in] | sigmaY | sigma along axis perpendicular to the main axis in the xyPlane |
| [out] | vecs | three 3D vectors to be convolved along |
| [out] | sigs | three sigmas to be used for those 3 convolutions |
We found out that in the 2D case usually 1 or 0 admissible bases is found.
Literature: S. Y. M. Lam and B. E. Shi. Recursive Anisotropic 2-D Gaussian Filtering Based on a Triple-axis Decomposition. In IEEE Transactions on Image Processing 16, 7. Pages 1925-1930. 2007.
| int GetParamsANIGaussU | ( | const double | xyPhi, | |
| const double | xzPsi, | |||
| const double | sigmaX, | |||
| const double | sigmaY, | |||
| const double | sigmaZ, | |||
| int | vecs[6][3], | |||
| double | sigs[6] | |||
| ) |
A parameter conversion routine. An arbitrary oriented anisotropic 3D Gaussian filter is expressed in 6 directional vectors and 6 associated sigmas.
This is a helper routine to the ApplyBaseConvolutions() function. It computes the parameters for a replacement of 3D Gaussian filtering with six 1D convolutions -- an extension to [Lam and Shi, 2007]. The speciality is that directional vectors consists only of integer elements. The input anisotropic, given by sigmaX, sigmaY and sigmaZ, arbitrarily oriented, given by xyPhi and xzPsi, 3D Gauss filter will be replaced with the following six convolutions:
The order of convolutions is not important. Or at least, a change in the order shouldn't be noticeable in terms of accuracy and time consumption.
The main sigma sigmaX must be strictly greater than both minor sigmas sigmaY and sigmaZ.
The i-th convolution shall be skipped whenever sigs[i] is zero.
| [in] | xyPhi | orientation of filter's main axis, xyPlane steering (in radians) |
| [in] | xzPsi | orientation of filter's main axis, tilting around y-axis (in radians) |
| [in] | sigmaX | sigma along main axis |
| [in] | sigmaY | sigma along axis perpendicular to the main axis in the xyPlane |
| [in] | sigmaZ | sigma along axis perpendicular to both previous axes |
| [out] | vecs | six 3D vectors to be convolved along |
| [out] | sigs | six sigmas to be used for those 6 convolutions |
Literature: S. Y. M. Lam and B. E. Shi. Recursive Anisotropic 2-D Gaussian Filtering Based on a Triple-axis Decomposition. In IEEE Transactions on Image Processing 16, 7. Pages 1925-1930. 2007.
| int GetParamsANIGaussUb | ( | const double | xyPhi, | |
| const double | xzPsi, | |||
| const double | sigmaX, | |||
| const double | sigmaY, | |||
| const double | sigmaZ, | |||
| const int | vecs[6][3], | |||
| double | sigs[6] | |||
| ) |
A parameter conversion routine. This one is, essentially, the same as GetParamsANIGaussU(). The only difference is that the base (the 6-tuple of 3D vectors in the parameter vecs) is supplied and only appropriate sigmas are computed in order for the replacement to work.
The main sigma sigmaX must be strictly greater than both minor sigmas sigmaY and sigmaZ.
The i-th convolution shall be skipped whenever sigs[i] is zero.
| [in] | xyPhi | orientation of filter's main axis, xyPlane steering (in radians) |
| [in] | xzPsi | orientation of filter's main axis, tilting around y-axis (in radians) |
| [in] | sigmaX | sigma along main axis |
| [in] | sigmaY | sigma along axis perpendicular to the main axis in the xyPlane |
| [in] | sigmaZ | sigma along axis perpendicular to both previous axes |
| [in] | vecs | six 3D vectors to be convolved along |
| [out] | sigs | six sigmas to be used for those 6 convolutions |
| int GetParamsANIGaussUb | ( | const double | xyPhi, | |
| const double | xzPsi, | |||
| const double | sigmaX, | |||
| const double | sigmaY, | |||
| const double | sigmaZ, | |||
| const int | baseID, | |||
| double | sigs[6] | |||
| ) |
A parameter conversion routine.
This one is, essentially, the same as GetParamsANIGaussU(). The only difference is that the base (the 6-tuple of 3D vectors via its base ID in the parameter baseID, see the function EnumerateBases() ) is supplied and only appropriate sigmas are computed in order for the replacement to work.
The main sigma sigmaX must be strictly greater than both minor sigmas sigmaY and sigmaZ.
The i-th convolution shall be skipped whenever sigs[i] is zero.
| [in] | xyPhi | orientation of filter's main axis, xyPlane steering (in radians) |
| [in] | xzPsi | orientation of filter's main axis, tilting around y-axis (in radians) |
| [in] | sigmaX | sigma along main axis |
| [in] | sigmaY | sigma along axis perpendicular to the main axis in the xyPlane |
| [in] | sigmaZ | sigma along axis perpendicular to both previous axes |
| [in] | baseID | base ID (as defined by EnumerateBases()) to be convolved along |
| [out] | sigs | six sigmas to be used for those 6 convolutions |
| int GetParamsANIGaussUb | ( | const double | xyPhi, | |
| const double | sigmaX, | |||
| const double | sigmaY, | |||
| const int | vecs[3][2], | |||
| double | sigs[3] | |||
| ) |
A parameter conversion routine.
This one is, essentially, the same as GetParamsANIGaussU(). The only difference is that the base (the 3-tuple of 2D vectors in the parameter vecs) is supplied and only appropriate sigmas are computed in order for the replacement to work.
The main sigma sigmaX must be strictly greater than minor sigma sigmaY.
The i-th convolution shall be skipped whenever sigs[i] is zero.
| [in] | xyPhi | orientation of filter's main axis, xyPlane steering (in radians) |
| [in] | sigmaX | sigma along main axis |
| [in] | sigmaY | sigma along axis perpendicular to the main axis in the xyPlane |
| [in] | vecs | three 3D vectors to be convolved along |
| [out] | sigs | three sigmas to be used for those 3 convolutions |
| int GetParamsANIGaussU2 | ( | const double | xyPhi, | |
| const double | xzPsi, | |||
| const double | sigmaX, | |||
| const double | sigmaY, | |||
| const double | sigmaZ, | |||
| int | vecs[6][3], | |||
| double | sigs[6] | |||
| ) |
A parameter conversion routine.
An arbitrary oriented anisotropic 3D Gaussian filter is expressed in 6 directional vectors and 6 associated sigmas.
This is an improved version of GetParamsANIGaussU(). The original GetParamsANIGaussU() function uses only one initial base set generated by the EnumerateBases() regardless of Gaussian type. As a result, it may not find new parameters for some input configurations or it provides parameters which give worse approximations.
This function uses different initial base sets depending on parameters of the demanded input Gaussian. The Gauss filter is first classified with DetermineGaussMatrixType() function and then a special optimized initial base set is used. Four different sets are used for type zero (one set) and type one (three sets owing to the three possible violations, see DetermineGaussMatrixType() for an explanation) together. A set of Look-Up-Tables is used for types three and four.
| [in] | xyPhi | orientation of filter's main axis, xyPlane steering (in radians) |
| [in] | xzPsi | orientation of filter's main axis, tilting around y-axis (in radians) |
| [in] | sigmaX | sigma along main axis |
| [in] | sigmaY | sigma along axis perpendicular to the main axis in the xyPlane |
| [in] | sigmaZ | sigma along axis perpendicular to both previous axes |
| [out] | vecs | six 3D vectors to be convolved along |
| [out] | sigs | six sigmas to be used for those 6 convolutions |
The main sigma sigmaX must be strictly greater than both minor sigmas sigmaY and sigmaZ. The order of convolutions is not important. Or at least, a change in the order shouldn't be noticeable in terms of accuracy and time consumption. The i-th convolution shall be skipped whenever sigs[i] is zero.
Literature: S. Y. M. Lam and B. E. Shi. Recursive Anisotropic 2-D Gaussian Filtering Based on a Triple-axis Decomposition. In IEEE Transactions on Image Processing 16, 7. Pages 1925-1930. 2007.
| int GetParamsANIGaussUBS | ( | const double | xyPhi, | |
| const double | xzPsi, | |||
| const double | sigmaX, | |||
| const double | sigmaY, | |||
| const double | sigmaZ, | |||
| int | vecs[6][3], | |||
| double | sigs[6] | |||
| ) |
A specialized parameter conversion routine.
An (almost) arbitrary oriented anisotropic 3D Gaussian filter (used as a part of Gabor bank filtering framework) is expressed in 6 directional vectors and 6 associated sigmas.
This function is aimed towards the shared convolution scheme when computing bank of Gabor filters. In this scenario, parameters for only vectors with 0 <= xyPhi <= PI/2 and 0 < xzPsi <= PI/2 are searched for. The function is primarily targeted to be called by the PrepareGaborBank() function.
| [in] | xyPhi | orientation of filter's main axis, xyPlane steering (in radians) |
| [in] | xzPsi | orientation of filter's main axis, tilting around y-axis (in radians) |
| [in] | sigmaX | sigma along main axis |
| [in] | sigmaY | sigma along axis perpendicular to the main axis in the xyPlane |
| [in] | sigmaZ | sigma along axis perpendicular to both previous axes |
| [out] | vecs | six 3D vectors to be convolved along |
| [out] | sigs | six sigmas to be used for those 6 convolutions |
The main sigma sigmaX must be strictly greater than both minor sigmas sigmaY and sigmaZ. The order of convolutions is not important. Or at least, a change in the order shouldn't be noticeable in terms of accuracy and time consumption. The i-th convolution shall be skipped whenever sigs[i] is zero.
| void EnumerateBasesBS | ( | int | bases[][6][3], | |
| int & | HowMany | |||
| ) |
Interger-valued 3D vectors are listed/enumerated into the bases list by this function.
The bases of special shape are enumerated for the purpose of base sharing involved in the Gabor bank filtering. Every base obeys the following template:
Where A,B is some of {0,1,2} but A and B must not be both equal to 2 or 0 at the same moment. Also note that A,B is accompanied with 0 in every vector. Hence for example in the second vector when A=0 and B=2 produces vector 2*(0,0,1)... so we won't let 2 be left alone in the vector.
The parameter HowMany tells the size of the Look-Up-Table bases. It should hold the length of the output array bases when calling this function. The enumerating will stop (and complain to the std::cerr) at this number eventually to avoid stepping out of allocated memory. On return, the function tells the total number of bases in this parameter.
| [out] | bases | the filled Look-Up-Table |
| [in,out] | HowMany | the size of the array bases as input, the number of filled bases as output |
| void ChangeToBestOrder | ( | const i3d::Image3d< VOXEL > & | srcIm, | |
| const i3d::Image3d< VOXEL > & | refIm, | |||
| int | vecs[6][3], | |||
| double | sigs[6], | |||
| int | newIndex[6] | |||
| ) |
This function changes the order of six vectors vecs and six sigmas sigs associated to them in the base (vectors with sigmas represent a base) to improve the base's accuracy.
The accuracy of given base is measured using the function NormalizedSquareError() between the test image and the reference image refIm. The test image is a result of the ApplyBaseConvolutions() with the given base on the source image srcIm. It is expected that image refIm is a good filtering result of srcIm. Hence, both srcIm and refIm must be of the same dimensions.
The best base, i.e. the one yelding result closest to the refIm, will be stored in the parameters vecs and sigs. The permutation that gave the best base from the original one is returned in the last parameter newIndex -- position of i-th vector in the original base is now newIndex[i].
| [in] | srcIm | source image before filtering |
| [in] | refIm | reference image after filtering |
| [in,out] | vecs | vectors in the base |
| [in,out] | sigs | sigmas in the base |
| [out] | newIndex | the permutation in the base that gave the closest filtering |
| void ChangeToBestOrderForGaussian | ( | const double | xyPhi, | |
| const double | xzPsi, | |||
| const double | sigmaX, | |||
| const double | sigmaY, | |||
| const double | sigmaZ, | |||
| int | vecs[6][3], | |||
| double | sigs[6], | |||
| int | newIndex[6] | |||
| ) |
This function changes the order of six vectors vecs and six sigmas sigs associated to them in the base (vectors with sigmas represent a base) to improve the base's accuracy.
Similarily to the ChangeToBestOrder(), the accuracy of given base is measured using the function NormalizedSquareError() between the test image and the reference Gaussian. The test image is a result of the ApplyBaseConvolutions() with the given base on the sample image of single impulse. The reference Gaussian is given by the input parameters xyPhi, xzPsi for rotation and sigma[XYZ] for span. It represents a valid result of Gaussian filtering on the sample image.
The best base, i.e. the one yelding result closest to the given Gaussian, will be stored in the parameters vecs and sigs. The permutation that gave the best base from the original one is returned in the last parameter newIndex -- position of i-th vector in the original base is now newIndex[i].
| [in] | xyPhi | orientation of filter's main axis, xyPlane steering (in radians) |
| [in] | xzPsi | orientation of filter's main axis, tilting around y-axis (in radians) |
| [in] | sigmaX | sigma along main axis |
| [in] | sigmaY | sigma along axis perpendicular to the main axis in the xyPlane |
| [in] | sigmaZ | sigma along axis perpendicular to both previous axes |
| [in,out] | vecs | vectors in the base |
| [in,out] | sigs | sigmas in the base |
| [out] | newIndex | the permutation in the base that gave the closest filtering |
| void ApplyBaseConvolutions | ( | i3d::Image3d< VOXEL > const & | in, | |
| i3d::Image3d< VOXEL > & | out, | |||
| const int | vecs[3][2], | |||
| const double | sigs[3] | |||
| ) |
This function conducts the three 1D convolutions along directional vectors of only integer elements.
In other words, three 1D convolutions without the need for interpolation performed by ApplyIIRGaussInteger1D().
This realizes the paper by [Lam and Shi, 2007].
The i-th convolution will be skipped whenever sigs[i] is below 0.01. The output image out remains untouched when no convolution took place (i.e. when sigs[i] were below 0.01 for all i).
| [in] | in | input image |
| [out] | out | output convolved image |
| [in] | vecs | three 3D vectors to be convolved along |
| [in] | sigs | three sigmas to be used for those 3 convolutions |
Literature: S. Y. M. Lam and B. E. Shi. Recursive Anisotropic 2-D Gaussian Filtering Based on a Triple-axis Decomposition. In IEEE Transactions on Image Processing 16, 7. Pages 1925-1930. 2007.
| void ApplyBaseConvolutions | ( | i3d::Image3d< VOXEL > const & | in, | |
| i3d::Image3d< VOXEL > & | out, | |||
| const int | vecs[6][3], | |||
| const double | sigs[6] | |||
| ) |
This function conducts the six 1D convolutions along directional vectors of only integer elements. In other words, six 1D convolutions without the need for interpolation performed by ApplyIIRGaussInteger1D(). However, it is expected that the first three directional vectors be x-, y- and z-axis aligned, respectively. Hence the ApplyIIRGauss3() function is used for the first three. The last three are computed with the ApplyIIRGaussInteger1D() function.
This merely realizes the 3D extension of the paper by [Lam and Shi, 2007].
The i-th convolution will be skipped whenever sigs[i] is below 0.01. The output image out remains untouched when no convolution took place (i.e. when sigs[i] were below 0.01 for all i).
| [in] | in | input image |
| [out] | out | output convolved image |
| [in] | vecs | six 3D vectors to be convolved along |
| [in] | sigs | six sigmas to be used for those 6 convolutions |
Literature: S. Y. M. Lam and B. E. Shi. Recursive Anisotropic 2-D Gaussian Filtering Based on a Triple-axis Decomposition. In IEEE Transactions on Image Processing 16, 7. Pages 1925-1930. 2007.
| void ApplyBaseConvolutions2 | ( | i3d::Image3d< VOXEL > const & | in, | |
| i3d::Image3d< VOXEL > & | out, | |||
| const int | vecs[6][3], | |||
| const double | sigs[6] | |||
| ) |
This function conducts the six 1D convolutions along directional vectors of only integer elements. In other words, six 1D convolutions without the need for interpolation performed by ApplyIIRGaussInteger1D().
This merely realizes the 3D extension of the paper by [Lam and Shi, 2007].
The i-th convolution will be skipped whenever sigs[i] is below 0.01. The output image out remains untouched when no convolution took place (i.e. when sigs[i] were below 0.01 for all i).
| [in] | in | input image |
| [out] | out | output convolved image |
| [in] | vecs | six 3D vectors to be convolved along |
| [in] | sigs | six sigmas to be used for those 6 convolutions |
Literature: S. Y. M. Lam and B. E. Shi. Recursive Anisotropic 2-D Gaussian Filtering Based on a Triple-axis Decomposition. In IEEE Transactions on Image Processing 16, 7. Pages 1925-1930. 2007.
| void ApplyBaseConvolutions | ( | i3d::Image3d< VOXEL > const & | in, | |
| i3d::Image3d< VOXEL > & | out, | |||
| const int | baseID, | |||
| const double | sigs[6] | |||
| ) |
This function conducts the six 1D convolutions along directional vectors of only integer elements.
In other words, six 1D convolutions without the need for interpolation performed by ApplyIIRGaussInteger1D().
This merely realizes the 3D extension of the paper by [Lam and Shi, 2007].
The i-th convolution will be skipped whenever sigs[i] is zero.
| [in] | in | input image |
| [out] | out | output convolved image |
| [in] | baseID | base ID (as defined by EnumerateBases()) to be convolved along |
| [in] | sigs | six sigmas to be used for those 6 convolutions |
Literature: S. Y. M. Lam and B. E. Shi. Recursive Anisotropic 2-D Gaussian Filtering Based on a Triple-axis Decomposition. In IEEE Transactions on Image Processing 16, 7. Pages 1925-1930. 2007.
| void AdjustInputOrientation | ( | double & | xyphi, | |
| double & | xzpsi, | |||
| int & | xDir, | |||
| int & | yDir, | |||
| int & | zDir | |||
| ) |
Adjust the 3D orientation of input Gaussian to easier find the appropriate cascade filtering setup.
Whenever we replace naive convolution with some other process, we usually think of some cascade of 1D convolutions. The directions of these 1D convolutions need to be properly adjusted. The searching for appropriate directions, however, can be demanding. Because of that, we've focused, and also tuned the finding algorithms, on just a representative range of orientations. The solutions for the rest of possible input orientations can be easily, and fast, derived from these "representative" solutions.
The purpose of this function is to change the given orientation to fit inside the "representative range" and give the information needed to restore the desired solution for the original input.
Once the cascade setup is determined, one needs to multiply the directional vectors' elements by respective [xyz]Dir constants to make the cascade compute the desired original input filter.
| [in] | xyphi | input and then "representative" orientation of filter's main axis, xyPlane stearing (in radians) |
| [in] | xzpsi | input and then "representative" orientation of filter's main axis, tilting around y-axis (in radians) |
| [out] | xDir | indicator of orientation change along the x-axis direction |
| [out] | yDir | indicator of orientation change along the y-axis direction |
| [out] | zDir | indicator of orientation change along the z-axis direction |
| void AdjustInputOrientation | ( | double & | xyphi, | |
| int & | xDir, | |||
| int & | yDir | |||
| ) |
Adjust the 2D orientation of input Gaussian to easier find the appropriate cascade filtering setup.
Similarily to 3D, this function changes the given orientation to fit inside the 2D "representative range" and give the information needed to restore the desired solution for the original input.
Once the cascade setup is determined, one needs to multiply the directional vectors' elements by respective [xy]Dir constants to make the cascade compute the desired original input filter.
| [in,out] | xyphi | input and then "representative" orientation of filter's main axis, xyPlane stearing (in radians) |
| [out] | xDir | indicator of orientation change along the x-axis direction |
| [out] | yDir | indicator of orientation change along the y-axis direction |
| void ApplyAlfaSymmetry | ( | const double | alfa, | |
| double & | new_alfa, | |||
| char & | revert_info | |||
| ) |
This is 3D Gauss filtering related function which utilizes the discovery of the alfa-symmetry.
Alfa-symmetry is a term we use to describe the fact that any two Gauss configurations (alfa,beta,S,s1,s2) and (90deg - alfa,beta,S,s1,s2) enjoys the directional vectors which are symmetric around the y=x axis. Values of sigmas (there is always certain sigma associated with every directional vector) remains unchanged. In other words, if (x,y,z) is a directional vector with Sigma in any admissible base for (alfa,beta,S,s1,s2) then there is (y,x,z) directional vector with the same Sigma in some admissible base for (90deg - alfa,beta,S,s1,s2). Further more, all directional vectors from given base translates through alfa-symmetry to directional vectors from the same ``alfa-symetric'' base.
Theoretically, there is no difference in the order in which the six 1D convolutions are applied (in case of 3D filtering, ApplyBaseConvolutions2(), the ApplyBaseConvolutions() constraints the first three vectors and as such these can't be changed). However, in practice we have observed that accuracy varies sometimes depending on the order of 1D convolutions. In order to preserve the quality of alfa-symmetrical admissible bases, one needs to change the order of directional vectors, besides the exchange of x and y elements, in the application of 1D convolutions. We have found that the following change in the order is working pretty good:
computational order in the original base -> new position in the computational order of the alfa-symmetric base:
1st -> 2nd
2nd -> 1st
3rd -> 3rd
4th -> 4th
5th -> 6th
6th -> 5th
Hence it is advised to additionally change the order of convolutions (or use the function RevertAlfaSymmetry()).
Since the determination of good filtering setup in terms of six directional vectors is available only for limited parameter space as defined in GetParamsANIGaussU2(), this function merely only detects whether given desired Gauss configuration is beyond the limits and, if so, it changes the configuration appropriately. The input Gauss configuration is represented only in the alfa parameter. Corrected configuration is stored in the new_alfa parameter. The information for the RevertAlfaSymmetry() function about the change is stored in the last parameter revert_info. Note that only parameter alfa, hence the name alfa-symmetry, of the Gauss configuration is important, the other Gauss configuration parameters should be used unchanged.
Ship the (new_alfa,beta,S,s1,s2) to the GetParamsANIGaussU2() and its results to the RevertAlfaSymmetry() to get the base (directional vectors with sigmas) for the original input (alfa,beta,S,s1,s2) Gaussian filter.
It is expected to prepare the input filter configuration via AdjustInputOrientation() function beforehand.
| [in] | alfa | part of input Gauss configuration, namely the angle xyPhi |
| [out] | new_alfa | part of alfa-symmetric Gauss configuration, the angle xyPhi |
| [out] | revert_info | information about the change for the function RevertAlfaSymmetry() |
Angles are expected in radians.
| void RevertAlfaSymmetry | ( | int | vecs[6][3], | |
| double | sigs[6], | |||
| const char | revert_info | |||
| ) |
This function modifies convolution setup as returned from the GetParamsANIGaussU2() utilizing the alfa-symmetry.
Look here for the explanation of what alfa-symmetry is. This function is intended to be used after a good base (i.e. directional vectors with sigmas) is found by the GetParamsANIGaussU2() function. It uses the information about the original Gauss filter's situation as provided by the function ApplyAlfaSymmetry() in the parameter revert_info and in-place modifies directional vectors vecs as well as it changes the order of them through parameters vecs and sigs.
| [in,out] | vecs | directional vectors of some base to be eventually modified |
| [in,out] | sigs | accompanied sigmas of some base to be eventually modified |
| [in] | revert_info | whether alfa-symmetry should be applied as detected by the ApplyAlfaSymmetry() |
The zero value of revert_info signals no changes are required. Any other value forces this function to exchange the x and y elements in every directional vector in vecs and change the order of 1D convolutions by changing the order of vectors and their sigmas in the arrays vecs and sigs. The change of order is described here.
| int DetermineGaussMatrixType | ( | const double | elems[6] | ) |
Gaussian classification bases on its covariance matrix.
An approach adopted by [Ulman, 2008] is applied here, equations (3), (4) and (5): A transition matrix, which is developed from directional vectors (i.e. from a base), is being combined with sigmas to form an expression equal to a Gaussian covariance matrix. To establish the equality a system of six linear equations is set and solved. The inputs to the system are directional vectors and the covariance matrix, sigmas act as unknows in it. This is essentially the core of both GetParamsANIGaussU() and GetParamsANIGaussU2() functions.
Three conditions can be defined. The number of them being satisfied or not satisfied determines sort of difficulty to solve the system. This is how the type of Gaussian matrix is being judged.
| [in] | elems | the diagonal and upper triangle of 3D Gaussian covariance matrix |
The positioning of input parameter elems in the scheme of Gaussian covariance matrix. Note that Gaussian covariance matrix is symetric.
elems[0] elems[1] elems[2] elems[1] elems[3] elems[4] elems[2] elems[4] elems[5]
x, 2x or 37 for the other typeswith x encoding which conditions are violated
x=1: the system is "over" xx=2: the system is "over" yx=4: the system is "over" zx=3: the system is "over" x and yx=5: the system is "over" x and zx=6: the system is "over" y and zx=7: the system is "over" x, y and zLiterature: V. Ulman. Arbitrarily-Oriented Anisotropic 3D Gaussian Filtering Computed with 1D Convolutions without Interpolation. In Proceedings of 8th WSEAS International Conference on SIGNAL PROCESSING, COMPUTATIONAL GEOMETRY and ARTIFICIAL VISION. Pages 56-62. 2008. ISBN: 978-960-6766-95-4.
| void LibFilters_GaussianLUT_LUTLoader | ( | std::map< int, std::vector< int > > & | lut | ) |
This fills the LibFilters_GaussianLUT::lut by calling many push_back() commands.
An external LUT loader hidden away in the ofLinearFilterANI3.cc source file.
Its purpose is purely ideological: not to disturb the continuity of ofLinearFilterANI2.cc file with its 6600+ lines of code. It is pulled into the class LibFilters_GaussianLUT by means of being called in the LibFilters_GaussianLUT::LoadLUT().
The Look-Up-Table (LUT) for directional vectors for Gaussians of types 2 and 3.
The initial base sets were not prepared for types 2 and 3. Instead, the Look-Up-Table lut is provided. It gives a mapping from some Gaussian parameters to six 3D directional vectors.
Every Gaussian is "flipped" to certain parameter space at first, see functions ApplyAlfaSymmetry() and AdjustInputOrientation(). At second, owing to the LUT, which is always finite, the Gaussian with closest parameters is determined (possibly with the method GroupGaussianForNearestLUT()). At third, Gaussian, represented with its parameters, is converted into an LUT index using the method EncodeGaussianToIndex(). At fourth, directional vectors are pulled from the LUT using the method ReadLUT(). These are supposed to be accompanied by appropriate Sigmas" for the original Gaussian.
Vectors in the LUT should be appropriate, i.e. they should give a good start for the computation of Sigmas that, together with supplied directional vectors, should yield a good approximation to the original demanded Gaussian filtering.
This is related to the function GetParamsANIGaussU2().
const BASE basesType0[2] [static] |
{
{{1,0,0},{0,1,0},{0,0,1}, {1,1,0},{0,1,1},{1,0,1}},
{{1,0,0},{0,1,0},{0,0,1},{-1,1,0},{0,1,1},{1,0,1}}
}
The initial base set for Gaussians of type 0.
This is related to the functions DetermineGaussMatrixType() and GetParamsANIGaussU2().
const BASE basesType1x[48] [static] |
The initial base set for Gaussians of type 1.
Such Gaussians have the property that exactly one condition out of three possible is violated. This is initial base set for those which are, so called, "over x".
This is related to the functions DetermineGaussMatrixType() and GetParamsANIGaussU2().
const BASE basesType1y[38] [static] |
Similar to the basesType1x.
const BASE basesType1z[44] [static] |
Similar to the basesType1x.
1.7.1