geomfum.descriptor package#

Submodules#

geomfum.descriptor.learned module#

Implementation of the learned descriptor.

The learned descriptor is a descriptor that uses a neural network to compute features.

class geomfum.descriptor.learned.BaseFeatureExtractor[source]#

Bases: ABC

Abstract base class for neural network feature extractors.

load_from_path(path)[source]#

Load model parameters from the provided file path.

Parameters:

path (str) – Path to the saved model parameters

save(path)[source]#

Save model parameters to the specified file path.

Parameters:

path (str) – Path to the saved model parameters

class geomfum.descriptor.learned.Descriptor[source]#

Bases: ABC

Abstract base class for shape descriptors.

class geomfum.descriptor.learned.FeatureExtractor(*args, **kwargs)[source]#

Bases: WhichRegistryMixins

Factory for creating feature extractors from registry.

class geomfum.descriptor.learned.FeatureExtractorRegistry[source]#

Bases: Registry

MAP = {'diffusionnet': ('DiffusionnetFeatureExtractor', None), 'pointnet': ('PointnetFeatureExtractor', None), 'transformer': ('TransformerFeatureExtractor', None)}#
default = 'diffusionnet'#
class geomfum.descriptor.learned.LearnedDescriptor(feature_extractor=None)[source]#

Bases: Descriptor, ABC, Module

Descriptor computed using neural network feature extractors.

Parameters:

feature_extractor (Feature Extractor) – Feature extractor to use.

forward(shape)[source]#

Compute descriptor.

Parameters:

shape (Shape.) – Shape.

Returns:

features (array-like, shape=[…, n_features, n_vertices]) – Descriptors of the shape, where n_features is the number of features extracted by the feature extractor.

class geomfum.descriptor.learned.WhichRegistryMixins(*args, **kwargs)[source]#

Bases: object

Mixin enabling registry-based instantiation via ‘which’ parameter.

classmethod from_registry(*args, which=None, **kwargs)[source]#

Create instance from registered implementation.

Parameters:

which (str) – A registered implementation.

Returns:

obj (BaseHeatKernelSignature) – Instantiated object.

geomfum.descriptor.pipeline module#

Descriptor pipeline.

class geomfum.descriptor.pipeline.ArangeSubsampler(subsample_step=1, axis=0)[source]#

Bases: Subsampler

Subsampler using uniform stride-based indexing.

Parameters:
  • subsample_step (int) – Arange step.

  • axis (int) – Axis from which to subsample.

class geomfum.descriptor.pipeline.Descriptor[source]#

Bases: ABC

Abstract base class for shape descriptors.

class geomfum.descriptor.pipeline.DescriptorPipeline(steps)[source]#

Bases: object

Sequential pipeline for computing and processing shape descriptors.

Parameters:

steps (list or tuple) – Steps to apply. Include: descriptor, subsampler, normalizer.

apply(shape)[source]#

Apply descriptor pipeline.

Parameters:

shape (Shape) – Shape to apply pipeline to.

Returns:

descr (array-like, shape=[…, n]) – Descriptor.

class geomfum.descriptor.pipeline.L2InnerNormalizer[source]#

Bases: Normalizer

Normalizer using L2 inner product with mass matrix.

class geomfum.descriptor.pipeline.LearnedDescriptor(feature_extractor=None)[source]#

Bases: Descriptor, ABC, Module

Descriptor computed using neural network feature extractors.

Parameters:

feature_extractor (Feature Extractor) – Feature extractor to use.

forward(shape)[source]#

Compute descriptor.

Parameters:

shape (Shape.) – Shape.

Returns:

features (array-like, shape=[…, n_features, n_vertices]) – Descriptors of the shape, where n_features is the number of features extracted by the feature extractor.

class geomfum.descriptor.pipeline.Normalizer[source]#

Bases: ABC

Abstract base class for descriptor normalization.

class geomfum.descriptor.pipeline.Subsampler[source]#

Bases: ABC

Abstract base class for array subsampling operations.

geomfum.descriptor.shot module#

SHOT (Signatures of Histograms of OrienTations) descriptor.

Shape-only implementation translated from the reference C++ code by Tombari, Salti and Di Stefano:

“Unique Signatures of Histograms for Local Surface Description” ECCV 2010

Only the shape channel (normal-alignment cosines) is implemented here; the color channel is omitted since geomfum meshes do not carry per-vertex RGB.

References

class geomfum.descriptor.shot.Descriptor[source]#

Bases: ABC

Abstract base class for shape descriptors.

class geomfum.descriptor.shot.ShotDescriptor(radius=None, n_bins=10, min_neighbors=5)[source]#

Bases: Descriptor

SHOT descriptor for triangle meshes.

Computes a 352-dimensional (by default) local shape signature per vertex by accumulating normal-alignment statistics of neighbours into a spatially structured histogram. The algorithm is translated directly from the reference C++ implementation by Tombari, Salti and Di Stefano (ECCV 2010).

Parameters:
  • radius (float, optional) – Support sphere radius. If None (default), the radius is set automatically to 0.05 × bounding-box diagonal of the input mesh, which gives a neighbourhood of roughly 50–200 vertices on typical normalised human-body meshes (FAUST, SMAL, …).

  • n_bins (int) – Number of histogram bins per spatial volume (default 10). Descriptor dimensionality = 32 × (n_bins + 1) = 352 for n_bins=10.

  • min_neighbors (int) – Minimum number of neighbours required to compute a descriptor for a vertex. Vertices with fewer neighbours receive an all-zero row.

References

property descriptor_size#

Dimensionality of the descriptor vector per vertex.

class geomfum.descriptor.shot.cKDTree#

Bases: object

cKDTree(data, leafsize=16, compact_nodes=True, copy_data=False,

balanced_tree=True, boxsize=None)

kd-tree for quick nearest-neighbor lookup

This class provides an index into a set of k-dimensional points which can be used to rapidly look up the nearest neighbors of any point.

Note

cKDTree is functionally identical to KDTree. Prior to SciPy v1.6.0, cKDTree had better performance and slightly different functionality but now the two names exist only for backward-compatibility reasons. If compatibility with SciPy < 1.6 is not a concern, prefer KDTree.

Parameters:
  • data (array_like, shape (n,m)) – The n data points of dimension m to be indexed. This array is not copied unless this is necessary to produce a contiguous array of doubles, and so modifying this data will result in bogus results. The data are also copied if the kd-tree is built with copy_data=True.

  • leafsize (positive int, optional) – The number of points at which the algorithm switches over to brute-force. Default: 16.

  • compact_nodes (bool, optional) – If True, the kd-tree is built to shrink the hyperrectangles to the actual data range. This usually gives a more compact tree that is robust against degenerated input data and gives faster queries at the expense of longer build time. Default: True.

  • copy_data (bool, optional) – If True the data is always copied to protect the kd-tree against data corruption. Default: False.

  • balanced_tree (bool, optional) – If True, the median is used to split the hyperrectangles instead of the midpoint. This usually gives a more compact tree and faster queries at the expense of longer build time. Default: True.

  • boxsize (array_like or scalar, optional) – Apply an m-d toroidal topology to the KDTree. The topology is generated by \(x_i + n_i L_i\) where \(n_i\) are integers and \(L_i\) is the boxsize along i-th dimension. The input data shall be wrapped into \([0, L_i)\). A ValueError is raised if any of the data is outside of this bound.

Notes

The algorithm used is described in [1]_. The general idea is that the kd-tree is a binary tree, each of whose nodes represents an axis-aligned hyperrectangle. Each node specifies an axis and splits the set of points based on whether their coordinate along that axis is greater than or less than a particular value.

During construction, the axis and splitting point are chosen by the “sliding midpoint” rule, which ensures that the cells do not all become long and thin.

The tree can be queried for the r closest neighbors of any given point (optionally returning only those within some maximum distance of the point). It can also be queried, with a substantial gain in efficiency, for the r approximate closest neighbors.

For large dimensions (20 is already large) do not expect this to run significantly faster than brute force. High-dimensional nearest-neighbor queries are a substantial open problem in computer science.

References

data#

The n data points of dimension m to be indexed. This array is not copied unless this is necessary to produce a contiguous array of doubles. The data are also copied if the kd-tree is built with copy_data=True.

Type:

ndarray, shape (n,m)

leafsize#

The number of points at which the algorithm switches over to brute-force.

Type:

positive int

m#

The dimension of a single data-point.

Type:

int

n#

The number of data points.

Type:

int

maxes#

The maximum value in each dimension of the n data points.

Type:

ndarray, shape (m,)

mins#

The minimum value in each dimension of the n data points.

Type:

ndarray, shape (m,)

tree#

This attribute exposes a Python view of the root node in the cKDTree object. A full Python view of the kd-tree is created dynamically on the first access. This attribute allows you to create your own query functions in Python.

Type:

object, class cKDTreeNode

size#

The number of nodes in the tree.

Type:

int

boxsize#
count_neighbors(self, other, r, p=2.0, weights=None, cumulative=True)#

Count how many nearby pairs can be formed.

Count the number of pairs (x1,x2) can be formed, with x1 drawn from self and x2 drawn from other, and where distance(x1, x2, p) <= r.

Data points on self and other are optionally weighted by the weights argument. (See below)

This is adapted from the “two-point correlation” algorithm described by Gray and Moore [1]_. See notes for further discussion.

Parameters:
  • other (cKDTree instance) – The other tree to draw points from, can be the same tree as self.

  • r (float or one-dimensional array of floats) – The radius to produce a count for. Multiple radii are searched with a single tree traversal. If the count is non-cumulative (cumulative=False), r defines the edges of the bins, and must be non-decreasing.

  • p (float, optional) – 1<=p<=infinity. Which Minkowski p-norm to use. Default 2.0. A finite large p may cause a ValueError if overflow can occur.

  • weights (tuple, array_like, or None, optional) – If None, the pair-counting is unweighted. If given as a tuple, weights[0] is the weights of points in self, and weights[1] is the weights of points in other; either can be None to indicate the points are unweighted. If given as an array_like, weights is the weights of points in self and other. For this to make sense, self and other must be the same tree. If self and other are two different trees, a ValueError is raised. Default: None

  • cumulative (bool, optional) – Whether the returned counts are cumulative. When cumulative is set to False the algorithm is optimized to work with a large number of bins (>10) specified by r. When cumulative is set to True, the algorithm is optimized to work with a small number of r. Default: True

Returns:

result (scalar or 1-D array) – The number of pairs. For unweighted counts, the result is integer. For weighted counts, the result is float. If cumulative is False, result[i] contains the counts with (-inf if i == 0 else r[i-1]) < R <= r[i]

Notes

Pair-counting is the basic operation used to calculate the two point correlation functions from a data set composed of position of objects.

Two point correlation function measures the clustering of objects and is widely used in cosmology to quantify the large scale structure in our Universe, but it may be useful for data analysis in other fields where self-similar assembly of objects also occur.

The Landy-Szalay estimator for the two point correlation function of D measures the clustering signal in D. [2]

For example, given the position of two sets of objects,

  • objects D (data) contains the clustering signal, and

  • objects R (random) that contains no signal,

\[\xi(r) = \frac{<D, D> - 2 f <D, R> + f^2<R, R>}{f^2<R, R>},\]

where the brackets represents counting pairs between two data sets in a finite bin around r (distance), corresponding to setting cumulative=False, and f = float(len(D)) / float(len(R)) is the ratio between number of objects from data and random.

The algorithm implemented here is loosely based on the dual-tree algorithm described in [1]_. We switch between two different pair-cumulation scheme depending on the setting of cumulative. The computing time of the method we use when for cumulative == False does not scale with the total number of bins. The algorithm for cumulative == True scales linearly with the number of bins, though it is slightly faster when only 1 or 2 bins are used. [5].

As an extension to the naive pair-counting, weighted pair-counting counts the product of weights instead of number of pairs. Weighted pair-counting is used to estimate marked correlation functions ([3], section 2.2), or to properly calculate the average of data per distance bin (e.g. [4], section 2.1 on redshift).

Examples

You can count neighbors number between two kd-trees within a distance:

>>> import numpy as np
>>> from scipy.spatial import cKDTree
>>> rng = np.random.default_rng()
>>> points1 = rng.random((5, 2))
>>> points2 = rng.random((5, 2))
>>> kd_tree1 = cKDTree(points1)
>>> kd_tree2 = cKDTree(points2)
>>> kd_tree1.count_neighbors(kd_tree2, 0.2)
1

This number is same as the total pair number calculated by query_ball_tree:

>>> indexes = kd_tree1.query_ball_tree(kd_tree2, r=0.2)
>>> sum([len(i) for i in indexes])
1
data#
indices#
leafsize#
m#
maxes#
mins#
n#
query(self, x, k=1, eps=0.0, p=2.0, distance_upper_bound=np.inf, workers=1)#

Query the kd-tree for nearest neighbors

Parameters:
  • x (array_like, last dimension self.m) – An array of points to query.

  • k (list of integer or integer) – The list of k-th nearest neighbors to return. If k is an integer it is treated as a list of [1, … k] (range(1, k+1)). Note that the counting starts from 1.

  • eps (non-negative float) – Return approximate nearest neighbors; the k-th returned value is guaranteed to be no further than (1+eps) times the distance to the real k-th nearest neighbor.

  • p (float, 1<=p<=infinity) – Which Minkowski p-norm to use. 1 is the sum-of-absolute-values “Manhattan” distance 2 is the usual Euclidean distance infinity is the maximum-coordinate-difference distance A finite large p may cause a ValueError if overflow can occur.

  • distance_upper_bound (nonnegative float) – Return only neighbors within this distance. This is used to prune tree searches, so if you are doing a series of nearest-neighbor queries, it may help to supply the distance to the nearest neighbor of the most recent point.

  • workers (int, optional) – Number of workers to use for parallel processing. If -1 is given all CPU threads are used. Default: 1.

    Changed in version 1.9.0: The “n_jobs” argument was renamed “workers”. The old name “n_jobs” was deprecated in SciPy 1.6.0 and was removed in SciPy 1.9.0.

Returns:

  • d (array of floats) – The distances to the nearest neighbors. If x has shape tuple+(self.m,), then d has shape tuple+(k,). When k == 1, the last dimension of the output is squeezed. Missing neighbors are indicated with infinite distances.

  • i (ndarray of ints) – The index of each neighbor in self.data. If x has shape tuple+(self.m,), then i has shape tuple+(k,). When k == 1, the last dimension of the output is squeezed. Missing neighbors are indicated with self.n.

Notes

If the KD-Tree is periodic, the position x is wrapped into the box.

When the input k is a list, a query for arange(max(k)) is performed, but only columns that store the requested values of k are preserved. This is implemented in a manner that reduces memory usage.

Examples

>>> import numpy as np
>>> from scipy.spatial import cKDTree
>>> x, y = np.mgrid[0:5, 2:8]
>>> tree = cKDTree(np.c_[x.ravel(), y.ravel()])

To query the nearest neighbours and return squeezed result, use

>>> dd, ii = tree.query([[0, 0], [2.2, 2.9]], k=1)
>>> print(dd, ii, sep='\n')
[2.         0.2236068]
[ 0 13]

To query the nearest neighbours and return unsqueezed result, use

>>> dd, ii = tree.query([[0, 0], [2.2, 2.9]], k=[1])
>>> print(dd, ii, sep='\n')
[[2.        ]
 [0.2236068]]
[[ 0]
 [13]]

To query the second nearest neighbours and return unsqueezed result, use

>>> dd, ii = tree.query([[0, 0], [2.2, 2.9]], k=[2])
>>> print(dd, ii, sep='\n')
[[2.23606798]
 [0.80622577]]
[[ 6]
 [19]]

To query the first and second nearest neighbours, use

>>> dd, ii = tree.query([[0, 0], [2.2, 2.9]], k=2)
>>> print(dd, ii, sep='\n')
[[2.         2.23606798]
 [0.2236068  0.80622577]]
[[ 0  6]
 [13 19]]

or, be more specific

>>> dd, ii = tree.query([[0, 0], [2.2, 2.9]], k=[1, 2])
>>> print(dd, ii, sep='\n')
[[2.         2.23606798]
 [0.2236068  0.80622577]]
[[ 0  6]
 [13 19]]
query_ball_point(x, r, p=2.0, eps=0.0, workers=None, return_sorted=None, return_length=False, **kwargs)#
query_ball_point(self, x, r, p=2.0, eps=0.0, workers=1, return_sorted=None,

return_length=False)

Find all points within distance r of point(s) x.

Parameters:
  • x (array_like, shape tuple + (self.m,)) – The point or points to search for neighbors of.

  • r (array_like, float) – The radius of points to return, shall broadcast to the length of x.

  • p (float, optional) – Which Minkowski p-norm to use. Should be in the range [1, inf]. A finite large p may cause a ValueError if overflow can occur.

  • eps (nonnegative float, optional) – Approximate search. Branches of the tree are not explored if their nearest points are further than r / (1 + eps), and branches are added in bulk if their furthest points are nearer than r * (1 + eps).

  • workers (int, optional) – Number of jobs to schedule for parallel processing. If -1 is given all processors are used. Default: 1.

    Changed in version 1.9.0: The “n_jobs” argument was renamed “workers”. The old name “n_jobs” was deprecated in SciPy 1.6.0 and was removed in SciPy 1.9.0.

  • return_sorted (bool, optional) – Sorts returned indices if True and does not sort them if False. If None, does not sort single point queries, but does sort multi-point queries which was the behavior before this option was added.

    Added in version 1.2.0.

  • return_length (bool, optional) – Return the number of points inside the radius instead of a list of the indices. .. versionadded:: 1.3.0

Returns:

results (list or array of lists) – If x is a single point, returns a list of the indices of the neighbors of x. If x is an array of points, returns an object array of shape tuple containing lists of neighbors.

Notes

If you have many points whose neighbors you want to find, you may save substantial amounts of time by putting them in a cKDTree and using query_ball_tree.

Examples

>>> import numpy as np
>>> from scipy import spatial
>>> x, y = np.mgrid[0:4, 0:4]
>>> points = np.c_[x.ravel(), y.ravel()]
>>> tree = spatial.cKDTree(points)
>>> tree.query_ball_point([2, 0], 1)
[4, 8, 9, 12]

Query multiple points and plot the results:

>>> import matplotlib.pyplot as plt
>>> points = np.asarray(points)
>>> plt.plot(points[:,0], points[:,1], '.')
>>> for results in tree.query_ball_point(([2, 0], [3, 3]), 1):
...     nearby_points = points[results]
...     plt.plot(nearby_points[:,0], nearby_points[:,1], 'o')
>>> plt.margins(0.1, 0.1)
>>> plt.show()
query_ball_tree(self, other, r, p=2.0, eps=0.0)#

Find all pairs of points between self and other whose distance is at most r

Parameters:
  • other (cKDTree instance) – The tree containing points to search against.

  • r (float) – The maximum distance, has to be positive.

  • p (float, optional) – Which Minkowski norm to use. p has to meet the condition 1 <= p <= infinity. A finite large p may cause a ValueError if overflow can occur.

  • eps (float, optional) – Approximate search. Branches of the tree are not explored if their nearest points are further than r/(1+eps), and branches are added in bulk if their furthest points are nearer than r * (1+eps). eps has to be non-negative.

Returns:

results (list of lists) – For each element self.data[i] of this tree, results[i] is a list of the indices of its neighbors in other.data.

Examples

You can search all pairs of points between two kd-trees within a distance:

>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> from scipy.spatial import cKDTree
>>> rng = np.random.default_rng()
>>> points1 = rng.random((15, 2))
>>> points2 = rng.random((15, 2))
>>> plt.figure(figsize=(6, 6))
>>> plt.plot(points1[:, 0], points1[:, 1], "xk", markersize=14)
>>> plt.plot(points2[:, 0], points2[:, 1], "og", markersize=14)
>>> kd_tree1 = cKDTree(points1)
>>> kd_tree2 = cKDTree(points2)
>>> indexes = kd_tree1.query_ball_tree(kd_tree2, r=0.2)
>>> for i in range(len(indexes)):
...     for j in indexes[i]:
...         plt.plot([points1[i, 0], points2[j, 0]],
...             [points1[i, 1], points2[j, 1]], "-r")
>>> plt.show()
query_pairs(self, r, p=2.0, eps=0.0, output_type='set')#

Find all pairs of points in self whose distance is at most r.

Parameters:
  • r (positive float) – The maximum distance.

  • p (float, optional) – Which Minkowski norm to use. p has to meet the condition 1 <= p <= infinity. A finite large p may cause a ValueError if overflow can occur.

  • eps (float, optional) – Approximate search. Branches of the tree are not explored if their nearest points are further than r/(1+eps), and branches are added in bulk if their furthest points are nearer than r * (1+eps). eps has to be non-negative.

  • output_type (string, optional) – Choose the output container, ‘set’ or ‘ndarray’. Default: ‘set’

Returns:

results (set or ndarray) – Set of pairs (i,j), with i < j, for which the corresponding positions are close. If output_type is ‘ndarray’, an ndarray is returned instead of a set.

Examples

You can search all pairs of points in a kd-tree within a distance:

>>> import matplotlib.pyplot as plt
>>> import numpy as np
>>> from scipy.spatial import cKDTree
>>> rng = np.random.default_rng()
>>> points = rng.random((20, 2))
>>> plt.figure(figsize=(6, 6))
>>> plt.plot(points[:, 0], points[:, 1], "xk", markersize=14)
>>> kd_tree = cKDTree(points)
>>> pairs = kd_tree.query_pairs(r=0.2)
>>> for (i, j) in pairs:
...     plt.plot([points[i, 0], points[j, 0]],
...             [points[i, 1], points[j, 1]], "-r")
>>> plt.show()
size#
sparse_distance_matrix(self, other, max_distance, p=2.0)#

Compute a sparse distance matrix

Computes a distance matrix between two cKDTrees, leaving as zero any distance greater than max_distance.

Parameters:
  • other (cKDTree)

  • max_distance (positive float)

  • p (float, 1<=p<=infinity) – Which Minkowski p-norm to use. A finite large p may cause a ValueError if overflow can occur.

  • output_type (string, optional) – Which container to use for output data. Options: ‘dok_matrix’, ‘coo_matrix’, ‘dict’, or ‘ndarray’. Default: ‘dok_matrix’.

Returns:

result (dok_matrix, coo_matrix, dict or ndarray) – Sparse matrix representing the results in “dictionary of keys” format. If a dict is returned the keys are (i,j) tuples of indices. If output_type is ‘ndarray’ a record array with fields ‘i’, ‘j’, and ‘v’ is returned,

Examples

You can compute a sparse distance matrix between two kd-trees:

>>> import numpy as np
>>> from scipy.spatial import cKDTree
>>> rng = np.random.default_rng()
>>> points1 = rng.random((5, 2))
>>> points2 = rng.random((5, 2))
>>> kd_tree1 = cKDTree(points1)
>>> kd_tree2 = cKDTree(points2)
>>> sdm = kd_tree1.sparse_distance_matrix(kd_tree2, 0.3)
>>> sdm.toarray()
array([[0.        , 0.        , 0.12295571, 0.        , 0.        ],
   [0.        , 0.        , 0.        , 0.        , 0.        ],
   [0.28942611, 0.        , 0.        , 0.2333084 , 0.        ],
   [0.        , 0.        , 0.        , 0.        , 0.        ],
   [0.24617575, 0.29571802, 0.26836782, 0.        , 0.        ]])

You can check distances above the max_distance are zeros:

>>> from scipy.spatial import distance_matrix
>>> distance_matrix(points1, points2)
array([[0.56906522, 0.39923701, 0.12295571, 0.8658745 , 0.79428925],
   [0.37327919, 0.7225693 , 0.87665969, 0.32580855, 0.75679479],
   [0.28942611, 0.30088013, 0.6395831 , 0.2333084 , 0.33630734],
   [0.31994999, 0.72658602, 0.71124834, 0.55396483, 0.90785663],
   [0.24617575, 0.29571802, 0.26836782, 0.57714465, 0.6473269 ]])
tree#

geomfum.descriptor.spectral module#

Spectral descriptors.

class geomfum.descriptor.spectral.HeatKernelFilter[source]#

Bases: SpectralFilter

Heat kernel filter computing exp(-t * λ) coefficients for HKS.

class geomfum.descriptor.spectral.HeatKernelSignature(scale=True, n_domain=3, domain=None, k=None)[source]#

Bases: WhichRegistryMixins, SpectralDescriptor

Heat Kernel Signature descriptor using heat diffusion over time.

Parameters:
  • scale (bool) – Whether to scale weights to sum to one.

  • n_domain (int) – Number of domain points. Ignored if domain is not None.

  • domain (callable or array-like, shape=[n_domain], optional) – Method to compute time domain points (f(shape)) or time domain points.

  • k (int, optional) – Number of eigenfunctions to use. If None, all eigenfunctions are used.

class geomfum.descriptor.spectral.HeatKernelSignatureRegistry[source]#

Bases: Registry

MAP = {'pyfm': ('PyfmHeatKernelSignature', None)}#
default = 'pyfm'#
has_internal = True#
class geomfum.descriptor.spectral.LandmarkHeatKernelSignature(scale=True, n_domain=3, domain=None, k=None)[source]#

Bases: WhichRegistryMixins, SpectralDescriptor

Heat Kernel Signature computed from landmark points.

Parameters:
  • scale (bool) – Whether to scale weights to sum to one.

  • n_domain (int) – Number of domain points. Ignored if domain is not None.

  • domain (callable or array-like, shape=[n_domain], optional) – Method to compute time domain points (f(shape)) or time domain points.

  • k (int, optional) – Number of eigenfunctions to use.

class geomfum.descriptor.spectral.LandmarkHeatKernelSignatureRegistry[source]#

Bases: Registry

MAP = {'pyfm': ('PyfmLandmarkHeatKernelSignature', None)}#
default = 'pyfm'#
has_internal = True#
class geomfum.descriptor.spectral.LandmarkScaleInvariantHeatKernelSignature(scale=True, n_domain=3, domain=None, k=None)[source]#

Bases: LandmarkHeatKernelSignature

Scale-Invariant Heat Kernel Signature descriptor on landmarks.

Parameters:
  • scale (bool, optional) – Whether to make the descriptor scale-invariant, by default True.

  • n_domain (int, optional) – Number of frequency domains, by default 3.

  • domain (list, optional) – List of frequency domain limits, by default None.

  • k (int, optional) – Number of eigenvalues and eigenfunctions to use, by default None.

class geomfum.descriptor.spectral.LandmarkWaveKernelSignature(scale=True, sigma=None, n_domain=3, domain=None, k=None)[source]#

Bases: WhichRegistryMixins, SpectralDescriptor

Wave Kernel Signature computed from landmark points.

Parameters:
  • scale (bool) – Whether to scale weights to sum to one.

  • sigma (float) – Standard deviation for the Gaussian.

  • n_domain (int) – Number of domain points. Ignored if domain is not None.

  • domain (callable or array-like, shape=[n_domain], optional) – Method to compute energy domain points (f(shape)) or energy domain points.

  • k (int, optional) – Number of eigenfunctions to use.

class geomfum.descriptor.spectral.LandmarkWaveKernelSignatureRegistry[source]#

Bases: Registry

MAP = {'pyfm': ('PyfmLandmarkWaveKernelSignature', None)}#
default = 'pyfm'#
has_internal = True#
class geomfum.descriptor.spectral.ScaleInvariantHeatKernelSignature(scale=True, n_domain=3, domain=None, k=None)[source]#

Bases: HeatKernelSignature

Scale-Invariant Heat Kernel Signature descriptor.

Parameters:
  • scale (bool, optional) – Whether to make the descriptor scale-invariant, by default True.

  • n_domain (int, optional) – Number of frequency domains, by default 3.

  • domain (list, optional) – List of frequency domain limits, by default None.

  • k (int, optional) – Number of eigenvalues and eigenfunctions to use, by default None.

References

[BK2010]

M. M. Bronstein and I. Kokkinos. “Scale-invariant heat kernel signatures for non-rigid shape recognition.” 2010 IEEE Computer Society Conference on Computer Vision and Pattern Recognition, San Francisco, CA, USA, 2010, pp. 1704-1711. https://doi.org/10.1109/CVPR.2010.5539838.

class geomfum.descriptor.spectral.SpectralDescriptor(spectral_filter=None, domain=None, sigma=1, scale=True, landmarks=False, k=None)[source]#

Bases: Descriptor, ABC

Spectral descriptor computed from Laplacian eigenfunctions with spectral filters.

Parameters:
  • spectral_filter (SpectralFilter) – Spectral filter.

  • domain (callable or array-like, shape=[n_domain]) – Method to compute domain points (f(basis, n_domain)) or domain points.

  • sigma (float) – Standard deviation for the Gaussian.

  • scale (bool) – Whether to scale weights to sum to one.

  • landmarks (bool) – Whether to compute landmarks based descriptors.

  • k (int, optional) – Number of eigenvalues and eigenvectors to use. If None, basis.use_k is used.

class geomfum.descriptor.spectral.SpectralFilter[source]#

Bases: ABC

Abstract base class for computing spectral filter coefficients from eigenvalues.

class geomfum.descriptor.spectral.WaveKernelFilter[source]#

Bases: SpectralFilter

Wave kernel filter using Gaussian weighting in log-eigenvalue space for WKS.

class geomfum.descriptor.spectral.WaveKernelSignature(scale=True, sigma=None, n_domain=3, domain=None, k=None)[source]#

Bases: WhichRegistryMixins, SpectralDescriptor

Wave Kernel Signature descriptor using quantum mechanical wave propagation.

Parameters:
  • scale (bool) – Whether to scale weights to sum to one.

  • sigma (float) – Standard deviation for the Gaussian.

  • n_domain (int) – Number of domain points. Ignored if domain is not None.

  • domain (callable or array-like, shape=[n_domain], optional) – Method to compute energy domain points (f(shape)) or energy domain points.

  • k (int, optional) – Number of eigenfunctions to use. If None, all eigenfunctions are used.

class geomfum.descriptor.spectral.WaveKernelSignatureRegistry[source]#

Bases: Registry

MAP = {'pyfm': ('PyfmWaveKernelSignature', None)}#
default = 'pyfm'#
has_internal = True#
class geomfum.descriptor.spectral.WhichRegistryMixins(*args, **kwargs)[source]#

Bases: object

Mixin enabling registry-based instantiation via ‘which’ parameter.

classmethod from_registry(*args, which=None, **kwargs)[source]#

Create instance from registered implementation.

Parameters:

which (str) – A registered implementation.

Returns:

obj (BaseHeatKernelSignature) – Instantiated object.

class geomfum.descriptor.spectral.WksDefaultDomain(n_domain, sigma=None, n_overlap=7, n_trans=2)[source]#

Bases: object

Default domain generator for Wave Kernel Signature using logarithmic energy sampling.

Parameters:
  • shape (Shape.) – Shape with basis.

  • n_domain (int) – Number of energy points to use.

  • n_overlap (int) – Controls Gaussian overlap. Ignored if sigma is not None.

  • n_trans (int) – Number of standard deviations to translate energy bound by.

geomfum.descriptor.spectral.hks_default_domain(shape, n_domain)[source]#

Compute HKS default domain. The domain is a set of sampled time points.

Parameters:
  • shape (Shape.) – Shape with basis.

  • n_domain (int) – Number of time points.

Returns:

domain (array-like, shape=[n_domain]) – Time points.

Module contents#

Descriptors Module. This module contains various shape descriptors used in Geomfum. Including spectral descriptors, distance from landmarks, and feature extractors.

class geomfum.descriptor.Descriptor[source]#

Bases: ABC

Abstract base class for shape descriptors.

class geomfum.descriptor.DistanceFromLandmarksDescriptor[source]#

Bases: Descriptor

Descriptor computing geodesic distances from landmark points.

class geomfum.descriptor.ShotDescriptor(radius=None, n_bins=10, min_neighbors=5)[source]#

Bases: Descriptor

SHOT descriptor for triangle meshes.

Computes a 352-dimensional (by default) local shape signature per vertex by accumulating normal-alignment statistics of neighbours into a spatially structured histogram. The algorithm is translated directly from the reference C++ implementation by Tombari, Salti and Di Stefano (ECCV 2010).

Parameters:
  • radius (float, optional) – Support sphere radius. If None (default), the radius is set automatically to 0.05 × bounding-box diagonal of the input mesh, which gives a neighbourhood of roughly 50–200 vertices on typical normalised human-body meshes (FAUST, SMAL, …).

  • n_bins (int) – Number of histogram bins per spatial volume (default 10). Descriptor dimensionality = 32 × (n_bins + 1) = 352 for n_bins=10.

  • min_neighbors (int) – Minimum number of neighbours required to compute a descriptor for a vertex. Vertices with fewer neighbours receive an all-zero row.

References

property descriptor_size#

Dimensionality of the descriptor vector per vertex.

class geomfum.descriptor.SpectralDescriptor(spectral_filter=None, domain=None, sigma=1, scale=True, landmarks=False, k=None)[source]#

Bases: Descriptor, ABC

Spectral descriptor computed from Laplacian eigenfunctions with spectral filters.

Parameters:
  • spectral_filter (SpectralFilter) – Spectral filter.

  • domain (callable or array-like, shape=[n_domain]) – Method to compute domain points (f(basis, n_domain)) or domain points.

  • sigma (float) – Standard deviation for the Gaussian.

  • scale (bool) – Whether to scale weights to sum to one.

  • landmarks (bool) – Whether to compute landmarks based descriptors.

  • k (int, optional) – Number of eigenvalues and eigenvectors to use. If None, basis.use_k is used.