Upload folder using huggingface_hub
Browse files- README.md +91 -91
- app.py +86 -167
- deploy_to_hf.py +0 -1
- requirements.txt +2 -5
README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
emoji: 🎲
|
4 |
colorFrom: blue
|
5 |
colorTo: red
|
@@ -7,120 +7,120 @@ sdk: gradio
|
|
7 |
sdk_version: 4.19.2
|
8 |
app_file: app.py
|
9 |
pinned: false
|
|
|
10 |
---
|
11 |
|
12 |
-
#
|
13 |
|
14 |
-
This is a deep learning model that can recognize and analyze Rubik's cubes in images. The model is built using TensorFlow
|
15 |
|
16 |
-
## Features
|
17 |
|
18 |
-
- Upload images of Rubik's cubes
|
19 |
-
-
|
20 |
-
- Simple and intuitive interface
|
|
|
21 |
|
22 |
-
## How to Use
|
23 |
|
24 |
-
1.
|
25 |
-
2.
|
26 |
-
3.
|
27 |
|
28 |
-
## Technical Details
|
29 |
|
30 |
-
-
|
31 |
-
-
|
32 |
-
-
|
|
|
|
|
33 |
|
34 |
-
##
|
35 |
|
36 |
-
|
|
|
|
|
|
|
|
|
37 |
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
## 🌟 Model Description
|
47 |
-
|
48 |
-
The model is based on RetinaNet with SpineNet-49 backbone, trained to detect:
|
49 |
-
- Rubik's cube faces
|
50 |
-
- Individual color tiles (red, white, blue, orange, green, yellow)
|
51 |
-
|
52 |
-
### Model Architecture
|
53 |
-
- Base Model: RetinaNet-SpineNet-49
|
54 |
-
- Input Size: 640x640x3
|
55 |
-
- Number of Classes: 7 (6 colors + face)
|
56 |
-
- Output: Bounding boxes with class predictions
|
57 |
|
58 |
## 📊 Performance Metrics
|
59 |
|
60 |
-
| Metric |
|
61 |
-
|
62 |
-
| mAP
|
63 |
-
|
|
|
|
64 |
|
65 |
-
##
|
66 |
|
67 |
```bash
|
68 |
# Clone the repository
|
69 |
-
git clone https://huggingface.co/spaces/
|
|
|
70 |
|
71 |
# Install dependencies
|
72 |
pip install -r requirements.txt
|
73 |
|
74 |
-
# Run the
|
75 |
python app.py
|
76 |
```
|
77 |
|
78 |
-
##
|
79 |
|
80 |
```
|
81 |
rubiks-cube-recognition/
|
82 |
-
├── app.py
|
83 |
-
├──
|
84 |
-
|
85 |
-
|
86 |
-
│
|
87 |
-
|
88 |
-
│
|
89 |
-
│
|
90 |
-
|
91 |
-
├──
|
92 |
-
├──
|
93 |
-
└──
|
94 |
```
|
95 |
|
96 |
-
##
|
97 |
|
98 |
-
|
99 |
-
|
100 |
-
```python
|
101 |
-
python src/model/trainer.py --config configs/retinanet_config.py
|
102 |
-
```
|
103 |
|
104 |
-
|
105 |
|
106 |
-
|
107 |
-
|
108 |
-
|
|
|
|
|
109 |
|
110 |
-
##
|
111 |
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
- Classes: 7 (face, red_tile, white_tile, blue_tile, orange_tile, green_tile, yellow_tile)
|
120 |
|
121 |
## 🤝 Contributing
|
122 |
|
123 |
-
Contributions are welcome!
|
|
|
|
|
|
|
|
|
124 |
|
125 |
## 📄 License
|
126 |
|
@@ -128,26 +128,26 @@ This project is licensed under the Apache License 2.0 - see the [LICENSE](LICENS
|
|
128 |
|
129 |
## 🙏 Acknowledgements
|
130 |
|
131 |
-
- TensorFlow Model Garden
|
132 |
-
-
|
133 |
-
-
|
|
|
134 |
|
135 |
## 📧 Contact
|
136 |
|
137 |
-
- GitHub
|
138 |
-
- Hugging Face
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
|
140 |
-
|
141 |
|
142 |
-
- [How to Train Custom Object Detection Models using RetinaNet](https://medium.com/@van.evanfebrianto/how-to-train-custom-object-detection-models-using-retinanet-aeed72f5d701)
|
143 |
-
- labelme2coco: https://github.com/fcakyon/labelme2coco
|
144 |
-
|
145 |
-
- **Keras RetinaNet**: https://github.com/fizyr/keras-retinanet
|
146 |
-
- **TensorFlow 2.x RetinaNet**: https://github.com/srihari-humbarwadi/retinanet-tensorflow2.x
|
147 |
-
- **SpineNet-PyTorch**: https://github.com/yan-roo/SpineNet-Pytorch
|
148 |
|
149 |
-
- **LabelMe to COCO Converter**: https://github.com/wkentaro/labelme
|
150 |
-
- **labelme-json-to-coco-json**: https://roboflow.com/convert/labelme-json-to-coco-json
|
151 |
|
152 |
-
|
153 |
-
|
|
|
1 |
---
|
2 |
+
title: Rubiks Cube Recognition
|
3 |
emoji: 🎲
|
4 |
colorFrom: blue
|
5 |
colorTo: red
|
|
|
7 |
sdk_version: 4.19.2
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
+
license: apache-2.0
|
11 |
---
|
12 |
|
13 |
+
# 🎲 Rubik's Cube Recognition with TensorFlow RetinaNet
|
14 |
|
15 |
+
This is a deep learning model that can recognize and analyze Rubik's cubes in images. The model is built using TensorFlow and RetinaNet architecture for object detection.
|
16 |
|
17 |
+
## 🚀 Features
|
18 |
|
19 |
+
- **Real-time Detection**: Upload images of Rubik's cubes for instant analysis
|
20 |
+
- **Multi-class Recognition**: Detect cube faces and 6 different color tiles
|
21 |
+
- **Interactive Interface**: Simple and intuitive Gradio web interface
|
22 |
+
- **Advanced AI**: Powered by RetinaNet with SpineNet-49 backbone
|
23 |
|
24 |
+
## 🎯 How to Use
|
25 |
|
26 |
+
1. **Upload**: Click "Upload Rubik's Cube Image" and select your image
|
27 |
+
2. **Analyze**: Click "🔍 Analyze Image" or wait for automatic processing
|
28 |
+
3. **Results**: View detection results and visualization with bounding boxes
|
29 |
|
30 |
+
## 🔬 Technical Details
|
31 |
|
32 |
+
- **Framework**: TensorFlow 2.15+ with Gradio interface
|
33 |
+
- **Architecture**: RetinaNet with SpineNet-49 backbone
|
34 |
+
- **Input Size**: 640×640 pixels
|
35 |
+
- **Classes**: 7 total (1 face + 6 color tiles)
|
36 |
+
- **Colors Detected**: Red, White, Blue, Orange, Green, Yellow
|
37 |
|
38 |
+
## 🌟 Model Architecture
|
39 |
|
40 |
+
### RetinaNet-SpineNet-49
|
41 |
+
- **Base Model**: RetinaNet for object detection
|
42 |
+
- **Backbone**: SpineNet-49 for feature extraction
|
43 |
+
- **Input Resolution**: 640×640×3
|
44 |
+
- **Output**: Bounding boxes with class predictions and confidence scores
|
45 |
|
46 |
+
### Detection Classes
|
47 |
+
1. `face` - Rubik's cube face
|
48 |
+
2. `red_tile` - Red color tile
|
49 |
+
3. `white_tile` - White color tile
|
50 |
+
4. `blue_tile` - Blue color tile
|
51 |
+
5. `orange_tile` - Orange color tile
|
52 |
+
6. `green_tile` - Green color tile
|
53 |
+
7. `yellow_tile` - Yellow color tile
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
|
55 |
## 📊 Performance Metrics
|
56 |
|
57 |
+
| Metric | Target | Status |
|
58 |
+
|--------|--------|--------|
|
59 |
+
| mAP@0.5 | >0.85 | In Training |
|
60 |
+
| Inference Speed | <100ms | Optimized |
|
61 |
+
| Accuracy | >90% | Evaluating |
|
62 |
|
63 |
+
## 🛠️ Local Development
|
64 |
|
65 |
```bash
|
66 |
# Clone the repository
|
67 |
+
git clone https://huggingface.co/spaces/itsyuimorii/rubiks-cube-recognition
|
68 |
+
cd rubiks-cube-recognition
|
69 |
|
70 |
# Install dependencies
|
71 |
pip install -r requirements.txt
|
72 |
|
73 |
+
# Run the application
|
74 |
python app.py
|
75 |
```
|
76 |
|
77 |
+
## 📁 Project Structure
|
78 |
|
79 |
```
|
80 |
rubiks-cube-recognition/
|
81 |
+
├── app.py # Main Gradio application
|
82 |
+
├── requirements.txt # Python dependencies
|
83 |
+
├── README.md # This file
|
84 |
+
├── configs/ # Model configurations
|
85 |
+
│ └── retinanet_config.py
|
86 |
+
├── src/ # Source code
|
87 |
+
│ ├── data/ # Data processing utilities
|
88 |
+
│ └── model/ # Model training and inference
|
89 |
+
└── images/ # Training and test datasets
|
90 |
+
├── train/ # Training images and annotations
|
91 |
+
├── test/ # Test images and annotations
|
92 |
+
└── valid/ # Validation images and annotations
|
93 |
```
|
94 |
|
95 |
+
## 🎮 Demo Status
|
96 |
|
97 |
+
⚠️ **Note**: This is a demo version. The complete trained model is currently being developed. The interface will show a preview of the detection capabilities.
|
|
|
|
|
|
|
|
|
98 |
|
99 |
+
## 📝 Dataset Information
|
100 |
|
101 |
+
- **Format**: COCO annotation format
|
102 |
+
- **Image Size**: 640×640 pixels
|
103 |
+
- **Training Images**: 50+ annotated cube images
|
104 |
+
- **Classes**: 7 object classes (face + 6 colors)
|
105 |
+
- **Annotation Tool**: LabelMe
|
106 |
|
107 |
+
## 🔧 Training Pipeline
|
108 |
|
109 |
+
```python
|
110 |
+
# Training command
|
111 |
+
python src/model/trainer.py --config configs/retinanet_config.py
|
112 |
|
113 |
+
# Inference command
|
114 |
+
python src/model/visualize.py --image path/to/cube_image.jpg
|
115 |
+
```
|
|
|
116 |
|
117 |
## 🤝 Contributing
|
118 |
|
119 |
+
Contributions are welcome! Areas for improvement:
|
120 |
+
- Additional training data
|
121 |
+
- Model optimization
|
122 |
+
- UI/UX enhancements
|
123 |
+
- Performance improvements
|
124 |
|
125 |
## 📄 License
|
126 |
|
|
|
128 |
|
129 |
## 🙏 Acknowledgements
|
130 |
|
131 |
+
- **TensorFlow Model Garden** - RetinaNet implementation
|
132 |
+
- **SpineNet** - Backbone architecture
|
133 |
+
- **Gradio** - Web interface framework
|
134 |
+
- **Hugging Face** - Model hosting and deployment
|
135 |
|
136 |
## 📧 Contact
|
137 |
|
138 |
+
- **GitHub**: [@itsyuimorii](https://github.com/itsyuimorii)
|
139 |
+
- **Hugging Face**: [@itsyuimorii](https://huggingface.co/itsyuimorii)
|
140 |
+
|
141 |
+
## 🔗 References
|
142 |
+
|
143 |
+
- [RetinaNet Paper](https://arxiv.org/abs/1708.02002)
|
144 |
+
- [SpineNet Architecture](https://arxiv.org/abs/1912.05027)
|
145 |
+
- [TensorFlow Object Detection API](https://github.com/tensorflow/models/tree/master/research/object_detection)
|
146 |
+
- [LabelMe Annotation Tool](https://github.com/wkentaro/labelme)
|
147 |
+
|
148 |
+
---
|
149 |
|
150 |
+
*🎲 Ready to solve your Rubik's cube detection challenges!*
|
151 |
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
|
|
|
|
|
153 |
|
|
|
|
app.py
CHANGED
@@ -1,8 +1,6 @@
|
|
1 |
import gradio as gr
|
2 |
-
import tensorflow as tf
|
3 |
import numpy as np
|
4 |
from PIL import Image
|
5 |
-
import cv2
|
6 |
import os
|
7 |
|
8 |
# Simplified category index
|
@@ -16,174 +14,84 @@ CATEGORY_INDEX = {
|
|
16 |
7: {'id': 7, 'name': 'yellow_tile'}
|
17 |
}
|
18 |
|
19 |
-
|
20 |
-
def preprocess_image(image):
|
21 |
-
"""
|
22 |
-
Preprocess input image
|
23 |
-
"""
|
24 |
-
if image is None:
|
25 |
-
return None
|
26 |
-
|
27 |
-
# Convert to PIL image
|
28 |
-
if isinstance(image, np.ndarray):
|
29 |
-
image = Image.fromarray(image)
|
30 |
-
|
31 |
-
# Resize to model expected size
|
32 |
-
image = image.resize((640, 640))
|
33 |
-
|
34 |
-
# Convert to numpy array and normalize
|
35 |
-
image_array = np.array(image) / 255.0
|
36 |
-
|
37 |
-
# Add batch dimension
|
38 |
-
image_array = np.expand_dims(image_array, axis=0)
|
39 |
-
|
40 |
-
return image_array.astype(np.float32)
|
41 |
-
|
42 |
-
|
43 |
-
def load_model():
|
44 |
-
"""
|
45 |
-
Load pretrained model
|
46 |
-
"""
|
47 |
-
try:
|
48 |
-
# Try to load saved model
|
49 |
-
if os.path.exists('exported_model'):
|
50 |
-
model = tf.saved_model.load('exported_model')
|
51 |
-
return model
|
52 |
-
else:
|
53 |
-
# If no model file exists, return None
|
54 |
-
return None
|
55 |
-
except Exception as e:
|
56 |
-
print(f"Model loading failed: {e}")
|
57 |
-
return None
|
58 |
-
|
59 |
-
|
60 |
def predict_image(image):
|
61 |
"""
|
62 |
-
Make predictions on input image
|
63 |
"""
|
64 |
if image is None:
|
65 |
return "Please upload an image", None
|
66 |
|
67 |
try:
|
68 |
-
#
|
69 |
-
|
70 |
-
|
71 |
-
if processed_image is None:
|
72 |
-
return "Image preprocessing failed", None
|
73 |
-
|
74 |
-
# Load model
|
75 |
-
model = load_model()
|
76 |
-
|
77 |
-
if model is None:
|
78 |
-
return "Model not found. This is a demo version, actual model needs to be trained first.\n\nDetected a Rubik's cube image!", image
|
79 |
-
|
80 |
-
# Make prediction
|
81 |
-
model_fn = model.signatures['serving_default']
|
82 |
-
|
83 |
-
# Convert input format
|
84 |
-
input_tensor = tf.convert_to_tensor(processed_image)
|
85 |
|
86 |
-
#
|
87 |
-
|
88 |
-
|
89 |
-
#
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
116 |
|
117 |
except Exception as e:
|
118 |
-
error_msg = f"Error
|
119 |
return error_msg, image
|
120 |
|
121 |
-
|
122 |
-
def draw_boxes_on_image(image, boxes, classes, scores):
|
123 |
-
"""
|
124 |
-
Draw detection boxes on image (simplified version)
|
125 |
-
"""
|
126 |
-
try:
|
127 |
-
# Convert to OpenCV format
|
128 |
-
if isinstance(image, Image.Image):
|
129 |
-
cv_image = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
|
130 |
-
else:
|
131 |
-
cv_image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
|
132 |
-
|
133 |
-
h, w = cv_image.shape[:2]
|
134 |
-
|
135 |
-
# Draw detection boxes
|
136 |
-
for box, cls, score in zip(boxes, classes, scores):
|
137 |
-
if score > 0.5:
|
138 |
-
# Convert coordinates (assuming normalized coordinates)
|
139 |
-
y1, x1, y2, x2 = box
|
140 |
-
x1, x2 = int(x1 * w), int(x2 * w)
|
141 |
-
y1, y2 = int(y1 * h), int(y2 * h)
|
142 |
-
|
143 |
-
# Draw rectangle
|
144 |
-
cv2.rectangle(cv_image, (x1, y1), (x2, y2), (0, 255, 0), 2)
|
145 |
-
|
146 |
-
# Add label
|
147 |
-
class_name = CATEGORY_INDEX.get(
|
148 |
-
cls, {}).get('name', f'class_{cls}')
|
149 |
-
label = f"{class_name}: {score:.2f}"
|
150 |
-
cv2.putText(cv_image, label, (x1, y1-10),
|
151 |
-
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
|
152 |
-
|
153 |
-
# Convert back to RGB
|
154 |
-
result_image = cv2.cvtColor(cv_image, cv2.COLOR_BGR2RGB)
|
155 |
-
return Image.fromarray(result_image)
|
156 |
-
|
157 |
-
except Exception as e:
|
158 |
-
print(f"Error drawing detection boxes: {e}")
|
159 |
-
return image
|
160 |
-
|
161 |
-
# Create Gradio interface
|
162 |
-
|
163 |
-
|
164 |
def create_demo():
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
**Features:**
|
172 |
-
- Detect cube faces and color tiles
|
173 |
-
- Support 6 color recognition: Red, White, Blue, Orange, Green, Yellow
|
174 |
-
- Real-time detection and visualization
|
175 |
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
|
|
|
|
|
|
180 |
""")
|
181 |
|
182 |
with gr.Row():
|
183 |
-
with gr.Column():
|
|
|
|
|
184 |
input_image = gr.Image(
|
185 |
label="Upload Rubik's Cube Image",
|
186 |
-
type="pil"
|
|
|
187 |
)
|
188 |
|
189 |
analyze_btn = gr.Button(
|
@@ -191,42 +99,53 @@ def create_demo():
|
|
191 |
variant="primary",
|
192 |
size="lg"
|
193 |
)
|
194 |
-
|
195 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
result_text = gr.Textbox(
|
197 |
-
label="Detection
|
198 |
-
lines=
|
199 |
-
max_lines=15
|
|
|
200 |
)
|
201 |
|
202 |
output_image = gr.Image(
|
203 |
-
label="
|
204 |
-
type="pil"
|
|
|
205 |
)
|
206 |
|
207 |
-
#
|
208 |
-
gr.Markdown("### 📋 Usage Examples")
|
209 |
-
gr.Markdown(
|
210 |
-
"Upload Rubik's cube images similar to the following for testing:")
|
211 |
-
|
212 |
-
# Bind events
|
213 |
analyze_btn.click(
|
214 |
fn=predict_image,
|
215 |
inputs=[input_image],
|
216 |
outputs=[result_text, output_image]
|
217 |
)
|
218 |
|
219 |
-
# Auto-analyze when image is uploaded
|
220 |
input_image.change(
|
221 |
fn=predict_image,
|
222 |
inputs=[input_image],
|
223 |
outputs=[result_text, output_image]
|
224 |
)
|
225 |
|
226 |
-
|
|
|
|
|
|
|
|
|
|
|
227 |
|
|
|
228 |
|
229 |
-
# Launch application
|
230 |
if __name__ == "__main__":
|
231 |
demo = create_demo()
|
232 |
demo.launch(
|
|
|
1 |
import gradio as gr
|
|
|
2 |
import numpy as np
|
3 |
from PIL import Image
|
|
|
4 |
import os
|
5 |
|
6 |
# Simplified category index
|
|
|
14 |
7: {'id': 7, 'name': 'yellow_tile'}
|
15 |
}
|
16 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
def predict_image(image):
|
18 |
"""
|
19 |
+
Make predictions on input image - Demo version
|
20 |
"""
|
21 |
if image is None:
|
22 |
return "Please upload an image", None
|
23 |
|
24 |
try:
|
25 |
+
# Convert to PIL image if needed
|
26 |
+
if isinstance(image, np.ndarray):
|
27 |
+
image = Image.fromarray(image)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
+
# Get image information
|
30 |
+
width, height = image.size
|
31 |
+
|
32 |
+
# Demo response since model is not trained yet
|
33 |
+
result_text = f"""🎲 Rubik's Cube Analysis Results
|
34 |
+
|
35 |
+
📊 Image Information:
|
36 |
+
- Dimensions: {width} × {height} pixels
|
37 |
+
- Format: {getattr(image, 'format', 'PIL Image')}
|
38 |
+
|
39 |
+
🔍 Detection Status:
|
40 |
+
✅ Image uploaded successfully
|
41 |
+
✅ Image format is valid
|
42 |
+
⚠️ AI model is currently in development
|
43 |
+
|
44 |
+
📝 Demo Mode:
|
45 |
+
This is a preview of the Rubik's cube recognition system.
|
46 |
+
The complete RetinaNet model will detect:
|
47 |
+
|
48 |
+
🎯 Target Detection Classes:
|
49 |
+
- Cube faces
|
50 |
+
- Red tiles
|
51 |
+
- White tiles
|
52 |
+
- Blue tiles
|
53 |
+
- Orange tiles
|
54 |
+
- Green tiles
|
55 |
+
- Yellow tiles
|
56 |
+
|
57 |
+
🚀 Coming Soon:
|
58 |
+
- Real-time object detection
|
59 |
+
- Bounding box visualization
|
60 |
+
- Confidence scores
|
61 |
+
- 3D cube state analysis
|
62 |
+
"""
|
63 |
+
|
64 |
+
return result_text, image
|
65 |
|
66 |
except Exception as e:
|
67 |
+
error_msg = f"Error processing image: {str(e)}\n\nThis is a demo version."
|
68 |
return error_msg, image
|
69 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
70 |
def create_demo():
|
71 |
+
"""Create the Gradio interface"""
|
72 |
+
|
73 |
+
with gr.Blocks(
|
74 |
+
title="🎲 Rubik's Cube Recognition System",
|
75 |
+
theme=gr.themes.Soft()
|
76 |
+
) as demo:
|
|
|
|
|
|
|
|
|
77 |
|
78 |
+
gr.HTML("""
|
79 |
+
<div style="text-align: center; padding: 20px;">
|
80 |
+
<h1>🎲 Rubik's Cube Recognition System</h1>
|
81 |
+
<p style="font-size: 18px; color: #666;">
|
82 |
+
Deep Learning-based Rubik's Cube Detection using RetinaNet Architecture
|
83 |
+
</p>
|
84 |
+
</div>
|
85 |
""")
|
86 |
|
87 |
with gr.Row():
|
88 |
+
with gr.Column(scale=1):
|
89 |
+
gr.Markdown("### 📤 Upload Image")
|
90 |
+
|
91 |
input_image = gr.Image(
|
92 |
label="Upload Rubik's Cube Image",
|
93 |
+
type="pil",
|
94 |
+
height=350
|
95 |
)
|
96 |
|
97 |
analyze_btn = gr.Button(
|
|
|
99 |
variant="primary",
|
100 |
size="lg"
|
101 |
)
|
102 |
+
|
103 |
+
gr.Markdown("""
|
104 |
+
### 💡 Tips
|
105 |
+
- Upload clear images of Rubik's cubes
|
106 |
+
- Good lighting recommended
|
107 |
+
- JPG/PNG formats supported
|
108 |
+
""")
|
109 |
+
|
110 |
+
with gr.Column(scale=1):
|
111 |
+
gr.Markdown("### 📊 Analysis Results")
|
112 |
+
|
113 |
result_text = gr.Textbox(
|
114 |
+
label="Detection Report",
|
115 |
+
lines=12,
|
116 |
+
max_lines=15,
|
117 |
+
show_copy_button=True
|
118 |
)
|
119 |
|
120 |
output_image = gr.Image(
|
121 |
+
label="Processed Image",
|
122 |
+
type="pil",
|
123 |
+
height=350
|
124 |
)
|
125 |
|
126 |
+
# Event handlers
|
|
|
|
|
|
|
|
|
|
|
127 |
analyze_btn.click(
|
128 |
fn=predict_image,
|
129 |
inputs=[input_image],
|
130 |
outputs=[result_text, output_image]
|
131 |
)
|
132 |
|
|
|
133 |
input_image.change(
|
134 |
fn=predict_image,
|
135 |
inputs=[input_image],
|
136 |
outputs=[result_text, output_image]
|
137 |
)
|
138 |
|
139 |
+
gr.HTML("""
|
140 |
+
<div style="text-align: center; padding: 20px; margin-top: 20px; border-top: 1px solid #eee;">
|
141 |
+
<p><strong>🔬 Technology Stack:</strong> TensorFlow • RetinaNet • SpineNet-49 • Gradio</p>
|
142 |
+
<p><strong>📧 Contact:</strong> <a href="https://huggingface.co/itsyuimorii">@itsyuimorii</a></p>
|
143 |
+
</div>
|
144 |
+
""")
|
145 |
|
146 |
+
return demo
|
147 |
|
148 |
+
# Launch the application
|
149 |
if __name__ == "__main__":
|
150 |
demo = create_demo()
|
151 |
demo.launch(
|
deploy_to_hf.py
CHANGED
@@ -11,7 +11,6 @@ def deploy_to_huggingface():
|
|
11 |
"""Deploy the project to Hugging Face Spaces"""
|
12 |
|
13 |
# Set your token
|
14 |
-
token = "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"
|
15 |
|
16 |
# Initialize HF API
|
17 |
api = HfApi()
|
|
|
11 |
"""Deploy the project to Hugging Face Spaces"""
|
12 |
|
13 |
# Set your token
|
|
|
14 |
|
15 |
# Initialize HF API
|
16 |
api = HfApi()
|
requirements.txt
CHANGED
@@ -1,6 +1,3 @@
|
|
1 |
gradio>=4.0.0
|
2 |
-
|
3 |
-
|
4 |
-
Pillow>=8.0.0
|
5 |
-
opencv-python-headless>=4.5.1
|
6 |
-
matplotlib>=3.2.2
|
|
|
1 |
gradio>=4.0.0
|
2 |
+
numpy>=1.21.0
|
3 |
+
Pillow>=8.0.0
|
|
|
|
|
|