In a recent photo gallery, I shared images of thousands of Vaux's Swifts gathering at their roosting chimney in the evening. While it was clear there were thousands of them, it was hard to visually estimate a count since they were flying quickly at times and swirling all around.
In this post I'll share a bit of code I used to count the birds in a photo I took. This helped me get a sense for how many birds I saw.
Earlier this year I published a little web app for counting things in photos. This app works well for a few dozen birds, or even for a few hundred, but there were thousands of Vaux's Swifts in the photo I took. Here's just a little crop:
of the photo:
I could have roughly counted the birds in the photo by 100s, but what fun is that when I can write some code and get a much more accurate number?
A DuckDuckGo search brought me to this StackOverflow question, where python and OpenCV are used in a similar situation. The swifts appear as dark silhouettes against the sky, so after converting to grayscale it seemed like there would be enough contrast for similar code to work for me. I've also used OpenCV in python before, so this was perfect.
After a little tinkering and browsing some of OpenCV's extensive documentation, I had my basic script ready to go. It outputs a copy of the image with each spot highlighted using one of several bright colors. This allows quickly verifying by eye that too many nor too few spots were counted.
I figured some of the incidental objects in frame, like trees and buildings, would be interpreted as many spots so I used Photoshop to crop the image and to paint over some areas with a solid color.
When I first ran the script, it began to list hundreds of thousands of found spots! After some tweaking of the lower and upper bounds for the area measurements of countable spots, I realized I should have instead used a small sample region of the photo within which to try to match the exact hand-counted number of birds.
I took a small crop of the photo, containing both large (near) and small (distant) birds and used my click counter app page. I found a surprising 235+ birds.
With a few tweaks to the area bounds I was able to very nearly match the roughly 235 birds counted by hand.
Running the script on the full image returned a count a bit over 5,000. The verification image showed that a few high-contrast areas in the clouds and along the image edges had been counted, so I painted over those areas and tried the script again.
The script found 4,900 birds this time. After a small tweak to output the spot highlights in one of several colors, just to verify that close-together birds were generally being counted as separate spots, I decided the 4900 number looked good.
The above image is a wider crop of the final counted photo. You can see the highlighted birds and where I painted over high-contrast clouds, trees, and the chimney.
Thanks to the OpenCV script I have a very good count for the number of birds in the photo. As for estimating the total number of swifts that were gathered there, I figured I may have been lucky to get a bit more than half of all the birds in the photo since I specifically took a very wide shot where a large relatively dense cloud of the birds had formed.
I would say there was likely somewhere between 6,000 and 10,000 Vaux's Swifts in total.
The script is available in its GitHub repo.