Spaces:
Runtime error
Runtime error
import gradio as gr | |
import pandas as pd | |
import subprocess | |
import os | |
from tempfile import mkdtemp | |
from timeit import default_timer as timer | |
# Download model and libraries from repo | |
try: | |
token = os.environ.get("model_token") | |
subprocess.run(["git", "clone", f"https://oauth2:{token}@huggingface.co/vincentlui/bridge_hand_detect"]) | |
except: | |
print('Fail to download code') | |
try: | |
from bridge_hand_detect2.predict import CardDetectionModel, draw_bboxes | |
from bridge_hand_detect2.pbn import create_pbn_file | |
model_dir = 'bridge_hand_detect2/model.onnx' | |
except: | |
from bridge_hand_detect.predict import CardDetectionModel, draw_bboxes | |
from bridge_hand_detect.pbn import create_pbn_file | |
model_dir = 'bridge_hand_detect/model.onnx' | |
custom_css = \ | |
""" | |
/* Hide sort buttons at gr.DataFrame */ | |
.sort-button { | |
display: none !important; | |
} | |
""" | |
INPUT_IMG_HEIGHT = 480 | |
OUTPUT_IMG_HEIGHT = 320 | |
css = ".output_img {display:block; margin-left: auto; margin-right: auto}" | |
model = CardDetectionModel(model_dir) | |
def predict(image_path): | |
start = timer() | |
df = None | |
try: | |
hands, (width,height) = model(image_path) | |
print(hands) | |
# Output dataframe | |
df = pd.DataFrame(['♠', '♥', '♦', '♣'], columns=['']) | |
for hand in hands: | |
df[hand.direction] = [''.join(c) for c in hand.cards] | |
except: | |
gr.Error('Cannot process image') | |
end = timer() | |
print(f'Process time: {end - start:.02f} seconds') | |
return df | |
default_df = df = pd.DataFrame({'':['♠', '♥', '♦', '♣'], | |
'N': ['']*4, | |
'E': ['']*4, | |
'S': ['']*4, | |
'W': ['']*4}) | |
def save_file2(df, cache_dir, total): | |
d = cache_dir | |
if cache_dir is None: | |
d = mkdtemp() | |
total += 1 | |
file_name = f'bridgehand{total:03d}.pbn' | |
file_path = os.path.join(d,file_name) | |
with open(file_path, 'w') as f: | |
pbn_str = create_pbn_file(df) | |
f.write(pbn_str) | |
return file_path, d, total | |
with gr.Blocks(css=custom_css) as demo: | |
gr.Markdown( | |
""" | |
# Bridge Hand Scanner - Read all four hands from an image | |
This app scans an image taken from (e.g. your smartphone) and reads all 52 cards. The top hand is regarded as North. | |
The results can be exported as a PBN file, which can be imported to other bridge software such as double dummy solvers. | |
1. Upload an image showing all four hands fanned as shown in the example. | |
2. Click *Submit*. The scan result will be displayed in the table. | |
3. Verify the output and correct any missing or wrong card in the table. Then click *Save* to generate a PBN file. | |
Tips: | |
- This AI reads the values at the top left corner of the playing cards. Make sure they are visible and as large as possible. | |
- To get the best accuracy, place the cards following the layout in the examples. | |
I need your feedback to make this app more useful. Please send your comments to <vincentlui123@gmail.com>. | |
""") | |
total = gr.State(0) | |
gradio_cache_dir = gr.State() | |
with gr.Row(): | |
with gr.Column(): | |
a1 = gr.Image(type="filepath",sources=['upload'],interactive=True,height=INPUT_IMG_HEIGHT) | |
with gr.Row(): | |
a2 = gr.ClearButton() | |
a3 = gr.Button('Submit',variant="primary") | |
a4 = gr.Examples('examples', a1) | |
with gr.Column(): | |
b1 = gr.Dataframe(value=default_df, datatype="str", row_count=(4,'fixed'), col_count=(5,'fixed'), | |
headers=['', 'N', 'E', 'S', 'W'], | |
interactive=True, column_widths=['8%', '23%','23%','23%','23%']) | |
b2 = gr.Button('Save') | |
b3 = gr.File(interactive=False) | |
a2.add([a1, b1, b3]) | |
a3.click(predict, [a1], [b1]) | |
b2.click(save_file2, [b1, gradio_cache_dir, total], [b3, gradio_cache_dir, total]) | |
demo.queue().launch() |