locus_core/lib.rs
1//! High-performance AprilTag and ArUco detection engine.
2//!
3//! Locus is a research-oriented, memory-safe fiducial marker detector targeting low
4//! latency. It provides a performance-focused pipeline for robotics and computer vision,
5//! with strict zero-heap allocation in the detection hot-path.
6
7/// Batched state container for Structure of Arrays (SoA) layout.
8pub mod batch;
9/// Configuration types for the detector pipeline.
10pub mod config;
11/// Tag decoding traits and implementations.
12pub mod decoder;
13/// The primary public API for the detector.
14pub mod detector;
15/// Tag family dictionaries (AprilTag, ArUco).
16pub mod dictionaries;
17/// EDLines localized quad extraction.
18pub(crate) mod edlines;
19/// Error types for the detection pipeline.
20pub mod error;
21/// Edge-preserving filtering for small tag detection.
22pub mod filter;
23/// Fast-path decoding funnel.
24pub mod funnel;
25/// Gradient computation for edge refinement.
26pub mod gradient;
27/// Gradient-Weighted Line Fitting (GWLF).
28pub mod gwlf;
29/// Image buffer abstractions.
30pub mod image;
31/// 3D Pose Estimation (PnP).
32pub mod pose;
33/// Weighted pose estimation logic.
34pub mod pose_weighted;
35/// Quad extraction and geometric primitives.
36pub mod quad;
37/// Connected components labeling using Union-Find.
38pub mod segmentation;
39/// SIMD optimized mathematical kernels.
40pub mod simd;
41/// SIMD-Accelerated Connected Components Labeling (CCL).
42pub mod simd_ccl_fusion;
43/// Decoding strategies (Hard vs Soft).
44pub mod strategy;
45/// Utilities for testing and synthetic data generation.
46pub mod test_utils;
47/// Adaptive thresholding implementation.
48pub mod threshold;
49/// Thread-local workspace arena for per-candidate allocations.
50pub(crate) mod workspace;
51
52// Re-exports for the public API
53pub use crate::config::{
54 CornerRefinementMode, DecodeMode, DetectOptions, DetectorConfig, PoseEstimationMode,
55 QuadExtractionMode, TagFamily,
56};
57pub use crate::detector::{Detector, DetectorBuilder};
58pub use crate::error::{ConfigError, DetectorError};
59pub use crate::image::ImageView;
60pub use crate::pose::CameraIntrinsics;
61
62#[cfg(feature = "bench-internals")]
63pub mod bench_api {
64 //! Internal API exposed exclusively for benchmarking and integration testing.
65 pub use crate::batch::*;
66 pub use crate::decoder::*;
67 pub use crate::dictionaries::*;
68 pub use crate::filter::*;
69 pub use crate::funnel::*;
70 pub use crate::pose::*;
71 pub use crate::quad::*;
72 pub use crate::segmentation::*;
73 pub use crate::simd::sampler::*;
74 pub use crate::simd_ccl_fusion::*;
75 pub use crate::test_utils::*;
76 pub use crate::threshold::*;
77}
78
79/// A single tag detection result.
80#[derive(Clone, Debug, Default)]
81pub struct Detection {
82 /// The decoded ID of the tag.
83 pub id: u32,
84 /// The center coordinates of the tag in image pixels (x, y).
85 pub center: [f64; 2],
86 /// The 4 corners of the tag in image pixels.
87 pub corners: [[f64; 2]; 4],
88 /// The number of hamming errors corrected during decoding.
89 pub hamming: u32,
90 /// The rotation of the tag relative to its canonical orientation (0-3).
91 pub rotation: u8,
92 /// The decision margin of the decoding (higher is more confident).
93 pub decision_margin: f64,
94 /// The extracted bits from the tag.
95 pub bits: u64,
96 /// The 3D pose of the tag relative to the camera (if requested).
97 pub pose: Option<crate::pose::Pose>,
98 /// The covariance of the estimated 3D pose (6x6 matrix), if computed.
99 pub pose_covariance: Option<[[f64; 6]; 6]>,
100}
101
102impl Detection {
103 /// Compute the axis-aligned bounding box (AABB) of the detection.
104 ///
105 /// Returns (min_x, min_y, max_x, max_y) in integer pixel coordinates.
106 #[must_use]
107 #[allow(clippy::cast_sign_loss)]
108 pub fn aabb(&self) -> (usize, usize, usize, usize) {
109 let mut min_x = f64::INFINITY;
110 let mut min_y = f64::INFINITY;
111 let max_x = self
112 .corners
113 .iter()
114 .fold(f64::NEG_INFINITY, |acc, p| acc.max(p[0]));
115 let max_y = self
116 .corners
117 .iter()
118 .fold(f64::NEG_INFINITY, |acc, p| acc.max(p[1]));
119 for p in &self.corners {
120 min_x = min_x.min(p[0]);
121 min_y = min_y.min(p[1]);
122 }
123
124 (
125 min_x.floor().max(0.0) as usize,
126 min_y.floor().max(0.0) as usize,
127 max_x.ceil().max(0.0) as usize,
128 max_y.ceil().max(0.0) as usize,
129 )
130 }
131}
132
133/// A 2D point with f64 precision.
134#[derive(Clone, Copy, Debug, Default)]
135pub struct Point {
136 /// X coordinate.
137 pub x: f64,
138 /// Y coordinate.
139 pub y: f64,
140}
141
142/// A 3D pose (rotation + translation).
143pub use crate::pose::Pose;
144
145/// Returns version and build information for the core library.
146#[must_use]
147pub fn core_info() -> String {
148 "Locus Core v0.1.0 Engine (Encapsulated)".to_string()
149}