from __future__ import print_function from __future__ import division import abc import six import numpy as np import open3d as o3 from sklearn import mixture from sklearn import svm @six.add_metaclass(abc.ABCMeta) class Feature(): @abc.abstractmethod def init(self): pass @abc.abstractmethod def compute(self, data): return None def annealing(self): pass def __call__(self, data): return self.compute(data) class FPFH(Feature): """Fast Point Feature Histograms Args: radius_normal (float): Radius search parameter for computing normal vectors radius_feature (float): Radius search parameter for computing FPFH. """ def __init__(self, radius_normal=0.1, radius_feature=0.5): self._param_normal = o3.geometry.KDTreeSearchParamHybrid(radius=radius_normal, max_nn=30) self._param_feature = o3.geometry.KDTreeSearchParamHybrid(radius=radius_feature, max_nn=100) def init(self): pass def estimate_normals(self, pcd): pcd.estimate_normals(search_param=self._param_normal) def compute(self, data): pcd = o3.geometry.PointCloud() pcd.points = o3.utility.Vector3dVector(data) self.estimate_normals(pcd) fpfh = o3.registration.compute_fpfh_feature(pcd, self._param_feature) return fpfh.data.T class GMM(Feature): """Feature points extraction using Gaussian mixture model Args: n_gmm_components (int): The number of mixture components. """ def __init__(self, n_gmm_components=800): self._n_gmm_components = n_gmm_components def init(self): self._clf = mixture.GaussianMixture(n_components=self._n_gmm_components, covariance_type='spherical') def compute(self, data): self._clf.fit(data) return self._clf.means_, self._clf.weights_ class OneClassSVM(Feature): """Feature points extraction using One class SVM Args: dim (int): The dimension of samples. sigma (float): Veriance of the gaussian distribution made from parameters of SVM. gamma (float, optional): Coefficient for RBF kernel. nu (float, optional): An upper bound on the fraction of training errors and a lower bound of the fraction of support vectors. delta (float, optional): Anealing parameter for optimization. """ def __init__(self, dim, sigma, gamma=0.5, nu=0.05, delta=10.0): self._dim = dim self._sigma = sigma self._gamma = gamma self._nu = nu self._delta = delta def init(self): self._clf = svm.OneClassSVM(nu=self._nu, kernel="rbf", gamma=self._gamma) def compute(self, data): self._clf.fit(data) z = np.power(2.0 * np.pi * self._sigma**2, self._dim * 0.5) return self._clf.support_vectors_, self._clf.dual_coef_[0] * z def annealing(self): self._gamma *= self._delta