EtanHey commited on
Commit
99710e8
·
verified ·
1 Parent(s): 5b806fe

Update model card with cleaner examples

Browse files
Files changed (1) hide show
  1. README.md +121 -141
README.md CHANGED
@@ -10,11 +10,11 @@ library_name: ultralytics
10
  # Hand Detection Model (YOLOv8)
11
 
12
  This model classifies images into three categories:
13
- - **hand**: Close-up hand with fingers visible
14
- - **arm**: Forearm or elbow area
15
- - **not_hand**: Neither hand nor arm
16
 
17
- ## Usage
18
 
19
  ```python
20
  from ultralytics import YOLO
@@ -25,195 +25,175 @@ model = YOLO('https://huggingface.co/EtanHey/hand-detection-3class/resolve/main/
25
  # Predict on an image
26
  results = model.predict('image.jpg')
27
 
28
- # Get predictions
29
- if results and results[0].probs:
30
- probs = results[0].probs
31
- top_class = probs.top1 # 0=hand, 1=arm, 2=not_hand
32
- confidence = probs.top1conf.item()
33
-
34
- classes = ['hand', 'arm', 'not_hand']
35
- print(f"Detected: {classes[top_class]} ({confidence:.1%})")
 
 
 
 
36
  ```
37
 
38
- ## Usage in Next.js/Node.js
39
 
40
- ### Option 1: Python API Backend
 
 
41
 
42
- ```javascript
43
- // app/api/detect/route.js (Next.js 13+ App Router)
44
- export async function POST(request) {
45
- const formData = await request.formData();
46
- const image = formData.get('image');
47
 
48
- // Call Python backend
49
- const response = await fetch('http://localhost:8000/predict', {
50
- method: 'POST',
51
- body: formData
52
- });
53
 
54
- const result = await response.json();
55
- return Response.json(result);
56
- }
57
 
58
- // Frontend component
59
- async function detectHand(file) {
60
- const formData = new FormData();
61
- formData.append('image', file);
62
 
63
- const response = await fetch('/api/detect', {
64
- method: 'POST',
65
- body: formData
66
- });
67
 
68
- const result = await response.json();
69
- // result = { class: 'hand', confidence: 0.98 }
70
- return result;
71
- }
 
72
  ```
73
 
74
- ### Option 2: Python Microservice (FastAPI)
 
 
75
 
 
76
  ```python
77
- # backend/api.py
78
  from fastapi import FastAPI, File, UploadFile
79
  from ultralytics import YOLO
80
- import numpy as np
81
  from PIL import Image
82
  import io
83
 
84
  app = FastAPI()
85
  model = YOLO('https://huggingface.co/EtanHey/hand-detection-3class/resolve/main/model.pt')
86
 
87
- @app.post("/predict")
88
- async def predict(file: UploadFile = File(...)):
89
- contents = await file.read()
90
- image = Image.open(io.BytesIO(contents))
91
-
92
  results = model.predict(image)
93
  probs = results[0].probs
94
 
95
- classes = ['hand', 'arm', 'not_hand']
96
  return {
97
- "class": classes[probs.top1],
98
- "confidence": float(probs.top1conf),
99
- "all_probs": {
100
- "hand": float(probs.data[0]),
101
- "arm": float(probs.data[1]),
102
- "not_hand": float(probs.data[2])
103
- }
104
  }
105
  ```
106
 
107
- ### Option 3: Using ONNX.js (Browser-based)
108
-
109
  ```javascript
110
- // First convert model to ONNX (run once)
111
- // python3 -c "from ultralytics import YOLO; YOLO('model.pt').export(format='onnx')"
 
112
 
113
- import * as ort from 'onnxruntime-web';
 
 
 
114
 
115
- async function detectHandBrowser(imageElement) {
116
- // Load ONNX model
117
- const session = await ort.InferenceSession.create('/model.onnx');
 
118
 
119
- // Preprocess image to 224x224
120
- const tensor = preprocessImage(imageElement);
121
 
122
- // Run inference
123
- const results = await session.run({ input: tensor });
124
- const probs = results.output.data;
 
 
 
125
 
126
- // Get prediction
127
- const classes = ['hand', 'arm', 'not_hand'];
128
- const maxIdx = probs.indexOf(Math.max(...probs));
129
 
130
- return {
131
- class: classes[maxIdx],
132
- confidence: probs[maxIdx],
133
- all_probs: {
134
- hand: probs[0],
135
- arm: probs[1],
136
- not_hand: probs[2]
137
- }
138
- };
139
- }
140
  ```
141
 
142
- ## Usage in React Native
143
 
144
  ```javascript
145
- import { launchImageLibrary } from 'react-native-image-picker';
146
-
147
- const detectHand = async () => {
148
- const result = await launchImageLibrary({ mediaType: 'photo' });
149
-
150
- if (result.assets) {
151
- const formData = new FormData();
152
- formData.append('image', {
153
- uri: result.assets[0].uri,
154
- type: 'image/jpeg',
155
- name: 'photo.jpg'
156
- });
157
-
158
- const response = await fetch('YOUR_API_URL/predict', {
159
- method: 'POST',
160
- body: formData
161
- });
162
-
163
- const detection = await response.json();
164
- console.log('Detected:', detection.class, detection.confidence);
165
- }
166
  };
167
  ```
168
 
169
- ## Usage with cURL
170
 
171
  ```bash
172
- # Test the model with cURL
173
- curl -X POST -F "image=@test.jpg" http://your-api-url/predict
174
-
175
- # Response: {"class": "hand", "confidence": 0.98}
176
  ```
177
 
178
- ## Usage in Swift (iOS)
179
-
180
- ```swift
181
- import CoreML
182
- import Vision
183
-
184
- func detectHand(image: UIImage) {
185
- // First convert YOLO to CoreML format
186
- // Then use in iOS app:
187
 
188
- guard let model = try? VNCoreMLModel(for: HandDetector().model) else { return }
 
 
 
 
189
 
190
- let request = VNCoreMLRequest(model: model) { request, error in
191
- guard let results = request.results as? [VNClassificationObservation] else { return }
192
 
193
- if let topResult = results.first {
194
- let className = topResult.identifier // "hand", "arm", or "not_hand"
195
- let confidence = topResult.confidence
196
- print("Detected: \(className) with \(confidence * 100)% confidence")
197
- }
198
- }
199
 
200
- // Process image...
201
- }
202
- ```
203
 
204
- ## Model Details
 
 
 
 
205
 
206
- - **Architecture**: YOLOv8s-cls
207
- - **Classes**: 3 (hand, arm, not_hand)
208
- - **Input Size**: 224x224
209
- - **Training Data**: 1740 images
210
- - **Accuracy**: >96%
211
 
212
- ## Training Details
213
 
214
- Trained on a custom dataset with:
215
- - 704 hand images
216
- - 320 arm images
217
- - 462 not_hand images
218
 
219
- Split 80/20 for training/validation.
 
 
 
 
 
 
 
 
 
 
10
  # Hand Detection Model (YOLOv8)
11
 
12
  This model classifies images into three categories:
13
+ - **hand**: Close-up hand with fingers visible (✋)
14
+ - **arm**: Forearm or elbow area (💪)
15
+ - **not_hand**: Neither hand nor arm (❌)
16
 
17
+ ## Quick Start
18
 
19
  ```python
20
  from ultralytics import YOLO
 
25
  # Predict on an image
26
  results = model.predict('image.jpg')
27
 
28
+ # Get the prediction
29
+ probs = results[0].probs
30
+ class_id = probs.top1 # 0=hand, 1=arm, 2=not_hand
31
+ confidence = probs.top1conf.item()
32
+
33
+ # Interpret results
34
+ if class_id == 0:
35
+ print(f"✋ Hand detected: {confidence:.1%}")
36
+ elif class_id == 1:
37
+ print(f"💪 Arm detected: {confidence:.1%}")
38
+ else:
39
+ print(f"❌ No hand/arm detected: {confidence:.1%}")
40
  ```
41
 
42
+ ## Live Demo (Webcam)
43
 
44
+ ```python
45
+ import cv2
46
+ from ultralytics import YOLO
47
 
48
+ model = YOLO('https://huggingface.co/EtanHey/hand-detection-3class/resolve/main/model.pt')
49
+ cap = cv2.VideoCapture(0)
 
 
 
50
 
51
+ while True:
52
+ ret, frame = cap.read()
53
+ if not ret:
54
+ break
 
55
 
56
+ results = model(frame)
57
+ probs = results[0].probs
 
58
 
59
+ classes = ['hand', 'arm', 'not_hand']
60
+ label = f"{classes[probs.top1]}: {probs.top1conf:.1%}"
 
 
61
 
62
+ cv2.putText(frame, label, (10, 30),
63
+ cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
64
+ cv2.imshow('Hand Detection', frame)
 
65
 
66
+ if cv2.waitKey(1) & 0xFF == ord('q'):
67
+ break
68
+
69
+ cap.release()
70
+ cv2.destroyAllWindows()
71
  ```
72
 
73
+ ## Use in Next.js/Node.js
74
+
75
+ ### Option 1: FastAPI Backend + Next.js
76
 
77
+ **Backend (Python):**
78
  ```python
 
79
  from fastapi import FastAPI, File, UploadFile
80
  from ultralytics import YOLO
 
81
  from PIL import Image
82
  import io
83
 
84
  app = FastAPI()
85
  model = YOLO('https://huggingface.co/EtanHey/hand-detection-3class/resolve/main/model.pt')
86
 
87
+ @app.post("/detect")
88
+ async def detect(file: UploadFile = File(...)):
89
+ image = Image.open(io.BytesIO(await file.read()))
 
 
90
  results = model.predict(image)
91
  probs = results[0].probs
92
 
 
93
  return {
94
+ "class": ['hand', 'arm', 'not_hand'][probs.top1],
95
+ "confidence": float(probs.top1conf)
 
 
 
 
 
96
  }
97
  ```
98
 
99
+ **Frontend (Next.js):**
 
100
  ```javascript
101
+ async function detectHand(imageFile) {
102
+ const formData = new FormData();
103
+ formData.append('file', imageFile);
104
 
105
+ const response = await fetch('http://localhost:8000/detect', {
106
+ method: 'POST',
107
+ body: formData
108
+ });
109
 
110
+ const result = await response.json();
111
+ console.log(`Detected: ${result.class} (${result.confidence * 100}%)`);
112
+ }
113
+ ```
114
 
115
+ ### Option 2: ONNX for Browser
 
116
 
117
+ ```bash
118
+ # Convert to ONNX first
119
+ from ultralytics import YOLO
120
+ model = YOLO('model.pt')
121
+ model.export(format='onnx')
122
+ ```
123
 
124
+ Then use with ONNX Runtime Web:
125
+ ```javascript
126
+ import * as ort from 'onnxruntime-web';
127
 
128
+ const session = await ort.InferenceSession.create('/model.onnx');
129
+ // Process and run inference...
 
 
 
 
 
 
 
 
130
  ```
131
 
132
+ ## React Native
133
 
134
  ```javascript
135
+ const detectHand = async (imageUri) => {
136
+ const formData = new FormData();
137
+ formData.append('image', {
138
+ uri: imageUri,
139
+ type: 'image/jpeg',
140
+ name: 'photo.jpg'
141
+ });
142
+
143
+ const response = await fetch('YOUR_API_URL/detect', {
144
+ method: 'POST',
145
+ body: formData
146
+ });
147
+
148
+ const result = await response.json();
149
+ Alert.alert(`Detected: ${result.class}`);
 
 
 
 
 
 
150
  };
151
  ```
152
 
153
+ ## cURL Test
154
 
155
  ```bash
156
+ curl -X POST -F "file=@test.jpg" http://localhost:8000/detect
 
 
 
157
  ```
158
 
159
+ ## Model Details
 
 
 
 
 
 
 
 
160
 
161
+ - **Architecture**: YOLOv8s-cls (5M parameters)
162
+ - **Classes**: 3 (hand, arm, not_hand)
163
+ - **Input Size**: 224x224
164
+ - **Accuracy**: >96% on validation set
165
+ - **Size**: ~3MB
166
 
167
+ ## Training Data
 
168
 
169
+ - **Total Images**: 1,740
170
+ - **Distribution**:
171
+ - Hand: 704 images (40%)
172
+ - Arm: 320 images (18%)
173
+ - Not Hand: 462 images (27%)
174
+ - Val: 254 images (15%)
175
 
176
+ ## Performance
 
 
177
 
178
+ | Metric | Value |
179
+ |--------|-------|
180
+ | Validation Accuracy | 96.3% |
181
+ | Inference Speed | 30+ FPS (Apple M1) |
182
+ | Model Size | 2.97 MB |
183
 
184
+ ## License
 
 
 
 
185
 
186
+ MIT - Free for commercial use
187
 
188
+ ## Citation
 
 
 
189
 
190
+ If you use this model, please cite:
191
+ ```
192
+ @software{hand_detection_yolo_2024,
193
+ author = {EtanHey},
194
+ title = {Hand Detection YOLOv8 Model},
195
+ year = {2024},
196
+ publisher = {HuggingFace},
197
+ url = {https://huggingface.co/EtanHey/hand-detection-3class}
198
+ }
199
+ ```