TensorFlow
Object Detection
Count Objects
Machine Learning
Computer Vision

How to count objects in Tensorflow Object Detection API

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

Introduction

Counting objects with the TensorFlow Object Detection API is usually a post-processing task, not a separate model feature. After the detector returns boxes, classes, and scores, you count the detections that pass your score threshold and optionally filter by class.

What The Detector Actually Returns

A detection model typically produces arrays such as:

  • detection boxes
  • detection scores
  • detection classes
  • number of detections

The raw num_detections value is not always the count you want, because many of those candidate detections may have low confidence scores.

That is why counting usually means:

  1. run inference
  2. filter detections by confidence threshold
  3. optionally keep only the classes you care about
  4. count what remains

A Simple Counting Example

Here is a minimal NumPy-style example using the typical output structure.

python
1import numpy as np
2
3scores = np.array([0.95, 0.87, 0.42, 0.12])
4classes = np.array([1, 1, 3, 1])
5
6score_threshold = 0.5
7valid = scores >= score_threshold
8count_all = int(valid.sum())
9count_class_1 = int(((classes == 1) & valid).sum())
10
11print(count_all)
12print(count_class_1)

This is the core logic behind most object-counting applications.

Applying It To TensorFlow Object Detection API Outputs

A common inference result dictionary looks conceptually like this:

python
1output_dict = {
2    "detection_scores": np.array([0.95, 0.87, 0.42, 0.12]),
3    "detection_classes": np.array([1, 1, 3, 1]),
4    "num_detections": 4,
5}

You can count detections above a threshold like this:

python
1def count_detections(output_dict, min_score=0.5, target_class=None):
2    scores = output_dict["detection_scores"]
3    classes = output_dict["detection_classes"].astype(int)
4
5    keep = scores >= min_score
6    if target_class is not None:
7        keep &= (classes == target_class)
8
9    return int(keep.sum())
10
11
12print(count_detections(output_dict, min_score=0.5))
13print(count_detections(output_dict, min_score=0.5, target_class=1))

That is usually enough for image-by-image counting.

Counting By Class

If you want a count per class rather than one total, group the filtered classes.

python
1from collections import Counter
2import numpy as np
3
4
5def count_by_class(output_dict, min_score=0.5):
6    scores = output_dict["detection_scores"]
7    classes = output_dict["detection_classes"].astype(int)
8
9    filtered = classes[scores >= min_score]
10    return Counter(filtered.tolist())
11
12
13print(count_by_class(output_dict, min_score=0.5))

This is useful for dashboards or inventory-style applications where you need counts of each detected category.

Why Threshold Selection Matters

The threshold is not just a cosmetic parameter. If it is too low, you overcount false positives. If it is too high, you undercount real objects.

A good threshold depends on:

  • model quality
  • object size and clutter
  • whether false positives or false negatives are more costly

There is no universal correct score threshold such as 0.5. It is a tuning decision tied to your deployment goals.

Beware Of Duplicate Boxes

Even after non-max suppression, detectors can still produce results that are not ideal for counting if the scene is crowded or the model is poorly calibrated.

So object counting quality depends on more than the counting code. It depends on the detector and the post-processing threshold.

If counts matter operationally, evaluate them directly on representative images instead of assuming that "good boxes" automatically means "good counts."

A TensorFlow-Friendly Filtering Pattern

If your outputs stay as tensors, you can do the same filtering with TensorFlow ops.

python
1import tensorflow as tf
2
3scores = tf.constant([0.95, 0.87, 0.42, 0.12])
4classes = tf.constant([1, 1, 3, 1])
5
6mask = scores >= 0.5
7selected_classes = tf.boolean_mask(classes, mask)
8count = tf.shape(selected_classes)[0]
9
10print(int(count.numpy()))

This is useful if you want to keep more of the logic inside TensorFlow instead of dropping into NumPy immediately.

Common Pitfalls

The most common mistake is using num_detections directly as the final count. That usually ignores score filtering.

Another mistake is counting all classes when the task really cares about one category such as people, cars, or bottles.

Developers also forget to cast class IDs to integers before comparing them, especially when model outputs come back as float arrays.

Finally, if the model produces double detections for the same object, the problem is not fixed by a different counting loop. It usually needs threshold tuning or model improvement.

Summary

  • Counting objects is usually done after inference by filtering detections.
  • Use confidence thresholds before treating detections as real counted objects.
  • Filter by class if you only care about certain object categories.
  • Count per class with a grouping step when needed.
  • The quality of the count depends on both the detector and the post-processing threshold.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

ML System Design practice on Codemia

Design recommenders, ranking systems and training pipelines the way ML interviews actually ask for them, with worked solutions.

Practice ML system design

All Rights Reserved.