David Driscoll commited on
Commit
dfc63b4
·
1 Parent(s): d33634b

Add description

Browse files
Files changed (1) hide show
  1. app.py +43 -34
app.py CHANGED
@@ -24,7 +24,7 @@ DESIRED_SIZE = (640, 480)
24
  # -----------------------------
25
  posture_cache = {"landmarks": None, "text": "Initializing...", "counter": 0}
26
  emotion_cache = {"text": "Initializing...", "counter": 0}
27
- objects_cache = {"boxes": None, "text": "Initializing...", "counter": 0}
28
  faces_cache = {"boxes": None, "text": "Initializing...", "counter": 0}
29
 
30
  # -----------------------------
@@ -47,6 +47,9 @@ obj_transform = transforms.Compose([transforms.ToTensor()])
47
  # Initialize the FER emotion detector
48
  emotion_detector = FER(mtcnn=True)
49
 
 
 
 
50
  # -----------------------------
51
  # Overlay Drawing Functions
52
  # -----------------------------
@@ -120,11 +123,16 @@ def compute_objects_overlay(image):
120
 
121
  threshold = 0.8
122
  boxes = []
123
- for box, score in zip(detections["boxes"], detections["scores"]):
 
124
  if score > threshold:
125
  boxes.append(tuple(box.int().cpu().numpy()))
 
 
 
126
  text = f"Detected {len(boxes)} object(s)" if boxes else "No objects detected"
127
- return boxes, text
 
128
 
129
  def compute_faces_overlay(image):
130
  frame_bgr = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
@@ -182,14 +190,16 @@ def analyze_objects_current(image):
182
  objects_cache["counter"] += 1
183
  current_frame = np.array(image)
184
  if objects_cache["counter"] % SKIP_RATE == 0 or objects_cache["boxes"] is None:
185
- boxes, text = compute_objects_overlay(image)
186
  objects_cache["boxes"] = boxes
187
  objects_cache["text"] = text
 
188
 
189
  output = current_frame.copy()
190
  if objects_cache["boxes"]:
191
  output = draw_boxes_overlay(output, objects_cache["boxes"], (255, 255, 0))
192
- return output, f"<div style='color: lime !important;'>Object Detection: {objects_cache['text']}</div>"
 
193
 
194
  def analyze_faces_current(image):
195
  global faces_cache
@@ -206,7 +216,6 @@ def analyze_faces_current(image):
206
  return output, f"<div style='color: lime !important;'>Face Detection: {faces_cache['text']}</div>"
207
 
208
  def analyze_all(image):
209
- # Run all analyses on the same image
210
  current_frame = np.array(image).copy()
211
 
212
  # Posture Analysis
@@ -218,7 +227,7 @@ def analyze_all(image):
218
  emotion_text = compute_emotion_overlay(image)
219
 
220
  # Object Detection
221
- boxes_obj, objects_text = compute_objects_overlay(image)
222
  if boxes_obj:
223
  current_frame = draw_boxes_overlay(current_frame, boxes_obj, (255, 255, 0))
224
 
@@ -227,26 +236,37 @@ def analyze_all(image):
227
  if boxes_face:
228
  current_frame = draw_boxes_overlay(current_frame, boxes_face, (0, 0, 255))
229
 
 
230
  combined_text = (
231
- f"Posture Analysis: {posture_text}<br>"
232
- f"Emotion Analysis: {emotion_text}<br>"
233
- f"Object Detection: {objects_text}<br>"
234
- f"Face Detection: {faces_text}"
 
235
  )
 
 
 
 
 
 
 
 
 
236
  combined_text_html = f"<div style='color: lime !important;'>{combined_text}</div>"
237
  return current_frame, combined_text_html
238
 
239
  # -----------------------------
240
- # Custom CSS (High-Tech Theme)
241
  # -----------------------------
242
  custom_css = """
243
  @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&display=swap');
244
  body {
245
  background-color: #0e0e0e;
246
- color: #ffffff;
247
  font-family: 'Orbitron', sans-serif;
248
  margin: 0;
249
  padding: 0;
 
250
  }
251
  .gradio-container {
252
  background: linear-gradient(135deg, #1a1a1a, #333333);
@@ -257,23 +277,14 @@ body {
257
  max-width: 1200px;
258
  margin: auto;
259
  }
260
- .gradio-title {
261
- font-size: 2.5em;
262
- color: #32CD32;
263
- text-align: center;
264
- margin-bottom: 0.2em;
265
  text-shadow: 0 0 10px #32CD32;
266
  }
267
- .gradio-description {
268
- font-size: 1.2em;
269
- text-align: center;
270
- margin-bottom: 1em;
271
- color: #32CD32;
272
- text-shadow: 0 0 8px #32CD32;
273
- }
274
- input, button, .output, .tab-item {
275
  border: 1px solid #32CD32;
276
  box-shadow: 0 0 8px #32CD32;
 
277
  }
278
  """
279
 
@@ -284,7 +295,7 @@ posture_interface = gr.Interface(
284
  fn=analyze_posture_current,
285
  inputs=gr.Image(label="Upload an Image for Posture Analysis"),
286
  outputs=[gr.Image(type="numpy", label="Annotated Output"), gr.HTML(label="Posture Analysis")],
287
- title="Posture Analysis",
288
  description="Detects your posture using MediaPipe with connector lines.",
289
  live=False
290
  )
@@ -293,7 +304,7 @@ emotion_interface = gr.Interface(
293
  fn=analyze_emotion_current,
294
  inputs=gr.Image(label="Upload an Image for Emotion Analysis"),
295
  outputs=[gr.Image(type="numpy", label="Annotated Output"), gr.HTML(label="Emotion Analysis")],
296
- title="Emotion Analysis",
297
  description="Detects facial emotions using FER.",
298
  live=False
299
  )
@@ -302,7 +313,7 @@ objects_interface = gr.Interface(
302
  fn=analyze_objects_current,
303
  inputs=gr.Image(label="Upload an Image for Object Detection"),
304
  outputs=[gr.Image(type="numpy", label="Annotated Output"), gr.HTML(label="Object Detection")],
305
- title="Object Detection",
306
  description="Detects objects using a pretrained Faster R-CNN.",
307
  live=False
308
  )
@@ -311,7 +322,7 @@ faces_interface = gr.Interface(
311
  fn=analyze_faces_current,
312
  inputs=gr.Image(label="Upload an Image for Face Detection"),
313
  outputs=[gr.Image(type="numpy", label="Annotated Output"), gr.HTML(label="Face Detection")],
314
- title="Face Detection",
315
  description="Detects faces using MediaPipe.",
316
  live=False
317
  )
@@ -338,10 +349,8 @@ tabbed_interface = gr.TabbedInterface(
338
  # -----------------------------
339
  demo = gr.Blocks(css=custom_css)
340
  with demo:
341
- gr.Markdown("<h1 class='gradio-title'>Multi-Analysis Image App</h1>")
342
- gr.Markdown(
343
- "<p class='gradio-description'>Upload an image to run high-tech analysis for posture, emotions, objects, and faces.</p>"
344
- )
345
  tabbed_interface.render()
346
 
347
  if __name__ == "__main__":
 
24
  # -----------------------------
25
  posture_cache = {"landmarks": None, "text": "Initializing...", "counter": 0}
26
  emotion_cache = {"text": "Initializing...", "counter": 0}
27
+ objects_cache = {"boxes": None, "text": "Initializing...", "object_list_text": "", "counter": 0}
28
  faces_cache = {"boxes": None, "text": "Initializing...", "counter": 0}
29
 
30
  # -----------------------------
 
47
  # Initialize the FER emotion detector
48
  emotion_detector = FER(mtcnn=True)
49
 
50
+ # Retrieve object categories from model weights metadata
51
+ object_categories = FasterRCNN_ResNet50_FPN_Weights.DEFAULT.meta["categories"]
52
+
53
  # -----------------------------
54
  # Overlay Drawing Functions
55
  # -----------------------------
 
123
 
124
  threshold = 0.8
125
  boxes = []
126
+ object_list = []
127
+ for box, score, label in zip(detections["boxes"], detections["scores"], detections["labels"]):
128
  if score > threshold:
129
  boxes.append(tuple(box.int().cpu().numpy()))
130
+ label_idx = int(label)
131
+ label_name = object_categories[label_idx] if label_idx < len(object_categories) else "Unknown"
132
+ object_list.append(f"{label_name} ({score:.2f})")
133
  text = f"Detected {len(boxes)} object(s)" if boxes else "No objects detected"
134
+ object_list_text = " | ".join(object_list) if object_list else "None"
135
+ return boxes, text, object_list_text
136
 
137
  def compute_faces_overlay(image):
138
  frame_bgr = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
 
190
  objects_cache["counter"] += 1
191
  current_frame = np.array(image)
192
  if objects_cache["counter"] % SKIP_RATE == 0 or objects_cache["boxes"] is None:
193
+ boxes, text, object_list_text = compute_objects_overlay(image)
194
  objects_cache["boxes"] = boxes
195
  objects_cache["text"] = text
196
+ objects_cache["object_list_text"] = object_list_text
197
 
198
  output = current_frame.copy()
199
  if objects_cache["boxes"]:
200
  output = draw_boxes_overlay(output, objects_cache["boxes"], (255, 255, 0))
201
+ combined_text = f"Object Detection: {objects_cache['text']}<br>Details: {objects_cache['object_list_text']}"
202
+ return output, f"<div style='color: lime !important;'>{combined_text}</div>"
203
 
204
  def analyze_faces_current(image):
205
  global faces_cache
 
216
  return output, f"<div style='color: lime !important;'>Face Detection: {faces_cache['text']}</div>"
217
 
218
  def analyze_all(image):
 
219
  current_frame = np.array(image).copy()
220
 
221
  # Posture Analysis
 
227
  emotion_text = compute_emotion_overlay(image)
228
 
229
  # Object Detection
230
+ boxes_obj, objects_text, object_list_text = compute_objects_overlay(image)
231
  if boxes_obj:
232
  current_frame = draw_boxes_overlay(current_frame, boxes_obj, (255, 255, 0))
233
 
 
236
  if boxes_face:
237
  current_frame = draw_boxes_overlay(current_frame, boxes_face, (0, 0, 255))
238
 
239
+ # Combined Analysis Text
240
  combined_text = (
241
+ f"<b>Posture Analysis:</b> {posture_text}<br>"
242
+ f"<b>Emotion Analysis:</b> {emotion_text}<br>"
243
+ f"<b>Object Detection:</b> {objects_text}<br>"
244
+ f"<b>Detected Objects:</b> {object_list_text}<br>"
245
+ f"<b>Face Detection:</b> {faces_text}"
246
  )
247
+
248
+ # Image Description Panel (High-Tech)
249
+ if object_list_text and object_list_text != "None":
250
+ description_text = f"Image Description: The scene features {object_list_text}."
251
+ else:
252
+ description_text = "Image Description: No prominent objects detected."
253
+
254
+ combined_text += f"<br><br><div style='border:1px solid lime; padding:10px; box-shadow: 0 0 10px lime;'><b>{description_text}</b></div>"
255
+
256
  combined_text_html = f"<div style='color: lime !important;'>{combined_text}</div>"
257
  return current_frame, combined_text_html
258
 
259
  # -----------------------------
260
+ # Custom CSS (High-Tech Neon Theme)
261
  # -----------------------------
262
  custom_css = """
263
  @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&display=swap');
264
  body {
265
  background-color: #0e0e0e;
 
266
  font-family: 'Orbitron', sans-serif;
267
  margin: 0;
268
  padding: 0;
269
+ color: #32CD32;
270
  }
271
  .gradio-container {
272
  background: linear-gradient(135deg, #1a1a1a, #333333);
 
277
  max-width: 1200px;
278
  margin: auto;
279
  }
280
+ .gradio-title, .gradio-description, .tab-item, .tab-item * {
281
+ color: #32CD32 !important;
 
 
 
282
  text-shadow: 0 0 10px #32CD32;
283
  }
284
+ input, button, .output {
 
 
 
 
 
 
 
285
  border: 1px solid #32CD32;
286
  box-shadow: 0 0 8px #32CD32;
287
+ color: #32CD32;
288
  }
289
  """
290
 
 
295
  fn=analyze_posture_current,
296
  inputs=gr.Image(label="Upload an Image for Posture Analysis"),
297
  outputs=[gr.Image(type="numpy", label="Annotated Output"), gr.HTML(label="Posture Analysis")],
298
+ title="Posture",
299
  description="Detects your posture using MediaPipe with connector lines.",
300
  live=False
301
  )
 
304
  fn=analyze_emotion_current,
305
  inputs=gr.Image(label="Upload an Image for Emotion Analysis"),
306
  outputs=[gr.Image(type="numpy", label="Annotated Output"), gr.HTML(label="Emotion Analysis")],
307
+ title="Emotion",
308
  description="Detects facial emotions using FER.",
309
  live=False
310
  )
 
313
  fn=analyze_objects_current,
314
  inputs=gr.Image(label="Upload an Image for Object Detection"),
315
  outputs=[gr.Image(type="numpy", label="Annotated Output"), gr.HTML(label="Object Detection")],
316
+ title="Objects",
317
  description="Detects objects using a pretrained Faster R-CNN.",
318
  live=False
319
  )
 
322
  fn=analyze_faces_current,
323
  inputs=gr.Image(label="Upload an Image for Face Detection"),
324
  outputs=[gr.Image(type="numpy", label="Annotated Output"), gr.HTML(label="Face Detection")],
325
+ title="Faces",
326
  description="Detects faces using MediaPipe.",
327
  live=False
328
  )
 
349
  # -----------------------------
350
  demo = gr.Blocks(css=custom_css)
351
  with demo:
352
+ gr.Markdown("<h1 class='gradio-title' style='color: #32CD32;'>Multi-Analysis Image App</h1>")
353
+ gr.Markdown("<p class='gradio-description' style='color: #32CD32;'>Upload an image to run high-tech analysis for posture, emotions, objects, and faces.</p>")
 
 
354
  tabbed_interface.render()
355
 
356
  if __name__ == "__main__":