Reading dice after they're tossed

Thread Starter

cmartinez

Joined Jan 17, 2007
8,220
You really put me into a fit with this one, Martinez. I'm not sure why; honestly the whole concept just seemed a little Rube Goldberg to me, but I suppose I've been itching for a reason to try some computer vision stuff and you gave me one. So for a few days I've been playing with this a little here, a little there.

Most of my programming of late has been Python; that's what's fresh in my head so that's what I wanted to use. I explored many avenues for image processing in Python (including opencv as Mr Chips linked); all of them turned me off in one way or another. Too complex, too much overkill, too little documentation, etc. So I went looking for the best language for simple image processing. I wanted something stupidly simple, as you alluded to maybe being a little programmatically averse, and whatever it would be, would be something I've never seen before. Seemed like anything that was good at image processing was hard to learn, and anything easy to learn had little or no native imaging capability. Then, in my quest for "simple image processing" I stumbled upon "Processing" - it's a java-based environment targeted at retards, noobs, and children (I meet all the criteria). I read about it in the past in "Making Things Talk" when playing with Arduino. I never downloaded it, but the book made it seem as if it were just some limited PC version of the arduino software. The IDEs look the same and in both the project is called a "sketch." Anyway, long story short, I was wrong. Processing is actually pretty badass. Stupid simple, good with images, plenty of examples come in the standard distribution. I never once had to google "how to _______ in Processing" - I was able to piecemeal my code together from the provided examples and fill in the gaps with intuition. It's less that 200MB fully extracted and requires no invasive installer. Very light on resources; I actually downloaded it to my little 7" winbook tablet and programmed everything you'll see here on that tablet (screenshots are from the tablet too, and I'm typing this on the tablet).

Here it is, without further ado...

View attachment 82820

View attachment 82821

code:
Code:
PImage img;  // Declare variable "a" of type PImage
int blackpxcount =0;
int notblackpxcount =0;
int hasran =0;
int pixelsperdie = 187;
int dots = 0;
void setup() {
  img = loadImage("dice2.jpg");  // Load the image into the program
  size(img.width, img.height); // scale the window to match the image
  image(img, 0, 0);// Display the image at its actual size at point (0,0)
}

void draw() {// begin main script...

  if (hasran == 0){ //run only once, not continuously
  int begintime =millis(); // set the stopwatch, and we're off..
    for (int y = 0; y < img.height-1; y++) { //for each row of pixels...
      for (int x = 0; x < img.width-1; x++){ //...and for each pixel in that row...
        color c = img.get(x, y);// read the color of the pixel, and...
        if (c < -10000000) {// if that pixel color is below a threshold, ...
          blackpxcount +=1;// we consider it black, and count it.
        }else{
          notblackpxcount +=1;
        }
      }
    }
    //determine how many dots there are, based on how many black pixels we counted:
    dots = blackpxcount/pixelsperdie;
    // wrap it up and report our findings...
    int runtime = millis()-begintime;
    println("DONE! execution time: ", runtime, "mS.");
    println("total pixels: ", (notblackpxcount+blackpxcount), ", black pixels: ", blackpxcount,", not black pixels: ", notblackpxcount);
    println("number of dots showing: ", dots);
    //TO DO: ADD SOME CODE HERE TO OVERLAY THE NUMBER OF DOTS ONTO THE DICE IMAGE IN LARGE FONT (INSTEAD OF JUST THE DEBUG WINDOW)
    hasran = 1; //set this high so that the script does not run again, until...
  }
  if (mousePressed) {// ...we click the mouse.
    blackpxcount = 0;
    notblackpxcount = 0;
    hasran =0;
    //TO DO: ADD SOME CODE HERE TO ADVANCE TO THE NEXT FILE IN THE FOLDER, IF IMAGES ARE TO BE TRANSFERRED
    //IN FROM ANOTHER SOURCE. -OR- ADD FUNTIONALITY FOR THE SCRIPT TO ACCESS THE TABLET'S ONBOARD CAM DIRECTLY
    //AND IMPORT A NEW IMAGE UPON CLICK/TAP
  }
  //TO DO: ADD A "LEARNING" FUNCTION TO CALIBRATE "pixelsperdie" PARAMETER IF (WHEN) DOT COUNT
  //BECOMES INCORRECT DUE TO DIFFERENT DICE OR DIFFERENT CAMERA POSITION OR OTHER FACTORS
}
I realize that this method works artificially well, using static images. No matter how many times I copy and paste those dice, they do no change, and I will always get the right answer. Real dice are bound to be a little more tricky, but I think that if conditions are controlled, the effect will be negligible.

I picture a trash bin with a tablet fixed in the bottom and a frosted glass plate on top. Think of a clear glass with wet (or maybe oiled) white paper on it. it is translucent and the camera can't see anything past the surface. Only what is sitting directly on the glass(or on the paper on the glass), and the glass is always at the same focal point, and light conditions inside the bin (provided by the tablet) should remain constant. I am confident that using 145 lines of code with an overkill computer vision plugin will not give any better end result than using these 39 lines of Processing caode with trash bin setup and tuning the threshold for die-dot-pixel-color and number-of-pixels-per-die-dot to your specific camera and trash bin depth.
A very good morning to you Strantor.

When I posted this problem, I knew it was going to give an earworm to some... although maybe the word brainworm would be a better term ;)...

Yes, there's a reason why at first I tried to avoid using image recognition for this little project. The main one not being the hardware that would be needed, but rather the complexity of the code... and after reading your example, I realize that maybe I've been over-afraid of this... or maybe not...

Your code seems to assume that the only thing present in the image is one dice... and a perfectly squared and aligned one, for that matter. What I want to do is read 5 dice of two different colors, and when you take into account that they would land rotated practically all of the time, and that there might be imperfections like scratches, or moisture, or dirt in the surface onto which they've landed... and that they could land on top of one another, or leaning against the sides of the box, or against each other... or maybe even perfectly flat on the surface but so close to each other that their faces could be touching.... well, then you realize that the problem is a little more complicated than it seems. Especially if the algorithm involved works by line-scanning the image, and then reconstructing each face of each dice... I can't think of any other way of approaching the logic...
I foresee that if all those factors were to be included into the code, it would grow in size, if not exponentially, at least geometrically.

But I'm not averse to programming (I don't remember saying or implying that, I actually love to code) and I'm not completely allergic to the idea of image recognition... I might be a little stubborn, but I'm never obstinate... I was just trying to see if I could find a method other than optical to solve the problem... but it seems that optical is the simplest way to solve it, at least when one considers that it has zero-invasiveness for the players and for the dice themselves. And maybe the only way of getting a good feel on how hard to solve, and how fast it will perform, is to do what you just did... that is by dipping my brains into the problem and write some code already...

Thanks for sharing that link on Processing... it's been an eye-opener.
 

strantor

Joined Oct 3, 2010
6,782
Cool beans. One note, my program does not scan only one die at a time perfectly aligned. If you review my screen shots you will see that in one of them i am scanning 6 dice and in the other I'm scanning 26 dice. In both, the program accurately detects the total dots of all 6 or 26 dots.

It could be easily modified to scan for dice with red dots, green dots, or any color dots, or a combination of dice; some dice with all green dots, some dice with all red dots, some with all blue, etc. Actually it occurs to me that using dice with a different color for each number could provide inherent error detection/correction. If you have a handful of dice and they all have blue dots for the "4" side, green dots for the "3" side, and red dots for the "6" side (and so on) and the program returns a value of 7 green dots counted, it can catch that as an error and recalculate.

If i get time, i will revisit this and make it recognize dots of other colors and experiment with it processing actual images of dice taken by my tablet camera against the opaque glass as i described. As of now i have no dice or glass plate in my home or i would have already tried it last night.
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,220
Cool beans. One note, my program does not scan only one die at a time perfectly aligned. If you review my screen shots you will see that in one of them i am scanning 6 dice and in the other I'm scanning 26 dice. In both, the program accurately detects the total dots of all 6 or 26 dots.

It could be easily modified to scan for dice with red dots, green dots, or any color dots, or a combination of dice; some dice with all green dots, some dice with all red dots, some with all blue, etc. Actually it occurs to me that using dice with a different color for each number could provide inherent error detection/correction. If you have a handful of dice and they all have blue dots for the "4" side, green dots for the "3" side, and red dots for the "6" side (and so on) and the program returns a value of 7 green dots counted, it can catch that as an error and recalculate.

If i get time, i will revisit this and make it recognize dots of other colors and experiment with it processing actual images of dice taken by my tablet camera against the opaque glass as i described. As of now i have no dice or glass plate in my home or i would have already tried it last night.
Thanks... I'll have to read your code more carefully... another thing, dice have different color faces, although the dots too are different colors... there's three red dice with white dots, and two white dice with black dots... but I doubt it makes much difference anyway.
Could you test your program again by randomly rotating the dice images? just curious...
 

strantor

Joined Oct 3, 2010
6,782
Could you test your program again by randomly rotating the dice images? just curious...
sure, but hang on... let me go get a vasectomy first. LOL.

you can LOL at that if you want, i did. But I'm not joking. Ill be at the doctor the rest of the day. Took today and tomorrow off. Should have free time tomorrow.
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,220
sure, but hang on... let me go get a vasectomy first. LOL.

you can LOL at that if you want, i did. But I'm not joking. Ill be at the doctor the rest of the day. Took today and tomorrow off. Should have free time tomorrow.
Good Lord... you've just provoked my first cringe of the day.... OUCH...
Good luck with your... intervention... and may you enjoy the results thoroughly... :D

Seriously now, hope everything goes ok... we'll talk later.
Take care.
 

strantor

Joined Oct 3, 2010
6,782
hey sorry I forgot all about this thread. Did you ever get a solution?
I was reminded of it when I stumbled across Python for android in the the google play store.
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,220
Well, the closest thing to a solution that I've seen is a smartphone app that counts the dots on domino tiles. It's come in quite handy these last few weeks, since my wife's friends love to play, and sometimes hundreds of dots have to be counted.
Other than that, I'm still waiting for an idea on how to identify the dice's position without using optics.
 

Jack OwwO

Joined Jun 18, 2015
6
(if you still searching)
As you already realize, the difficulty of the optical solution will depend on the variability of the environment. But the basic problem with good lighting, only D6 with pips, a fairly vertical view and dice of similar size, it can be done 'quite' easily (with opencv for example).

Without optics, you use an accelerometer, once your dice is stable, you have the orientation of g, therefore the upside and downside face of your dice. But you also need the provide a network interface and a power supply. A lot of possible practical problem already arise, even with the power supply (the easier part), if you use a chargeable battery, you'll need a way to plug your device which is 'cover up' so it won't hinder its rolling, if you use a changeable you have an access problem, and that you dice need to stay well balance,..

Here's an non optical dice :http://dicepl.us/
Here's some open code of dice detection:
in py :https://github.com/andli/dicecounter/
in C++ : https://github.com/chenxiao07/opencv-dice/
 

Jack OwwO

Joined Jun 18, 2015
6
Did you already thought doing it with color sensor, coloring your dice face with 12 (off/def) or 27 different color and using sensors under a glass?
It seem there must be a simple solution somewhere. :d
 

Thread Starter

cmartinez

Joined Jan 17, 2007
8,220
Did you already thought doing it with color sensor, coloring your dice face with 12 (off/def) or 27 different color and using sensors under a glass?
It seem there must be a simple solution somewhere. :d
That is an excellent idea! That way image recognition won't even be necessary, programming would be quite simple and speed would be increased considerably!
Thanks for the suggestion!
 
Top