Repository navigation
Closed
Labels
enhancementNew feature or requestNew feature or requestready-for-agentFully specified, ready for an AFK agentFully specified, ready for an AFK agentv1.0Required for the v1.0 releaseRequired for the v1.0 release
Milestone
Description
Parent
What to build
A retake or slightly panned frame from the same camera joins a neighbour's burst: two photos are similar when OpenCV feature matching (ORB keypoints, RANSAC for one consistent transform) on their stored 300 px thumbnails reaches a configurable share of matching keypoints. Matching chains, is bounded in time, and connects camera-labelled bursts.
Acceptance criteria
- A picture-comparison seam (two thumbnails in, a similarity score 0–1 out) with an OpenCV implementation (OpenCvSharp or Emgu CV), after confirming a native linux-arm64 build exists and the licence is compatible with AGPL-3.0. If neither qualifies, stop and bring it back to the maintainer. The Worker image runs it on amd64 and arm64.
- An ADR records the OpenCV dependency and why perceptual hashes were rejected (measurements in spec: Bursts — group photos of the same scene by camera label or feature similarity, show one cover per burst #296).
- Outside a
BurstUUID, a photo joins only when it matches a neighbouring frame; time alone never groups. - Matching chains (A
B, BC puts all three in one burst), with consecutive frames at most 2 minutes apart and a whole burst spanning at most 5 minutes. - Only photos with an EXIF capture time are compared, and only with frames of the same camera make and model; two photos without camera data count as different cameras.
- A similar photo joins a
BurstUUIDburst; a photo matching frames of two bursts merges them, the stored cover being the earliest member. - Unchecked photos are compared against their time neighbours, checked or not; checked pairs are not compared again.
- Settings
Worker:Burst…for gap (2 min), span (5 min) and similarity threshold (about 25%), Worker-wide, validated at startup. - Each compared pair's score is logged at
Debug; the run's result adds pairs matched and not matched. - The real comparison is tested on committed fixtures: a 300 px copy of the maintainer's IMG_4386/4387 without EXIF (approved) scores above the default threshold, clearly different images below it. Grouping rules are tested at the handler seam with a substituted comparison. Mutation score 100% on the changed files.
- Repair deletes bursts with no member rows in one statement (
ExecuteDelete), as the design note's section 5 step 1 says, instead of loading and EF-removing them in every config's run. Today two per-user Workers repairing at once both remove the same memberless burst, and the secondSaveChangesthrowsDbUpdateConcurrencyExceptionand fails thatBurstDetectionitem. Found in the 2026-10-24 architecture review (Architecture review due (10 PRs since arch-review/2026-10-18) #302).
First caller
The BurstDetection handler from #297 calls the picture comparison for each candidate pair.
Design
Design note: #296 (comment) (sections 4, 5)
Decision (maintainer, 2026-10-23): #296 (comment) — OpenCvSharp4 (4A); the smoke test in the Worker image on amd64 and arm64 comes first, and the ADR is written here.
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or requestready-for-agentFully specified, ready for an AFK agentFully specified, ready for an AFK agentv1.0Required for the v1.0 releaseRequired for the v1.0 release
Activity
fix(worker): Build StorageConfigSkipped.MissingOrInactive per call (#298
feat(worker): Similar photos join bursts through OpenCV feature match…