scoop_volume_read — DRIVE scoop op

• Data kinds: image2d × scalar × scalar × scalar × scalar → table

• Call: import fullseye as fs; fs.ledger.scoop_volume_read(side, rim_row: 'int', a_px: 'float', h_px: 'float', pitch: 'float', *, opaque: 'bool' = True, assume_level: 'bool' = False, heap_min_frac: 'float' = 0.005, level_tol: 'float' = 0.01, rim_full_frac: 'float' = 0.95, fit_angle: 'bool' = True) -> 'dict' (to call the implementation directly, import scoop; scoop.scoop_volume_read(side, rim_row: 'int', a_px: 'float', h_px: 'float', pitch: 'float', *, opaque: 'bool' = True, assume_level: 'bool' = False, heap_min_frac: 'float' = 0.005, level_tol: 'float' = 0.01, rim_full_frac: 'float' = 0.95, fit_angle: 'bool' = True) -> 'dict'; from the registry, opsdrive.get("scoop_volume_read"))

Usage

Reads the scooped volume from a side image of the spoon.

• opaque=True (metal bowl): below the rim is not visible, so the heap above the rim is measured with revolution_volume_side and added to the level closed form (spoon_bowl_volume): V = V_struck + V_above. If nothing is above the rim, the side view cannot distinguish level from short — unless assume_level=True, ValueError (it does not silently claim level).

• opaque=False (transparent bowl / cross-section image): integrates the whole in Pappus form, and if it is below 1 − level_tol of level, returns under with the depth via the inverse (bisection) of the closed form V_fill(y) (assumes a flat powder surface).

• fit_angle: if the heap is large enough (8 or more points left and right), treats the rim as the ground and reads the heap's slope angle with granular's repose_angle_silhouette (for comparison with the angle of repose; None for small heaps).

Returns: V, V_struck, V_above, state (heaped / level / under), heap_angle_deg, heap_base_frac (heap width at the rim row / rim diameter), rim_full (heap_base_frac ≥ rim_full_frac: the foot of the heap reaches the rim = the bowl is likely full up to the rim. In an "almost heap" that does not reach it, the edge near the rim is not completely filled, and the opaque reading comes out higher by the closed-form amount — in MuJoCo +9 % at 0.90, +1 % at 0.99), axis_col, fill_depth_px (when transparent). Raises ValueError: rim_row outside the image / nothing above the rim and not assume_level (when opaque) / argument ranges.

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.

• The canonical algorithm (author, year) and its uses are named in the family usage guide above.

Runnable examples (verified samples that actually call this op)

• poc_powder_scoop_pour — py -3.11 examples/poc_powder_scoop_pour.py

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

course_layout · course_occupancy · course_contains · world_build · world_camera · world_move · lidar_scan · rss_longitudinal_same

Same category (scoop)

spoon_bowl_volume · scoop_synth_side · revolution_volume_side · two_view_volume · scoop_count · scoop_image_limit · tilt_wedge_retained · tilt_pour_rate


*Provenance: scoop.py — DRIVE 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.