Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -4,54 +4,75 @@ import os
|
|
| 4 |
from pathlib import Path
|
| 5 |
import pathlib
|
| 6 |
|
| 7 |
-
|
| 8 |
if os.name == "nt": # Windows
|
| 9 |
pathlib.PosixPath = pathlib.WindowsPath
|
| 10 |
|
| 11 |
model_path = os.path.join(os.getcwd(), "cards_classification.pkl")
|
| 12 |
-
print(f"model path:
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
|
|
|
| 15 |
|
| 16 |
def classify_image(image):
|
| 17 |
if image is None:
|
| 18 |
return {}
|
| 19 |
-
img = PILImage.create(image)
|
| 20 |
pred_class, pred_idx, probs = learn.predict(img)
|
| 21 |
-
|
| 22 |
return {learn.dls.vocab[i]: float(probs[i]) for i in range(len(probs))}
|
| 23 |
-
# return (str(pred_class))
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
CARDS = ['ace of clubs', 'ace of diamonds', 'ace of hearts', 'ace of spades', 'eight of clubs', 'eight of diamonds', 'eight of hearts', 'eight of spades', 'five of clubs', 'five of diamonds', 'five of hearts', 'five of spades', 'four of clubs', 'four of diamonds', 'four of hearts', 'four of spades', 'jack of clubs', 'jack of diamonds', 'jack of hearts', 'jack of spades', 'joker', 'king of clubs', 'king of diamonds', 'king of hearts', 'king of spades', 'nine of clubs', 'nine of diamonds', 'nine of hearts', 'nine of spades', 'queen of clubs', 'queen of diamonds', 'queen of hearts', 'queen of spades', 'seven of clubs', 'seven of diamonds', 'seven of hearts', 'seven of spades', 'six of clubs', 'six of diamonds', 'six of hearts', 'six of spades', 'ten of clubs', 'ten of diamonds', 'ten of hearts', 'ten of spades', 'three of clubs', 'three of diamonds', 'three of hearts', 'three of spades', 'two of clubs', 'two of diamonds', 'two of hearts', 'two of spades']
|
| 27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 28 |
|
| 29 |
# Create the interface with detailed description
|
| 30 |
with gr.Blocks() as iface:
|
| 31 |
gr.Markdown(
|
| 32 |
-
|
| 33 |
π Playing Card Image Classifier
|
| 34 |
-
|
| 35 |
This AI model can recognize and classify images of standard playing cards using deep learning.
|
| 36 |
-
|
| 37 |
### How it works:
|
| 38 |
Upload an image of a playing card, and the model will predict which card it is from a full deck of cards.
|
| 39 |
-
|
| 40 |
### Supported Cards:
|
| 41 |
The model can identify **all standard playing cards**, including:
|
| 42 |
- Aces, numbers (2β10), Jacks, Queens, and Kings
|
| 43 |
- All four suits: Clubs, Diamonds, Hearts, and Spades
|
| 44 |
-
- Joker card
|
| 45 |
-
|
| 46 |
-
(In total: 53 classes)
|
| 47 |
-
|
| 48 |
### Tips for best results:
|
| 49 |
- Use clear, high-resolution images
|
| 50 |
- Make sure the card is fully visible
|
| 51 |
- Avoid heavy glare, blur, or occlusion
|
| 52 |
- One card per image works best
|
| 53 |
"""
|
| 54 |
-
|
| 55 |
)
|
| 56 |
|
| 57 |
with gr.Row():
|
|
@@ -60,21 +81,42 @@ with gr.Blocks() as iface:
|
|
| 60 |
submit_btn = gr.Button("π Identify Card", variant="primary")
|
| 61 |
with gr.Column():
|
| 62 |
output_label = gr.Label(num_top_classes=3, label="Predictions")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 63 |
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
],
|
| 72 |
-
inputs=input_image,
|
| 73 |
-
label="Try an example"
|
| 74 |
-
)
|
| 75 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
|
| 77 |
submit_btn.click(fn=classify_image, inputs=input_image, outputs=output_label)
|
| 78 |
|
| 79 |
if __name__ == "__main__":
|
| 80 |
-
iface.launch(server_name="0.0.0.0", server_port=7860)
|
|
|
|
| 4 |
from pathlib import Path
|
| 5 |
import pathlib
|
| 6 |
|
|
|
|
| 7 |
if os.name == "nt": # Windows
|
| 8 |
pathlib.PosixPath = pathlib.WindowsPath
|
| 9 |
|
| 10 |
model_path = os.path.join(os.getcwd(), "cards_classification.pkl")
|
| 11 |
+
print(f"model path: {model_path}")
|
| 12 |
+
|
| 13 |
+
# Debug: Print current working directory and list files
|
| 14 |
+
print(f"Current working directory: {os.getcwd()}")
|
| 15 |
+
print(f"Files in current directory: {os.listdir('.')}")
|
| 16 |
+
|
| 17 |
+
# Check if test_images directory exists
|
| 18 |
+
if os.path.exists('test_images'):
|
| 19 |
+
print(f"test_images directory found!")
|
| 20 |
+
print(f"Files in test_images: {os.listdir('test_images')}")
|
| 21 |
+
else:
|
| 22 |
+
print(f"test_images directory NOT found!")
|
| 23 |
+
# Check home directory
|
| 24 |
+
home_app = '/home/user/app'
|
| 25 |
+
if os.path.exists(home_app):
|
| 26 |
+
print(f"Files in {home_app}: {os.listdir(home_app)}")
|
| 27 |
+
if os.path.exists(os.path.join(home_app, 'test_images')):
|
| 28 |
+
print(f"Files in {home_app}/test_images: {os.listdir(os.path.join(home_app, 'test_images'))}")
|
| 29 |
|
| 30 |
+
learn = load_learner(model_path, cpu=True)
|
| 31 |
|
| 32 |
def classify_image(image):
|
| 33 |
if image is None:
|
| 34 |
return {}
|
| 35 |
+
img = PILImage.create(image)
|
| 36 |
pred_class, pred_idx, probs = learn.predict(img)
|
|
|
|
| 37 |
return {learn.dls.vocab[i]: float(probs[i]) for i in range(len(probs))}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
|
| 39 |
+
CARDS = ['ace of clubs', 'ace of diamonds', 'ace of hearts', 'ace of spades',
|
| 40 |
+
'eight of clubs', 'eight of diamonds', 'eight of hearts', 'eight of spades',
|
| 41 |
+
'five of clubs', 'five of diamonds', 'five of hearts', 'five of spades',
|
| 42 |
+
'four of clubs', 'four of diamonds', 'four of hearts', 'four of spades',
|
| 43 |
+
'jack of clubs', 'jack of diamonds', 'jack of hearts', 'jack of spades',
|
| 44 |
+
'joker', 'king of clubs', 'king of diamonds', 'king of hearts', 'king of spades',
|
| 45 |
+
'nine of clubs', 'nine of diamonds', 'nine of hearts', 'nine of spades',
|
| 46 |
+
'queen of clubs', 'queen of diamonds', 'queen of hearts', 'queen of spades',
|
| 47 |
+
'seven of clubs', 'seven of diamonds', 'seven of hearts', 'seven of spades',
|
| 48 |
+
'six of clubs', 'six of diamonds', 'six of hearts', 'six of spades',
|
| 49 |
+
'ten of clubs', 'ten of diamonds', 'ten of hearts', 'ten of spades',
|
| 50 |
+
'three of clubs', 'three of diamonds', 'three of hearts', 'three of spades',
|
| 51 |
+
'two of clubs', 'two of diamonds', 'two of hearts', 'two of spades']
|
| 52 |
|
| 53 |
# Create the interface with detailed description
|
| 54 |
with gr.Blocks() as iface:
|
| 55 |
gr.Markdown(
|
| 56 |
+
"""
|
| 57 |
π Playing Card Image Classifier
|
| 58 |
+
|
| 59 |
This AI model can recognize and classify images of standard playing cards using deep learning.
|
| 60 |
+
|
| 61 |
### How it works:
|
| 62 |
Upload an image of a playing card, and the model will predict which card it is from a full deck of cards.
|
| 63 |
+
|
| 64 |
### Supported Cards:
|
| 65 |
The model can identify **all standard playing cards**, including:
|
| 66 |
- Aces, numbers (2β10), Jacks, Queens, and Kings
|
| 67 |
- All four suits: Clubs, Diamonds, Hearts, and Spades
|
| 68 |
+
- Joker card (In total: 53 classes)
|
| 69 |
+
|
|
|
|
|
|
|
| 70 |
### Tips for best results:
|
| 71 |
- Use clear, high-resolution images
|
| 72 |
- Make sure the card is fully visible
|
| 73 |
- Avoid heavy glare, blur, or occlusion
|
| 74 |
- One card per image works best
|
| 75 |
"""
|
|
|
|
| 76 |
)
|
| 77 |
|
| 78 |
with gr.Row():
|
|
|
|
| 81 |
submit_btn = gr.Button("π Identify Card", variant="primary")
|
| 82 |
with gr.Column():
|
| 83 |
output_label = gr.Label(num_top_classes=3, label="Predictions")
|
| 84 |
+
|
| 85 |
+
# Use absolute paths or check which path works
|
| 86 |
+
example_paths = []
|
| 87 |
+
test_dir = "test_images"
|
| 88 |
+
|
| 89 |
+
# Try to find the correct path
|
| 90 |
+
if os.path.exists(test_dir):
|
| 91 |
+
base_path = test_dir
|
| 92 |
+
elif os.path.exists("/home/user/app/test_images"):
|
| 93 |
+
base_path = "/home/user/app/test_images"
|
| 94 |
+
else:
|
| 95 |
+
base_path = None
|
| 96 |
+
print("WARNING: Could not find test_images directory!")
|
| 97 |
+
|
| 98 |
+
if base_path:
|
| 99 |
+
example_files = ["king_of_diamonds.jpg", "jack_of_spades.jpg",
|
| 100 |
+
"ace_of_diamonds.jpg", "three_of_hearts.jpg", "ace_of_spades.jpg"]
|
| 101 |
|
| 102 |
+
for filename in example_files:
|
| 103 |
+
full_path = os.path.join(base_path, filename)
|
| 104 |
+
if os.path.exists(full_path):
|
| 105 |
+
example_paths.append([full_path])
|
| 106 |
+
print(f"Found example: {full_path}")
|
| 107 |
+
else:
|
| 108 |
+
print(f"Missing example: {full_path}")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
|
| 110 |
+
if example_paths:
|
| 111 |
+
gr.Examples(
|
| 112 |
+
examples=example_paths,
|
| 113 |
+
inputs=input_image,
|
| 114 |
+
label="Try an example"
|
| 115 |
+
)
|
| 116 |
+
else:
|
| 117 |
+
gr.Markdown("β οΈ Example images not found. Please upload your own image.")
|
| 118 |
|
| 119 |
submit_btn.click(fn=classify_image, inputs=input_image, outputs=output_label)
|
| 120 |
|
| 121 |
if __name__ == "__main__":
|
| 122 |
+
iface.launch(server_name="0.0.0.0", server_port=7860)
|