File size: 3,757 Bytes
8c12269
76ac45d
 
8c12269
 
53a37e4
 
 
 
8c12269
 
74ba2b6
76ac45d
 
 
8c12269
76ac45d
8c12269
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74ba2b6
8c12269
 
76ac45d
16b0d4f
76ac45d
 
 
 
 
 
 
 
2ccc3fb
f7af810
 
 
aaf3d3a
f7af810
 
d0896bd
2ccc3fb
 
 
 
 
 
76ac45d
 
8c12269
 
 
53a37e4
8c12269
 
 
76ac45d
74ba2b6
76ac45d
8c12269
2ccc3fb
 
8c12269
d0896bd
 
f3eeaf3
8c12269
76ac45d
2ccc3fb
3306f0c
8c12269
c23a2a5
53a37e4
2ccc3fb
 
76ac45d
 
 
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
import cv2
from matplotlib.pyplot import hsv
from PIL import ImageOps
import numpy as np
import gradio as gr
import warnings

# Filter out user warnings to avoid any unnecessary clutter in the output
warnings.filterwarnings("ignore", category=UserWarning)

font = cv2.FONT_HERSHEY_SIMPLEX
font_scale = 1
color_search = np.zeros((200, 200, 3), np.uint8)
color_selected = np.zeros((200, 200, 3), np.uint8)
hue = 0

def search_contours(mask, frame, source):
    contours_count = 0
    contours, hierarchy = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    pip_count = 0
    for contour in contours:
        area = cv2.contourArea(contour)
        if 200 < area < 10000:
            cv2.drawContours(frame, [contour], -1, (0, 255, 0), 2)
            contours_count += 1
            M = cv2.moments(contour)
            if M["m00"] != 0:
                cX = int(M["m10"] / M["m00"])
                cY = int(M["m01"] / M["m00"])
            else:
                cX, cY = 0, 0
            cv2.circle(frame, (cX, cY), 3, (255, 255, 255), -1)
            pip_count += 1
            cv2.putText(frame, str(pip_count), (cX - 16, cY + 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 1)
    return pip_count, frame

def center_crop_with_padding(image):
    im = image.fromarray(image)
    width, height = im.size
    new_size = min(width, height)
    im = im.crop(((width - new_size) // 2, (height - new_size) // 2, (width + new_size) // 2, (height + new_size) // 2))
    im = im.crop((25, 25, new_size - 25, new_size - 25))
    im_with_border = ImageOps.expand(im, border=3, fill=(255,255,255))
    return np.array(im_with_border)


sample_images = {
    "23.jpg": "23.jpg",
    "28.png": "28.png",
    "35.jpg": "35.jpg",
    "36w.jpg": "36w.jpg",
    "46.jpg": "46.jpg",
    "64.jpg": "64.jpg",
    "86.jpg": "86.jpg",
}

def detect_pips(uploaded_image, sample_image_selection, hue_threshold):
    if uploaded_image is not None:
        image = uploaded_image[:, :, :3]
    else:
        image = cv2.imread(sample_image_selection)
    
    image = cv2.resize(image, (512, 512))
    hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
    hue = 60
    lower_hue, upper_hue = max(0, hue - hue_threshold), min(179, hue + hue_threshold)
    lower_hsv = np.array([lower_hue, 50, 20])
    upper_hsv = np.array([upper_hue, 255, 255])
    mask = cv2.inRange(hsv, lower_hsv, upper_hsv)
    count, result_frame = search_contours(mask, image, source="image")
    cv2.putText(result_frame, f'Total pip count is: {count}', (10, result_frame.shape[0] - 30), font, 1, (0, 255, 255), 2, cv2.LINE_AA)
    return result_frame

iface = gr.Interface(
    detect_pips,
    inputs=[
        gr.inputs.Image(type="numpy", label="Upload your Domino Image (jpg or png)", source="upload", optional=True), # Image upload
        gr.inputs.Dropdown(choices=list(sample_images.keys()), label="Use 'Clear' to remove any image above and select an example from the drop down and 'Submit' it", default=None), # Dropdown for sample images
        gr.inputs.Slider(label="Hue Threshold - Use this to adjust the sensitvity on what it counts", minimum=0, maximum=500, step=1, default=250)
    ],
    outputs=gr.outputs.Image(type="numpy", label="Result"),
    title='<b><font size="4">🁫Image Processing demonstration using OpenCV and Python:🁫</b>',
    description='<div style="text-align:center;"><b style="font-size:20px;">App to help you keep score when playing Dominos</b><br>Use your iPad to take a photo and upload to calculate a score<br> Please leave a ❤️ if you enjoyed this :)</div>',
    allow_flagging=False,
    live=False,
    theme="dark",
)

# Launch the Gradio interface if the script is run as the main program
if __name__ == '__main__':
    iface.launch()