vincentlui commited on
Commit
aedbeed
1 Parent(s): 04774ac

initial commit

Browse files
Files changed (5) hide show
  1. .gitignore +2 -0
  2. app.py +116 -0
  3. examples/example1.webp +0 -0
  4. examples/example2.webp +0 -0
  5. requirements.txt +5 -0
.gitignore ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ bridge_hand_detect
2
+ bridge_hand_detect2
app.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import subprocess
4
+ import os
5
+ from tempfile import mkdtemp
6
+ from timeit import default_timer as timer
7
+
8
+ # Download model and libraries from repo
9
+ try:
10
+ token = os.environ.get("model_token")
11
+ subprocess.run(["git", "clone", f"https://oauth2:{token}@huggingface.co/vincentlui/bridge_hand_detect"])
12
+ except:
13
+ print('Fail to download code')
14
+
15
+ try:
16
+ from bridge_hand_detect2.predict import CardDetectionModel, draw_bboxes
17
+ from bridge_hand_detect2.pbn import create_pbn_file
18
+ model_dir = 'bridge_hand_detect2/model.onnx'
19
+ except:
20
+ from bridge_hand_detect.predict import CardDetectionModel, draw_bboxes
21
+ from bridge_hand_detect.pbn import create_pbn_file
22
+ model_dir = 'bridge_hand_detect/model.onnx'
23
+
24
+ custom_css = \
25
+ """
26
+ /* Hide sort buttons at gr.DataFrame */
27
+ .sort-button {
28
+ display: none !important;
29
+ }
30
+ """
31
+
32
+ INPUT_IMG_HEIGHT = 480
33
+ OUTPUT_IMG_HEIGHT = 320
34
+ css = ".output_img {display:block; margin-left: auto; margin-right: auto}"
35
+ model = CardDetectionModel(model_dir)
36
+
37
+ def predict(image_path):
38
+ start = timer()
39
+ df = None
40
+ try:
41
+ hands, (width,height) = model(image_path)
42
+ print(hands)
43
+ # Output dataframe
44
+ df = pd.DataFrame(['♠', '♥', '♦', '♣'], columns=[''])
45
+ for hand in hands:
46
+ df[hand.direction] = [''.join(c) for c in hand.cards]
47
+ except:
48
+ gr.Error('Cannot process image')
49
+
50
+ end = timer()
51
+ print(f'Process time: {end - start:.02f} seconds')
52
+
53
+ return df
54
+
55
+
56
+ default_df = df = pd.DataFrame({'':['♠', '♥', '♦', '♣'],
57
+ 'N': ['']*4,
58
+ 'E': ['']*4,
59
+ 'S': ['']*4,
60
+ 'W': ['']*4})
61
+
62
+
63
+ def save_file2(df, cache_dir, total):
64
+ d = cache_dir
65
+ if cache_dir is None:
66
+ d = mkdtemp()
67
+ total += 1
68
+ file_name = f'bridgehand{total:03d}.pbn'
69
+ file_path = os.path.join(d,file_name)
70
+ with open(file_path, 'w') as f:
71
+ pbn_str = create_pbn_file(df)
72
+ f.write(pbn_str)
73
+
74
+ return file_path, d, total
75
+
76
+ with gr.Blocks(css=custom_css) as demo:
77
+ gr.Markdown(
78
+ """
79
+ # Bridge Hand Scanner - Read all four hands from an image
80
+
81
+ This app scans an image taken from (e.g. your smartphone) and reads all 52 cards. The top hand is regarded as North.
82
+ The results can be exported as a PBN file, which can be imported to other bridge software such as double dummy solvers.
83
+ 1. Upload an image showing all four hands fanned as shown in the example.
84
+ 2. Click *Submit*. The scan result will be displayed in the table.
85
+ 3. Verify the output and correct any missing or wrong card in the table. Then click *Save* to generate a PBN file.
86
+
87
+ Tips:
88
+ - This AI reads the values at the top left corner of the playing cards. Make sure they are visible and as large as possible.
89
+ - To get the best accuracy, place the cards following the layout in the examples.
90
+
91
+ I need your feedback to make this app more useful. Please send your comments to <vincentlui123@gmail.com>.
92
+ """)
93
+
94
+ total = gr.State(0)
95
+ gradio_cache_dir = gr.State()
96
+
97
+ with gr.Row():
98
+ with gr.Column():
99
+ a1 = gr.Image(type="filepath",sources=['upload'],interactive=True,height=INPUT_IMG_HEIGHT)
100
+ with gr.Row():
101
+ a2 = gr.ClearButton()
102
+ a3 = gr.Button('Submit',variant="primary")
103
+ a4 = gr.Examples('examples', a1)
104
+
105
+ with gr.Column():
106
+ b1 = gr.Dataframe(value=default_df, datatype="str", row_count=(4,'fixed'), col_count=(5,'fixed'),
107
+ headers=['', 'N', 'E', 'S', 'W'],
108
+ interactive=True, column_widths=['8%', '23%','23%','23%','23%'])
109
+ b2 = gr.Button('Save')
110
+ b3 = gr.File(interactive=False)
111
+
112
+ a2.add([a1, b1, b3])
113
+ a3.click(predict, [a1], [b1])
114
+ b2.click(save_file2, [b1, gradio_cache_dir, total], [b3, gradio_cache_dir, total])
115
+
116
+ demo.queue().launch()
examples/example1.webp ADDED
examples/example2.webp ADDED
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ scikit-learn
2
+ onnx
3
+ onnxruntime
4
+ lap
5
+ opencv-python