fix warping
Browse files
app.py
CHANGED
@@ -220,6 +220,7 @@ def stabilize_video_using_csv(video_file, csv_file, zoom=1.0, vertical_only=Fals
|
|
220 |
if not ret:
|
221 |
break
|
222 |
|
|
|
223 |
if zoom != 1.0:
|
224 |
zoomed_frame = cv2.resize(frame, None, fx=zoom, fy=zoom, interpolation=cv2.INTER_LINEAR)
|
225 |
zoomed_h, zoomed_w = zoomed_frame.shape[:2]
|
@@ -232,6 +233,7 @@ def stabilize_video_using_csv(video_file, csv_file, zoom=1.0, vertical_only=Fals
|
|
232 |
dx = 0 # Only vertical stabilization.
|
233 |
transform = np.array([[1, 0, dx],
|
234 |
[0, 1, dy]], dtype=np.float32)
|
|
|
235 |
stabilized_frame = cv2.warpAffine(frame, transform, (width, height), borderMode=cv2.BORDER_REPLICATE)
|
236 |
|
237 |
out.write(stabilized_frame)
|
@@ -252,7 +254,7 @@ def process_video_ai(video_file, zoom, vertical_only, compress_mode, target_widt
|
|
252 |
Gradio interface function:
|
253 |
- Optionally compresses the video if compress_mode is True, resizing it to the chosen resolution.
|
254 |
- Generates motion data from the (possibly compressed) video.
|
255 |
-
- If auto_zoom is enabled, computes the optimal zoom level based on the maximum cumulative
|
256 |
- Stabilizes the video based on the generated motion data.
|
257 |
- If vertical_only is True, only vertical stabilization is applied.
|
258 |
|
@@ -285,26 +287,23 @@ def process_video_ai(video_file, zoom, vertical_only, compress_mode, target_widt
|
|
285 |
csv_file = generate_motion_csv(video_file, progress=progress, progress_offset=motion_offset, progress_scale=motion_scale)
|
286 |
gr.Info("Motion CSV generated successfully.")
|
287 |
|
288 |
-
#
|
289 |
if auto_zoom:
|
290 |
gr.Info("Auto Zoom Mode enabled. Computing optimal zoom factor...")
|
291 |
motion_data = read_motion_csv(csv_file)
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
|
|
296 |
cap = cv2.VideoCapture(video_file)
|
297 |
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
298 |
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
299 |
cap.release()
|
300 |
-
|
301 |
-
|
302 |
-
else
|
303 |
-
|
304 |
-
if height - 2*max_dy > 0:
|
305 |
-
zoom_y = height / (height - 2*max_dy)
|
306 |
-
else:
|
307 |
-
zoom_y = 1.0
|
308 |
auto_zoom_factor = max(1.0, zoom_x, zoom_y)
|
309 |
gr.Info(f"Auto zoom factor computed: {auto_zoom_factor:.2f}")
|
310 |
zoom = auto_zoom_factor
|
|
|
220 |
if not ret:
|
221 |
break
|
222 |
|
223 |
+
# Apply zoom by resizing and then center-cropping
|
224 |
if zoom != 1.0:
|
225 |
zoomed_frame = cv2.resize(frame, None, fx=zoom, fy=zoom, interpolation=cv2.INTER_LINEAR)
|
226 |
zoomed_h, zoomed_w = zoomed_frame.shape[:2]
|
|
|
233 |
dx = 0 # Only vertical stabilization.
|
234 |
transform = np.array([[1, 0, dx],
|
235 |
[0, 1, dy]], dtype=np.float32)
|
236 |
+
# Use BORDER_REPLICATE to avoid black borders
|
237 |
stabilized_frame = cv2.warpAffine(frame, transform, (width, height), borderMode=cv2.BORDER_REPLICATE)
|
238 |
|
239 |
out.write(stabilized_frame)
|
|
|
254 |
Gradio interface function:
|
255 |
- Optionally compresses the video if compress_mode is True, resizing it to the chosen resolution.
|
256 |
- Generates motion data from the (possibly compressed) video.
|
257 |
+
- If auto_zoom is enabled, computes the optimal zoom level based on the maximum cumulative displacements.
|
258 |
- Stabilizes the video based on the generated motion data.
|
259 |
- If vertical_only is True, only vertical stabilization is applied.
|
260 |
|
|
|
287 |
csv_file = generate_motion_csv(video_file, progress=progress, progress_offset=motion_offset, progress_scale=motion_scale)
|
288 |
gr.Info("Motion CSV generated successfully.")
|
289 |
|
290 |
+
# Auto Zoom Mode: compute the optimal zoom factor to avoid black borders.
|
291 |
if auto_zoom:
|
292 |
gr.Info("Auto Zoom Mode enabled. Computing optimal zoom factor...")
|
293 |
motion_data = read_motion_csv(csv_file)
|
294 |
+
# Compute separate left/right and top/bottom displacements.
|
295 |
+
left_disp = abs(min(v[0] for v in motion_data.values()))
|
296 |
+
right_disp = max(v[0] for v in motion_data.values())
|
297 |
+
top_disp = abs(min(v[1] for v in motion_data.values()))
|
298 |
+
bottom_disp = max(v[1] for v in motion_data.values())
|
299 |
cap = cv2.VideoCapture(video_file)
|
300 |
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
|
301 |
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
|
302 |
cap.release()
|
303 |
+
safe_width = width - (left_disp + right_disp)
|
304 |
+
safe_height = height - (top_disp + bottom_disp)
|
305 |
+
zoom_x = width / safe_width if safe_width > 0 else 1.0
|
306 |
+
zoom_y = height / safe_height if safe_height > 0 else 1.0
|
|
|
|
|
|
|
|
|
307 |
auto_zoom_factor = max(1.0, zoom_x, zoom_y)
|
308 |
gr.Info(f"Auto zoom factor computed: {auto_zoom_factor:.2f}")
|
309 |
zoom = auto_zoom_factor
|