Counting Cars

Camera view of the street in front of the house with a parked pickup truck outlined in a red detection box and lawn areas outlined in blue exclude boxes

In 2026, we added a car counter to the display. We had always been curious about how many people were actually watching and what the traffic patterns looked like across a night and across the season. Just as importantly, we wanted to give people planning a visit some idea of how busy we are before they get in the car. The live count is shown on our home page and Plan Your Visit page so visitors can check traffic before driving over, and a summary is on vote-now.org along with the other show stats.

How it Works

Two security cameras watch different sections of the street in front of the house. Each camera has its own instance of the car counter, running as a separate pod in our home k3s cluster.

  1. Each pod reads the camera’s video stream over RTSPS and processes about one frame per second. The rest of the frames are read and thrown away so the stream never falls behind.
  2. Each frame goes through YOLOv8, an AI object detection model that finds cars, trucks, and buses in the image. We use the extra-large version of the model because the smaller ones weren’t reliable enough at night. It all runs on regular CPUs, so no GPU is needed.
  3. After dark, frames are brightened and sharpened before detection. Dark color frames and black-and-white infrared frames each get their own contrast boost (CLAHE). The counter checks each frame’s brightness, so there is no time-of-day schedule to maintain.
  4. When the count changes, the pod publishes an MQTT message with the camera name and the new count, and sends a heartbeat every few seconds even when nothing changes. If the camera stream drops, it publishes a “disconnected” status so a missing camera never looks like an empty street.
  5. The vote-now.org server listens for these messages and adds up the cameras to get the live total shown there and on this website. At the same time, the ChristmasStats server records every count in its database along with the votes, names, and songs it already tracks. The vote-now.org statistics page uses that history to show the most cars seen in the last hour, 8 hours, 24 hours, and so far this year.
  6. For deeper analysis, the full history is available in Grafana. There we can compare nights, see how quickly traffic builds after the show starts, and see what the weather does to attendance.

Every time the count changes, the counter also saves an annotated screenshot (like the one here) to shared storage in the cluster. A small image viewer lets us browse them by camera and date to check what the counter actually saw.

Dealing with False Positives

Object detection isn’t perfect. A counter that just counted every car it saw would have been wrong in several ways:

It still isn’t perfect, so treat the numbers as a good estimate rather than an exact count. It is accurate enough to show when the street is quiet and when it’s packed.

Running in Kubernetes

The counter is built to run as a well-behaved Kubernetes service:

Source Code

Photos

Seasons featuring this

Years where Counting Cars shows up in the display write-up.