SpyC0der77 commited on
Commit
ffcdb51
·
verified ·
1 Parent(s): 7c3a3aa

Added compression mode

Browse files
Files changed (1) hide show
  1. app.py +79 -15
app.py CHANGED
@@ -27,11 +27,56 @@ except Exception as e:
27
  raft_model = None
28
  gr.Warning("Falling back to OpenCV Farneback optical flow.")
29
 
30
- def generate_motion_csv(video_file, output_csv=None, progress=gr.Progress(), progress_offset=0.0, progress_scale=0.5):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  """
32
  Generates a CSV file with motion data (columns: frame, mag, ang, zoom) from an input video.
33
  Uses RAFT if available, otherwise falls back to OpenCV's Farneback optical flow.
34
-
35
  Updates progress from progress_offset to progress_offset+progress_scale.
36
  """
37
  start_time = time.time()
@@ -121,7 +166,6 @@ def generate_motion_csv(video_file, output_csv=None, progress=gr.Progress(), pro
121
  def read_motion_csv(csv_filename):
122
  """
123
  Reads a motion CSV file and computes cumulative offset per frame.
124
-
125
  Returns a dictionary mapping frame numbers to (dx, dy) offsets.
126
  """
127
  print(f"[INFO] Reading motion CSV: {csv_filename}")
@@ -143,11 +187,10 @@ def read_motion_csv(csv_filename):
143
  print("[INFO] Completed reading motion CSV.")
144
  return motion_data
145
 
146
- def stabilize_video_using_csv(video_file, csv_file, zoom=1.0, vertical_only=False, progress=gr.Progress(), progress_offset=0.5, progress_scale=0.5, output_file=None):
147
  """
148
- Stabilizes the input video using motion data from the CSV.
149
  If vertical_only is True, only vertical motion is corrected.
150
-
151
  Updates progress from progress_offset to progress_offset+progress_scale.
152
  """
153
  start_time = time.time()
@@ -207,30 +250,46 @@ def stabilize_video_using_csv(video_file, csv_file, zoom=1.0, vertical_only=Fals
207
  print(f"[INFO] Stabilized video saved to: {output_file} in {elapsed:.2f} seconds")
208
  return output_file
209
 
210
- def process_video_ai(video_file, zoom, vertical_only, progress=gr.Progress(track_tqdm=True)):
211
  """
212
  Gradio interface function:
213
- - Generates motion data from the input video using an AI model (RAFT if available, else Farneback).
 
214
  - Stabilizes the video based on the generated motion data.
215
  - If vertical_only is True, only vertical stabilization is applied.
216
 
217
  Returns:
218
  Tuple: (original video file path, stabilized video file path, log output)
219
  """
220
- # Display an info alert.
221
  gr.Info("Starting AI-powered video processing...")
222
-
223
  log_buffer = io.StringIO()
224
  with redirect_stdout(log_buffer):
225
  if isinstance(video_file, dict):
226
  video_file = video_file.get("name", None)
227
  if video_file is None:
228
  raise gr.Error("Please upload a video file.")
229
-
230
- csv_file = generate_motion_csv(video_file, progress=progress, progress_offset=0.0, progress_scale=0.5)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  gr.Info("Motion CSV generated successfully.")
232
  stabilized_path = stabilize_video_using_csv(video_file, csv_file, zoom=zoom, vertical_only=vertical_only,
233
- progress=progress, progress_offset=0.5, progress_scale=0.5)
234
  gr.Info("Video stabilization complete.")
235
  print("[INFO] Video processing complete.")
236
  logs = log_buffer.getvalue()
@@ -239,13 +298,18 @@ def process_video_ai(video_file, zoom, vertical_only, progress=gr.Progress(track
239
  # Build the Gradio UI.
240
  with gr.Blocks() as demo:
241
  gr.Markdown("# AI-Powered Video Stabilization")
242
- gr.Markdown("Upload a video, select a zoom factor, and choose whether to apply only vertical stabilization. The system will generate motion data using an AI model (RAFT if available) and then stabilize the video.")
 
 
 
243
 
244
  with gr.Row():
245
  with gr.Column():
246
  video_input = gr.Video(label="Input Video")
247
  zoom_slider = gr.Slider(minimum=1.0, maximum=2.0, step=0.1, value=1.0, label="Zoom Factor")
248
  vertical_checkbox = gr.Checkbox(label="Vertical Stabilization Only", value=False)
 
 
249
  process_button = gr.Button("Process Video")
250
  with gr.Column():
251
  original_video = gr.Video(label="Original Video")
@@ -254,7 +318,7 @@ with gr.Blocks() as demo:
254
 
255
  process_button.click(
256
  fn=process_video_ai,
257
- inputs=[video_input, zoom_slider, vertical_checkbox],
258
  outputs=[original_video, stabilized_video, logs_output]
259
  )
260
 
 
27
  raft_model = None
28
  gr.Warning("Falling back to OpenCV Farneback optical flow.")
29
 
30
+ def compress_video(video_file, compression_factor, progress=gr.Progress(), progress_offset=0.0, progress_scale=0.2, output_file=None):
31
+ """
32
+ Compresses the video by resizing each frame to a lower resolution.
33
+ The new resolution is (original_width * compression_factor, original_height * compression_factor).
34
+ Updates progress from progress_offset to progress_offset+progress_scale.
35
+ """
36
+ start_time = time.time()
37
+ cap = cv2.VideoCapture(video_file)
38
+ if not cap.isOpened():
39
+ raise gr.Error("Could not open video file for compression.")
40
+
41
+ original_width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
42
+ original_height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
43
+ new_width = max(1, int(original_width * compression_factor))
44
+ new_height = max(1, int(original_height * compression_factor))
45
+ fps = cap.get(cv2.CAP_PROP_FPS)
46
+
47
+ if output_file is None:
48
+ temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.mp4')
49
+ output_file = temp_file.name
50
+ temp_file.close()
51
+
52
+ fourcc = cv2.VideoWriter_fourcc(*'mp4v')
53
+ out = cv2.VideoWriter(output_file, fourcc, fps, (new_width, new_height))
54
+
55
+ total_frames = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
56
+ frame_idx = 1
57
+ print(f"[INFO] Starting video compression: {total_frames} frames, target resolution: {new_width}x{new_height}")
58
+ while True:
59
+ ret, frame = cap.read()
60
+ if not ret:
61
+ break
62
+ # Resize frame to new resolution
63
+ compressed_frame = cv2.resize(frame, (new_width, new_height))
64
+ out.write(compressed_frame)
65
+ if frame_idx % 10 == 0 or frame_idx == total_frames:
66
+ print(f"[INFO] Compressed frame {frame_idx}/{total_frames}")
67
+ progress(progress_offset + (frame_idx/total_frames)*progress_scale, desc="Compressing Video")
68
+ frame_idx += 1
69
+
70
+ cap.release()
71
+ out.release()
72
+ elapsed = time.time() - start_time
73
+ print(f"[INFO] Compressed video saved to: {output_file} in {elapsed:.2f} seconds")
74
+ return output_file
75
+
76
+ def generate_motion_csv(video_file, output_csv=None, progress=gr.Progress(), progress_offset=0.0, progress_scale=0.4):
77
  """
78
  Generates a CSV file with motion data (columns: frame, mag, ang, zoom) from an input video.
79
  Uses RAFT if available, otherwise falls back to OpenCV's Farneback optical flow.
 
80
  Updates progress from progress_offset to progress_offset+progress_scale.
81
  """
82
  start_time = time.time()
 
166
  def read_motion_csv(csv_filename):
167
  """
168
  Reads a motion CSV file and computes cumulative offset per frame.
 
169
  Returns a dictionary mapping frame numbers to (dx, dy) offsets.
170
  """
171
  print(f"[INFO] Reading motion CSV: {csv_filename}")
 
187
  print("[INFO] Completed reading motion CSV.")
188
  return motion_data
189
 
190
+ def stabilize_video_using_csv(video_file, csv_file, zoom=1.0, vertical_only=False, progress=gr.Progress(), progress_offset=0.6, progress_scale=0.4, output_file=None):
191
  """
192
+ Stabilizes the video using motion data from the CSV.
193
  If vertical_only is True, only vertical motion is corrected.
 
194
  Updates progress from progress_offset to progress_offset+progress_scale.
195
  """
196
  start_time = time.time()
 
250
  print(f"[INFO] Stabilized video saved to: {output_file} in {elapsed:.2f} seconds")
251
  return output_file
252
 
253
+ def process_video_ai(video_file, zoom, vertical_only, compress_mode, compression_factor, progress=gr.Progress(track_tqdm=True)):
254
  """
255
  Gradio interface function:
256
+ - Optionally compresses the video if compress_mode is True.
257
+ - Generates motion data from the (possibly compressed) video.
258
  - Stabilizes the video based on the generated motion data.
259
  - If vertical_only is True, only vertical stabilization is applied.
260
 
261
  Returns:
262
  Tuple: (original video file path, stabilized video file path, log output)
263
  """
 
264
  gr.Info("Starting AI-powered video processing...")
 
265
  log_buffer = io.StringIO()
266
  with redirect_stdout(log_buffer):
267
  if isinstance(video_file, dict):
268
  video_file = video_file.get("name", None)
269
  if video_file is None:
270
  raise gr.Error("Please upload a video file.")
271
+
272
+ # If compression is enabled, compress the video first.
273
+ if compress_mode:
274
+ gr.Info("Compressing video before processing...")
275
+ # Compression phase uses progress 0 to 0.2
276
+ video_file = compress_video(video_file, compression_factor, progress=progress, progress_offset=0.0, progress_scale=0.2)
277
+ gr.Info("Video compression complete.")
278
+ # Set new progress offsets for subsequent phases.
279
+ motion_offset = 0.2
280
+ motion_scale = 0.4
281
+ stabilization_offset = 0.6
282
+ stabilization_scale = 0.4
283
+ else:
284
+ motion_offset = 0.0
285
+ motion_scale = 0.5
286
+ stabilization_offset = 0.5
287
+ stabilization_scale = 0.5
288
+
289
+ csv_file = generate_motion_csv(video_file, progress=progress, progress_offset=motion_offset, progress_scale=motion_scale)
290
  gr.Info("Motion CSV generated successfully.")
291
  stabilized_path = stabilize_video_using_csv(video_file, csv_file, zoom=zoom, vertical_only=vertical_only,
292
+ progress=progress, progress_offset=stabilization_offset, progress_scale=stabilization_scale)
293
  gr.Info("Video stabilization complete.")
294
  print("[INFO] Video processing complete.")
295
  logs = log_buffer.getvalue()
 
298
  # Build the Gradio UI.
299
  with gr.Blocks() as demo:
300
  gr.Markdown("# AI-Powered Video Stabilization")
301
+ gr.Markdown(
302
+ "Upload a video, select a zoom factor, choose whether to apply only vertical stabilization, and optionally compress the video before processing. "
303
+ "The system will generate motion data using an AI model (RAFT if available) and then stabilize the video with live progress updates and alerts."
304
+ )
305
 
306
  with gr.Row():
307
  with gr.Column():
308
  video_input = gr.Video(label="Input Video")
309
  zoom_slider = gr.Slider(minimum=1.0, maximum=2.0, step=0.1, value=1.0, label="Zoom Factor")
310
  vertical_checkbox = gr.Checkbox(label="Vertical Stabilization Only", value=False)
311
+ compress_checkbox = gr.Checkbox(label="Compress Video Before Processing", value=False)
312
+ compression_slider = gr.Slider(minimum=0.1, maximum=1.0, step=0.1, value=0.5, label="Compression Factor (Scale)")
313
  process_button = gr.Button("Process Video")
314
  with gr.Column():
315
  original_video = gr.Video(label="Original Video")
 
318
 
319
  process_button.click(
320
  fn=process_video_ai,
321
+ inputs=[video_input, zoom_slider, vertical_checkbox, compress_checkbox, compression_slider],
322
  outputs=[original_video, stabilized_video, logs_output]
323
  )
324