pacomesimon commited on
Commit
77ebf86
·
verified ·
1 Parent(s): 2603c31

Initialize

Browse files
Files changed (4) hide show
  1. app.py +328 -0
  2. histogram.png +0 -0
  3. requirements.txt +5 -0
  4. yolov8s-world.pt +3 -0
app.py ADDED
@@ -0,0 +1,328 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import cv2
2
+ import numpy as np
3
+ import gradio as gr
4
+ import time
5
+ from collections import deque
6
+ import matplotlib.pyplot as plt
7
+ from ultralytics import YOLO
8
+ import os
9
+
10
+
11
+ def compare_images_optical_flow(img1, img2):
12
+ """
13
+ Compares two images and returns a grayscale image of flow magnitude normalized to 0 - 1.
14
+
15
+ Args:
16
+
17
+ Returns:
18
+ A grayscale image of flow magnitude normalized to 0 - 1, or None if an error occurs.
19
+ """
20
+ # Convert images to grayscale
21
+ gray1 = cv2.cvtColor(img1, cv2.COLOR_BGR2GRAY)
22
+ gray2 = cv2.cvtColor(img2, cv2.COLOR_BGR2GRAY)
23
+
24
+
25
+ # Calculate optical flow using Farneback method
26
+ flow = cv2.calcOpticalFlowFarneback(gray1, gray2, None, 0.5, 3, 15, 3, 5, 1.2, 0)
27
+
28
+ # Calculate the magnitude of the optical flow
29
+ flow_magnitude = np.sqrt(flow[..., 0]**2 + flow[..., 1]**2)
30
+
31
+ # # Normalize the magnitude to the range 0-1
32
+ # flow_magnitude_normalized = cv2.normalize(flow_magnitude, None, 0, 1, cv2.NORM_MINMAX, cv2.CV_32F)
33
+
34
+ #The output is already a grayscale image. No need to convert it.
35
+ return flow_magnitude
36
+
37
+ model = YOLO("yolov8s-world.pt")
38
+ # Define custom classes
39
+ CUSTOM_CLASSES = ["one bird", "one airplane", "one kite","a flying object","sky"]
40
+ model.set_classes(CUSTOM_CLASSES)
41
+
42
+ def detect_birds(image):
43
+ results = model(image,
44
+ conf = 0.1,
45
+ verbose=False,
46
+
47
+ )
48
+ return results[0].plot()
49
+
50
+ optical_flow_runtime = []
51
+ object_detection_runtime = []
52
+ change_detection_runtime = []
53
+ example_videos_folder = "./example_videos"
54
+
55
+ EXAMPLE_VIDEOS_LIST = os.listdir(example_videos_folder)
56
+ EXAMPLE_VIDEOS_LIST = [os.path.join(example_videos_folder, v)
57
+ for v in EXAMPLE_VIDEOS_LIST]
58
+
59
+ HEIGHT_STANDARD = 480
60
+ WIDTH_STANDARD = 640
61
+ frame_stack = deque(maxlen=2)
62
+ detection_stack = deque(maxlen=1)
63
+
64
+ fall_back_frame = np.zeros((256, 256, 3), dtype=np.uint8) + 127
65
+ flow_magnitude_normalized = np.zeros((256, 256), dtype=np.uint8)
66
+ FLAGS = {
67
+ "OBJECT_DETECTING": False,
68
+ }
69
+ CAP = []
70
+
71
+ # Function to compute optical flow
72
+ def compute_optical_flow(mean_norm = None):
73
+ global FLAGS, flow_magnitude_normalized, frame_stack
74
+ if mean_norm is None:
75
+ mean_norm = .4
76
+ else:
77
+ mean_norm = float(mean_norm)
78
+ FLAGS["OBJECT_DETECTING"] = False
79
+ while True:
80
+ if (len(frame_stack) > 1) and not(FLAGS["OBJECT_DETECTING"]): #
81
+
82
+ prev_frame, curr_frame = frame_stack
83
+ original_height, original_width = curr_frame.shape[:2]
84
+ start_time = time.time() # Start timing
85
+ prev_frame_resized, curr_frame_resized = [
86
+ cv2.resize(
87
+ frame,
88
+ (original_width // 4, original_height // 4)
89
+ ) for frame in [prev_frame, curr_frame]
90
+ ]
91
+ flow_magnitude = compare_images_optical_flow(prev_frame_resized,
92
+ curr_frame_resized)
93
+ end_time = time.time() # End timing
94
+ optical_flow_runtime.append(end_time - start_time) # Append the elapsed time
95
+
96
+ flow_magnitude_normalized = cv2.normalize(flow_magnitude, None, 0, 1, cv2.NORM_MINMAX, cv2.CV_32F)
97
+ flow_magnitude_normalized = cv2.resize(
98
+ flow_magnitude_normalized,
99
+ (original_width, original_height)
100
+ )
101
+ yield flow_magnitude_normalized
102
+
103
+ if flow_magnitude_normalized.mean() < mean_norm:
104
+ detection_stack.append((curr_frame,prev_frame, flow_magnitude_normalized))
105
+ else:
106
+ yield np.stack((flow_magnitude_normalized,flow_magnitude_normalized*0, flow_magnitude_normalized*0), axis=-1)
107
+
108
+ # Function to perform object detection
109
+ def object_detection_stream(classes = ""):
110
+ if classes.strip() == "":
111
+ classes = "one bird, one airplane, one kite,a flying object,sky"
112
+ classes_list = classes.split(",")
113
+ global FLAGS, fall_back_frame, model
114
+ model.set_classes(classes_list)
115
+
116
+ detected_frame = fall_back_frame.copy()
117
+ while True:
118
+ if len(detection_stack)>0:
119
+ FLAGS["OBJECT_DETECTING"] = True
120
+ curr_frame, prev_frame, flow_magnitude_normalized = detection_stack.pop()
121
+ frame = curr_frame
122
+ start_time = time.time() # Start timing
123
+ detected_frame = detect_birds(frame)
124
+ end_time = time.time() # End timing
125
+ object_detection_runtime.append(end_time - start_time) # Append the elapsed time
126
+ FLAGS["OBJECT_DETECTING"] = False
127
+ yield detected_frame
128
+ FLAGS["OBJECT_DETECTING"] = False
129
+
130
+ def change_detection_stream(useless_var = None):
131
+ detected_frame = fall_back_frame.copy()
132
+ while True:
133
+ if len(detection_stack)>0:
134
+ FLAGS["OBJECT_DETECTING"] = True
135
+ curr_frame, prev_frame, flow_magnitude_normalized = detection_stack.pop()
136
+ frame = curr_frame
137
+ start_time = time.time() # Start timing
138
+ ret, thresh = cv2.threshold((flow_magnitude_normalized*255).astype(np.uint8),
139
+ 127, 255, 0)
140
+ _, contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
141
+ detected_frame = frame.copy()
142
+ for contour in contours:
143
+ x, y, w, h = cv2.boundingRect(contour)
144
+ cv2.rectangle(detected_frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
145
+ end_time = time.time() # End timing
146
+ change_detection_runtime.append(end_time - start_time) # Append the elapsed time
147
+ FLAGS["OBJECT_DETECTING"] = False
148
+ yield detected_frame
149
+ FLAGS["OBJECT_DETECTING"] = False
150
+
151
+ def video_stream(frame_rate = ""):
152
+ if frame_rate.strip() == "":
153
+ frame_rate = 2.0
154
+ else:
155
+ frame_rate = float(frame_rate)
156
+ if len(CAP) > 0:
157
+ while True:
158
+ cap = cv2.VideoCapture(CAP[-1])
159
+ ret, frame = cap.read()
160
+ while ret:
161
+ frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
162
+ frame_stack.append(
163
+ cv2.resize(
164
+ frame,
165
+ (WIDTH_STANDARD, HEIGHT_STANDARD) # Resize the frame
166
+ )
167
+ )
168
+ yield frame
169
+ ret, frame = cap.read()
170
+ time.sleep(1/frame_rate)
171
+ else:
172
+ yield fall_back_frame
173
+
174
+ def yield_frame(s):
175
+ while True:
176
+ yield frame_stack[0]
177
+ # Gradio interface
178
+ with gr.Blocks() as demo:
179
+ with gr.Tab("Using a custom Video"):
180
+ with gr.Row():
181
+ with gr.Column():
182
+ with gr.Row():
183
+ video = gr.Video(label="Video Source")
184
+ with gr.Row():
185
+ examples = gr.Examples(
186
+ examples=EXAMPLE_VIDEOS_LIST,
187
+ inputs=[video],
188
+ )
189
+
190
+ with gr.Column():
191
+ webcam_img = gr.Interface(video_stream,
192
+ inputs=gr.Textbox(label="Acquisition: Enter the frame rate", value = 2.0), #
193
+ outputs="image")
194
+ with gr.Row():
195
+ # with gr.Column():
196
+ optical_flow_img = gr.Interface(compute_optical_flow,
197
+ inputs=gr.Slider(label="Optical Flow: Noise Tolerance", minimum=0.0, maximum=1.0, value=0.4),
198
+ outputs=gr.Image(),#,"image",
199
+ )
200
+ detection_img = gr.Interface(object_detection_stream,
201
+ inputs=gr.Textbox(label="Classes: Enter the classes", value = "one bird, one airplane, one kite,a flying object,sky"),
202
+ outputs="image")
203
+
204
+ video.change(
205
+ fn=lambda video: CAP.append(video),
206
+ inputs=[video],
207
+ )
208
+
209
+ with gr.Tab("Using a custom Video (Change Detection)"):
210
+ with gr.Row():
211
+ with gr.Column():
212
+ with gr.Row():
213
+ video_CD = gr.Video(label="Video Source")
214
+ with gr.Row():
215
+ examples_CD = gr.Examples(
216
+ examples=EXAMPLE_VIDEOS_LIST,
217
+ inputs=[video_CD],
218
+ )
219
+
220
+ with gr.Column():
221
+ webcam_img_CD = gr.Interface(video_stream,
222
+ inputs=gr.Textbox(label="Acquisition: Enter the frame rate", value = 2.0), #
223
+ outputs="image")
224
+ with gr.Row():
225
+ optical_flow_img_CD = gr.Interface(compute_optical_flow,
226
+ inputs=gr.Slider(label="Optical Flow: Noise Tolerance", minimum=0.0, maximum=1.0, value=0.4),
227
+ outputs=gr.Image(),#,"image",
228
+ )
229
+ detection_img_CD = gr.Interface(change_detection_stream,
230
+ inputs=gr.Textbox(label="Change detection", value = "DUMMY"),
231
+ outputs="image")
232
+
233
+ video_CD.change(
234
+ fn=lambda video: CAP.append(video),
235
+ inputs=[video_CD],
236
+ )
237
+
238
+
239
+ with gr.Tab("Using a Real Time Camera"):
240
+ with gr.Row():
241
+ webcam_img_RT = gr.Image(label="Webcam", sources="webcam")
242
+ webcam_img_RT.stream(lambda s: frame_stack.append(
243
+ cv2.resize(
244
+ s,
245
+ (WIDTH_STANDARD, HEIGHT_STANDARD)
246
+ )
247
+ ),
248
+ webcam_img_RT,
249
+ time_limit=15, stream_every=1.0,
250
+ concurrency_limit=30
251
+ )
252
+ optical_flow_img_RT = gr.Interface(compute_optical_flow,
253
+ inputs=gr.Slider(label="Optical Flow: Noise Tolerance", minimum=0.0, maximum=1.0, value=0.4),
254
+ outputs="image",
255
+ )
256
+
257
+
258
+ with gr.Row():
259
+ detection_img_RT = gr.Interface(object_detection_stream,
260
+ inputs=gr.Textbox(label="Classes: Enter the classes",
261
+ value = "one bird, one airplane, one kite,a flying object,sky"),
262
+ outputs="image")
263
+
264
+
265
+
266
+ with gr.Tab("Using a Real Time Camera (Change Detection)"):
267
+ with gr.Row():
268
+ webcam_img_RT_CD = gr.Image(label="Webcam", sources="webcam")
269
+ webcam_img_RT_CD.stream(lambda s: frame_stack.append(
270
+ cv2.resize(
271
+ s,
272
+ (WIDTH_STANDARD, HEIGHT_STANDARD)
273
+ )
274
+ ),
275
+ webcam_img_RT_CD,
276
+ time_limit=15, stream_every=1.0,
277
+ concurrency_limit=30
278
+ )
279
+ optical_flow_img_RT_CD = gr.Interface(compute_optical_flow,
280
+ inputs=gr.Slider(label="Optical Flow: Noise Tolerance", minimum=0.0, maximum=1.0, value=0.4),
281
+ outputs="image",
282
+ )
283
+
284
+
285
+ with gr.Row():
286
+ detection_img_RT_CD = gr.Interface(change_detection_stream,
287
+ inputs=gr.Textbox(label="Changes will be detected here",
288
+ value = "DUMMY"),
289
+ outputs="image")
290
+
291
+ with gr.Tab("Runtime Histograms"):
292
+ def plot_histogram(data, title, color):
293
+ plt.figure(figsize=(10, 6))
294
+ plt.hist(data, bins=30, color=color, alpha=0.7)
295
+ plt.title(title)
296
+ plt.xlabel('Runtime (seconds)')
297
+ plt.ylabel('Frequency')
298
+ plt.grid(True)
299
+ plt.tight_layout()
300
+ plt.savefig('histogram.png')
301
+ img_plt = cv2.imread('histogram.png')
302
+ return img_plt
303
+
304
+ def update_optical_flow_plot():
305
+ return plot_histogram(np.array(optical_flow_runtime), 'Histogram of Optical Flow Runtime', 'blue')
306
+
307
+ def update_object_detection_plot():
308
+ return plot_histogram(object_detection_runtime, 'Histogram of Object Detection Runtime', 'green')
309
+
310
+ def update_change_detection_plot():
311
+ return plot_histogram(change_detection_runtime, 'Histogram of Change Detection Runtime', 'red')
312
+
313
+ with gr.Row():
314
+ optical_flow_image = gr.Image(update_optical_flow_plot, label="Optical Flow Runtime Histogram")
315
+ with gr.Row():
316
+ optical_flow_button = gr.Button("Update Optical Flow Histogram")
317
+ optical_flow_button.click(fn=update_optical_flow_plot, outputs=optical_flow_image)
318
+ with gr.Row():
319
+ object_detection_image = gr.Image(update_object_detection_plot, label="Object Detection Runtime Histogram")
320
+ with gr.Row():
321
+ object_detection_button = gr.Button("Update Object Detection Histogram")
322
+ object_detection_button.click(fn=update_object_detection_plot, outputs=object_detection_image)
323
+ with gr.Row():
324
+ change_detection_image = gr.Image(update_change_detection_plot, label="Change Detection Runtime Histogram")
325
+ with gr.Row():
326
+ change_detection_button = gr.Button("Update Change Detection Histogram")
327
+ change_detection_button.click(fn=update_change_detection_plot, outputs=change_detection_image)
328
+ demo.launch(debug=True)
histogram.png ADDED
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ gradio==5.15.0
2
+ matplotlib==3.6.0
3
+ numpy==2.2.2
4
+ opencv_python==4.9.0.80
5
+ ultralytics==8.3.49
yolov8s-world.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:095f5266bb9b654bd5ad9e21e9cdeda78e0f2c8460f5d652eaf04bab7ee251cf
3
+ size 27169314