A 3D model sees unordered coordinates; unit, sensor pose, point density and scan-level split rules determine whether those coordinates mean the same thing later.
Point-cloud coordinate frames, sampling and scan identity
Keep geometry in declared units
A warehouse depth sensor may export meters while an annotation tool displays millimeters. The same numeric triple then describes a very different object. Record units, handedness, axis directions, sensor-to-world transform, capture time and sensor calibration revision with each scan. Transform points into a declared frame before computing features. The code centers four points after validating their dimensions; centering alone does not correct a wrong physical scale.
Preserve scan identity across crops
A large pallet scan is often cut into several training crops. Neighboring crops share the pallet, warehouse lighting and scanner artifacts. Split by physical pallet or acquisition session before crop generation, then report the number of independent pallets in every evaluation set. Do not place one face of a pallet in training and another face in final test. The parent split rule applies to 3D scans as strongly as it does to images.
Choose a point budget openly
Sampling a fixed number of points controls memory and batch shape. Uniform random sampling is cheap but can miss a small broken corner; grid or farthest-point methods change coverage and cost. Keep the raw scan and the sampling seed so reviewers can inspect whether the defect existed in the selected subset. Record point count before and after filtering, and reject a scan with too few usable returns rather than padding it silently into apparent certainty.
Separate pose changes from defects
Centering removes translation, but rotation and scale require explicit handling. Random rotation augmentation is valid only if the label is invariant under those rotations; a tipped pallet may be a defect, so arbitrary rotation can erase the signal. Estimate sensor pose when available and compare a model trained in physical coordinates against one using centered local coordinates. The set model handles ordering, not every geometric transform automatically.
Replay the deployed path
Compare training and serving transformations on a fixed raw scan: unit conversion, coordinate frame, crop bounds, point sampling, outlier filtering and normalization. Audit missing depth returns and reflective wrap separately. Measure p95 scan decode, sampling and model inference time at the target point budget. The inspection project reports defect recall by point density and scanner site.
Implementation
from math import isfinite
scan_points_m = [(1.2, 2.4, 0.7), (1.4, 2.5, 0.7),
(1.2, 2.6, 0.9), (1.4, 2.3, 0.9)]
def center_scan(points_m):
if not points_m or any(len(point) != 3 or not all(map(isfinite, point)) for point in points_m):
raise ValueError("scan needs finite x, y and z coordinates")
center = tuple(sum(point[axis] for point in points_m) / len(points_m)
for axis in range(3))
return [tuple(point[axis] - center[axis] for axis in range(3))
for point in points_m], center
centered_points, scan_center = center_scan(scan_points_m)
assert len(centered_points) == 4
assert all(abs(sum(point[axis] for point in centered_points)) < 1e-9
for axis in range(3))
assert all(abs(actual - expected) < 1e-9
for actual, expected in zip(scan_center, (1.3, 2.45, 0.8)))Performance and operating cost
Centering N points takes O(N) time and O(N) output storage; the raw scan may be much larger than a sampled model input. A dense voxel grid with K cells along each axis uses O(K cubed) space even when most cells are empty, while point-set storage is O(N). More points improve the chance of retaining a small flaw but raise feature and neighbor-search costs. The snippet verifies a coordinate operation, not a calibrated sensor transform.
Common Mistakes
- Do not mix millimeters and meters in one model input.
- Do not split crops from one physical scan across train and final test.
- Do not assume centering makes the model rotation invariant.
