← Back to portfolio
Case Study · 11 / 17
Computer Vision · Full-Stack · 2025

A speedcube timer
that can see the cube.

Rubiklog is a Rubik's Cube solve tracker — a space-bar timer, real solving statistics, and a webcam scanner that reads the physical cube's state into a scramble. Django REST on the back, React on the front, OpenCV in between.

Role
Solo — full-stack & CV
Discipline
Web app + color detection
Stack
Django · React · Postgres · OpenCV · TF
Status
Open-source, Docker-ready
Fig. 11 · hold, release, solve
11
Ao5 and Ao12 are the numbers that actually tell you if you're improving.
§ 01 — The problem

Timing is easy. Logging honestly is the useful part.

Every speedcuber has a timer. What separates a toy from a training tool is what happens around the timer: a precise hold-to-ready start, a scramble you can trust, and rolling averages — Ao5, Ao12 — that show whether you're actually getting faster or just remembering your best days.

Rubiklog set out to be the training tool, and then added the ambitious bit: let the webcam read the real cube so entering a scrambled state doesn't mean typing 54 stickers by hand.

A timer measures a solve. A log measures a solver.

§ 02 — Constraints

What the app had to nail.

§ 03 — Architecture

React front, Django core, CV on the side.

A React client owns the timer and stats display; a Django REST backend with Postgres persists solves; an OpenCV pipeline handles cube-state detection; and a TensorFlow model experiments with predicting solve times.

01 — Timer
React client
Space-bar timer, hold-to-ready, scramble generator, dark mode.
02 — Scan
OpenCV
Webcam colour normalisation + recognition reads the cube's face state.
03 — Store
Django REST
Solves persisted to Postgres via DRF serializers, documented with Swagger.
04 — Predict
TensorFlow
A model service explores solve-time prediction from history.

The whole thing is containerised — docker-compose up brings the app up — and configured for Render deploys, so the CV dependencies don't turn setup into a yak-shave.

§ 04 — What broke first

Colour is a lie the lighting tells.

The cube scanner ran straight into the classic computer-vision headache: a cube's red under warm light and its orange under cool light can land on nearly the same raw pixel value. Naive colour thresholds misread faces the moment the lighting changed, which for a scanner is a fatal flaw — one wrong sticker invalidates the whole scramble.

That's exactly why manual entry stayed the reliable default and colour normalisation became the focus of the vision work — reducing the scan to relative colour relationships rather than absolute values.

Ao5 / Ao12
Rolling averages tracked per session
54
Stickers the scanner reads to reconstruct a state
1
Command to stand the whole stack up in Docker
§ 05 — Design

Out of the way while you solve.

The timer screen is intentionally quiet — a big time, a scramble, and nothing competing for attention mid-solve, with a dark mode for the late-night practice sessions the audience actually lives in. Statistics and history sit one step away, so the loop of solve-log-check-average stays fast.

§ 06 — What I'd do differently

Three things, next time.