fullseye

fullseye 3D Vision Toolkit (for Physical AI, differentiating from HALCON/OpenCV)

日本語 · English

We systematize 3D object matching on a grid of “input data structure” × “methods established in 2D”, and exhaustively expand it via the data transforms that connect the two (splat / projection / FFT / gradient field / distance field / PCA canonicalization). Core idea: many 3D methods can be built by “transforming 3D data into a representation where a known 2D method works.” With matching at the core, we integrate transform graphs, morphology, geometric metrology, surface approximation, curvilinear coordinates, optics, and projection/rendering into a single stack (built via 2D→3D dimensional lift + diverge→converge).

Differentiation (a vision library for Physical AI):

Method list (established in 2D → lifted to 3D). ★=TRIZ principle 17 (moving to another dimension) / line→surface lift

| Method | 2D origin | Key to 3D-ization | Transform | |—|—|—|—| | NCC / template | normalized cross-correlation | conv3d + box3d normalization | (direct) | | shape-based / gradient direction | Steger / HALCON | directional correlation of 3D gradients (3-component conv3d) | sobel3d | | phase correlation | Reddy & Chatterji | cross-power spectrum of the 3D FFT (translation) | FFT | | Fourier-Mellin / log-polar | Reddy & Chatterji | z-projection |FFT|→log-polar→phase correlation (rotation+scale) | FFT→log-polar | | chamfer / distance field | Barrow 1977 | chamfer score from the edge EDT (all-GPU=JFA) | distance transform (GPU-JFA) | | moment / PCA axes | principal-axis alignment | pose from inertia-tensor eigenvectors | PCA canonicalization | | generalized Hough | Ballard | 3D R-table voting (sum of orientation-bin correlations) | gradient→voting | | projection (dimensionality reduction) | — | apply 2D methods on orthogonal MIP/silhouette | 3D→2D projection | | ★curvature / shape index | contour curvature (1 scalar) | principal curvatures κ1,κ2 (2 = intrinsic to the surface) Koenderink shape index | Hessian (2nd order) | | ★spherical-harmonic descriptor | Fourier descriptor (1D FFT of the contour) | band energy of the surface SH = rotation invariant (Kazhdan) | SH (spherical FFT) | | parametric Hough | Hough line/circle | vote planes/spheres into parameter space (template-free = RANSAC family) | gradient→param voting | | feature descriptor (TODO) | Harris/SIFT | 3D corner + descriptor (spin image/FPFH/SHOT) | local shape | | iterative refinement (in progress) | LK / ICP / GN | high-precision convergence of a coarse estimate via Newton/Gauss-Newton/ICP | Jacobian/Hessian |

Data-structure rows (input format) × transform graph

Transforming 3D data into a representation where a method works” is the core of the matrix. Formats are diverse → connect them to each other via transforms.

Structure/format Description Main transforms (implementations)
voxel grid (dense) dense grid central representation
point cloud point set points_to_voxel (splat) / estimate_point_normals (normals=PCA)
3DGS (anisotropic Gaussians) means+scale+opacity gaussians_to_voxel (splat)
mesh (vertices+faces) triangle mesh mesh_to_voxel (occupancy) / mesh_to_points (face sampling)
depth / range (2.5D) depth map depth_to_points (back-projection) / tsdf_from_depth (TSDF)
SDF / TSDF signed distance field signed_distance_field (voxel→SDF) / sdf_to_occupancy
occupancy / binary occupancy 0/1 threshold ↔ voxel ↔ SDF
normals (point/face normals) orientation estimate_point_normals (for FPFH/ICP-p2plane)

Transform graph (→=implemented): points ⇄ voxel (splat / marching cubes), voxel → mesh (voxel_to_mesh=marching cubes), mesh → points (mesh_to_points), voxel ⇄ SDF ⇄ occupancy, depth → {points, TSDF}, 3DGS → voxel, points → normals. If any input format is brought onto a common voxel/point/SDF, every method becomes usable (= all row × column cells are connected by transforms).

3D morphology (3D lift of the 2D operators. grey & binary)

accel_vol.py: grey erode/dilate/median/gaussian + binary region (ball/cross, opening). match3d.py additions (preprocessing/feature extraction): morph_gradient3d (dilation−erosion=boundary extraction, sobel alternative) / morph_tophat3d (small-bright-structure extraction, keypoint preprocessing) / morph_blackhat3d (dark structures) / morph_dilate3d / morph_erode3d. GPU (max_pool3d).

Geometric primitives / metrology (2 points→line, 3 points→plane/angle; common to 2D/3D)

The layer that turns detection/matching into “measurement” (equivalent to HALCON 2D/3D metrology). All in closed form and rigorously verified:

Sparse feature registration (keypoint + descriptor + RANSAC) = large rotation + partial overlap with no initial estimate

The regime that dense matching (NCC/Hough) cannot handle. In a Workflow we explore 4 methods in parallel and, after integration, primary-verify (measured rot_err): | Method | Module | Measured (60° rotation + 70% overlap) | |—|—|—| | Harris3D keypoint (mineig) | feat_harris.harris3d_keypoints | repeatability 85% (2D’s k=0.04 detects 0 in 3D → adopt mineig) | | Spin Image + RANSAC | feat_spin.register_spin | rot_err 1.84°, MC 100% success | | FPFH + RANSAC | feat_fpfh.register_fpfh | rot_err 0.83° | | SHOT + RANSAC + ICP | feat_shot.register_shot | rot_err 0.00° (with ICP refinement) |

honest limits: degrades sharply at overlap <60% (wrong-basin lock), impossible for featureless shapes (a bare sphere), depends on normal sign. → feed the output as ICP’s coarse init.

Integration of heterogeneous structures (TRIZ merging/composition: combine all 5 structures) = fuse3d

Cross-multiply the “rows” of the matrix. Any structure can be handled mutually if it is converted to a common representation (point cloud/voxel) and brought together:

Surface approximation z=f(x,y) (2 variables→1 variable, information compression)

fit_poly_surface / eval_poly_surface (polynomial least squares) / surface_form_error (flatness/sphericity = residual to an ideal surface) / background_flatten (illumination unevenness = subtract a low-order surface = shading correction). Used heavily in both image processing and metrology.

Expansion into curvilinear coordinate systems (not limited to Cartesian)

polar_unwrap (annulus/disc → θ×r, ring/label inspection) / cylinder_unwrap (cylindrical surface → height×θ×r, pipe inspection) / fit_zernike (orthogonal basis on a disc = polar surface approximation, optics/wavefront metrology; tilt/defocus/astigmatism map to (n,m)).

Optical primitives (specular/transparent bodies, all rigorously verified)

reflect (specular reflection) / refract (Snell refraction, transparent body + refractive index, TIR handling) / fresnel_reflectance (reflection/transmission ratio, 0.04 at normal incidence) / normal_from_reflection (deflectometry = measure specular normals from reflection) / snell_angle. For inspection/measurement of glass/lenses/mirror surfaces.

Projection / rendering (3D → 2D synthesis, closing the loop)

The reverse of the transform (2D→3D) = observation synthesis, appearance-inspection sample generation, 3D-measurement sample-space generation (directly connected to Physical AI/simulation): project_points (pinhole projection) / render_point_depth (point cloud→depth, z-buffer) / render_volume_projection (arbitrary-view xray=DRR / mip) / render_shaded (normals+light source→Lambertian, connected to optics).

Transform graph of data formats (connecting structures) = additions

signed_distance_field (voxel→SDF) / sdf_to_occupancy / estimate_point_normals (point cloud→normals=PCA) / mesh_to_points / voxel_to_mesh (marching cubes) / tsdf_from_depth (RGB-D→TSDF). Bring any format onto a common representation and apply all methods.

Matrix (by method mode × data structure)

All 5 structures (voxel / point cloud / 3DGS / mesh / depth 2.5D) load onto a common voxel/point representation via transform T, so each method below applies to any structure (= 5 structures × number of methods cells). Methods are organized by “what they output (mode)”:

① Localization (output the template position within the scene) | Method | Characteristic | GPU | |—|—|—| | NCC | normalized cross-correlation, pyramid/sub-voxel | 46× (pyramid 244×) | | shape-based | gradient direction, contrast invariant | 68-89× | | chamfer | distance field, occlusion robust, all-GPU (JFA) | beats scipy at N≥96 | | gen. Hough | voting, multiple instances · occlusion robust | 8× | | ★curvature | shape index, matches by surface shape rather than intensity | 6× | | MIP→2D | drop to 2D methods via orthogonal projection (cheap coarse) | 1.3× |

② Pose (output the rotation/scale/translation transform parameters) | Method | Output | Characteristic | |—|—|—| | phase-corr | translation | template-free, FFT, 18-28× | | PCA/moment | rotation+translation | with correspondence, residual 0, 0.2ms | | Fourier-Mellin | rotation+scale | no correspondence, 30×, coarse (±45/90° aliasing) |

⑤ Iterative refinement (coarse estimate → high-precision convergence). Diverge without narrowing to one means (6 methods verified in parallel in a Workflow, all PASS, primary re-verified after integration) | Method | Convergence precision (measured) | Iters/time | vs baseline | |—|—|—|—| | Newton sub-voxel peak refine_peak_newton | 0.011 voxel (cross curvature from the full Hessian) | 7 / 1.5ms | ~9× vs parabolic | | Gauss-Newton translation (inverse-compositional LK) refine_translation_lk | 0.008-0.023 voxel | 6 / 1.2ms | ~60× vs NCC-COM | | Levenberg-Marquardt translation+scale refine_lm | translation 0.007 voxel + scale recovery | 4 / 6ms | ~40-70× vs COM (scale is new) | | Gauss-Newton z rotation refine_rotation_z | 0.002-0.017° | 4 / 12ms | ~5000× over Fourier-Mellin’s ±3° | | ICP point-to-point (Kabsch) icp_point2point_3d | RMSE 1e-14, Trimmed for partial overlap | 6 / 2.5ms | coarse ±0.5vox → machine precision | | ICP point-to-plane (GN) icp_point2plane | RMSE 1e-10, fast convergence to the surface | 4-16 / 8ms | fewer iters than point-to-point (Low 2004) |

③ Detection (output primitive shapes without a template) | Method | Output | Characteristic | |—|—|—| | parametric Hough | plane (n,d) / sphere (c,r) | RANSAC family, normal exact · inlier 93%, 4.9×/2× |

④ Description (match/retrieve with a rotation-invariant global signature) | Method | Output | Characteristic | |—|—|—| | ★spherical-harmonic descriptor | (radius × frequency) band energy | invariant under 3D rotation (sim 0.999), shape discrimination |

★ Currently 11 methods (localization 6 / pose 3 / detection 1 / description 1) + 6 refinement methods × 5 structures. ★=line→surface lift (curvature · SH). The mesh→voxel translation is fully recovered by phase-corr, and depth back-projection is also verified. The coarse-estimate→refinement pipeline holds (e.g., rotation ±3° with Fourier-Mellin → 0.01° with refine_rotation_z / integer sphere center with Hough → sub-voxel with refine_peak_newton).

Implementation (match3d.py / accel_match / accel_vol):

pyramid / sub-voxel centroid apply across all NCC methods. Rotation is handled by 3 lineages: shape-based (invariant) + PCA (explicit recovery with correspondence) + Fourier-Mellin (rotation+scale without correspondence).

Processing time (measured N=64³, CPU=py3.11 torch cpu / GPU=RTX5090 torch cu128, median ms)

We measure the diverged method group to make it a basis for method selection. ★=GPU is clearly favorable, ▲=CPU is faster/equal (for small problems, transfer/launch overhead wins).

Method CPU ms GPU ms GPU/CPU Note
phase_3d ★ 37.7 0.49 77× FFT, fastest pose (translation)
logpolar_z ★ 96.2 2.84 34× FFT, rotation+scale
hough_plane ★ 16.8 3.62 4.6× plane detection
refine_rot_z ★ 33.2 3.87 8.6× rotation refinement
NCC (locate) ★ 189 9.07 21× localization baseline
shape_3d ★ 69.7 9.23 7.6× contrast-invariant localization
curvature ★ 58 10.4 5.6× shape localization
hough_sphere ★ 21.5 10.2 2.1× sphere detection
chamfer (scipy) 36.1 16.7 2.2× occlusion robust (EDT on CPU)
scene_flow_lk ★ 65.2 17.5 3.7× motion field
chamfer (jfa) 89.5 23.3 3.8× all-GPU distance field (favorable at large N)
edt_jfa 64.7 27.8 2.3× beats scipy at N≥96
hough_3d (vote) ★ 527 63.0 8.4× multiple instances, heavy
mip_2d ▲ 50.6 46.6 1.1× transfer-bound, thin GPU benefit
sh_descriptor ▲ 27.5 60.3 0.5× per-radius loop, CPU advantage
refine_newton ▲ 1.3 6.5 0.2× small problem, CPU suffices
refine_lk ▲ 1.02 2.2 0.5× small problem, CPU suffices
refine_lm ▲ 3.86 10.3 0.4× autograd, CPU advantage
pca (point cloud) ▲ 0.21 numpy eigh, CPU-only
icp_p2p (point cloud) ▲ 15.3 scipy cKDTree, CPU
icp_p2plane (point cloud) ▲ 19.0 torch/CPU

Method selection (compute resource): FFT methods (phase/logpolar), NCC, voting, flow, curvature go on GPU. Small iterative refinements (newton/lk/lm), point-cloud methods (pca/icp), and SH are faster on CPU (GPU launch/transfer overhead exceeds the problem size).

Method selection (situation → method). A decision guide that converges the diverged methods

| Situation / requirement | Recommended method | Reason | |—|—|—| | translation only, template available | NCC or phase_3d | phase is template-free and fastest (0.5ms) | | contrast/illumination varies | shape_3d (gradient direction) | intensity invariant | | distinguish same-intensity objects with different local shape | curvature (shape index) | matches by surface type | | occlusion/partial present | chamfer or gen. Hough | missing parts only lower the peak | | multiple instances | gen. Hough (NMS peaks) | voting accumulator | | z rotation + scale, no correspondence | logpolar_z (coarse) → refine_rot_z (fine) | seed with FMT, tighten with GN | | arbitrary rotation, point cloud with correspondence | PCA (coarse) → ICP (fine) | principal-axis alignment → point-to-plane ICP | | arbitrary rotation, point cloud without correspondence · partial overlap | feature descriptor (FPFH/SHOT, in progress) → RANSAC → ICP | global registration with no initial estimate | | primitive shape detection (ground/wall/ball) | parametric Hough (plane/sphere) | template-free | | rotation-invariant retrieval/matching | SH descriptor | invariant band energy | | estimate motion/deformation | scene_flow_lk | dense motion field | | refine a coarse estimate to high precision | Newton/LK/LM/ICP (per parameter) | see table below |

Coarse → fine pipeline (mapping coarse estimates to their fine tighteners)

| Coarse estimate (output) | Refinement | Attained precision | |—|—|—| | integer peak of NCC/shape/Hough | refine_peak_newton | 0.01 voxel | | integer translation | refine_translation_lk / refine_lm (+scale) | 0.008 voxel | | Fourier-Mellin rotation ±3° | refine_rotation_z | 0.01° | | coarse pose of PCA / descriptor RANSAC | icp_point2point_3d / icp_point2plane | RMSE 1e-10 |

Cells to fill next (TODO). Policy = diverge without narrowing to one means (know-how accumulates in breadth)

Progress log