Turn in one line

One ordinary camera runs a restaurant floor. Turn sees which table needs someone, sends the right server, clears the task when that server's printed badge shows up at the table, and gives guests a live wait estimate on their phone. No face recognition, and no frame is ever saved.

Results at a glance

What we measured, on real restaurant footage Result
Is each table occupied? YOLOX-S vs hand labels 83% of zones right, vs 45% for NanoDet. Never called an empty seat occupied
OpenCV 5's new dnn engine vs the classic one 1.5x faster on YOLOX-S, 2.6x faster on NanoDet, identical detections
Staff badge reading (ArUco) on 40 real frames 100% flat at every size, 0 false badges. Turned 60° or blurred needs about 56 px
End to end on real footage Seated, Not greeted, badge clears it, HELP card routed to that server, cleared again. No script
Camera view 22 fps with every face blurred (it was 2.5 fps before we split detection onto its own thread)
Tests 24 automated tests

All on a Ryzen 7 3700X desktop CPU, no GPU. The full report, with every number and every failure case, is linked in "Try it out".

Inspiration

Shire, a YC Fall 2026 startup, turns a restaurant's CCTV into a live floor map for the host. We loved it, and we kept seeing who it leaves out.

  • The guest at the door still gets a guess for the wait.
  • It's built around a CCTV system and a POS integration, which a small restaurant doesn't have.
  • It labels waiters from video, and servers hate being watched like that.

So we built Shire's floor, plus answers to those gaps. Turn needs one camera. Staff are known by a printed badge, never by their face. Guests can flip a card on the table instead of waving. And guests finally see how long they'll wait.

What it does

For servers

  • Alerts route themselves: Not greeted, Check in, Help requested, Waiting on check, Needs bussing. Each goes to the table's server, or to whoever has the lightest load. They go amber, then red when overdue.
  • A badge visit clears the alert. Staff wear a printed ArUco marker. When the camera sees it at the table, the alert clears and that server owns the table. Nobody taps a screen.
  • Guests ask without waving: they flip a HELP or CHECK card, and the camera reads it.

For the host (everything in Shire's host view)

  • Floor map: every table in its place, coloured Open, Seated, Needs attention, Dirty or Blocked, with the server's initials.
  • Server rotation: each server's tables, and who should get the next party.
  • Waitlist and reservations:
    • walk-ins with notes like "birthday"
    • a suggested table and server for every party
    • a quoted wait and one-tap Seat
    • an Arrived button for reservations
    • double-seating blocked
  • Block a table that's broken, and Turn leaves it out of seating and wait times.

For the owner

  • Shift Flow:
    • covers, tables turned, turn time and the peak
    • "Do this next" actions worked out from the live floor
    • dirty seats shown in dollars at your average check
  • Insights are per table, never per person. Server load counts tables, not speed.

For guests (Shire has nothing here)

  • A live wait estimate on their phone, served from Amazon S3, so it works from anywhere. Turn simulates seating everyone ahead of them at the soonest table that fits.

How we built it

  • OpenCV 5.0.0, from Java 25:
    • dnn runs YOLOX-S and NanoDet from the OpenCV model zoo. We ported their pre and post processing from the zoo's Python demos to Java, and we use OpenCV 5's new graph engine after measuring it against the classic one.
    • objdetect: ArucoDetector reads badges and table cards, and FaceDetectorYN (YuNet) finds faces to blur.
    • videoio reads a webcam, a clip, or an RTSP stream from existing CCTV.
  • From pixels to tables:
    • A person counts for the table whose zone holds the centre of their box.
    • A badge marks only the nearest person as staff, so a server leaning over a guest doesn't turn the guest into staff.
    • Detection runs on its own thread, so the view stays smooth.
  • Spring Boot 4.1 runs the floor engine: table states, alert routing, rotation, waitlist, reservations and the wait simulation.
  • AWS:
    • S3 serves the guest page and a wait board updated every 10 s.
    • A least-privilege IAM key can only write two folders.
    • CloudFormation launches a hosted demo on EC2 with no SSH (Session Manager only), a health-check gate and an auto-recovery alarm.
    • Video never leaves the restaurant. Only counts and estimates go to the cloud.
  • Front end: plain HTML, CSS and JS with light and dark themes, designed by Basu.

Challenges we ran into

  • Background subtraction forgets people who sit still. MOG2 marked a seated guest as gone after about 4 seconds, so we switched to a person detector.
  • "People per frame" was the wrong metric. It made NanoDet look fine. When we scored the thing Turn actually needs, "is this table occupied", against hand labels, NanoDet got 45% and YOLOX-S 83%. That's why YOLOX-S is the default.
  • A diner behind the sushi counter is still missed. YOLOX found her in 6% of frames. It's our main failure case; the fix is mounting the camera higher.
  • Badges have to be big enough. We pasted badges into real frames at every size and angle. A flat badge reads at 24 px; a turned or moving one needs about 56 px, roughly a 10 to 12 cm card at 3 m.
  • OpenCV 5 in Java moved things:
    • the HOG detector is gone
    • perspective transforms live in a new geometry module
    • dnn outputs come back in a different order than the Python demo
  • The first camera view was a slideshow, until we split detection from drawing.
  • Our first wait estimate was wrong: 4 minutes for a party of 4 while a 6-top sat empty. We rebuilt it as a seating simulation, with a test for that exact case.

Accomplishments that we're proud of

  • The whole badge loop works on real footage, decided by OpenCV 5 alone:
    1. Booth 2 is seated from the video.
    2. Not greeted fires.
    3. A staff badge clears it.
    4. The guest's HELP card goes to that same server.
    5. It clears on the next visit.
  • Every face in the view is blurred, including a diner the body detector missed, because YuNet found her face.
  • Guests get a real wait estimate on their phone, and no names or images leave the restaurant.
  • We measured everything and wrote down where it fails.

What we learned

  • Measure what the product needs, not what's easy to count. The occupancy test is what showed us the hidden diner.
  • Privacy choices made the product better. Tracking tables instead of people made Turn simpler, fairer to staff and easier to explain to guests.
  • Keep the cloud for what only the cloud can do. Video stays in the restaurant; AWS serves guests and hosts the demo.

Questions regarding the product:

  • Where does the camera read the badge? OpenCV 5's ArucoDetector runs on every detection frame, next to YOLOX. Each badge goes to the nearest person and the table zone it's in. A badge at a seated table is a visit: the alerts clear and that server owns the table.
  • What if a server forgets their badge? The alert stays up, which is the safe direction. Nothing gets marked done that wasn't. A spare badge lives at the host stand.
  • How big does a badge have to be? About 56 px in the image, which we measured. That's roughly a 10 to 12 cm lanyard card for a camera about 3 m away.
  • Can someone fake a badge? With a printout, yes. It only clears an alert the host can see. It's a convenience signal, not security.
  • Why not face recognition? It's a surveillance risk and regulated in many places. A badge is opt-in and comes off on a break.
  • Can guests on the restaurant Wi-Fi see the camera? Not with the staff PIN set. Guests only get the wait page. Our public demo has no PIN so judges can try it.
  • Does it work with our existing CCTV? Yes, through an RTSP stream.
  • How long is setup? About 10 minutes a camera. Take one frame, write down each table's rectangle in the config, and print the badges and cards.
  • What hardware? Everything above ran on a Ryzen 7 3700X desktop CPU with no GPU, the kind of PC a back office can have. On weaker PCs, NanoDet runs in 37 ms a frame.
  • What does it cost? About $2.60 a month in S3 writes, plus about $7.60 a month for the hosted demo server.
  • Why no menu pricing like Shire? That needs POS data, and not needing a POS is the point.

Responsible use

  • No face recognition. Faces are only found so they can be blurred.
  • Staff are known by a badge they choose to wear and can take off.
  • No frames stored or sent. No per-person scores.
  • An optional staff PIN keeps the floor and camera view away from guests on the Wi-Fi.
  • All footage is free-licence stock. No real customers' CCTV was used.

What's next for Turn

  • Film printed badges on real servers in a real restaurant, then run a pilot.
  • More than one camera per restaurant.
  • Draw table zones in the browser.
  • Check the wait estimate against real waits.
  • Text guests when their table is ready.

Built With

Share this project:

Updates

Submission history