Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Dice detection using DBSCAN
#1
Hi there,

I'm trying to make dice detection system using a Raspberry with a camera. I want to use the live video feed for this.

Now I'm able to detect the dice, but there is a slight problem.
Eventually there will be multiple dice rolled by a machine. This means it is possible that there will be dice right next to eachother.

The problem is that when I put 2 dice against eachother, the number on the dice will be calculated as if it was one dice. Now I've kinda fixed it by saying there cannot be more then 6 points in a cluster.

But now if I have a 2 on a dice and it's against a 5 for example it still counts as 6. Now i've tried tweaking the eps value, but the distance between the 2 pips on a 2 dice roll are greater than one of the pips from the 2 next to another dice roll. I've added some pictures for you to see. Down here is the code

import cv2
import numpy as np
from picamera2 import Picamera2
from sklearn import cluster

# Setup van de camera
picam2 = Picamera2()
picam2.preview_configuration.main.size = (1920, 1080)
picam2.video_configuration.controls.FrameRate = 25
picam2.preview_configuration.main.format = "RGB888"
picam2.start()

params = cv2.SimpleBlobDetector_Params()

params.filterByInertia = True
params.minInertiaRatio = 0.6

detector = cv2.SimpleBlobDetector_create(params)

def get_blobs(frame):
    frame_blurred = cv2.medianBlur(frame, 7)
    frame_gray = cv2.cvtColor(frame_blurred, cv2.COLOR_BGR2GRAY)
    blobs = detector.detect(frame_gray)
    
    return blobs

def get_dice_from_blobs(blobs):
    
    X = []
    for b in blobs:
        pos = b.pt
        
        if pos!= None:
            X.append(pos)
            
    X = np.asarray(X)
    
    if len(X) > 0:
        
        clustering = cluster.DBSCAN(eps=60, min_samples=1).fit(X)
        
        num_dice = max(clustering.labels_) + 1
        
        dice = []
        
        for i in range(num_dice):
            X_dice = X[clustering.labels_ == i]
            
            centroid_dice = np.mean(X_dice, axis=0)
            
            dice.append([len(X_dice), *centroid_dice])
            
        return dice
    
    else:
        
        return[]

def overlay_info(frame, dice, blobs):
    
    for b in blobs:
        pos = b.pt
        r = b.size / 2
        
        cv2.circle(frame, (int(pos[0]), int(pos[1])),
                   int(r), (255, 0, 0), 2)
        
        for d in dice:
            
            textsize = cv2.getTextSize(
                str(d[0]), cv2.FONT_HERSHEY_PLAIN, 3, 2)[0]
            
            cv2.putText(frame, str(d[0]),
                        (int(d[1] - textsize[0] / 2),
                         int(d[2] + textsize[1] / 2)),
                        cv2.FONT_HERSHEY_PLAIN, 3, (0, 255, 0), 2)

while True:
    # Neem een afbeelding van de camera
    frame = picam2.capture_array()
    
    blobs = get_blobs(frame)
    dice = get_dice_from_blobs(blobs)
    out_frame = overlay_info (frame, dice, blobs)
    
    cv2.imshow('frame', frame)
    
    res = cv2.waitKey(1)
    
    if res & 0xFF == ord('q'):
        break
    
    
picam2.stop()
cv2.destroyAllWindows()

Attached Files

Thumbnail(s)
   
Reply


Messages In This Thread
Dice detection using DBSCAN - by Termiik - Oct-15-2024, 09:50 PM
RE: Dice detection using DBSCAN - by Pedroski55 - Oct-17-2024, 03:06 PM
RE: Dice detection using DBSCAN - by Termiik - Oct-29-2024, 10:07 PM
RE: Dice detection using DBSCAN - by Pedroski55 - Oct-30-2024, 06:49 PM
RE: Dice detection using DBSCAN - by Pedroski55 - Dec-19-2024, 06:03 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
  Making a percentile dice roller and dice roller Fixer243 2 4,103 Sep-30-2018, 12:18 PM
Last Post: gruntfutuk

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020