annotate3d op• Data kinds: image2d → image2d
• Call: import fullseye as fs; fs.ledger.annotate3d_axes(img, pose, K, origin=(0.0, 0.0, 0.0), length=1.0, depth=None, labels=('X', 'Y', 'Z'), colors=('wrong', 'right', 'reference'), width=2, font_size=11, occlusion_tol=0.01, scheme='okabe_ito', font_path=None) (to call the implementation directly, import annotate3d; annotate3d.annotate3d_axes(img, pose, K, origin=(0.0, 0.0, 0.0), length=1.0, depth=None, labels=('X', 'Y', 'Z'), colors=('wrong', 'right', 'reference'), width=2, font_size=11, occlusion_tol=0.01, scheme='okabe_ito', font_path=None); from the registry, ops3d.get("annotate3d_axes"))
Returns an image (image2d): the three axes of the object coordinates (the input side of pose) as a gnomon, projected from origin.
ValueError
length is non-positive, the origin or an axis end is behind the camera, labels/colors are not 3 items,
the axis text does not fit in the image, both the origin and an axis end are outside the image.
Procedure: project origin and the 3 points reached by going length from it in the object +X / +Y / +Z directions (same convention as annotate3d_project), and from the origin pixel to each axis-end pixel draw annotate.arrow (arrowhead 8x6 px). At a position 0.7 * font_size px beyond the axis end, place labels[i] as text without background (box_alpha=0).
Arguments:
• origin (3,) (object coordinates), length: axis length (mesh units, > 0).
• labels: 3 strings (default ("X", "Y", "Z")). colors: 3 colours (role names or RGB; the default ("wrong", "right", "reference") are palette role names).
• width: line width [px], an integer of 1 or more. font_size [px].
• depth / occlusion_tol: passed to the projection, but this op does not do hidden display (dashing) (the test is only used for the shape check of depth).
Return value: a new drawn image (float64 [0, 1]).
Error conditions: length <= 0 / the length of labels or colors is not 3 / the origin or any axis end has z <= 1e-9 / invalid pose, K or depth / the axis text does not fit in the image / both the origin and the axis end are outside the image (annotate.arrow rejects it). If only the axis end is outside the frame, it is drawn (the arrow runs towards the outside). An axis that coincides with the line of sight and collapses to a point (pixel length under 1e-9) is silently skipped.
Use: explaining the pose of a figure (gnomon). Pass the pose of render3d.look_at as is, and put origin at the mesh centroid or a corner of bounds. Coordinate frame: both origin and the axis directions are read in the frame that pose maps from (object coordinates). The pose from look_at is world→camera, so in that case they are the world axes. Passing pose @ M, which includes the object's pose M (object→world), draws the object's axes.
• 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.
• annotate3d_figure — py -3.11 examples_3d/annotate3d_figure.py
image2d as input)fuse_to_voxel · fit_poly_surface · eval_poly_surface · surface_form_error · background_flatten · polar_unwrap · fit_zernike · matcap_shade
annotate3d)annotate3d_project · annotate3d_arrow · annotate3d_label · annotate3d_scale_bar · annotate3d_bbox · annotate3d_measure
*Provenance: annotate3d.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.