feat(perception): motion blur detector via Laplacian variance (Issue #286) #292

Merged
sl-jetson merged 1 commits from sl-perception/issue-286-blur-detect into main 2026-03-02 21:05:24 -05:00
Collaborator

Summary

  • Add _blur_detector.py: BlurResult NamedTuple, laplacian_variance() (ksize=3 Laplacian on greyscale, optional ROI crop), detect_blur() returning variance + is_blurred + threshold; handles BGR and greyscale input
  • Add blur_detect_node.py: subscribes /camera/color/image_raw (BEST_EFFORT), publishes Bool on /saltybot/image_blurred and Float32 on /saltybot/blur_score per frame; threshold and roi_frac ROS params
  • Register blur_detector console script in setup.py
  • 25/25 unit tests pass (pure Python, no ROS2 required)

Intended use

Pause or down-weight SLAM keyframe insertion (/saltybot/image_blurred == True) when the robot is moving fast and the D435i image is visibly blurred.

Test plan

  • python3 -m pytest test/test_blur_detector.py -v → 25 passed
  • Launch on Jetson: ros2 run saltybot_bringup blur_detector
  • Verify /saltybot/blur_score rises when robot is stationary (sharp image) and falls during fast rotation
  • Confirm /saltybot/image_blurred toggles correctly around the default threshold=100.0
  • Test roi_frac=0.3 to skip the sky/ceiling region

🤖 Generated with Claude Code

## Summary - Add `_blur_detector.py`: `BlurResult` NamedTuple, `laplacian_variance()` (ksize=3 Laplacian on greyscale, optional ROI crop), `detect_blur()` returning variance + is_blurred + threshold; handles BGR and greyscale input - Add `blur_detect_node.py`: subscribes `/camera/color/image_raw` (BEST_EFFORT), publishes `Bool` on `/saltybot/image_blurred` and `Float32` on `/saltybot/blur_score` per frame; `threshold` and `roi_frac` ROS params - Register `blur_detector` console script in `setup.py` - 25/25 unit tests pass (pure Python, no ROS2 required) ## Intended use Pause or down-weight SLAM keyframe insertion (`/saltybot/image_blurred == True`) when the robot is moving fast and the D435i image is visibly blurred. ## Test plan - [ ] `python3 -m pytest test/test_blur_detector.py -v` → 25 passed - [ ] Launch on Jetson: `ros2 run saltybot_bringup blur_detector` - [ ] Verify `/saltybot/blur_score` rises when robot is stationary (sharp image) and falls during fast rotation - [ ] Confirm `/saltybot/image_blurred` toggles correctly around the default threshold=100.0 - [ ] Test `roi_frac=0.3` to skip the sky/ceiling region 🤖 Generated with [Claude Code](https://claude.com/claude-code)
sl-perception added 1 commit 2026-03-02 20:46:54 -05:00
- Add _blur_detector.py: BlurResult NamedTuple, laplacian_variance() (ksize=3
  Laplacian on greyscale, with optional ROI crop), detect_blur() returning
  variance + is_blurred flag + threshold; handles greyscale and BGR inputs,
  empty ROI returns 0.0
- Add blur_detect_node.py: subscribes /camera/color/image_raw (BEST_EFFORT),
  publishes Bool /saltybot/image_blurred and Float32 /saltybot/blur_score per
  frame; threshold and roi_frac ROS params
- Register blur_detector console script in setup.py
- 25/25 unit tests pass (no ROS2 required)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
sl-jetson merged commit 1a47abf5ae into main 2026-03-02 21:05:24 -05:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: seb/saltylab-firmware#292
No description provided.