luminoussg commited on
Commit
4dc298a
·
verified ·
1 Parent(s): d4ffdb9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +130 -21
app.py CHANGED
@@ -1,15 +1,21 @@
1
  import gradio as gr
2
  import cv2
3
  import os
4
- import subprocess
 
 
5
  from ultralytics import YOLO
6
  from ultralytics.solutions import object_counter
 
 
7
 
8
  # Initialize the YOLO model
9
  MODEL = "yolov8n.pt"
10
  model = YOLO(MODEL)
11
  model.fuse()
12
 
 
 
13
  # Auxiliary functions
14
  def resize_frame(frame, scale_percent):
15
  width = int(frame.shape[1] * scale_percent / 100)
@@ -18,38 +24,129 @@ def resize_frame(frame, scale_percent):
18
  resized = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)
19
  return resized
20
 
21
- @gr.spaces.GPU
22
  def process_video(video_file, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness, draw_tracks, view_img, view_in_counts, view_out_counts, track_thickness, region_thickness, line_dist_thresh, persist, conf, iou, classes, verbose):
23
- # Video processing logic here
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
  def preview_line(video_file, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness):
26
- # Generate a preview of the line on the video
27
- # Code here
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
  def gradio_app(video, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness, draw_tracks, view_img, view_in_counts, view_out_counts, track_thickness, region_thickness, line_dist_thresh, persist, conf, iou, classes_to_track, verbose):
30
- # Main Gradio app logic
31
- # Code here
32
 
33
  def update_preview(video, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness):
34
- # Update preview logic
35
- # Code here
36
 
37
  def set_4k_coordinates():
38
  return 0, 1500, 3840, 1500
39
 
40
  def set_1080p_coordinates():
41
  return 0, 700, 1920, 700
42
-
43
  with gr.Blocks(css="style.css", theme="dark") as demo:
44
  with gr.Row():
45
  with gr.Column(scale=1):
46
  video_input = gr.File(label="Upload your video")
47
- set_4k_button = gr.Button("Set 4K Line")
48
- set_1080p_button = gr.Button("Set 1080p Line")
49
- line_start_x = gr.Number(label="Line Start X", value=500)
50
- line_start_y = gr.Number(label="Line Start Y", value=1500)
51
- line_end_x = gr.Number(label="Line End X", value=3400)
52
- line_end_y = gr.Number(label="Line End Y", value=1500)
 
53
  line_thickness = gr.Slider(minimum=1, maximum=10, value=2, label="Line Thickness")
54
  draw_tracks = gr.Checkbox(label="Draw Tracks", value=True)
55
  view_img = gr.Checkbox(label="Display Image with Annotations", value=True)
@@ -61,7 +158,7 @@ with gr.Blocks(css="style.css", theme="dark") as demo:
61
  persist = gr.Checkbox(label="Persist Tracks", value=True)
62
  conf = gr.Slider(minimum=0.0, maximum=1.0, value=0.1, step=0.05, label="Confidence Threshold")
63
  iou = gr.Slider(minimum=0.0, maximum=1.0, value=0.7, step=0.05, label="IOU Threshold")
64
- classes_to_track = gr.Textbox(label="Classes to Track", value="2,3,5,7")
65
  verbose = gr.Checkbox(label="Verbose Tracking", value=True)
66
  scale_percent = gr.Slider(minimum=10, maximum=100, value=100, step=10, label="Scale Percentage")
67
  process_button = gr.Button("Process Video")
@@ -70,9 +167,21 @@ with gr.Blocks(css="style.css", theme="dark") as demo:
70
  video_output = gr.Video(label="Processed Video")
71
  download_button = gr.File(label="Download Processed Video")
72
 
73
- set_4k_button.click(set_4k_coordinates, outputs=[line_start_x, line_start_y, line_end_x, line_end_y])
74
- set_1080p_button.click(set_1080p_coordinates, outputs=[line_start_x, line_start_y, line_end_x, line_end_y])
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  process_button.click(gradio_app, inputs=[video_input, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness, draw_tracks, view_img, view_in_counts, view_out_counts, track_thickness, region_thickness, line_dist_thresh, persist, conf, iou, classes_to_track, verbose], outputs=[video_output, download_button])
76
- video_input.change(update_preview, inputs=[video_input, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness], outputs=[preview_image])
77
 
78
- demo.launch()
 
1
  import gradio as gr
2
  import cv2
3
  import os
4
+ import pandas as pd
5
+ import numpy as np
6
+ import torch
7
  from ultralytics import YOLO
8
  from ultralytics.solutions import object_counter
9
+ import subprocess
10
+ import spaces # Import spaces for ZeroGPU integration
11
 
12
  # Initialize the YOLO model
13
  MODEL = "yolov8n.pt"
14
  model = YOLO(MODEL)
15
  model.fuse()
16
 
17
+ dict_classes = model.model.names
18
+
19
  # Auxiliary functions
20
  def resize_frame(frame, scale_percent):
21
  width = int(frame.shape[1] * scale_percent / 100)
 
24
  resized = cv2.resize(frame, dim, interpolation=cv2.INTER_AREA)
25
  return resized
26
 
27
+ @spaces.GPU
28
  def process_video(video_file, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness, draw_tracks, view_img, view_in_counts, view_out_counts, track_thickness, region_thickness, line_dist_thresh, persist, conf, iou, classes, verbose):
29
+ # Ensure classes is a list of integers
30
+ classes = [int(x) for x in classes.split(',') if x.strip().isdigit()] if classes else None
31
+
32
+ line_points = [(line_start_x, line_start_y), (line_end_x, line_end_y)]
33
+
34
+ cap = cv2.VideoCapture(video_file)
35
+ if not cap.isOpened():
36
+ raise ValueError("Failed to open video file")
37
+
38
+ tmp_output_path = "processed_output_temp.mp4"
39
+ w = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH) * scale_percent / 100)
40
+ h = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT) * scale_percent / 100)
41
+ fps = int(cap.get(cv2.CAP_PROP_FPS))
42
+ video_writer = cv2.VideoWriter(tmp_output_path, cv2.VideoWriter_fourcc(*'mp4v'), fps, (w, h))
43
+
44
+ counter = object_counter.ObjectCounter(
45
+ classes_names=model.names,
46
+ view_img=view_img,
47
+ reg_pts=line_points,
48
+ draw_tracks=draw_tracks,
49
+ line_thickness=int(line_thickness),
50
+ track_thickness=int(track_thickness),
51
+ region_thickness=int(region_thickness),
52
+ line_dist_thresh=line_dist_thresh,
53
+ view_in_counts=view_in_counts,
54
+ view_out_counts=view_out_counts,
55
+ count_reg_color=(255, 0, 255), # Magenta
56
+ track_color=(0, 255, 0), # Green
57
+ count_txt_color=(255, 255, 255), # White
58
+ count_bg_color=(50, 50, 50) # Dark gray
59
+ )
60
+
61
+ prev_frame = None
62
+ prev_keypoints = None
63
+
64
+ while cap.isOpened():
65
+ ret, frame = cap.read()
66
+ if not ret:
67
+ break
68
+ frame = resize_frame(frame, scale_percent)
69
+
70
+ # Adjust line points based on scaling
71
+ scaled_line_points = [(int(x * scale_percent / 100), int(y * scale_percent / 100)) for x, y in line_points]
72
+ for point1, point2 in zip(scaled_line_points[:-1], scaled_line_points[1:]):
73
+ cv2.line(frame, tuple(map(int, point1)), tuple(map(int, point2)), (255, 255, 0), int(line_thickness))
74
+
75
+ tracks = model.track(frame, persist=persist, conf=conf, iou=iou, classes=classes, verbose=verbose)
76
+
77
+ # Update the counter with the current frame and tracks
78
+ frame = counter.start_counting(frame, tracks)
79
+
80
+ # Check if the previous frame is initialized for optical flow calculation
81
+ if prev_frame is not None:
82
+ try:
83
+ prev_frame_resized = resize_frame(prev_frame, scale_percent)
84
+ matched_keypoints, status, _ = cv2.calcOpticalFlowPyrLK(prev_frame_resized, frame, prev_keypoints, None)
85
+ prev_keypoints = matched_keypoints
86
+ except cv2.error as e:
87
+ print(f"Error in optical flow calculation: {e}")
88
+
89
+ prev_frame = frame.copy()
90
+ prev_keypoints = cv2.goodFeaturesToTrack(cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY), maxCorners=100, qualityLevel=0.3, minDistance=7, blockSize=7)
91
+
92
+ video_writer.write(frame)
93
+
94
+ cap.release()
95
+ video_writer.release()
96
+
97
+ # Reduce the resolution of the video for download
98
+ output_path = "processed_output.mp4"
99
+ if h > 1080:
100
+ resolution = "1920x1080"
101
+ else:
102
+ resolution = "1280x720"
103
+
104
+ subprocess.run(
105
+ ["ffmpeg", "-y", "-i", tmp_output_path, "-vf", f"scale={resolution}", "-crf", "18", "-preset", "veryfast", "-hide_banner", "-loglevel", "error", output_path]
106
+ )
107
+ os.remove(tmp_output_path)
108
+
109
+ return output_path
110
 
111
  def preview_line(video_file, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness):
112
+ cap = cv2.VideoCapture(video_file)
113
+ ret, frame = cap.read()
114
+ if not ret:
115
+ raise ValueError("Failed to read video frame")
116
+
117
+ frame = resize_frame(frame, scale_percent)
118
+ line_points = [(line_start_x, line_start_y), (line_end_x, line_end_y)]
119
+ scaled_line_points = [(int(x * scale_percent / 100), int(y * scale_percent / 100)) for x, y in line_points]
120
+ for point1, point2 in zip(scaled_line_points[:-1], scaled_line_points[1:]):
121
+ cv2.line(frame, tuple(map(int, point1)), tuple(map(int, point2)), (255, 255, 0), int(line_thickness))
122
+
123
+ preview_path = "preview_line.jpg"
124
+ cv2.imwrite(preview_path, frame)
125
+ return preview_path
126
 
127
  def gradio_app(video, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness, draw_tracks, view_img, view_in_counts, view_out_counts, track_thickness, region_thickness, line_dist_thresh, persist, conf, iou, classes_to_track, verbose):
128
+ output_path = process_video(video.name, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, int(line_thickness), draw_tracks, view_img, view_in_counts, view_out_counts, int(track_thickness), int(region_thickness), line_dist_thresh, persist, conf, iou, classes_to_track, verbose)
129
+ return output_path, output_path
130
 
131
  def update_preview(video, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness):
132
+ return preview_line(video.name, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, int(line_thickness))
 
133
 
134
  def set_4k_coordinates():
135
  return 0, 1500, 3840, 1500
136
 
137
  def set_1080p_coordinates():
138
  return 0, 700, 1920, 700
 
139
  with gr.Blocks(css="style.css", theme="dark") as demo:
140
  with gr.Row():
141
  with gr.Column(scale=1):
142
  video_input = gr.File(label="Upload your video")
143
+ with gr.Row():
144
+ set_4k_button = gr.Button("4K")
145
+ set_1080p_button = gr.Button("1080p")
146
+ line_start_x = gr.Number(label="Line Start X", value=500, precision=0)
147
+ line_start_y = gr.Number(label="Line Start Y", value=1500, precision=0)
148
+ line_end_x = gr.Number(label="Line End X", value=3400, precision=0)
149
+ line_end_y = gr.Number(label="Line End Y", value=1500, precision=0)
150
  line_thickness = gr.Slider(minimum=1, maximum=10, value=2, label="Line Thickness")
151
  draw_tracks = gr.Checkbox(label="Draw Tracks", value=True)
152
  view_img = gr.Checkbox(label="Display Image with Annotations", value=True)
 
158
  persist = gr.Checkbox(label="Persist Tracks", value=True)
159
  conf = gr.Slider(minimum=0.0, maximum=1.0, value=0.1, step=0.05, label="Confidence Threshold")
160
  iou = gr.Slider(minimum=0.0, maximum=1.0, value=0.7, step=0.05, label="IOU Threshold")
161
+ classes_to_track = gr.Textbox(label="Classes to Track (comma-separated ids)", value="2,3,5,7")
162
  verbose = gr.Checkbox(label="Verbose Tracking", value=True)
163
  scale_percent = gr.Slider(minimum=10, maximum=100, value=100, step=10, label="Scale Percentage")
164
  process_button = gr.Button("Process Video")
 
167
  video_output = gr.Video(label="Processed Video")
168
  download_button = gr.File(label="Download Processed Video")
169
 
170
+ def update_preview_and_display(video, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness):
171
+ preview_path = update_preview(video, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness)
172
+ return preview_path
173
+
174
+ video_input.change(update_preview_and_display, inputs=[video_input, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness], outputs=preview_image)
175
+ for component in [scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness, draw_tracks, view_img, view_in_counts, view_out_counts, track_thickness, region_thickness, line_dist_thresh, persist, conf, iou, classes_to_track, verbose]:
176
+ component.change(update_preview_and_display, inputs=[video_input, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness], outputs=preview_image)
177
+
178
+ set_4k_button.click(lambda: set_4k_coordinates(), outputs=[line_start_x, line_start_y, line_end_x, line_end_y])
179
+ set_1080p_button.click(lambda: set_1080p_coordinates(), outputs=[line_start_x, line_start_y, line_end_x, line_end_y])
180
+
181
+ def clear_previous_video():
182
+ return None, None
183
+
184
+ process_button.click(clear_previous_video, outputs=[video_output, download_button], queue=False)
185
  process_button.click(gradio_app, inputs=[video_input, scale_percent, line_start_x, line_start_y, line_end_x, line_end_y, line_thickness, draw_tracks, view_img, view_in_counts, view_out_counts, track_thickness, region_thickness, line_dist_thresh, persist, conf, iou, classes_to_track, verbose], outputs=[video_output, download_button])
 
186
 
187
+ demo.launch()