-
Notifications
You must be signed in to change notification settings - Fork 0
/
dice_roll.py
100 lines (78 loc) · 2.85 KB
/
dice_roll.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import cv2
import numpy as np
from sklearn import cluster
input_video_path = 'videos/IMG_1912.mp4'
# Initialize a video feed
paramsDice = cv2.SimpleBlobDetector_Params()
# Filter by Area
paramsDice.filterByArea = True
paramsDice.minArea = 50
paramsDice.maxArea = 80
# Filter by Circularity
paramsDice.filterByCircularity = True
paramsDice.minCircularity = 0.7
# Filter by Convexity
paramsDice.filterByConvexity = True
paramsDice.minConvexity = 0.7
# Filter by Inertia
paramsDice.filterByInertia = True
paramsDice.minInertiaRatio = 0.7
lower = (50,0,0) #130,150,80 # hard set
upper = (200,200,200) #250,250,120
def get_blobs(frame):
mask = cv2.inRange(frame, lower, upper)
frame[mask > 0] = 0
frame_blurred = cv2.medianBlur(frame, 7)
frame_gray = cv2.cvtColor(frame_blurred, cv2.COLOR_BGR2GRAY)
blobs = detectorDice.detect(frame_gray)
return blobs
def get_dice_from_blobs(blobs):
X = np.asarray([b.pt for b in blobs if b.pt != None])
if len(X) > 0:
# Important to set min_sample to 0, as a dice may only have one dot
clustering = cluster.DBSCAN(eps=40, min_samples=0).fit(X)
dice = []
# Calculate centroid of each dice, the average between all a dice's dots
X_dice = X[clustering.labels_ == 0]
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):
if len(dice) > 0:
dice = dice[0]
# Overlay dice number
textsize = cv2.getTextSize(
str(dice[0]), cv2.FONT_HERSHEY_PLAIN, 3, 2)[0]
cv2.putText(frame, str(dice[0]),
(int(dice[1] - textsize[0] / 2),
int(dice[2] + textsize[1] / 2)),
cv2.FONT_HERSHEY_PLAIN, 3, (0, 255, 0), 2)
def getDiceValue(frame):
blobs = get_blobs(frame, detectorDice)
dice = get_dice_from_blobs(blobs)
if len(dice) == 0:
return 0
else: return dice[0]
if __name__ == "__main__":
cap = cv2.VideoCapture(input_video_path)
detectorDice = cv2.SimpleBlobDetector_create(paramsDice)
while(cap.isOpened()):
ret, frame = cap.read()
blobs = get_blobs(frame, detectorDice)
dice = get_dice_from_blobs(blobs)
out_frame = overlay_info(frame, dice, blobs)
scale_percent = 50 # percent of original size
width = int(frame.shape[1] * scale_percent / 100)
height = int(frame.shape[0] * scale_percent / 100)
dim = (width, height)
resized = cv2.resize(frame, dim, interpolation = cv2.INTER_AREA)
cv2.imshow("frame", resized)
res = cv2.waitKey(1)
# Stop if the user presses "q"
if res & 0xFF == ord('q'):
break
# When everything is done, release the capture
cap.release()
cv2.destroyAllWindows()