All work

Foundry Vision and Traceability

Cameras, sensors and chemistry, tracing every ladle

Year
2026
Kind
Vision & edge
Status
In use
Built at
QED Analyticals

A platform for a ductile iron pipe foundry that watches treatment stations on camera, ingests sensor, lab and historian data, and infers which metal became which pipe.

A YOLO detector finds ladles on the shop-floor cameras, and masks, thresholds and a debounced state machine confirm each magnesium treatment from its flash. Pyrometer, lab chemistry and process-historian data are ingested exactly once, with file offsets committed alongside the rows they read. Where no IDs link one stage to the next, lineage is inferred from timing and from chemistry that the next step doesn't change, with a confidence on every link. It all runs as one Docker image on an edge GPU server at the plant.

The problem

A ductile iron pipe foundry moves liquid metal through several stages, from a blast furnace through induction furnaces and magnesium treatment to centrifugal casting. The record of each stage lives somewhere different: temperature sensors, a lab's chemistry database, a process historian, and the shop floor itself, which only cameras see. Nothing links a pipe back to the metal it was cast from. This platform watches the floor, ingests every source, and reconstructs that path.

How it works

  1. 01

    Find the ladle with a detector

    A YOLO detector, running in half precision on the GPU, finds the vessel in each frame, sampled at 2.5 frames a second with one thread per camera. A ladle counts as in a station when its box's centre is inside the zone or at least 20% of it overlaps. Entering takes one frame and leaving takes three, so a single missed detection can't end a treatment.

  2. 02

    Detect the flash without a model

    Magnesium treatment shows up as a burst of near-white light. Each station's region is masked for near-white pixels and for bright, unsaturated ones, a painted mask hides fixed lights, and blobs under 200 pixels, the size of a spark, are dropped. The region is split into a top third and the rest, and each part counts as lit when 5% of its pixels are.

  3. 03

    A state machine that ignores glare

    A treatment starts when the lower part stays lit for four frames in a row with a ladle in position, becomes active when the top stays lit for four frames, and ends after the top has been dark for 30 seconds. Four frames, about 1.6 seconds, is enough to reject one frame of glare, dust or sparks. A 15-second re-light window tells a hot ladle being lifted apart from a treatment resuming, and a camera gap of more than 3 seconds never counts as darkness, so an outage isn't mistaken for the end of a reaction.

  4. 04

    Ingest every sensor without losing a row

    Pyrometer files are tailed every 2 seconds, with columns matched by device from the header, never by position. The file offset is committed in the same database transaction as each 500-row batch, so a crash can neither skip nor duplicate readings. Lab chemistry is replicated every minute from a watermark, and historian tags are harvested minute by minute, with up to 24 hours of backfill after an outage.

  5. 05

    Infer lineage where no IDs exist

    No shared key links a casting to its treatment, its furnace or its blast-furnace tap. For each hop, the parent must come before the child within a time window, and each candidate is scored on timing and on chemistry: elements the next step doesn't change should match, measured against normal production spread. Chemistry counts slightly more than timing, links backed by timing alone are capped, and weak matches are reported as unlinked rather than guessed.

  6. 06

    One container on an edge GPU

    Everything ships as one Docker image on a GPU server at the plant: a React 19 front end, a Django REST API, and six supervised daemons for cameras, sensors, lab data, the historian and the shop-floor display boards. PyTorch is built for the Blackwell GPU. The camera daemon is the only writer of a shared cache, updated by writing a temp file and renaming it, which the web workers read.

Results

461
backend test functions, behind a 70% coverage floor in CI
150
of the repo's 157 commits are mine, including every vision and traceability module

Decisions

  • A model for the ladle, thresholds for the flash

    A ladle changes position, size and angle, which is what a learned detector is for. The flash is just bright, colourless light, so masks and thresholds find it faster, explain themselves, and need no labelled examples of a reaction.

  • Debounce everything in time

    Every decision waits for agreement across frames or seconds rather than trusting one reading. On a shop floor full of sparks, steam and passing cranes, single frames lie.

  • Commit the offset with the data

    Storing how far a file has been read in the same transaction as the rows read from it makes ingestion exactly-once without any extra bookkeeping.

  • Score links and admit uncertainty

    A traceability link that is wrong is worse than one that is missing. Each inferred link carries a confidence, and anything below the threshold says unlinked.