- Introduction
- Latest Release
- Key Features
- Typical Workflow
- Project Structure
- Configuration
- How to Use
- Application Outputs
- Installation
- Distribution
- Further Development
- Licensing
This release adds
- editable YOLO bounding boxes (for future model training)
- improved review navigation
- more reliable correction handling
- master class registry
See the Changelog for version history
The latest version of this application now serves two purposes.
Firstly, it provides a lightweight desktop application for the batch processing tasks of detection, classification, and manual review of trail-camera images, designed specifically for predator control in the New Zealand conservation context.
Secondly, you now have the ability to start your own catalogue (or add to it), of images with paired YOLO labels that can be used to build further YOLO detection models (and export to ONNX for using in this application).
This now supports the starting objective of being able to iteratively tailor or improve a detection model to your own particular use case. Whether that is to cope with specific camera scene limitations, or a tailored list of classes that you want to detect for. For example, you could start with the model provided here and start to split 'Non Target' (which in this model includes Thrush, Blackbird and similar birds) into species specific detection labels.
The tool combines fast automated detection (via ONNX models) with a manual review interface, making it easy to standardise initial classification and then efficiently correct or confirm results. Both initial detection and manual review generate filing of image copies and summary csv file for both statistics and easily finding images that can be added to new builds of the detection model. The review process will now also allow for confirming bounding boxes and adding where target classes have been missed in any image.
Although this tool has been developed for predator detection, it would be capable of being used for any custom ONNX model with editing of the config.yaml file for classes specific to the model.
The current model supplied with this application has been developed on 7,000 images from approximately 60 trail cameras captured in New Zealand native bush. Class labels included in the supplied model are:
- Cat
- Possum
- Ferret
- Stoat
- Rat
- Kiwi
- Non Target
- Native Non Target
- Person
The confusion matrix for this model (20% validation split) is here.
-
ONNX-based object detection
-
No PyTorch or Ultralytics runtime required
-
Compact, fast, and suitable for standalone distribution
-
-
Config-driven class setup
-
Classes, display names, colours, priorities, and keyboard shortcuts are defined in config.yaml
-
Supports custom-trained ONNX models
-
-
Automated batch classification
-
Processes folders of images
-
Outputs both plain and annotated copies (optional)
-
Optional mirroring of sub-folder structure (e.g. camera or date based)
-
Confidence-based splitting (e.g. high / low confidence)
-
Creates a matching YOLO .txt label file for each processed image. Images with no detections receive and empty label file
-
-
Interactive review & correction UI
-
Image-by-image navigation
-
Keyboard shortcuts for rapid reclassification
-
Toggle between the plain image and an editable bounding-box view
-
Undo support for recent actions
-
Resume review from where you left off
-
Add a new class during review (e.g. a species not currently in the detection model / config.yaml)
-
Delete, reclassify, or add bounding boxes in the Edit boxes view (generates paired YOLO label .txt file)
-
-
Structured outputs
-
Final folder structure containing reviewed images (both plain and annotated) and YOLO label files.
-
Optional class-prefixed filenames
-
Summary csv file capturing:
-
model classification (i.e. initial detected class)
-
final reviewed classification
-
-
filenames and confidence scores
-
-
Run detection
-
Select the root input folder of images (Note: the original source images remain unchanged and unmoved)
-
Choose (create if needed) an output folder
-
Choose config.yaml (default is from /models) for classes being detected for
-
Choose ONNX model (default is from /models) for detection run
-
Choose master_classes.yaml
-
Run automated classification
-
Initial counts and detection confidence are displayed
-
.csv file is generated with image filed folder, original and saved name, main detection (priority class), detection confidence, all detections found
-
-
Review results
-
Images are automatically loaded for review
-
Navigate through detections
-
Correct classifications where needed (mouse or keyboard with key association per class set in config.yaml)
- Where there are multiple detections, then 'tab' key to navigate or mouse select to either re-classify or delete if false positive
-
Last reviewed image is saved so you can close and return to the same review spot on re-opening
-
-
Final outputs
-
A _final folder containing reviewed images (plain and annotated) and YOLO label files
-
A csv summary file suitable for reporting or further analysis
-
app
|-- classifier_core.py
|-- classify_review_gui.py
|-- main.py
models
|-- config.yaml
|-- model.onnx
master_classes.yaml
-
classifier_core - model loading, detection run and image filing
-
classify_review_gui - user interface using Python tkinter and customtkinter
-
model.onnx – your ONNX detection model
-
config.yaml – class; definitions, priorities, colours, and hotkeys
-
master_classes.yaml - definitive list of class IDs for classes to generate consistent YOLO label files across different detection runs
The application is intentionally model-agnostic.
config.yaml describes the active detection model and review interface, including model classes, priority, display names, colours, hotkeys, and additional review actions. master_classes.yaml is the long term definitive class registery used when saving reviewed YOLO labels. Its numeric IDs should remain stable across different models and review runs. Every model class must resolve to a class in master_classes.yaml, either by matching it's definitive name or through an alias. What does this mean in practise? If the model you are using contains a class of 'rat', which in the config.yaml has an ID of '2', and your master_classes.yaml also has a class of 'rat' (for cataloguing rat images for futher training), but a class ID of '0', then the generated YOLO label will be given '0' for any bounding box of a rat. So that in future runs with a different model (and paired config.yaml file) where 'rat' might have an ID of '1', then any bounding box for a rat will still receive an ID of '0' as per the master_classes.yaml file.
-
You can:
-
Replace model.onnx with a compatible custom ONNX detection model
-
Edit 'config.yaml' to define:
-
class names and display labels (This must match the class list and order for the ONNX model used)
-
priority order for resolving multiple detections (e.g. cat detected takes priority over rat detected in same image)
-
actions which allow additional classes not currently in the detection model to be used when reviewing and filing images
-
bounding box colours for annotated images created
-
preferred keyboard shortcuts
-
-
Maintain stable training class IDs in 'master_classes.yaml'
-
This allows the tool to adapt to different projects, species, or environments without code changes.
-
Detection Run Settings
- Input folder: a folder containing images directly, or one level of immediate subfolders containing images - for example, one subfolder level per camera
- Output folder: where the copies of images after detection should be saved
- Config YAML: location of the config.yaml file to be used
- ONNX model: location of the ONNX model to be used
- Master classes: location of master classes which holds the definitive list of class and id's used when generating YOLO label .txt files between detection and review runs
- Confidence threshold: set the confidence score at which detections are saved in high_conf or low_conf folders
- Single output tree: is the default and combines images from all input subfolders beneath the detected class folders
- Mirror sub-folders: preserves the immediate input subfolder - such as camera name inside each output tree
- Save plain copies: On by default. Select to save images into class detection plain folder
- Save annotated copies: On by default. Select to save images with bounding box and class label into class detection annotated folder
- Run classification: Start the classification and image filing
- Progress bar showing number of images scanned and filed out of all images found in Input folder
- EMA conf (detected): The average confidence score of all detections made so far
- Save Image Filename: gives additional prefixes that can be added to the ==saved== copies of each image
- Sub folder name: Useful if you want to maintain the camera name for example in the classified image filename
- Save Datetime: If the image capture datetime is available in the original image, this can then be written in the saved image copy filename
-
Detection and Reviewed Statistics
- Class: Class name. Can be added to dynamically during review with [+ Add review class] button
- EMA: The average confidence score of that class during detection
- Detected: The count of class detections made during the detection run
- Final counts: The final number by class after review and any corrections made
-
Navigation
- Source folder for the filed detection images for reviewing (will be defaulted from Output folder after Run classification completes)
- Load Images: Will start at the first image of the first sub-folder, unless you are resuming a previously incomplete review session, in which case loaded image will be the next image still to be reviewed
- Prefix class in final filenames: Off by default. Select this if you want to prefix all image files with class name.
- << Prev / Next >>: Buttons for navigating images (also can use left / right arrow keys). Important Moving to the next image (button or ← / → keys) finalises the current image using its reviewed bounding box(es). If no boxes remain, it is saved as no_detection; otherwise, the final image-level class is selected from the remaining box(es) using the configured class priority. ==New in v1.2.0:== using previous or left arrow will go back one image but does not undo the previous confirmation. 'Ctrl+z' undoes the most recent bounding-box edit on the current image, including drawing, deletion, or box classification
-
Review and Correction Window
- Plain / Edit boxes (annotated): Default view is of the Edit boxes (annotated image) view. During 'Run classification' with default of save plain and annotated, you will end up with a mirrored folder structure. One with Plain and one with Annotated images. With both, you can toggle between the annotated or plain image to view the same image without any bounding box or label. Use ↑ / ↓ keys to toggle between the same image with and without annotation
- Where there are multiple detections, using the tab or shift+tab keys will navigate between bounding boxes. You can then use the delete key to delete a bounding box (and associated class from the statistics), or re-classify the detection in the bounding box
- When 'Draw boxes:' in the User Actions is set to 'On' you can then use the mouse to draw a bounding box around a missed detection
-
User Actions
- Detected: The current class of the priority detected class in the image (high_conf / low_conf). Image navigation will go through each sub-folder (e.g. camera) at a time, then by class for that sub-folder and high_conf / low_conf within that class. This means that you should be reviewing images in 'batches' by the class (and confidence) that has been detected. This will be reflected in the 'Progress' area where the maximum number of folders will reflect the count of class+confidence combinations
- Image filename. For filenames that are too wide to display, simply click on the filename to get a popup. 'Esc' or clicking elsewhere will close this
- Bounding boxes.
- Use either the mouse to select a bounding box (Draw boxes must be off) or 'tab' key to select a box. Use either the 'Delete selected box' or the 'Del' key to delete a bounding box. 'Ctrl+z' to undo
- A selected bounding box (yellow) can now have its detection class changed. Either with the class button, or hotkey selection
- Toggle 'Draw boxes' to On to enable drawing of a box around a missed detection in the image (Edit boxes). Selecting the New box class will display a dropdown list from which you can select the class detected. Once the bounding box has been drawn, you can re-classify that bounding box when it is selected.
- Mark correction as: All classes possible to correct to. Can be altered in the config.yaml file including the shortcut key you would like to assign to that class
-
- Add review class: This button adds a new review class to the selected configuration and makes it available immediately as a correction button. If the class is not already in master_classes.yaml, you will be asked whether to add it as a permanent master training class For example if you come across an image with a species not included in the list of classes, you can add a new species. This will then appear in the Detection and Reviewed Statistics. A new button will be created (with a hotkey you define) and a new sub-folder for the new class will have images saved to it as corrections are made. Added classes will then be available in the draw box dropdown list of classes. You will be asked if you want to add this new class to the master_classes.yaml file. You would do this if you wanted to define a new class for future model builds
- Progress: Folders completed / Total Folders......Images completed / Total Images
- The following is a snippet of the output from both running classification and then reviewing. The result is
- Input folder 'April 2024/Cam52' containing 3 sub-folders of /Cat /Other /Rat (these images had already been through a pre-classification exercise)
- Output folder '/Cam52_April2024' now with top-level sub-folders of /annotated /labels_yolo /plain
- below each sub-folder we now have a folder for each class detected and a high_conf / low_conf split
- a classified_results.csv file
- Final Output folder 'Cam52_April2024_final' containing the same highest level sub-folders of /annotated /labels_yolo /plain
- below each sub-folder we have a folder for each class reviewed. high_conf and low_conf are dropped now as the review confirms the class
- a classified_results.csv file (see below)
- master_classes_snapshot.yaml (which is the class and class id pairing used for the YOLO label .txt files)
- a review_state.json file which records the user's current position in reviewing images and allows starting back at the same place
- classified_results.csv Here we now have sub-folders by class for each class detected with the model. The confidence threshold sets the split between high_conf and low_conf
- classified_results.csv
- review_state.json In the final review output, the folder structure is flattened to class only. Here you can see that 'possum' which was a detected class has now been corrected and disappears. 'hedgehog' which was not in the detection run, has been added as a class in the final review.
At this point, you could just delete the detection run output of Cam52_April2024. One reason you might want to consider keeping this is to compare false positives between the detection and review to get clues as to why the model has made a wrong detection, or missed detection. For cataloguing images for future model training, you would only need to keep the 'plain' folder and the 'labels_yolo' folders from the final review
Summary Output
- classified_results.csv
- folder name if sub-folders where specified (Mirrored) in Run classification
- original filename:
- saved filename: merges folder name and filename as a safety in case multiple images have the same file name as well as datetime stamp found for image
- datetime_stamp: if datetime metadata is found in the image, then this is written here
- could be parsed for example to give class counts per calendar day, week of year etc.
- main label: the initial detected class
- main_confidence_pct: percentage confidence the model had during the detection for that image (note no_detection is always 0% as a detection calculation isn't actually made)
- all detection: if multiple classes were detected, they will be listed here
- final_filename:
- final classification: the final classification after review (in this example, one possum detection has been corrected to 'hedgehog' during review)
This file can be useful for reporting on pest incidence rates as well as finding images that will be useful for fine-tuning future models. For example you could filter for all images where main label <> final classification to correct for classes. Examples I get are cat = possum. cat = kiwi. stoat = rat. Also highly recommended are gathering images where there was an initial detection but final classification is no detection. These reviewed false-positive images are useful negative training examples. Retain the plain image with its empty YOLO label file so the model sees difficult backgrounds where no target object is present
Options for installing and running
- Requires
- Windows 10 +
- x64 CPU
- Run from source (recommended for devs): Python 3.10+ + pip install -r requirements.txt
- Standalone executable (recommended for users without Python):
- Go to the Releases page and download the latest PredatorClassifier-...windows-x64.zip
- Extract the zip, ensure you keep the models/ folder next to the .exe, then run the .exe
- Build it yourself: PyInstaller recommended
A standalone Windows executable is provided via GitHub Releases.
The executable:
-
Does not require Python to be installed
-
Loads models and configuration from the bundled models folder
-
Can be redistributed within teams or volunteer groups
This tool was developed to support conservation and predator-control programmes by:
-
speeding up image review workflows
-
reducing manual classification effort
-
maintaining consistency across reviewers
-
enabling continuous improvement of detection models through corrected data as well as larger data sets with specific class lists and camera scene context for your own project
Please follow this project for further updates as I will also be publishing two further github repos and blog posts.
-
Firstly, a python tkinter application for training your own detection model with YOLO (exporting to ONNX) that would be specific to your own environment that could then be used with this application. This application will now support this by giving you the plain image <-> YOLO label file pairs required by ultralytics YOLO
-
Secondly, a repository for a how to guide for building and deploying a remote detection service paired to a trail camera that can be configured to check for images and send sms alerts on schedule for any high priority animals. I have already developed the software side of this project and am in the process of finishing a prototype for testing
The application code is licensed under the MIT License - see LICENSE






