This update essentially serves as an extension of the waterholes update. As covered in that update’s documentation, TrapTagger was built around the most-common camera-trap use case – where motion-triggered cameras are placed perpendicular to a game trail. In such a setup, a batch of images is typically triggered in quick succession, documenting a single event. To capture this information, we have always used a simple time-based clustering technique whereby images taken at the same site/station (across the potentially multiple cameras there) within one minute of each other are clustered together. This occurs up to a maximum period of 15 minutes upon which an alternative clustering technique is triggered to split up the giant cluster – where the intention is to better handle cases where animals spend extended periods in front of the camera (like waterholes) by splitting up long potentially multi-hour clusters into more-useful chunks. Significantly, these smaller units of time help strike a balance between reducing the amount of data one needs to work with, whilst also helping ensure that nothing is missed in the midst of one of these excessively long clusters.

Figure 1: The trigger-source option on the import form.
However, this approach had one (known) blind side – cameras used in a time-lapse mode where an image is instead triggered on a regular time interval. If the time interval was less than or equal to a minute, all the images would be clustered into one giant cluster, be subject to the alternate clustering technique, and thus be handled cleanly. On the other hand, if a camera was set to a greater period, the images would not be clustered in any way. Arguably, this is erring on the side of caution, and is not incorrect. However, clusters are quite useful in a number of different ways – they improve species classification (by providing more classification opportunities), they help with data interpretation (by allowing you to look at events), and they aid in human annotation by significantly reducing the number of images that need to be viewed. Therefore, we wanted to improve the handling of this edge case through clustering.
By design motion-activated cameras automatically create some sort of clustering based on the presence/absence of targets (false triggers aside), and we wanted to emulate this. As such, we have put together a clustering algorithm that – at its core – separately groups consecutive images with AI detections, and those without, on a per site/station basis up to a maximum of 15 minutes. In cases where there are multiple cameras at a particular site/station, the presence/absence of a target at the site – across all the cameras – is considered. This algorithm has actually been the fall-back clustering approach for splitting up large clusters (>15 minutes) since the waterholes update (minus some edge-case tweaks).
We considered implementing this in an automatic way – where we could detect when a camera is being triggered on a regular interval or not. In principle, this is pretty simple. However, it’s something where the edge cases can get out of hand pretty quickly: how do we handle cases where there is some jitter in the image rate? At what point does jitter dissolve into a non-periodic event? What if the detected periodicity comes and goes over the course of time? As such, we decided it was simpler, cleaner, and safer to leave the call in the your hands by making your trigger source selectable at import time (see Figure 1) as either motion-triggered or time-triggered based on how you setup your cameras.
For those of you who use motion-triggers, do not worry – if you select the appropriate option, your data will still be clustered in the same way it always has.