Dhiryashil commited on
Commit
4c9ae97
Β·
verified Β·
1 Parent(s): 4019199

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +94 -12
  2. app.py +364 -0
  3. requirements.txt +8 -0
README.md CHANGED
@@ -1,12 +1,94 @@
1
- ---
2
- title: Farm Human Recognition
3
- emoji: πŸŒ–
4
- colorFrom: red
5
- colorTo: green
6
- sdk: gradio
7
- sdk_version: 5.49.0
8
- app_file: app.py
9
- pinned: false
10
- ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Farm Human Recognition API
3
+ emoji: πŸ‘₯
4
+ colorFrom: purple
5
+ colorTo: pink
6
+ sdk: gradio
7
+ sdk_version: 4.28.3
8
+ app_file: app.py
9
+ pinned: false
10
+ license: apache-2.0
11
+ short_description: Farm worker detection and safety analysis
12
+ ---
13
+
14
+ # πŸ‘₯ Farm Human Recognition API
15
+
16
+ Advanced farm worker detection and analysis using YOLOS models for workplace safety and productivity assessment.
17
+
18
+ ## 🎯 Capabilities
19
+ - **Worker Detection**: Precise identification of farm workers in images
20
+ - **Safety Analysis**: Workplace safety scoring and risk assessment
21
+ - **Activity Recognition**: Classification of farm work activities
22
+ - **Productivity Metrics**: Performance analysis and recommendations
23
+
24
+ ## πŸ€– Models
25
+ - **YOLOS Tiny**: Fastest processing for real-time applications
26
+ - **YOLOS Small**: Balanced accuracy and speed (recommended)
27
+ - **YOLOS Base**: Highest accuracy for detailed analysis
28
+
29
+ ## πŸ“‘ API Usage
30
+
31
+ ### Python
32
+ ```python
33
+ import requests
34
+ import base64
35
+
36
+ def detect_farm_workers(image_path, model="yolos_small"):
37
+ with open(image_path, "rb") as f:
38
+ image_b64 = base64.b64encode(f.read()).decode()
39
+
40
+ response = requests.post(
41
+ "https://YOUR-USERNAME-farm-human-recognition.hf.space/api/predict",
42
+ json={"data": [image_b64, model]}
43
+ )
44
+ return response.json()
45
+
46
+ result = detect_farm_workers("farm_workers.jpg")
47
+ print(result)
48
+ ```
49
+
50
+ ## πŸ“Š Response Format
51
+ ```json
52
+ {
53
+ "humans_detected": 3,
54
+ "detections": [
55
+ {
56
+ "class": "person",
57
+ "confidence": 0.92,
58
+ "bbox": [120, 45, 180, 200],
59
+ "activity": "ground_work",
60
+ "area": 7200
61
+ }
62
+ ],
63
+ "safety_analysis": {
64
+ "status": "safe",
65
+ "score": 0.85,
66
+ "concerns": [],
67
+ "workers_detected": 3
68
+ },
69
+ "productivity_metrics": {
70
+ "active_workers": 3,
71
+ "productivity_score": 0.75,
72
+ "activity_breakdown": {
73
+ "ground_work": 2,
74
+ "operating_equipment": 1
75
+ },
76
+ "recommendations": [
77
+ "Consider team coordination for efficiency"
78
+ ]
79
+ },
80
+ "processing_time": 1.5
81
+ }
82
+ ```
83
+
84
+ ## 🏭 Activity Classification
85
+ - **ground_work**: Field operations, planting, harvesting
86
+ - **close_work**: Inspection, detailed tasks, quality control
87
+ - **operating_equipment**: Tractor/machinery operation
88
+ - **general_activity**: Walking, standing, general movement
89
+
90
+ ## πŸ›‘οΈ Safety Features
91
+ - Automatic detection of high worker density
92
+ - Equipment operation safety analysis
93
+ - Workplace hazard identification
94
+ - Safety score calculation (0-1)
app.py ADDED
@@ -0,0 +1,364 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Farm Human Recognition API - Gradio Interface
3
+ YOLO and pose estimation models for farm worker detection
4
+ """
5
+
6
+ import gradio as gr
7
+ import torch
8
+ import cv2
9
+ import numpy as np
10
+ from PIL import Image
11
+ import json
12
+ import base64
13
+ import io
14
+ import time
15
+ from typing import List, Dict, Any
16
+
17
+ # Import models
18
+ try:
19
+ from transformers import YolosImageProcessor, YolosForObjectDetection
20
+ from transformers import AutoImageProcessor, AutoModelForObjectDetection
21
+ MODELS_AVAILABLE = True
22
+ except ImportError:
23
+ MODELS_AVAILABLE = False
24
+
25
+ class HumanRecognitionAPI:
26
+ def __init__(self):
27
+ self.models = {}
28
+ self.processors = {}
29
+ self.model_configs = {
30
+ "yolos_tiny": "hustvl/yolos-tiny",
31
+ "yolos_small": "hustvl/yolos-small",
32
+ "yolos_base": "hustvl/yolos-base"
33
+ }
34
+
35
+ # Human activity classes relevant to farming
36
+ self.farm_activities = {
37
+ "harvesting": ["picking", "collecting", "gathering", "harvesting"],
38
+ "planting": ["sowing", "planting", "seeding"],
39
+ "maintenance": ["pruning", "watering", "fertilizing", "weeding"],
40
+ "inspection": ["examining", "checking", "monitoring", "inspecting"],
41
+ "operation": ["driving", "operating", "machinery", "equipment"],
42
+ "general": ["working", "standing", "walking", "person"]
43
+ }
44
+
45
+ if MODELS_AVAILABLE:
46
+ self.load_models()
47
+
48
+ def load_models(self):
49
+ """Load human detection models"""
50
+ for model_key, model_name in self.model_configs.items():
51
+ try:
52
+ print(f"Loading {model_name}...")
53
+ processor = YolosImageProcessor.from_pretrained(model_name)
54
+ model = YolosForObjectDetection.from_pretrained(model_name)
55
+
56
+ self.processors[model_key] = processor
57
+ self.models[model_key] = model
58
+ print(f"βœ… {model_name} loaded successfully")
59
+ except Exception as e:
60
+ print(f"❌ Failed to load {model_name}: {e}")
61
+
62
+ def detect_humans(self, image: Image.Image, model_key: str = "yolos_small") -> Dict[str, Any]:
63
+ """Detect humans and analyze farm activities"""
64
+ if not MODELS_AVAILABLE or model_key not in self.models:
65
+ return {"error": "Model not available"}
66
+
67
+ start_time = time.time()
68
+
69
+ try:
70
+ # Preprocess image
71
+ processor = self.processors[model_key]
72
+ model = self.models[model_key]
73
+
74
+ inputs = processor(images=image, return_tensors="pt")
75
+
76
+ # Run inference
77
+ with torch.no_grad():
78
+ outputs = model(**inputs)
79
+
80
+ # Post-process results
81
+ target_sizes = torch.tensor([image.size[::-1]])
82
+ results = processor.post_process_object_detection(
83
+ outputs, threshold=0.5, target_sizes=target_sizes
84
+ )[0]
85
+
86
+ # Filter for human detections
87
+ human_detections = []
88
+ for score, label, box in zip(results["scores"], results["labels"], results["boxes"]):
89
+ class_name = model.config.id2label[label.item()].lower()
90
+ if "person" in class_name and score > 0.5:
91
+ human_detections.append({
92
+ "class": "person",
93
+ "confidence": float(score),
94
+ "bbox": [float(x) for x in box],
95
+ "area": float((box[2] - box[0]) * (box[3] - box[1])),
96
+ "activity": self.infer_activity(box, image.size)
97
+ })
98
+
99
+ # Analyze safety and productivity
100
+ safety_analysis = self.analyze_safety(human_detections, image.size)
101
+ productivity_metrics = self.calculate_productivity_metrics(human_detections)
102
+
103
+ processing_time = time.time() - start_time
104
+
105
+ return {
106
+ "humans_detected": len(human_detections),
107
+ "detections": human_detections,
108
+ "safety_analysis": safety_analysis,
109
+ "productivity_metrics": productivity_metrics,
110
+ "processing_time": round(processing_time, 2),
111
+ "model_used": model_key
112
+ }
113
+
114
+ except Exception as e:
115
+ return {"error": str(e)}
116
+
117
+ def infer_activity(self, bbox: List[float], image_size: tuple) -> str:
118
+ """Infer farm activity from bounding box characteristics"""
119
+ x1, y1, x2, y2 = bbox
120
+ width = x2 - x1
121
+ height = y2 - y1
122
+
123
+ # Simple activity inference based on pose characteristics
124
+ aspect_ratio = width / height
125
+ relative_size = (width * height) / (image_size[0] * image_size[1])
126
+
127
+ if aspect_ratio > 1.2: # Wide bounding box
128
+ return "operating_equipment"
129
+ elif relative_size > 0.1: # Large person in frame
130
+ return "close_work"
131
+ elif y2 > image_size[1] * 0.8: # Person near bottom
132
+ return "ground_work"
133
+ else:
134
+ return "general_activity"
135
+
136
+ def analyze_safety(self, detections: List[Dict], image_size: tuple) -> Dict[str, Any]:
137
+ """Analyze workplace safety factors"""
138
+ if not detections:
139
+ return {"status": "no_workers", "score": 1.0}
140
+
141
+ safety_score = 1.0
142
+ concerns = []
143
+
144
+ # Check worker density
145
+ workers_per_area = len(detections) / (image_size[0] * image_size[1] / 1000000) # per megapixel
146
+ if workers_per_area > 5:
147
+ safety_score -= 0.2
148
+ concerns.append("High worker density - ensure adequate spacing")
149
+
150
+ # Check for workers near equipment (simplified check)
151
+ for detection in detections:
152
+ if detection["activity"] == "operating_equipment":
153
+ # Check if other workers are nearby
154
+ nearby_workers = sum(1 for d in detections
155
+ if d != detection and self.calculate_distance(d["bbox"], detection["bbox"]) < 100)
156
+ if nearby_workers > 0:
157
+ safety_score -= 0.3
158
+ concerns.append("Workers detected near operating equipment")
159
+
160
+ return {
161
+ "status": "safe" if safety_score > 0.7 else "caution" if safety_score > 0.4 else "unsafe",
162
+ "score": max(0.0, safety_score),
163
+ "concerns": concerns,
164
+ "workers_detected": len(detections)
165
+ }
166
+
167
+ def calculate_distance(self, bbox1: List[float], bbox2: List[float]) -> float:
168
+ """Calculate distance between bounding box centers"""
169
+ center1 = [(bbox1[0] + bbox1[2]) / 2, (bbox1[1] + bbox1[3]) / 2]
170
+ center2 = [(bbox2[0] + bbox2[2]) / 2, (bbox2[1] + bbox2[3]) / 2]
171
+ return ((center1[0] - center2[0]) ** 2 + (center1[1] - center2[1]) ** 2) ** 0.5
172
+
173
+ def calculate_productivity_metrics(self, detections: List[Dict]) -> Dict[str, Any]:
174
+ """Calculate farm productivity metrics"""
175
+ if not detections:
176
+ return {"active_workers": 0, "productivity_score": 0.0}
177
+
178
+ activity_counts = {}
179
+ for detection in detections:
180
+ activity = detection["activity"]
181
+ activity_counts[activity] = activity_counts.get(activity, 0) + 1
182
+
183
+ # Simple productivity scoring
184
+ productive_activities = ["close_work", "ground_work", "operating_equipment"]
185
+ productive_workers = sum(activity_counts.get(activity, 0) for activity in productive_activities)
186
+ productivity_score = productive_workers / len(detections) if detections else 0
187
+
188
+ return {
189
+ "active_workers": len(detections),
190
+ "productivity_score": round(productivity_score, 2),
191
+ "activity_breakdown": activity_counts,
192
+ "recommendations": self.generate_productivity_recommendations(activity_counts)
193
+ }
194
+
195
+ def generate_productivity_recommendations(self, activity_counts: Dict[str, int]) -> List[str]:
196
+ """Generate productivity improvement recommendations"""
197
+ recommendations = []
198
+ total_workers = sum(activity_counts.values())
199
+
200
+ if activity_counts.get("general_activity", 0) > total_workers * 0.3:
201
+ recommendations.append("Consider assigning specific tasks to idle workers")
202
+
203
+ if activity_counts.get("operating_equipment", 0) > 1:
204
+ recommendations.append("Multiple equipment operators detected - ensure coordination")
205
+
206
+ if total_workers > 10:
207
+ recommendations.append("Large workforce detected - consider team organization")
208
+
209
+ return recommendations[:3] # Limit to 3 recommendations
210
+
211
+ def draw_detections(self, image: Image.Image, detections: List[Dict]) -> Image.Image:
212
+ """Draw bounding boxes and labels on image"""
213
+ img_array = np.array(image)
214
+
215
+ for detection in detections:
216
+ bbox = detection["bbox"]
217
+ x1, y1, x2, y2 = [int(coord) for coord in bbox]
218
+
219
+ # Draw bounding box
220
+ cv2.rectangle(img_array, (x1, y1), (x2, y2), (0, 255, 0), 2)
221
+
222
+ # Draw label
223
+ label = f"Worker {detection['confidence']:.2f}"
224
+ cv2.putText(img_array, label, (x1, y1-10),
225
+ cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2)
226
+
227
+ return Image.fromarray(img_array)
228
+
229
+ # Initialize API
230
+ api = HumanRecognitionAPI()
231
+
232
+ def predict_humans(image, model_choice):
233
+ """Gradio prediction function"""
234
+ if image is None:
235
+ return None, "Please upload an image"
236
+
237
+ # Convert to PIL Image
238
+ if isinstance(image, np.ndarray):
239
+ image = Image.fromarray(image)
240
+
241
+ # Run human detection
242
+ results = api.detect_humans(image, model_choice)
243
+
244
+ if "error" in results:
245
+ return None, f"Error: {results['error']}"
246
+
247
+ # Create visualization
248
+ annotated_image = api.draw_detections(image, results["detections"])
249
+
250
+ # Format results text
251
+ safety = results["safety_analysis"]
252
+ productivity = results["productivity_metrics"]
253
+
254
+ safety_emoji = "🟒" if safety["status"] == "safe" else "🟑" if safety["status"] == "caution" else "πŸ”΄"
255
+
256
+ results_text = f"""
257
+ πŸ‘₯ **Farm Worker Analysis**
258
+
259
+ {safety_emoji} **Safety Status**: {safety['status'].title()} (Score: {safety['score']:.1%})
260
+ πŸ‘· **Workers Detected**: {results['humans_detected']}
261
+ πŸ“Š **Productivity Score**: {productivity['productivity_score']:.1%}
262
+
263
+ **πŸ›‘οΈ Safety Analysis**:
264
+ """
265
+
266
+ if safety["concerns"]:
267
+ for concern in safety["concerns"]:
268
+ results_text += f"\n⚠️ {concern}"
269
+ else:
270
+ results_text += "\nβœ… No immediate safety concerns detected"
271
+
272
+ results_text += f"\n\n**πŸ“ˆ Productivity Metrics**:"
273
+ if productivity["activity_breakdown"]:
274
+ for activity, count in productivity["activity_breakdown"].items():
275
+ results_text += f"\nβ€’ {activity.replace('_', ' ').title()}: {count} workers"
276
+
277
+ if productivity["recommendations"]:
278
+ results_text += f"\n\n**πŸ’‘ Recommendations**:"
279
+ for rec in productivity["recommendations"]:
280
+ results_text += f"\nβ€’ {rec}"
281
+
282
+ return annotated_image, results_text
283
+
284
+ # Gradio Interface
285
+ with gr.Blocks(title="πŸ‘₯ Farm Human Recognition API") as app:
286
+ gr.Markdown("# πŸ‘₯ Farm Human Recognition API")
287
+ gr.Markdown("AI-powered farm worker detection, safety analysis, and productivity assessment")
288
+
289
+ with gr.Tab("πŸ‘· Worker Detection"):
290
+ with gr.Row():
291
+ with gr.Column():
292
+ image_input = gr.Image(type="pil", label="Upload Farm Image")
293
+ model_choice = gr.Dropdown(
294
+ choices=["yolos_tiny", "yolos_small", "yolos_base"],
295
+ value="yolos_small",
296
+ label="Select Model"
297
+ )
298
+ detect_btn = gr.Button("πŸ” Detect Workers", variant="primary")
299
+
300
+ with gr.Column():
301
+ output_image = gr.Image(label="Worker Detection Results")
302
+ results_text = gr.Textbox(label="Analysis Results", lines=20)
303
+
304
+ detect_btn.click(
305
+ predict_humans,
306
+ inputs=[image_input, model_choice],
307
+ outputs=[output_image, results_text]
308
+ )
309
+
310
+ with gr.Tab("πŸ“‘ API Documentation"):
311
+ gr.Markdown("""
312
+ ## πŸš€ API Endpoint
313
+
314
+ **POST** `/api/predict`
315
+
316
+ ### Request Format
317
+ ```json
318
+ {
319
+ "data": ["<base64_image>", "<model_choice>"]
320
+ }
321
+ ```
322
+
323
+ ### Model Options
324
+ - **yolos_tiny**: Fastest processing, basic accuracy
325
+ - **yolos_small**: Balanced performance (recommended)
326
+ - **yolos_base**: Highest accuracy, slower processing
327
+
328
+ ### Response Format
329
+ ```json
330
+ {
331
+ "humans_detected": 3,
332
+ "detections": [
333
+ {
334
+ "class": "person",
335
+ "confidence": 0.92,
336
+ "bbox": [120, 45, 180, 200],
337
+ "activity": "ground_work"
338
+ }
339
+ ],
340
+ "safety_analysis": {
341
+ "status": "safe",
342
+ "score": 0.85,
343
+ "concerns": []
344
+ },
345
+ "productivity_metrics": {
346
+ "active_workers": 3,
347
+ "productivity_score": 0.75,
348
+ "activity_breakdown": {
349
+ "ground_work": 2,
350
+ "operating_equipment": 1
351
+ }
352
+ }
353
+ }
354
+ ```
355
+
356
+ ### Activity Types
357
+ - **ground_work**: Workers performing field operations
358
+ - **close_work**: Detailed inspection or harvesting
359
+ - **operating_equipment**: Machinery operation
360
+ - **general_activity**: General farm activities
361
+ """)
362
+
363
+ if __name__ == "__main__":
364
+ app.launch()
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ torch>=2.0.0
2
+ torchvision>=0.15.0
3
+ transformers>=4.30.0
4
+ gradio>=4.28.3
5
+ Pillow>=9.0.0
6
+ opencv-python>=4.8.0
7
+ numpy>=1.21.0
8
+ huggingface-hub>=0.15.0