hough_plane_3d — 3D detect op

• Data kinds: voxel → primitive

• Call: import fullseye as fs; fs.ledger.hough_plane_3d(vol, device='cpu', ndir=200, nd=128, mc=0.0, iso=0.5, tol=1.0) (to call the implementation directly, import match3d; match3d.hough_plane_3d(vol, device='cpu', ndir=200, nd=128, mc=0.0, iso=0.5, tol=1.0); from the registry, ops3d.get("hough_plane_3d"))

• GPU: this op has a GPU path (device="cuda")

Usage

Plane detection (the 3-D lift of the 2-D Hough line). Uses the gradient as the normal and votes into (normal n, distance d) space.

Each voxel of the thin boundary surface votes for its own normal-direction bin and d=n·p → peak = dominant plane. The normal is refined by averaging the actual normals in the winning bin, d by the mode of the projection. For extracting the ground or walls from point clouds/voxels. Returns (n(3,), d, inliers, total).

Procedure: take the 1-voxel-thick boundary surface of (vol > iso) (occupied voxels that disappear under a 3³ erosion), and use the unit gradient of those voxels (sobel3d; mc is a threshold on the raw output) as the normal n. n is folded into the hemisphere where the axis-0 component is non-negative, d = n·p (p is the integer voxel index (z,y,x)). Votes go into ndir reference directions (26-neighbourhood for 26 or fewer, a fibonacci sphere above that) and nd d-bins; n is refined by the mean of the actual normals in the most-voted bin, and d by the median near the mode of the projection histogram onto that n. Returns (n(3,), d, inliers, total): n is the unit normal in (z,y,x) order (numpy float32), the plane is n·(z,y,x) = d (voxel units). inliers is the number of boundary voxels with |n·p − d| < tol, total the total number of boundary voxels (inliers/total is the share taken by the dominant plane).

• With fewer than 10 boundary voxels it returns None (not an exception).

• Density voxels are binarised (2-valued) by iso (for count density, 0.5 means "1 or more points").

• Returns only 1 plane. For multiple planes, remove the inliers and run again, or for point clouds use plane_segmentation

/ ransac_plane.

Downstream: measure with distance_point_plane / angle_between_planes.

References (sample data, literature)

• Sample-data catalog (download URLs / licences) — 2-D uses skimage.data (BSD/public domain) plus synthetic images; 3-D lists download URLs for real data sources (Stanford, PDS, …).

• Operator provenance and references — the sources of the research/methods this op family came from.

Runnable examples (verified samples that actually call this op)

• detect_primitives_3d — py -3.11 examples_3d/detect_primitives_3d.py

Ops the type connects to (they accept primitive as input)

fuse_to_voxel · angle_between_lines · angle_between_planes · angle_line_plane · distance_point_plane · distance_point_line · distance_line_line · distance_segment_segment

Same category (detect)

hough_sphere_3d


*Provenance: match3d.py — 3D operator registry. This per-op note is generated by tools/opdocs.py md (do not hand-edit).*

© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.