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/// Error types for the detection pipeline.
18pub mod error;
19/// Edge-preserving filtering for small tag detection.
20pub mod filter;
21/// Gradient computation for edge refinement.
22pub mod gradient;
23/// Image buffer abstractions.
24pub mod image;
25/// 3D Pose Estimation (PnP).
26pub mod pose;
27/// Weighted pose estimation logic.
28pub mod pose_weighted;
29/// Quad extraction and geometric primitives.
30pub mod quad;
31/// Connected components labeling using Union-Find.
32pub mod segmentation;
33/// SIMD optimized mathematical kernels.
34pub mod simd;
35/// Decoding strategies (Hard vs Soft).
36pub mod strategy;
37/// Utilities for testing and synthetic data generation.
38pub mod test_utils;
39/// Adaptive thresholding implementation.
40pub mod threshold;
41
42// Re-exports for the public API
43pub use crate::config::{
44 CornerRefinementMode, DecodeMode, DetectOptions, DetectorConfig, PoseEstimationMode, TagFamily,
45};
46pub use crate::detector::{Detector, DetectorBuilder};
47pub use crate::error::{ConfigError, DetectorError};
48pub use crate::image::ImageView;
49pub use crate::pose::CameraIntrinsics;
50
51#[cfg(feature = "bench-internals")]
52pub mod bench_api {
53 //! Internal API exposed exclusively for benchmarking and integration testing.
54 pub use crate::batch::*;
55 pub use crate::decoder::*;
56 pub use crate::dictionaries::*;
57 pub use crate::filter::*;
58 pub use crate::pose::*;
59 pub use crate::quad::*;
60 pub use crate::segmentation::*;
61 pub use crate::test_utils::*;
62 pub use crate::threshold::*;
63}
64
65/// A single tag detection result.
66#[derive(Clone, Debug, Default)]
67pub struct Detection {
68 /// The decoded ID of the tag.
69 pub id: u32,
70 /// The center coordinates of the tag in image pixels (x, y).
71 pub center: [f64; 2],
72 /// The 4 corners of the tag in image pixels.
73 pub corners: [[f64; 2]; 4],
74 /// The number of hamming errors corrected during decoding.
75 pub hamming: u32,
76 /// The rotation of the tag relative to its canonical orientation (0-3).
77 pub rotation: u8,
78 /// The decision margin of the decoding (higher is more confident).
79 pub decision_margin: f64,
80 /// The extracted bits from the tag.
81 pub bits: u64,
82 /// The 3D pose of the tag relative to the camera (if requested).
83 pub pose: Option<crate::pose::Pose>,
84 /// The covariance of the estimated 3D pose (6x6 matrix), if computed.
85 pub pose_covariance: Option<[[f64; 6]; 6]>,
86}
87
88impl Detection {
89 /// Compute the axis-aligned bounding box (AABB) of the detection.
90 ///
91 /// Returns (min_x, min_y, max_x, max_y) in integer pixel coordinates.
92 #[must_use]
93 #[allow(clippy::cast_sign_loss)]
94 pub fn aabb(&self) -> (usize, usize, usize, usize) {
95 let mut min_x = f64::INFINITY;
96 let mut min_y = f64::INFINITY;
97 let max_x = self
98 .corners
99 .iter()
100 .fold(f64::NEG_INFINITY, |acc, p| acc.max(p[0]));
101 let max_y = self
102 .corners
103 .iter()
104 .fold(f64::NEG_INFINITY, |acc, p| acc.max(p[1]));
105 for p in &self.corners {
106 min_x = min_x.min(p[0]);
107 min_y = min_y.min(p[1]);
108 }
109
110 (
111 min_x.floor().max(0.0) as usize,
112 min_y.floor().max(0.0) as usize,
113 max_x.ceil().max(0.0) as usize,
114 max_y.ceil().max(0.0) as usize,
115 )
116 }
117}
118
119/// A 2D point with f64 precision.
120#[derive(Clone, Copy, Debug, Default)]
121pub struct Point {
122 /// X coordinate.
123 pub x: f64,
124 /// Y coordinate.
125 pub y: f64,
126}
127
128/// A 3D pose (rotation + translation).
129pub use crate::pose::Pose;
130
131/// Returns version and build information for the core library.
132#[must_use]
133pub fn core_info() -> String {
134 "Locus Core v0.1.0 Engine (Encapsulated)".to_string()
135}