Skip to content

Conversation

mohamedelabbas1996
Copy link
Contributor

@mohamedelabbas1996 mohamedelabbas1996 commented May 27, 2025

Summary

This PR introduces and adapts the occurrence tracking feature to the Antenna platform, ensuring it works seamlessly with the ML processing job flow.

List of Changes

  • Adapted and integrated the tracking logic from the AMI Data Companion project to work with the Antenna models and processing flow.

-Introduced tracking as a separate job that can be triggered from the admin page.

  • Added a new field next_detection to the Detection model to link detections in temporal order within a session.

  • Implemented checks to:

    • Run tracking only after all detections in an event are fully processed.

    • Skip events with human identifications to preserve valuable manually reviewed data in this v1 implementation.

  • Added a robust pair_detections algorithm that matches detections between consecutive frames based on feature similarity and spatial cost.

  • Old occurrences are deleted and reassigned based on the new tracking logic (when safe to do so).

Related Issues

#457

Detailed Description

Tracking is now a separate jonb that builds chains of related detections across consecutive source images within a session. These chains are constructed using a cost function that considers both feature vectors and spatial relationships.

The new Detection.next_detection field allows explicit, traceable linkage between detections and makes it easy to visualize or debug tracking chains.

  1. Load a test project with synthetic data and occurrences.

  2. Run the ML processing job on a selected collection.

  3. Trigger the tracking job from admin page.

  4. Verify in the occurrence list view that:

    • New occurrences have been created only for eligible sessions.

    • Some occurrences include multiple detections.

    • Detections are linked via the next_detection field.

Screenshots

Tracked occurrences with multiple detections
image
image

Deployment Notes

N/A

Checklist

  • I have tested these changes appropriately.
  • I have added and/or modified relevant tests.
  • I updated relevant documentation or comments.
  • I have verified that this PR follows the project's coding standards.
  • Any dependent changes have already been merged to main.

@mohamedelabbas1996 mohamedelabbas1996 linked an issue May 27, 2025 that may be closed by this pull request
Copy link

netlify bot commented May 27, 2025

Deploy Preview for antenna-preview ready!

Name Link
🔨 Latest commit 785a8f2
🔍 Latest deploy log https://app.netlify.com/projects/antenna-preview/deploys/68a8dbe2cf1476000974edb3
😎 Deploy Preview https://deploy-preview-863--antenna-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 60 (no change from production)
Accessibility: 80 (no change from production)
Best Practices: 100 (no change from production)
SEO: 92 (no change from production)
PWA: 80 (no change from production)
View the detailed breakdown and full score reports

To edit notification comments on pull requests, go to your Netlify project configuration.

@mohamedelabbas1996 mohamedelabbas1996 changed the title Bring back tracking Bring back occurrence tracking May 27, 2025
@mihow mihow changed the base branch from main to deployments/ood.antenna.insectai.org May 28, 2025 20:40
)


def get_latest_feature_vector(detection: Detection):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure all detections use the same feature extraction algorithm for both captures. See the most_common_algorithm function in the clustering function.

job_logger.info(f"Creating occurrences for {len(detections)} detections ")
job_logger.info("type logger: " + str(type(job_logger)))

assign_occurrences_by_tracking(detections=detections, logger=job_logger)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check if all captures have been processed in a Session before calling assign_occurrences_by_tracking().

Add logging statement to say when a session is complete. But this check should only consider captures that are in the collection (not all captures).

@mihow
Copy link
Collaborator

mihow commented May 28, 2025

@mohamedelabbas1996 Notes from our call

  1. For current code:
  • Don't shuffle images by default, we want them to be processed one session at a time (mostly).
  • In each call of save_results check if all frames from a session have been processed. If yes, then trigger the tracking / occurrence function.
  • For this check: Something capture.event.captures.all().filter(detections__classifications__algorithm=current_algorithm).count() == capture.event.captures.all()
  • Could experiment with calculating previous/next detections per batch and just updating previous_detection (or next_detection). Then the final function will make the Occurrences.
  • The synthetic data in the test project has occurrences with multiple detections. Use this to write a test and validate the tracking code. Or create a json fixtures file with known occurrences & detections with features to use as test data.
  • Experiment with deleting & recreating occurrences (for occurrences created before tracking was applied). How can we "merge" occurrences? Consider ones that may already have identifications.

Other approaches:

  1. Update the pipeline to process images in sequence, one session at a time. If you want to call the tracking algo in the save_results function. Here is where images are collected for a processing job. We can also fix the current issue where sometimes images of different dimensions from different cameras/stations are sent in the same batch.
    https://github.com/RolnickLab/antenna/blob/main/ami/jobs/models.py#L365

  2. When a random image is sent to the pipeline, always send the previous capture as well. Then the detection results will always contain features from pairs of sequential frames. This will work from the save_results function as you have it now.

  • Send frame 50
  • Find previous frame
  • If frame 49 has been processed, then don't reprocess, otherwise, send frame 49 with frame 50
  • Compare detections from both frame 50 & frame 49
  • Update previous_detection field for detections in frame 50 (or next_detection)
  • Check if all frames from a session have been processed.
  • If yes, then use the previous_detection to group detections into Occurrences in a final function. This function will process all captures in the session, not just in the save_results batch.
  • There will always be a need to join multiple sequences together
  1. Or for now make a new tracking job type that is manually triggered. Or at minimum an admin task.

Other notes:
Consider adding a previous_detection field to the Detection model.
Consider adding a previous_capture field to the SourceImage model.

Copy link

netlify bot commented May 29, 2025

Deploy Preview for antenna-ood ready!

Name Link
🔨 Latest commit 785a8f2
🔍 Latest deploy log https://app.netlify.com/projects/antenna-ood/deploys/68a8dbe2c0e64b0008c5328c
😎 Deploy Preview https://deploy-preview-863--antenna-ood.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@mohamedelabbas1996 mohamedelabbas1996 changed the title Bring back occurrence tracking [Draft] Bring back occurrence tracking May 31, 2025
@mohamedelabbas1996 mohamedelabbas1996 self-assigned this Jun 3, 2025
@mihow
Copy link
Collaborator

mihow commented Jun 17, 2025

@mohamedelabbas1996 can you make this a separate job for now? So it's optional to run, and possible to run on existing occurrences that have already been processed. It can be triggered from the Django admin, as a start.

@mohamedelabbas1996 mohamedelabbas1996 changed the title [Draft] Bring back occurrence tracking Add supprot to occurrence tracking Jun 20, 2025
@mohamedelabbas1996 mohamedelabbas1996 changed the title Add supprot to occurrence tracking Add support to occurrence tracking Jun 20, 2025
@mohamedelabbas1996 mohamedelabbas1996 changed the title Add support to occurrence tracking Add support for occurrence tracking Jun 20, 2025
@mohamedelabbas1996 mohamedelabbas1996 marked this pull request as ready for review June 20, 2025 22:15
@mihow
Copy link
Collaborator

mihow commented Jun 25, 2025

Thanks for the great work @mohamedelabbas1996, I started testing today. Here are some observations so far:

The code checks if all captures in an event have been processed. Which makes sense however there are two caveats I am running into:

  1. If an image is processed, but it has no detections, then the whole event appears as "not completely processed" and I can't run tracking (which is the case for everything I have tested). We need a way (in general) to know if captures have been processed. Right now the "has detections" method is just a proxy.
  2. It would be ideal if not all images are required to be processed in an event. We should be able to make a collection of 10 second snapshots an run tracking on just those. Instead of requiring all of the motion-triggered captures to be processed. Or perhaps this is just because we have avoided processing all motion-triggered captures since tracking was not previously available and processing is slow. So we can focus on those problems too.

We really need a way to process a whole session at once! (quick actions or a filter in the new collection form). Maybe can be added to #800. Or for now perhaps we add a quick action from the Django admin. It's difficult to test tracking at the moment.

Small TODOs (I will complete these or add more detail later.

  • Make a new column for detections per occurrence instead of overriding the existing one
  • Update a few names and logs
  • Create a smaller dataset with real data for testing (i'm working on this now)

@mihow mihow force-pushed the deployments/ood.antenna.insectai.org branch from a011a5f to 3528f27 Compare August 21, 2025 02:22
@mihow
Copy link
Collaborator

mihow commented Sep 9, 2025

I just found this note in the save_results function in pipeline.py. Let's review if this should be removed in this PR:

    # Create a new occurrence for each detection (no tracking yet)
    # @TODO remove when we implement tracking!
    create_and_update_occurrences_for_detections(
        detections=detections,
        logger=job_logger,
    )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bring back occurrence tracking
2 participants