Skip to content

Camera Traps in Potato: Reviewing MegaDetector Output, Camtrap DP and Darwin Core

Import MegaDetector or COCO Camera Traps output into Potato, triage images and correct boxes, and export MegaDetector JSON, a Camtrap DP package or Darwin Core.

Potato 2.12.0 reviews camera-trap images after a detector has run over them. You import MegaDetector's batch output or a COCO Camera Traps file, annotators triage each image and correct its boxes, and the result exports as reviewed MegaDetector JSON, a Camtrap DP data package or Darwin Core occurrences.

Potato reads the detector's output and does not run the detector. Run MegaDetector, or the classifier you use for species, on your own machine first.

Import the detector output

bash
# MegaDetector batch output; images under /data/traps
potato import -i md_output.json --image-dir /data/traps -o review-project/
 
# The same, with the images hosted elsewhere
potato import -i md_output.json --image-url-prefix https://example.org/traps -o review-project/
 
# Keep only detections with confidence 0.5 or more
potato import -i md_output.json --image-dir /data/traps --md-threshold 0.5 -o review-project/
 
# COCO Camera Traps, one item per sequence
potato import -i cct.json --image-dir /data/traps --sequences -o review-project/

The format is detected from the content, and -f megadetector or -f coco_camera_traps chooses explicitly. With --image-dir, the generated config sets media_directory to that folder, so Potato serves the images from where they already are. With --image-url-prefix, the prefix is joined to each file name instead.

Each image is one item with these questions:

SchemeTypePre-filled with
triageradio: empty, animal, person, vehicleThe category of the most confident detection, or empty when no detection reaches the threshold
detectionsimage annotation, bounding boxesEvery detection at or above the threshold, labelled with its top species classification when the file has one, otherwise its category
speciesmultiselectThe species of those detections, created only when the source names species

The triage question is a quick first pass: annotators answer it with the keys 1 to 4 and move on, then come back to the boxes of the images that need them. Boxes keep the detector's provenance ("source": "ai", the detector's name and the confidence), and get "edited": true when an annotator changes them. The item keeps datetime, location, seq_id and frame_num when the source has them.

The MegaDetector importer reads batch-output format 1.x. Its bbox is [x, y, width, height] as fractions of the image from the top-left corner, which is how Potato stores boxes, so no image size is needed. Images with a failure are left out and counted, and so are detections below --md-threshold (default 0.2). A file of video results is reviewed at clip level, with each video as one item that has the triage and species questions.

A COCO file whose images carry seq_id is read as COCO Camera Traps, with its categories as the species plus empty. With --sequences, images that share a seq_id become one item, shown as a gallery of the frames in order, with triage and species but no boxes.

Review

bash
python potato/flask_server.py start review-project/config.yaml -p 8000

On each image, the annotator checks the triage answer, moves, resizes, relabels or deletes boxes, draws any animal the detector missed, and ticks the species present. Pre-filled answers are stored only when the annotator saves, so an export contains reviewed images only. Detecting Rubber-Stamped Pre-Labels covers checking whether reviewers accepted suggestions without looking.

Export reviewed MegaDetector JSON

bash
python -m potato.export -c review-project/config.yaml -f megadetector -o export/

megadetector_reviewed.json uses batch-output format 1.4, with one entry per reviewed image, so it can go back into tools that read MegaDetector results. A box the reviewer drew or changed gets conf 1.0, and a detector box left as it was keeps the detector's score. When several people reviewed an image, the first by user ID is written with a warning, and --option annotator=<user> picks one person.

Export a Camtrap DP package

bash
python -m potato.export -c review-project/config.yaml -f camtrap_dp -o export/ \
    --option timezone=-05:00 --option contributor="Your Name" \
    --option sampling_design=opportunistic --option capture_method=activityDetection

The export writes a Camtrap DP 1.0 data package: datapackage.json, deployments.csv, media.csv and observations.csv. Observations are one per box, one per ticked species without a box, and one blank observation for an image triaged empty. classificationMethod is machine for a detector box the reviewer left unchanged, and human otherwise. Sequence items give event-level observations.

Camtrap DP requires facts Potato does not have: the coordinates of each deployment, a UTC offset on every timestamp, and package metadata. Pass what you know as options:

OptionFills
timezoneUTC offset added to timestamps that have none, such as +02:00 or Z
titletitle and project.title (default: annotation_task_name)
contributorcontributors, one entry with role contact
licenselicenses, scope data
sampling_designproject.samplingDesign
capture_methodproject.captureMethod and media.captureMethod (activityDetection or timeLapse)

Anything still missing is listed in the export warnings. Fill it in, such as the deployment coordinates in deployments.csv, and check the package with a Camtrap DP validator before publishing it.

Export Darwin Core occurrences

bash
python -m potato.export -c review-project/config.yaml -f darwin_core -o export/

occurrence.csv has one Darwin Core occurrence per animal observation that has a scientific name. Animals labelled only animal are left out, since an occurrence needs a scientific name, and the export says how many. basisOfRecord is MachineObservation when the identification is the detector's and the reviewer left it unchanged, and HumanObservation when a person drew, changed or added it.

A reviewer can answer empty and still leave boxes on the image. The exports write the boxes, because deleting a box is the reviewer's decision, and the warnings list each such item and annotator, so fix them in Potato and export again.

Example

examples/image/camera-trap-review/ has eight synthetic frames from two cameras (deer, a raccoon at night, a person, a vehicle and empty frames) and the MegaDetector file they were imported from.

bash
python potato/flask_server.py start examples/image/camera-trap-review/config.yaml -p 8000

Further Reading

For implementation details, see the source documentation.