robokudo.utils.shape_fitting

Utilities for fitting primitive shapes to 3D points.

This module provides robust least-squares based fitting for sphere and cylinder models, plus a cuboid approximation based on oriented bounding boxes. The implementation is intended for segmented object-level point sets.

Attributes

Classes

SphereFit

Fitted sphere model with inlier and quality information.

CylinderFit

Fitted cylinder model with inlier and quality information.

CuboidFit

Fitted cuboid model with inlier and quality information.

CylinderFitConstraints

Numerical constraints used during cylinder fitting and validation.

CylinderInitializationSettings

Search settings controlling cylinder multi-start initialization.

Functions

sphere_residuals(→ numpy.ndarray)

Compute sphere residuals for optimization.

cylinder_residuals(→ numpy.ndarray)

Compute cylinder residuals for optimization.

fit_sphere(→ typing_extensions.Optional[SphereFit])

Fit a sphere model and return model quality and inliers.

fit_cylinder(→ typing_extensions.Optional[CylinderFit])

Fit a cylinder model and return model quality and inliers.

_fit_cylinder_from_initialization(...)

Run one cylinder optimization from one initialization and validate the result.

_build_cylinder_fit_from_parameters(...)

Validate one optimized cylinder parameter vector and construct a fit object.

_generate_cylinder_initial_parameter_sets(...)

Generate distinct initialization vectors for cylinder multi-start optimization.

_consensus_axis_candidates(...)

Return axis candidates ranked by provisional inlier ratio and residual error.

_provisional_cylinder_axis_quality(...)

Return provisional inlier ratio and error for one axis and radius hypothesis.

_initial_cylinder_radius(...)

Estimate a robust initial cylinder radius for one axis hypothesis.

_append_axis_if_distinct(→ None)

Append a normalized axis direction unless it duplicates an existing direction.

_is_better_cylinder_fit(→ bool)

Return whether one cylinder fit is better under inlier-target-aware ranking.

fit_cuboid(→ typing_extensions.Optional[CuboidFit])

Fit a cuboid model and return model quality and inliers.

select_best_shape(...)

Return the best shape candidate with volume-aware tie-breaking.

point_to_oriented_box_surface_distance(→ numpy.ndarray)

Compute absolute distance from points to cuboid surface.

compute_fit_score(→ float)

Compute a scalar quality score for model comparison.

_principal_axes(→ typing_extensions.List[numpy.ndarray])

_normalize_vector(→ numpy.ndarray)

_fitted_shape_volume(→ float)

Return primitive volume for volume-aware candidate comparison.

_cross_section_max_extent(→ float)

Return largest observed cross-section extent orthogonal to the cylinder axis.

_orthogonal_basis(→ tuple[numpy.ndarray, numpy.ndarray])

Create two unit vectors orthogonal to the provided axis direction.

_point_cloud_max_extent(→ float)

Return largest principal-axis extent of a point cloud.

_is_box_like_extent_profile(→ bool)

Return whether extents represent a box-like profile rather than axisymmetry.

Module Contents

robokudo.utils.shape_fitting.MAX_ACCEPTABLE_RADIUS_GROWTH_WITHOUT_STRONG_INLIER_GAIN = 1.35
robokudo.utils.shape_fitting.MIN_INLIER_GAIN_TO_ACCEPT_LARGER_RADIUS = 0.03
robokudo.utils.shape_fitting.MIN_ACCEPTABLE_CYLINDER_SCORE = 0.0
class robokudo.utils.shape_fitting.SphereFit

Fitted sphere model with inlier and quality information.

center: numpy.ndarray
radius: float
inlier_indices: numpy.ndarray
inlier_ratio: float
root_mean_square_error: float
score: float
class robokudo.utils.shape_fitting.CylinderFit

Fitted cylinder model with inlier and quality information.

axis_center: numpy.ndarray
axis_direction: numpy.ndarray
radius: float
height: float
inlier_indices: numpy.ndarray
inlier_ratio: float
root_mean_square_error: float
score: float
class robokudo.utils.shape_fitting.CuboidFit

Fitted cuboid model with inlier and quality information.

center: numpy.ndarray
rotation_matrix: numpy.ndarray
extents: numpy.ndarray
inlier_indices: numpy.ndarray
inlier_ratio: float
root_mean_square_error: float
score: float
robokudo.utils.shape_fitting.FittedShape
class robokudo.utils.shape_fitting.CylinderFitConstraints

Numerical constraints used during cylinder fitting and validation.

distance_threshold: float
robust_loss: str
max_radius: float
max_height: float
max_radius_to_bbox_diagonal_ratio: float
max_radius_to_cross_section_extent_ratio: float
max_axis_center_distance_to_bbox_diagonal_ratio: float
class robokudo.utils.shape_fitting.CylinderInitializationSettings

Search settings controlling cylinder multi-start initialization.

max_initializations: int
consensus_trials: int
inlier_polishing_iterations: int
robokudo.utils.shape_fitting.sphere_residuals(parameters: numpy.ndarray, points: numpy.ndarray) numpy.ndarray

Compute sphere residuals for optimization.

robokudo.utils.shape_fitting.cylinder_residuals(parameters: numpy.ndarray, points: numpy.ndarray) numpy.ndarray

Compute cylinder residuals for optimization.

robokudo.utils.shape_fitting.fit_sphere(points: numpy.ndarray, distance_threshold: float, robust_loss: str = 'soft_l1', max_radius: float = np.inf, max_radius_to_bbox_diagonal_ratio: float = np.inf, max_radius_to_observed_extent_ratio: float = np.inf, max_center_distance_to_bbox_diagonal_ratio: float = np.inf, min_inlier_ratio: float = 0.0) typing_extensions.Optional[SphereFit]

Fit a sphere model and return model quality and inliers.

robokudo.utils.shape_fitting.fit_cylinder(points: numpy.ndarray, distance_threshold: float, robust_loss: str = 'soft_l1', max_radius: float = np.inf, max_height: float = np.inf, max_radius_to_bbox_diagonal_ratio: float = np.inf, max_radius_to_cross_section_extent_ratio: float = np.inf, max_axis_center_distance_to_bbox_diagonal_ratio: float = np.inf, min_inlier_ratio: float = 0.0, max_initializations: int = 8, consensus_trials: int = 24, inlier_polishing_iterations: int = 0) typing_extensions.Optional[CylinderFit]

Fit a cylinder model and return model quality and inliers.

robokudo.utils.shape_fitting._fit_cylinder_from_initialization(points: numpy.ndarray, initial_parameters: numpy.ndarray, lower_bounds: numpy.ndarray, upper_bounds: numpy.ndarray, constraints: CylinderFitConstraints, initialization_settings: CylinderInitializationSettings) typing_extensions.Optional[CylinderFit]

Run one cylinder optimization from one initialization and validate the result.

robokudo.utils.shape_fitting._build_cylinder_fit_from_parameters(parameters: numpy.ndarray, points: numpy.ndarray, constraints: CylinderFitConstraints) typing_extensions.Optional[CylinderFit]

Validate one optimized cylinder parameter vector and construct a fit object.

robokudo.utils.shape_fitting._generate_cylinder_initial_parameter_sets(points: numpy.ndarray, constraints: CylinderFitConstraints, initialization_settings: CylinderInitializationSettings) typing_extensions.List[numpy.ndarray]

Generate distinct initialization vectors for cylinder multi-start optimization.

robokudo.utils.shape_fitting._consensus_axis_candidates(points: numpy.ndarray, axis_point: numpy.ndarray, distance_threshold: float, max_radius: float, trial_count: int) typing_extensions.List[typing_extensions.Tuple[numpy.ndarray, float, float]]

Return axis candidates ranked by provisional inlier ratio and residual error.

robokudo.utils.shape_fitting._provisional_cylinder_axis_quality(points: numpy.ndarray, axis_point: numpy.ndarray, axis_direction: numpy.ndarray, radius: float, distance_threshold: float) typing_extensions.Tuple[float, float]

Return provisional inlier ratio and error for one axis and radius hypothesis.

robokudo.utils.shape_fitting._initial_cylinder_radius(points: numpy.ndarray, axis_point: numpy.ndarray, axis_direction: numpy.ndarray, max_radius: float) typing_extensions.Optional[float]

Estimate a robust initial cylinder radius for one axis hypothesis.

robokudo.utils.shape_fitting._append_axis_if_distinct(axis_candidates: typing_extensions.List[numpy.ndarray], axis_direction: numpy.ndarray, min_angle_degrees: float = 8.0) None

Append a normalized axis direction unless it duplicates an existing direction.

robokudo.utils.shape_fitting._is_better_cylinder_fit(candidate_fit: CylinderFit, best_fit: CylinderFit, minimum_target_inlier_ratio: float) bool

Return whether one cylinder fit is better under inlier-target-aware ranking.

robokudo.utils.shape_fitting.fit_cuboid(points: numpy.ndarray, distance_threshold: float, max_extent: float = np.inf, min_inlier_ratio: float = 0.0) typing_extensions.Optional[CuboidFit]

Fit a cuboid model and return model quality and inliers.

robokudo.utils.shape_fitting.select_best_shape(candidates: typing_extensions.List[FittedShape], score_tolerance: float = 0.05, prefer_cuboid_when_close: bool = False, cuboid_preference_score_margin: float = 0.06, cuboid_preference_inlier_ratio_tolerance: float = 0.05, cuboid_box_like_cross_section_asymmetry_threshold: float = 0.12, cuboid_box_like_cube_axis_similarity_tolerance: float = 0.12) typing_extensions.Optional[FittedShape]

Return the best shape candidate with volume-aware tie-breaking.

robokudo.utils.shape_fitting.point_to_oriented_box_surface_distance(points: numpy.ndarray, center: numpy.ndarray, rotation_matrix: numpy.ndarray, extents: numpy.ndarray) numpy.ndarray

Compute absolute distance from points to cuboid surface.

robokudo.utils.shape_fitting.compute_fit_score(inlier_ratio: float, root_mean_square_error: float, distance_threshold: float, complexity_penalty: float) float

Compute a scalar quality score for model comparison.

robokudo.utils.shape_fitting._principal_axes(points: numpy.ndarray) typing_extensions.List[numpy.ndarray]
robokudo.utils.shape_fitting._normalize_vector(vector: numpy.ndarray) numpy.ndarray
robokudo.utils.shape_fitting._fitted_shape_volume(candidate: FittedShape) float

Return primitive volume for volume-aware candidate comparison.

robokudo.utils.shape_fitting._cross_section_max_extent(points: numpy.ndarray, axis_center: numpy.ndarray, axis_direction: numpy.ndarray) float

Return largest observed cross-section extent orthogonal to the cylinder axis.

robokudo.utils.shape_fitting._orthogonal_basis(axis_direction: numpy.ndarray) tuple[numpy.ndarray, numpy.ndarray]

Create two unit vectors orthogonal to the provided axis direction.

robokudo.utils.shape_fitting._point_cloud_max_extent(points: numpy.ndarray) float

Return largest principal-axis extent of a point cloud.

robokudo.utils.shape_fitting._is_box_like_extent_profile(extents: numpy.ndarray, cross_section_asymmetry_threshold: float, cube_axis_similarity_tolerance: float) bool

Return whether extents represent a box-like profile rather than axisymmetry.