Open-source project
kkoomen/qbr avatar
kkoomen/qbr

qbr reads your cube through a webcam and prints the moves

A webcam-based 3x3x3 rubik's cube solver written in Python 3 and OpenCV.

662 stars104 forksPythonMIT

At a glance

What is it?
qbr is an MIT licensed Python 3 and OpenCV program that detects a 3x3x3 cube's stickers from a webcam, works out the state, and prints the solution, and its design puts the difficult part in color calibration rather than in the solving algorithm.
Who is it for?
qbr fits a person with a webcam and a cube who wants a solution without a solver app, and it fits a developer who wants to see how colour detection and a solver library are stitched together, since the source is small and readable. It does not fit a blindfolded solver, since you must turn the cube to the camera, and it does not fit a room with poor lighting, which the documentation itself calls out as the condition for reliable detection.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the program actually does with your webcam

qbr, pronounced as Cuber, is a webcam-based 3x3x3 Rubik's cube solver written in Python 3 and OpenCV. The README lists three headline properties: accurate color detection, accurate 3x3x3 cube detection, and a multilingual interface.

The flow is what you would expect from the name. You point a webcam at a face of the cube, the program shows what it thinks it sees, you confirm with a key press, you turn the cube and repeat for all six faces, and then it prints a solution in move notation.

The origin story in the introduction is worth a line, because it sets expectations. The author set out to build a cube-solving robot of their own after seeing professional programmers build machines that solve a cube in five seconds and, since 2016, in one second. He started with images only and eventually switched to a webcam. So the project is the software half of that idea, minus the robot, and it is a desktop program that reads a camera.

The solution itself is not computed by this project. The solving comes from a library listed in the dependencies, so the interesting engineering here is entirely in perception: deciding which sticker is which colour, working out which face you are looking at, and holding six faces in a consistent orientation.

Installing on Linux with a virtual environment

The installation instructions are for Linux and start with two system packages, python3-dev and build-essential, which the project needs in order to build the parts of its dependency stack that ship as compiled wheels for some platforms:

code
$ sudo apt-get install python3-dev build-essential

Then the project itself is cloned and installed into a virtual environment:

code
$ git clone --depth 1 https://github.com/kkoomen/qbr.git
$ cd qbr
$ python3 -m venv env
$ source ./env/bin/activate
$ pip3 install -r requirements.txt

The clone uses --depth 1, so you get the current state without the history, which is the right choice for a program you intend to run rather than study.

The program is then started with:

code
$ ./src/qbr.py

And the usage section makes one instruction emphatic: you must run source ./env/bin/activate every time you want to run the program. That is a real operational detail for a program invoked by path from the source directory, and it is the kind of thing that produces a confusing error for someone who skips it once and then runs the script from a different directory.

The pinned dependencies tell you what does the work

The requirements file is short and fully pinned:

code
kociemba==1.2.1
numpy==1.22.0
opencv-python==4.8.1.78
pillow==10.3.0
pydocstyle==5.1.1
python-i18n==0.3.9

Read in that order, the list maps onto the program almost feature by feature. kociemba is the cube solver, so the actual algorithm for finding the solution lives there and qbr only has to present the cube state to it. opencv-python and numpy are the image processing, which is the webcam preview, the colour detection and the geometry. pillow handles the images the program writes out. python-i18n is the translation layer that produces the multilingual interface, and pydocstyle is a docstring linter, which is a development tool rather than a runtime one and suggests the project keeps its docstrings in check.

The pins are exact, which is a deliberate choice for a program people install with a single command and then forget about. The trade-off is age: numpy 1.22.0 and opencv-python 4.8.1.78 are not current releases, and an exact pin on old versions of numpy is exactly the kind of thing that fails to build on a recent Python. The project is a small repository with a src/ directory, a requirements.txt and an .editorconfig, so there is no lock file with hashes and no matrix of wheels behind these pins.

Four displays and four keys

The interface is described as a webcam window with four distinct regions, and knowing what each one means is the difference between using the program and fighting it.

The first 9-sticker display in the upper left corner is the live preview showing the detected colours. The second 9-sticker display is the snapshot state: pressing SPACE saves what has been detected so far, and you can press it as many times as you like if the detection was wrong. The centre piece colour of the face is used to detect which side is being saved, which is how the program knows the orientation of each face rather than relying on your memory of the order.

The bottom left corner shows the amount of sides scanned, so you can tell whether all six are in before you finish. The bottom right corner shows the full 2D cube state visualisation, which is the thing to look at when the solution comes back wrong, because it tells you which face was misread. The top right corner shows the current interface language.

The keys are SPACE to save the current state, ESC to quit, c to toggle calibrate mode, and l to cycle the interface language. The documentation also explains the ESC behaviour in the solution section: the program checks whether all six sides have been filled in when ESC is pressed, and if so it calculates a solution, otherwise you get an error.

The scanning procedure is strict on purpose

There is a strict way of scanning in the cube, and the README is blunt that the way you rotate the cube while scanning is crucial for the solution to come out right, even though Qbr detects the side automatically.

The procedure has three phases. You start with the green side facing the camera and white on top, green away from you, and scan the green side. You then rotate the cube 90 or minus 90 degrees horizontally, and it does not matter whether you go clockwise or counter-clockwise, and you continue in this way for the green, blue, red and orange sides until you are back at the green side.

You should now be in the same position you started, with green facing the camera and white on top. You rotate the cube forward 90 degrees, which puts green at the bottom and white facing the camera, and you scan the white side. After that you turn the cube back to the starting position, green in front and white on top, rotate it backwards 90 degrees so that green is on top and yellow faces the camera, and you scan the last yellow side.

The reason a strict procedure is needed is that the six faces are stitched together using the centre colours, and if the cube is rotated the wrong way between faces the centres no longer line up and the state you assembled is not a real cube state. The solver would then return a sequence for a cube that does not exist. A program that lets you scan faces in any order has to solve the orientation problem geometrically, and this one does not, it asks for a convention instead.

Calibrate mode is the answer to a bad colour scheme

The default colour scheme contains the most prominent colours for white, yellow, red, orange, blue and green, and if that does not detect your cube properly, calibrate mode exists for that case.

Calibrate mode is entered with c, and it lets Qbr become familiar with your cube's colour scheme by following the on-screen instructions. The README makes a strong claim about the result: if your room has proper lighting, this will give you a 99.9 per cent guarantee that your colours will be detected properly.

The mechanism is straightforward. Rather than mapping pixels to the six canonical colours, the calibration stores what the six colours actually look like under your lighting and on your stickers, which removes both the ambient light shift and the plastic tint of the cube from the problem. If you have scanned wrong, you can go out of calibrate mode by pressing c and back in by pressing c again.

Calibrated settings are saved automatically after a successful calibration and loaded automatically the next time you start Qbr, so the calibration is a one-off per cube and lighting setup rather than a ritual you repeat every session.

The output, the normalise flag, and the alternatives

When all six sides are in, the program prints a starting position, the number of moves and the solution in standard notation:

code
$ ./qbr.py
Starting position:
front: green
top: white

Moves: 20
Solution: U2 R D2 L2 F2 L U2 L F' U L U R2 B2 U' F2 D2 R2 D2 R2

The -n or --normalize parameter adds a human-readable form of the same solution, one numbered instruction per move, such as R becoming "Turn the right side a quarter turn away from you." and F2 becoming "Turn the front face 180 degrees." That is a small feature with a real use, because reading twenty moves of notation is slow for someone who is holding a cube.

The alternatives differ in what they ask of you. The first is to skip the computer vision entirely: type the six faces of colours into a solver library, which is what the kociemba dependency does anyway, and get the same answer in a fraction of a second. The second is the robot, the machine with cameras and motors that solves a cube in five seconds or, since 2016, in one second, which the author cites as the inspiration for the project. The third is a physical solver or a cube with sensors in the pieces.

qbr sits between the first and the second. It is slower than typing and far slower than a robot, but it removes the typing, and it needs nothing but a webcam and a cube.

MIT terms, no releases, and a last push in April

The project is released under the MIT Licence, with the LICENSE file at the repository root, and it is a personal project with a personal origin: the author built it because he wanted to solve his own cubes.

The repository has no GitHub releases at all. Every version is a commit, and the release list in the project metadata is empty, which is a coherent choice for a program you install from a clone with pip, but it does mean there is no version marker to pin and no changelog to read.

The last push was on 2026-04-13, which is more than six months before the present date, so the project is not currently receiving updates and the pins in requirements.txt are the ones a user gets today. That is worth weighing if you plan to extend it, since the colour detection code and the interface are the parts most likely to need attention for a new Python or a new OpenCV.

The repository itself is minimal: an .editorconfig, the LICENSE, the README, the three demo images, the requirements file and a src/ directory. There is no test suite in the tree and no CI configuration listed at the top level, so the code is meant to be read rather than verified by a test run, and a fork that wanted to improve the detection would be starting from a project without a regression harness.

Editorial conclusion

qbr fits a person with a webcam and a cube who wants a solution without a solver app, and it fits a developer who wants to see how colour detection and a solver library are stitched together, since the source is small and readable. It does not fit a blindfolded solver, since you must turn the cube to the camera, and it does not fit a room with poor lighting, which the documentation itself calls out as the condition for reliable detection. Before running it, read the scanning procedure and the calibration mode, and check that the pinned dependencies in requirements.txt install on your Python version, since the pins are old.

Frequently asked questions

How do I install qbr on Linux?

Install python3-dev and build-essential first, then clone the repository, create a virtual environment with python3 -m venv env, activate it with source ./env/bin/activate, and install the dependencies with pip3 install -r requirements.txt. The program is then started with ./src/qbr.py.

What are the key bindings in qbr?

SPACE saves the current detected state, ESC quits, c toggles calibrate mode, and l cycles through the interface languages. The documentation also notes that the program checks whether all six sides are filled in when ESC is pressed before calculating a solution.

What does calibrate mode do and when do I need it?

It lets the program learn your cube's colour scheme, which the documentation says gives a 99.9 per cent guarantee of correct detection if your room has proper lighting. Calibrated settings are saved automatically and loaded the next time you start the program.

Which languages does the qbr interface support?

The README lists English, Hungarian, Deutsch, French, Spanish, Dutch, Simplified Chinese, Traditional Chinese for Taiwan, Arabic and Farsi. English is the default and the language is changed by pressing l to cycle through them.

What does the -n option do in qbr?

The -n or --normalize parameter also outputs the solution in a human-readable format, with numbered instructions such as R being described as turning the right side a quarter turn away from you and F2 as turning the front face 180 degrees.

Official sources

  1. Issues
  2. kkoomen/qbr on GitHub
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/kkoomen-qbr.svg)](https://hysenlabs.com/projects/kkoomen-qbr)

Was this useful?