To look for color blobs you supply the threshold() function with a color, an RGB value, and a "distance" value (how close a pixel is to the specified color). Behind the scenes this is based on LAB colorspace and euclidean distance between colors.
bin = image.threshold([(160, 210, 255)], 20)
Note the dice are actually bluish-white |
# image closing
bin.dilate(5)
bin.erode(2)
# Find white dice dbin = image.threshold([(160, 210, 255)], 20) # image closing dbin.dilate(5) dbin.erode(2) # find dice dice = dbin.find_blobs() # Draw rectangles around detected dice for d in dice: image.draw_rectangle(d[0:4])
Now to find the pips. Same process all over again, only this time, the color is sort of a bluish black. I had to experiment with the color and the dilate/erode calls to get it working.
# Find pips in dice blobs binary = image.threshold([(40, 60, 110)], 25) # Image closing binary.dilate(4) binary.erode(1) # Detect blobs in image blobs = binary.find_blobs()
Finally, go through all the pips and count the ones that are inside the bounds of the white blobs, the dice. Then display the numbers in the corners of the dice and the total at the bottom. The find_blobs() function returns a list of (x, y, width, height) for each blob.
# Count pips pips = 0 for d in dice: dr = (d[0], d[1], d[0]+d[2], d[1]+d[3]) subpips = 0 for p in blobs: pr = (p[0], p[1], p[0]+p[2], p[1]+p[3]) if pr[0] > dr[0] and pr[2] < dr[2] and pr[1] > dr[1] and pr[3] < dr[3]: subpips += 1 image.draw_rectangle(p[0:4]) image.draw_string(d[0]-8, d[1]-8, str(subpips), (50, 255, 50)) pips += subpips image.draw_string(55, 120, "total="+str(pips), (50, 255, 50))
And that's all there is. It works pretty ok for having spent very little time on it. There's some room for improvement. More tuning might help. Better lighting. Real dice. Also, when you roll a 6, it merges adjacent pips.
That's because the firmware normally ignores blobs that are too small. Small blobs next to each other can only be detected if you dilate() enough to make them bigger than the threshold, but that merges them because they're close together. We just have to lower the blob size threshold, I think.
Also, we might get more accurate detection by refactoring threshold() to take separate parameters for color and lightness thresholds.
Meanwhile, OpenMV Cam's Kickstarter ends Feb 25. If you want one click here.