Giter VIP home page Giter VIP logo

rubiks-cube-tracker's Introduction

rubiks-cube-tracker

Analyze an image, directory of images, or video feed to locate a rubiks cube. The RGB values for each square will be printed to STDOUT.

This works for 2x2x2, 3x3x3, 4x4x4, 5x5x5, and 6x6x6 cubes. 6x6x6 is the largest cube I have test with but 7x7x7 and larger should also work if all of the squares are the same size.

If you are using the --webcam option a solution will be displayed on the screen for 2x2x2, 3x3x3 and 4x4x4 cubes. I have a solver for 5x5x5 but it takes about a minute to compute the solution and the solutions tend to be 90+ steps so this doesn't work very well for displaying on camera.

Install

$ sudo pip install git+https://github.com/dwalton76/rubiks-cube-tracker.git

Installing rubiks-color-resolver

Follow the instructions at https://github.com/dwalton76/rubiks-color-resolver to install the rubiks-color-resolver library

Installing solvers

Follow the instructions at https://github.com/dwalton76/rubiks-cube-NxNxN-solver to install a solver for 2x2x2, 3x3x3, 4x4x4, 5x5x5, 6x6x6, and 7x7x7 cubes

How To Use

Web Camera

$ rubiks-cube-tracker.py --webcam 0
  • --webcam 0 means use /dev/video0, --webcam 1 means use /dev/video1, etc
  • Press the SPACEBAR to scan a side
  • You MUST scan the sides in F R B L U D order. Once you've scanned L you want to put F back in front and then flip forward one time to scan U, this way U is oriented correctly. To go from U to D just flip forward two times. Once you've scanned D, D will be facing the camera, U will be facing you and F will be on top.
  • Flip the cube so that U is on top and F is facing you, then follow the solve steps on the screen.
  • Press "r" to reset

Single File

Analyze a single image. This is only used for debugging and will pop up images at various stages of locating the squares.

$ rubiks-cube-tracker.py --filename test-data/3x3x3-random-01/rubiks-side-B.png

Directory of Files

Analyze a directory of images where the files are named rubiks-side-U.png, rubiks-side-L.png, etc

$ rubiks-cube-tracker.py --directory test-data/3x3x3-random-01/

rubiks-cube-tracker's People

Contributors

dwalton76 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rubiks-cube-tracker's Issues

run problem

hi
i am noob i had run your program
for my school project and run pretty well
but reinstall raspberry and i install everything
without errors by instructions left.
and now when i start the program and when it see rubik's cube
show me some errors like this
pi@raspberrypi:~ $ rubiks-cube-tracker.py --webcam 0 Traceback (most recent call last): File "/usr/local/bin/rubiks-cube-tracker.py", line 49, in <module> rvid.analyze_webcam() File "/usr/local/lib/python2.7/dist-packages/rubikscubetracker/__init__.py", line 1711, in analyze_webcam if self.analyze(webcam=True): File "/usr/local/lib/python2.7/dist-packages/rubikscubetracker/__init__.py", line 1417, in analyze missing = self.find_missing_squares(missing_count) File "/usr/local/lib/python2.7/dist-packages/rubikscubetracker/__init__.py", line 1202, in find_missing_squares self.set_contour_row_col_index(con) File "/usr/local/lib/python2.7/dist-packages/rubikscubetracker/__init__.py", line 979, in set_contour_row_col_index row_size = round(cube_height / float(self.median_square_width + self.black_border_width)) ZeroDivisionError: float division by zero pi@raspberrypi:~ $ rubiks-cube-tracker.py --webcam 0 Traceback (most recent call last): File "/usr/local/bin/rubiks-cube-tracker.py", line 49, in <module> rvid.analyze_webcam() File "/usr/local/lib/python2.7/dist-packages/rubikscubetracker/__init__.py", line 1711, in analyze_webcam if self.analyze(webcam=True): File "/usr/local/lib/python2.7/dist-packages/rubikscubetracker/__init__.py", line 1407, in analyze self.get_black_border_width() File "/usr/local/lib/python2.7/dist-packages/rubikscubetracker/__init__.py", line 1050, in get_black_border_width "black_border_width %s, median_square_width %s" % (self.black_border_width, self.median_square_width) AssertionError: black_border_width 23, median_square_width 15

Raspberry pi camera

Hi, i want to ask you if it's s possible to use raspberry pi camera instead a webcam. Sorry for making this an issue and hope you will reply to this. Thanks!

Isn't working after 2019 update

Hello,
I just updated the version of this project (last update was in april 2018) and do this command:
rubiks-cube-tracker.py --directory /home/pi/cubescan
But give me this error:

2019-04-25 09:10:20,990 init.py INFO: Analyze /home/pi/cubescan/rubiks-side-U.png
Traceback (most recent call last):
File "/usr/local/bin/rubiks-cube-tracker.py", line 74, in
rimg.analyze_file(filename, cube_size)
File "/usr/local/lib/python2.7/dist-packages/rubikscubetracker/init.py", line 1555, in analyze_file
return self.analyze(webcam=False, cube_size=cube_size)
File "/usr/local/lib/python2.7/dist-packages/rubikscubetracker/init.py", line 1407, in analyze
self.get_black_border_width()
File "/usr/local/lib/python2.7/dist-packages/rubikscubetracker/init.py", line 1050, in get_black_border_width
"black_border_width %s, median_square_width %s" % (self.black_border_width, self.median_square_width)
AssertionError: black_border_width 60, median_square_width 21
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1545, in call
return self.func(*args)
File "window.py", line 42, in first
cube3.analizer()
File "/home/pi/cube3.py", line 724, in analizer
output1 = check_output(cmd1, shell=True)
File "/usr/lib/python2.7/subprocess.py", line 219, in check_output
raise CalledProcessError(retcode, cmd, output=output)
CalledProcessError: Command 'rubiks-cube-tracker.py --directory /home/pi/cubescan' returned non-zero exit status 1

I tested the same image in the previous update and worked perfect. I need to do this comand instead of -webcam because this is the way i implemented it in my software (I work to a robot that can solve the 3x3x3 cube). Here is my image:

rubiks-side-U

If you can help me with that or maybe just give me the previous version and how to intall it because i'm new to linux (use the raspberry pi3 now - also for the robot project).#

THANKS in advance,
Steven

AttributeError: 'RubiksImage' object has no attribute 'get_black_border_width'

I'm having a nightmare trying to get my EV3/BrickPi3 Rubik's cube solver robot to work after having to re-install the software from scratch (SD card threw in the towel and no back-up image!)

Running BricKuber.py the message I was getting yesterday was as follows:

Taking pictures of each face, and determining cube configuration.
START: Read Face Colors: top
Picture taken
Failed in processing image: 2022-10-04 20:11:36,396            __init__.py     INFO: Analyze /tmp/BricKuber_top_face.jpg
Traceback (most recent call last):
  File "/usr/local/bin/rubiks-cube-tracker.py", line 56, in <module>
    rimg.analyze_file(args.filename)
  File "/usr/local/lib/python3.7/dist-packages/rubikscubetracker/__init__.py", line 1685, in analyze_file
    return self.analyze(webcam=False, cube_size=cube_size)
  File "/usr/local/lib/python3.7/dist-packages/rubikscubetracker/__init__.py", line 1531, in analyze
    self.get_black_border_width(webcam)
File "/usr/local/lib/python3.7/dist-packages/rubikscubetracker/__init__.py", line 1134, in 
get_black_border_width
         ), f"black_border_width  {self.black_border_width},  median_square_width  {self.median_square_width}"
 AssertionError: black_border_width 94,  median_square_width 39

which to my untutored eye seemed to be saying that the black border was wider than the detected square.

I left it at that for the rest of the day and came back to the problem this evening. I printed out the whole of 'init.py' in an attempt to trace the flow through the code. Much to my surprise, when I ran BricKuber.py again I got a different error:

Taking pictures of each face, and determining cube configuration.
START: Read Face Colors: top
Picture taken
Failed in processing image: 2022-10-04 20:11:36,396            __init__.py     INFO: Analyze /tmp/BricKuber_top_face.jpg
Traceback (most recent call last):
  File "/usr/local/bin/rubiks-cube-tracker.py", line 56, in <module>
    rimg.analyze_file(args.filename)
  File "/usr/local/lib/python3.7/dist-packages/rubikscubetracker/__init__.py", line 1685, in analyze_file
    return self.analyze(webcam=False, cube_size=cube_size)
  File "/usr/local/lib/python3.7/dist-packages/rubikscubetracker/__init__.py", line 1531, in analyze
    self.get_black_border_width(webcam)
AttributeError: 'RubiksImage' object has no attribute 'get_black_border_width'

As far as I'm aware I haven't altered the code in any way nor reinstalled any packages but the Class RubiksImage has no attribute 'get_black_border_width'

Please can you throw any light on this puzzle?

confusing between red and orange

The cube scanning seems to be confusing between red and orange for me. I have tried Pi Camera v1.3 as well as v2.0. I have also tried multiple cubes and played around with many settings (AWB gains, contrast, mode etc), but it still gets confused between red and orange on alternate squares. See the attached file - which is the output from the color-resolver program.

rubiks-color-resolver.html.zip

Typo?

Is line 1307 in __init__.py supposed to be elif con.row_index == row_index + 1: instead of elif con.row_index == row_index - 1:?

This photo fails an assert

This photo fails an assert . Any idea why? All other faces are good to go.

pi@raspberrypi:~/brickuber $ rubiks-cube-tracker.py --filename ./BricKuber_back_face.jpg
2020-03-24 15:02:16,739            __init__.py     INFO: Analyze ./BricKuber_back_face.jpg
Traceback (most recent call last):
  File "/usr/local/bin/rubiks-cube-tracker.py", line 65, in <module>
    rimg.analyze_file(args.filename)
  File "/usr/local/lib/python2.7/dist-packages/rubikscubetracker/__init__.py", line 1832, in analyze_file
    return self.analyze(webcam=False, cube_size=cube_size)
  File "/usr/local/lib/python2.7/dist-packages/rubikscubetracker/__init__.py", line 1669, in analyze
    self.get_black_border_width(webcam)
  File "/usr/local/lib/python2.7/dist-packages/rubikscubetracker/__init__.py", line 1220, in get_black_border_width     
    % (self.black_border_width, self.median_square_width)
AssertionError: black_border_width 75, median_square_width 33

BricKuber_back_face

Webcam issues

Hi dwalton!

I was trying your codes :) but I got some errors with the cube's tracker, looks like it is not getting access to the webcam? here the error log...

> Traceback (most recent call last):
>   File "rubiks-cube-tracker.py", line 48, in <module>
>     rvid.analyze_webcam()
>   File "/Users/Manuel/miniconda2/lib/python2.7/site-packages/rubikscubetracker/__init__.py", line 1632, in analyze_webcam
>     if self.analyze(webcam=True):
>   File "/Users/Manuel/miniconda2/lib/python2.7/site-packages/rubikscubetracker/__init__.py", line 1261, in analyze
>     (_, contours, hierarchy) = cv2.findContours(dilated.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
> ValueError: need more than 2 values to unpack
> Cleaned up camera.

Any idea? Thanks!
Cheers,

BTW, very nice blog ;)

brickuber_lib.py modified for RaspiOS Bullseye with libcamera-still

Hi Daniel,

Not sure if anyone will be interested but I've modified brickuber_lib.py for use under RaspiOS Bullseye.

With the advent of Bullseye, raspistill was removed from the repository and the use of libcamera-still was mandated. It turned out to be not very difficult to implement this. There were a couple of gotchas but I had a new install of Bullseye with all the software up and running in a little under a day of my time (part-time).

Later: this issue is slightly complicated as, hidden in the small print in the documentation for the camera, it says that libcamera is only mandated if you’re using the 64-bit version of Bullseye. If using the 32-bit version, the revert to legacy camera stack is allowed and raspistill is available from the repo. I had opted for the 64-bit version so was constrained.

In the process I changed all the:

if(cmd.find("U") != -1):

instances to that recommended by the Python3 documentation i.e.

if("U" in cmd):

Python Standard Library states:

Note The find() method should be used only if you need to know the position of sub. 
To check if sub is a substring or not, use the in operator:
>>>
>>> 'Py' in 'Python'
True

There are a couple of additional lines to add to /boot/config.txt

dtoverlay=imx219 if you're using a Raspberry Pi Camera V2.x
camera_autodetect=1
dtoverlay=vc4-kms-v3d

The latter 2 are added when you run raspi-config and configure for camera but the imx219 is needed for V2.x cameras.

The code to use the libcamera-still program is:

 subprocess.run(['libcamera-still', '--width=300', '--height=300', '-v', 
'0', '-n', '-t', '1', '--sharpness', '-100', '-o', filename])

which replaces the original line using raspistill.

I have also hacked together a cube randomiser. It is pretty crude and would certainly not satisfy the WCA competition rules but it saves me juggling with a cube. It uses the BricKuber robot and brickuber_lib.py to make the moves. Unlike the WCA code it disallows successive moves on the same face. A minor point but one which offended my OCD. :-)

I can upload the modified brickuber_lib.py and Scrambler.py if you're interested.

A slight niggle: running Bullseye on my Pi3B is unstable and the system sometimes hangs. The only way to recover is to cycle power. I hold my breath each time I'm forced to do that.

BTW I reinstated all the original motor speed values to those in the original code and the cube stays in the cradle. That speeded up the overall solve time somewhat too.

Another oddity: If you present the system with a solved cube, it still comes up with a few moves which do ultimately produce a solved cube. Seems like there is a test for solved missing somewhere in the code?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.