Skip to main content
← All case studies
Vision AIAI & ML·Parcelist

Vision-AI Parcel Detection for Smart Locker Kiosks

A vision-LLM pipeline that lets self-managing delivery kiosks understand their scan table from a single webcam frame—replacing custom-trained computer vision models with prompted Gemini calls.

ScalaGoogle GeminiCirceSTTPOpenTelemetryPython + JupyterScalaTestNix

The Problem

Parcelist builds self-managing delivery hubs for residential buildings—smart parcel lockers where couriers drop packages 24/7 with no staff involved. For that to work, the kiosk has to understand what is happening at its scan table the moment a courier places a parcel: how many parcels are present, whether the label sign is clear or obstructed, and whether a person is still standing there.

The traditional computer vision route would mean collecting and labeling image datasets for every camera type—webcam, security camera, depth camera—and retraining models whenever hardware or lighting conditions change. At the prototyping stage of a physical product, that cycle is too slow and too costly, and it turns every hardware iteration into a machine learning project.

What We Built

We replaced custom-trained models with prompted vision-LLM calls: a resized webcam frame goes to Google Gemini with a detailed natural-language prompt and a fixed JSON response schema covering parcel counts, sign emptiness and obstruction, human presence, and per-field confidence scores. Business rules layer confidence thresholds over the parsed response to drive kiosk workflow decisions—so changing detection behavior is a prompt edit, not a retraining cycle.

The contract was validated research-first in a Jupyter notebook against real labeled kiosk imagery—empty scenes, parcels present, night vision, bad lighting—then hardened into a typed, fully test-covered Scala service with an image-quality gate that rejects black or underexposed frames before spending an LLM call, and OpenTelemetry tracing and per-kiosk latency histograms throughout. Alongside the vision layer, we also built the storefront application that runs on the kiosks themselves and the shared library serving the platform’s end-to-end delivery flow.

Prompted detection instead of trained models

One Gemini call on a single frame returns parcel counts, label-sign state, and human presence as structured JSON with confidence scores—no datasets, no labeling, no per-camera retraining.

Image-quality gating

Brightness and black-frame checks reject unusable frames before they reach the model, so the kiosk never spends an LLM call on an image that cannot be interpreted.

Confidence-threshold business rules

Workflow decisions like "is the scan area empty" combine several returned confidences against tuned thresholds rather than trusting any single boolean from the model.

Production observability per kiosk

OpenTelemetry metrics and distributed tracing capture Gemini latency and error histograms for each kiosk, with trace context propagated into every model call.

How It Works in Practice

A courier walks up to an unstaffed kiosk at night and places two parcels on the scan table.

  1. 1

    Capture and gate

    The kiosk grabs a webcam frame, and the quality gate checks brightness and exposure—a black night-vision misfire is rejected and retried instead of being sent to the model.

  2. 2

    One call, full scene

    The frame goes to Gemini with the structured prompt, returning parcel count, sign state, and human presence with per-field confidence scores in a single response.

  3. 3

    Decide with thresholds

    Business rules weigh the confidences—the kiosk waits while the courier is still detected at the table, then proceeds once the scene is stable.

  4. 4

    Route and notify

    The kiosk workflow moves the parcels into the delivery flow, with every model call traced and its latency recorded against that kiosk for monitoring.

Screenshots

Parcelist — self-managing delivery hubs for multi-unit residential buildings.
Parcelist — self-managing delivery hubs for multi-unit residential buildings.

Engineering Approach

Research first, production second

The prompt and JSON contract were iterated in a notebook against labeled real-world imagery before any service code was written—so the hard uncertainty was resolved cheaply, then engineered once.

Typed contracts over raw model output

Constrained JSON output with low temperature and a fixed seed is decoded into typed Scala case classes, turning a probabilistic model into a dependable, testable interface.

Built to merge, not to demo

The service mirrors the packages, constructors, and DTOs of the main kiosk controller, with injected fakes for all external calls—so reintegration into production is low-risk and no test touches a live API.

Have a similar problem?

Tell us what you're working on and we'll tell you honestly whether we can help.

Copyright © 2026 Datum Brain

facebookinstagramlinkedintwitteryoutube