Skip to content

Commit 716cbdf

Browse files
kalwaltclaude
andcommitted
feat(kpm): port FREAK descriptor + Keyframe to Rust (M8 step 4)
Port the C++ FREAKExtractor + Keyframe + FindFeatures orchestration to two new Rust sibling modules under crates/core/src/kpm/freak/, and replace the M7 find_features stub in hough.rs with a real vision::FindFeatures-style orchestrator. This is the final step of Milestone 8 — the FREAK pipeline is now end-to-end runnable in pure Rust (pyramid -> DoG detector -> FREAK descriptor -> FeatureStore). New: crates/core/src/kpm/freak/descriptor.rs (~390 lines) - FREAK_DESCRIPTOR_BYTES = 96 const (storage layout: 84 data + 12 zero padding, matches C++ BinaryFeatureStore and M7 hamming_distance_96) - 7 sigma + 6 ring [f32; 12] constants ported verbatim from matchers/freak84-inline.h (no rounding, no reorder) - mExpansionFactor = 7.0 const - extract_freak_descriptors(pyramid, keypoints, &mut Vec<u8>) free fn - Private sample_pyramid_freak84 / sample_ring / sample_pyramid_at helpers mirroring C++ SamplePyramidFREAK84 sample order (ring5 -> ring4 -> ... -> ring0 -> center) - LSB-first bit packing via `desc[pos/8] |= 1 << (pos%8)` matches C++ bitstring_set_bit; 666 pairs (0 <= i < j < 37) with the less-than comparison from CompareFREAK84 - 5 unit tests (length single/multiple, padding zero, empty input, reproducibility) + 1 dual-mode FFI parity test New: crates/core/src/kpm/freak/keyframe.rs (~110 lines) - Passive container Keyframe { store, width, height } mirroring C++ vision::Keyframe<96>. No build() method — orchestration lives in find_features (matches C++ FindFeatures architecture). - 2 unit tests (constructor wiring; find_features populates the store on found.jpg) Replaces: crates/core/src/kpm/freak/hough.rs find_features stub - Removes the Keyframe placeholder struct from M7 - Implements the real find_features(keyframe, pyramid, detector) mirroring C++ vision::FindFeatures from visual_database.h: 1. detector.detect(pyramid) 2. project rich DoGFeaturePoint -> persistent FeaturePoint via the M8-3 From<&DoGFeaturePoint> impl 3. extract_freak_descriptors(pyramid, &points, &mut buf) 4. populate keyframe.store via FeatureStore::add Dual-mode FFI bridge (kpm_c_api.{h,cpp}): - webarkit_cpp_extract_freak_descriptors: Rust supplies the keypoint list (4 floats per keypoint: x, y, angle, scale), C++ builds the pyramid + runs FREAKExtractor::extract, returns 96 bytes per keypoint (84 data + 12 zero padding from BinaryFeatureStore layout). - This factors out detection variance and tests the descriptor algorithm in isolation. Design choices (see docs/design/m8-4-freak-descriptor.md for full decision log): - Faithful C++ port (Option A): 96-byte storage with 84 data bytes packed via < comparison and LSB-first bit packing - Module split (orientation pattern from M8-2/M8-3): descriptor.rs for the algorithm + keyframe.rs for the container - M8-3 deferred OrientationAssignment items NOT absorbed in this PR — YAGNI: the FREAK descriptor samples the Gaussian pyramid directly, not gradient images. Tracking moved to issue #138. - Free function `extract_freak_descriptors(... &mut Vec<u8>)` instead of marker struct or stateful extractor — C++ "state" is all constants (naturally `const` at module scope in Rust). - Caller-owns orchestration model: find_features as a free function in hough.rs (matches C++ vision::FindFeatures architecture). Empirical result (Windows MSVC, clean rebuild): the dual-mode test shows |diff| = 0 across all 10 top-keypoint descriptors (Hamming distance = 0). The tolerance is kept at 2 in source to absorb potential cross-platform variance; CI will reveal whether it can be tightened to 0 across all platforms in a follow-up. Tests (8 total, all passing): - descriptor.rs: 5 unit tests + 1 dual-mode FFI parity test - keyframe.rs: 2 unit tests - Full dual-mode sweep: 391 passed, 0 failed, 2 ignored Harris detector intentionally NOT ported (dead code from removed SURF pipeline). M8-3-deferred OA items intentionally NOT absorbed (no real consumer in M8-4; tracked in #138). refs #125 #129 Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
1 parent 6ec758c commit 716cbdf

7 files changed

Lines changed: 949 additions & 12 deletions

File tree

0 commit comments

Comments
 (0)