Consider a scenario where you are conducting a survey of an area of coastline. You want to understand whether it would be appropriate to build another dock to ensure that the existing docks are not overcrowded during the day. This is a problem that can be solved with computer vision.

With computer vision, you can identify different objects in an image. You can then use code to count the number of instances of a given object in an image.

In this guide, we are going to talk about how to count the number of objects that appear in aerial imagery of a coastline. We’ll keep counts of each separate object type so that we can see how many boats and jet skis there are in an image.

Without further ado, let’s begin!

How to Count Objects in an Image in Python

To count objects in an image, we first need a list that contains all of the predictions returned by a computer vision model. We’re going to use the Aerial Maritime model hosted on Roboflow, but you can use any model that you want.

Our model predicts:

  1. Boats
  2. Cars
  3. Docks
  4. Jet skis
  5. Lifts

Before we begin, make sure that you have a list called “predictions” in your code that contains a list of dictionaries. Each dictionary should contain the name of a prediction class and any auxiliary information to which you may want to refer (i.e. coordinates of a prediction).

Here’s an example predictions list:

{'predictions': [{'x': 127.0, 'y': 566.0, 'width': 78.0, 'height': 104.0, 'confidence': 0.8159579038619995, 'class': 'dock'}, {'x': 1200.0, 'y': 475.5, 'width': 52.0, 'height': 85.0, 'confidence': 0.7788712978363037, 'class': 'dock''}]

Let's count all of the instances of the aforementioned objects in this image:

We can write a Python function that counts how many times each class comes up in the list:

def count_instances(predictions: dict) -> dict:
    classes = {}

    for bounding_box in predictions['predictions']:
        if bounding_box['class'] in classes:
            classes[bounding_box['class']] += 1
        else:
            classes[bounding_box['class']] = 1

    return classes
    
inference.save("aerial_with_bounding_boxes.jpg")

In this function, we create a dictionary called “classes”. We then iterate over each prediction. For each class, we add 1 to a counter for that class in the “classes” dictionary. If the class is not in the dictionary, the class is added with the value 1.

The last line of code saves the predictions to a file so we can see them plotted. If you are not running a Roboflow model, you can comment out this code.

Let’s run our code and see what happens. The following output is returned:

{'dock': 4, 'jetski': 1, 'lift': 5}

This dictionary gives us a lot of information. We can conclude that there are no boats in our image, according to our model. We can also see that, at the time the photo was taken, there were no boats in the docks. We could draw more conclusions, too.

We have successfully counted the number of objects in our image!

Our code has also plotted our predictions and saved them to an image called “aerial_with_bounding_boxes.jpg”. We can open this file to see how our model performed:

Adding Logic After Counting Objects

We could add logic to our code to do something if the number of counted objects is too high. For example, we could make our code save a record to a CSV file when an overcrowded dock is found:

with open("results.csv", "w+") as f:
    writer = csv.writer(f)

    writer.writerow(["class", "count", "image"])

    if results["boat"] > 0:
        writer.writerow(["boat", results["boat"], "aerial.jpeg"])

This code will write a record to a CSV file if more than 10 boats are found in the aerial.jpeg image. This code could be adapted to work with a whole folder of images, running for each image and logging instances where a dock is overcrowded.

Configuring a Model (Optional)

In the above example, we use the Aerial Maritime project hosted on Roboflow Universe, an open repository of more than 110,000 computer vision datasets and over 10,000 trained models.

We can test the dataset by opening the project in our browser and clicking “Deploy”. This will open an interactive widget through which we can interact with our model. Drag an image into the model to retrieve predictions:

0:00
/

We can get our predictions in code using the Roboflow pip package. To use the package, first install it via the command line:

pip install roboflow

Next, scroll down on the Deploy tab and copy the Python code that appears. This code will let you load your model into your Python program. The code will look like this:

from roboflow import Roboflow

rf = Roboflow(api_key="YOUR_API_KEY")

project = rf.workspace().project("aerial-maritime")
model = project.version(22).model

Substitute the YOUR_API_KEY text with your API key. This will appear automatically in the code on the Deploy tab.

To retrieve predictions on an image, use this code:

inference = model.predict("aerial.jpg", confidence=40, overlap=30)

predictions = inference.json()

This returns a JSON object of predictions that you can use in the earlier example to count the number of times each class identified in an image appears.

Conclusion

In this guide, we have discussed how to count objects in an image using Python. We used a Python dictionary to keep count of the number of times each object appeared in a provided image. We then connected the code with logic to save a record in a CSV file when more than 10 boats were found in an image, which was a signal that an area of a coastline may require another dock.

Now you have the information you need to count objects in images. Happy building!