CosmicM commited on
Commit
4a93598
·
verified ·
1 Parent(s): 4cf0e36

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -26
app.py CHANGED
@@ -22,26 +22,30 @@ def cleanup_temp_files():
22
  # Register cleanup function
23
  atexit.register(cleanup_temp_files)
24
 
25
- def detect_objects_image(image):
26
  """Process image with YOLO detection."""
27
  if image is None:
28
- return None
29
 
30
  # Convert PIL image to numpy array
31
  image_np = np.array(image)
32
 
33
- # Perform detection
34
- results = model(image_np)
35
 
36
  # Get annotated image
37
  annotated_image = results[0].plot()
38
 
39
- return Image.fromarray(annotated_image)
 
 
 
 
40
 
41
- def detect_objects_video(video):
42
  """Process video with YOLO detection."""
43
  if video is None:
44
- return None
45
 
46
  # Read input video
47
  cap = cv2.VideoCapture(video)
@@ -50,12 +54,16 @@ def detect_objects_video(video):
50
  fps = int(cap.get(cv2.CAP_PROP_FPS))
51
  width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
52
  height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
 
53
 
54
  # Create output video file in our temp directory
55
  output_path = os.path.join(TEMP_DIR, f"output_{os.urandom(8).hex()}.mp4")
56
  fourcc = cv2.VideoWriter_fourcc(*'mp4v')
57
  out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
58
 
 
 
 
59
  try:
60
  # Process each frame
61
  while cap.isOpened():
@@ -63,20 +71,31 @@ def detect_objects_video(video):
63
  if not ret:
64
  break
65
 
66
- # Perform detection
67
- results = model(frame)
68
  annotated_frame = results[0].plot()
69
 
 
 
 
70
  # Convert RGB to BGR for cv2.VideoWriter
71
  annotated_frame_bgr = cv2.cvtColor(annotated_frame, cv2.COLOR_RGB2BGR)
72
 
73
  # Write annotated frame
74
  out.write(annotated_frame_bgr)
 
 
 
 
 
75
  finally:
76
  cap.release()
77
  out.release()
78
 
79
- return output_path
 
 
 
80
 
81
  # Periodic cleanup function to remove old processed videos
82
  def periodic_cleanup():
@@ -94,14 +113,23 @@ def periodic_cleanup():
94
  except Exception:
95
  pass
96
 
 
 
 
 
 
 
 
 
 
97
  # Create Gradio interface
98
- with gr.Blocks(title="YOLO Object Detection", theme=gr.themes.Soft()) as demo:
99
- gr.Markdown("# 🔍 YOLO Object Detection App")
100
- gr.Markdown("Upload an image or video to detect objects using YOLOv8!")
101
 
102
  with gr.Tabs():
103
  # Image Detection Tab
104
- with gr.TabItem("📸 Image Detection"):
105
  with gr.Row():
106
  with gr.Column():
107
  image_input = gr.Image(
@@ -109,59 +137,89 @@ with gr.Blocks(title="YOLO Object Detection", theme=gr.themes.Soft()) as demo:
109
  label="Upload Image",
110
  height=400
111
  )
112
- image_button = gr.Button("🔍 Detect Objects", variant="primary")
 
 
 
 
 
 
 
 
113
 
114
  with gr.Column():
115
  image_output = gr.Image(
116
  label="Detection Results",
117
  height=400
118
  )
 
 
 
 
119
 
120
  # Video Detection Tab
121
- with gr.TabItem("🎥 Video Detection"):
122
  with gr.Row():
123
  with gr.Column():
124
  video_input = gr.Video(
125
  label="Upload Video",
126
  height=400
127
  )
128
- video_button = gr.Button("🔍 Process Video", variant="primary")
 
 
 
 
 
 
 
 
129
 
130
  with gr.Column():
131
  video_output = gr.Video(
132
  label="Processed Video",
133
  height=400
134
  )
 
 
 
 
135
 
136
- gr.Markdown("⚠️ **Note:** Video processing may take some time depending on file size and length.")
137
 
138
  # Info section
139
- with gr.Accordion("ℹ️ About", open=False):
140
  gr.Markdown("""
141
  ### About This App
142
  - **Model:** YOLOv8 nano for efficient object detection
143
  - **Supported Images:** JPG, JPEG, PNG
144
  - **Supported Videos:** MP4, AVI, MOV, WebM
145
- - **Features:** Real-time detection, downloadable results
146
 
147
  ### How to Use
148
  1. Choose the **Image** or **Video** tab
149
  2. Upload your file
150
- 3. Click the detect/process button
151
- 4. Download your results
 
 
 
 
 
 
152
  """)
153
 
154
  # Connect functions to buttons
155
  image_button.click(
156
  fn=detect_objects_image,
157
- inputs=image_input,
158
- outputs=image_output
159
  )
160
 
161
  video_button.click(
162
  fn=detect_objects_video,
163
- inputs=video_input,
164
- outputs=video_output
165
  )
166
 
167
  # Run periodic cleanup every time the interface loads
 
22
  # Register cleanup function
23
  atexit.register(cleanup_temp_files)
24
 
25
+ def detect_objects_image(image, confidence):
26
  """Process image with YOLO detection."""
27
  if image is None:
28
+ return None, "No image provided"
29
 
30
  # Convert PIL image to numpy array
31
  image_np = np.array(image)
32
 
33
+ # Perform detection with confidence threshold
34
+ results = model(image_np, conf=confidence)
35
 
36
  # Get annotated image
37
  annotated_image = results[0].plot()
38
 
39
+ # Count detections
40
+ num_detections = len(results[0].boxes)
41
+ detection_info = f"Detected {num_detections} object(s) with confidence ≥ {confidence:.0%}"
42
+
43
+ return Image.fromarray(annotated_image), detection_info
44
 
45
+ def detect_objects_video(video, confidence, progress=gr.Progress()):
46
  """Process video with YOLO detection."""
47
  if video is None:
48
+ return None, "No video provided"
49
 
50
  # Read input video
51
  cap = cv2.VideoCapture(video)
 
54
  fps = int(cap.get(cv2.CAP_PROP_FPS))
55
  width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
56
  height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
57
+ total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
58
 
59
  # Create output video file in our temp directory
60
  output_path = os.path.join(TEMP_DIR, f"output_{os.urandom(8).hex()}.mp4")
61
  fourcc = cv2.VideoWriter_fourcc(*'mp4v')
62
  out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))
63
 
64
+ frame_count = 0
65
+ total_detections = 0
66
+
67
  try:
68
  # Process each frame
69
  while cap.isOpened():
 
71
  if not ret:
72
  break
73
 
74
+ # Perform detection with confidence threshold
75
+ results = model(frame, conf=confidence)
76
  annotated_frame = results[0].plot()
77
 
78
+ # Count detections in this frame
79
+ total_detections += len(results[0].boxes)
80
+
81
  # Convert RGB to BGR for cv2.VideoWriter
82
  annotated_frame_bgr = cv2.cvtColor(annotated_frame, cv2.COLOR_RGB2BGR)
83
 
84
  # Write annotated frame
85
  out.write(annotated_frame_bgr)
86
+
87
+ # Update progress
88
+ frame_count += 1
89
+ if total_frames > 0:
90
+ progress((frame_count / total_frames), desc=f"Processing frame {frame_count}/{total_frames}")
91
  finally:
92
  cap.release()
93
  out.release()
94
 
95
+ avg_detections = total_detections / frame_count if frame_count > 0 else 0
96
+ video_info = f"Processed {frame_count} frames | Total detections: {total_detections} | Average per frame: {avg_detections:.1f}"
97
+
98
+ return output_path, video_info
99
 
100
  # Periodic cleanup function to remove old processed videos
101
  def periodic_cleanup():
 
113
  except Exception:
114
  pass
115
 
116
+ # Custom CSS for Inter font
117
+ custom_css = """
118
+ @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
119
+
120
+ * {
121
+ font-family: 'Inter', sans-serif !important;
122
+ }
123
+ """
124
+
125
  # Create Gradio interface
126
+ with gr.Blocks(title="YOLO Object Detection", theme=gr.themes.Soft(), css=custom_css) as demo:
127
+ gr.Markdown("# YOLO Object Detection")
128
+ gr.Markdown("Upload an image or video to detect objects using YOLOv8")
129
 
130
  with gr.Tabs():
131
  # Image Detection Tab
132
+ with gr.TabItem("Image Detection"):
133
  with gr.Row():
134
  with gr.Column():
135
  image_input = gr.Image(
 
137
  label="Upload Image",
138
  height=400
139
  )
140
+ image_confidence = gr.Slider(
141
+ minimum=0.1,
142
+ maximum=1.0,
143
+ value=0.25,
144
+ step=0.05,
145
+ label="Confidence Threshold",
146
+ info="Minimum confidence for detection (lower = more detections)"
147
+ )
148
+ image_button = gr.Button("Detect Objects", variant="primary")
149
 
150
  with gr.Column():
151
  image_output = gr.Image(
152
  label="Detection Results",
153
  height=400
154
  )
155
+ image_info = gr.Textbox(
156
+ label="Detection Summary",
157
+ interactive=False
158
+ )
159
 
160
  # Video Detection Tab
161
+ with gr.TabItem("Video Detection"):
162
  with gr.Row():
163
  with gr.Column():
164
  video_input = gr.Video(
165
  label="Upload Video",
166
  height=400
167
  )
168
+ video_confidence = gr.Slider(
169
+ minimum=0.1,
170
+ maximum=1.0,
171
+ value=0.25,
172
+ step=0.05,
173
+ label="Confidence Threshold",
174
+ info="Minimum confidence for detection (lower = more detections)"
175
+ )
176
+ video_button = gr.Button("Process Video", variant="primary")
177
 
178
  with gr.Column():
179
  video_output = gr.Video(
180
  label="Processed Video",
181
  height=400
182
  )
183
+ video_info = gr.Textbox(
184
+ label="Processing Summary",
185
+ interactive=False
186
+ )
187
 
188
+ gr.Markdown("Note: Video processing may take some time depending on file size and length.")
189
 
190
  # Info section
191
+ with gr.Accordion("About", open=False):
192
  gr.Markdown("""
193
  ### About This App
194
  - **Model:** YOLOv8 nano for efficient object detection
195
  - **Supported Images:** JPG, JPEG, PNG
196
  - **Supported Videos:** MP4, AVI, MOV, WebM
197
+ - **Features:** Confidence threshold control, detection counting, automatic cleanup
198
 
199
  ### How to Use
200
  1. Choose the **Image** or **Video** tab
201
  2. Upload your file
202
+ 3. Adjust the confidence threshold if needed (default: 0.25)
203
+ 4. Click the detect/process button
204
+ 5. Download your results
205
+
206
+ ### Confidence Threshold
207
+ - Higher values (0.5-1.0): Fewer, more certain detections
208
+ - Lower values (0.1-0.4): More detections, may include false positives
209
+ - Default (0.25): Balanced approach
210
  """)
211
 
212
  # Connect functions to buttons
213
  image_button.click(
214
  fn=detect_objects_image,
215
+ inputs=[image_input, image_confidence],
216
+ outputs=[image_output, image_info]
217
  )
218
 
219
  video_button.click(
220
  fn=detect_objects_video,
221
+ inputs=[video_input, video_confidence],
222
+ outputs=[video_output, video_info]
223
  )
224
 
225
  # Run periodic cleanup every time the interface loads