Added vertical only mode
Browse files
app.py
CHANGED
@@ -141,9 +141,10 @@ def read_motion_csv(csv_filename):
|
|
141 |
print("[INFO] Completed reading motion CSV.")
|
142 |
return motion_data
|
143 |
|
144 |
-
def stabilize_video_using_csv(video_file, csv_file, zoom=1.0, output_file=None):
|
145 |
"""
|
146 |
Stabilizes the input video using motion data from the CSV file.
|
|
|
147 |
"""
|
148 |
start_time = time.time()
|
149 |
print(f"[INFO] Starting stabilization using CSV: {csv_file}")
|
@@ -183,6 +184,9 @@ def stabilize_video_using_csv(video_file, csv_file, zoom=1.0, output_file=None):
|
|
183 |
frame = zoomed_frame[start_y:start_y+height, start_x:start_x+width]
|
184 |
|
185 |
dx, dy = motion_data.get(frame_idx, (0, 0))
|
|
|
|
|
|
|
186 |
transform = np.array([[1, 0, dx],
|
187 |
[0, 1, dy]], dtype=np.float32)
|
188 |
stabilized_frame = cv2.warpAffine(frame, transform, (width, height))
|
@@ -198,11 +202,12 @@ def stabilize_video_using_csv(video_file, csv_file, zoom=1.0, output_file=None):
|
|
198 |
print(f"[INFO] Stabilized video saved to: {output_file} in {elapsed:.2f} seconds")
|
199 |
return output_file
|
200 |
|
201 |
-
def process_video_ai(video_file, zoom):
|
202 |
"""
|
203 |
Gradio interface function:
|
204 |
- Generates motion data (CSV) from the input video using an AI model (RAFT if available, else Farneback).
|
205 |
- Stabilizes the video based on the generated motion data.
|
|
|
206 |
|
207 |
Returns:
|
208 |
Tuple containing the original video file path, the stabilized video file path, and log output.
|
@@ -216,7 +221,7 @@ def process_video_ai(video_file, zoom):
|
|
216 |
|
217 |
print("[INFO] Starting AI-powered video processing...")
|
218 |
csv_file = generate_motion_csv(video_file)
|
219 |
-
stabilized_path = stabilize_video_using_csv(video_file, csv_file, zoom=zoom)
|
220 |
print("[INFO] Video processing complete.")
|
221 |
logs = log_buffer.getvalue()
|
222 |
return video_file, stabilized_path, logs
|
@@ -224,12 +229,13 @@ def process_video_ai(video_file, zoom):
|
|
224 |
# Build the Gradio UI.
|
225 |
with gr.Blocks() as demo:
|
226 |
gr.Markdown("# AI-Powered Video Stabilization")
|
227 |
-
gr.Markdown("Upload a video
|
228 |
|
229 |
with gr.Row():
|
230 |
with gr.Column():
|
231 |
video_input = gr.Video(label="Input Video")
|
232 |
zoom_slider = gr.Slider(minimum=1.0, maximum=2.0, step=0.1, value=1.0, label="Zoom Factor")
|
|
|
233 |
process_button = gr.Button("Process Video")
|
234 |
with gr.Column():
|
235 |
original_video = gr.Video(label="Original Video")
|
@@ -238,7 +244,7 @@ with gr.Blocks() as demo:
|
|
238 |
|
239 |
process_button.click(
|
240 |
fn=process_video_ai,
|
241 |
-
inputs=[video_input, zoom_slider],
|
242 |
outputs=[original_video, stabilized_video, logs_output]
|
243 |
)
|
244 |
|
|
|
141 |
print("[INFO] Completed reading motion CSV.")
|
142 |
return motion_data
|
143 |
|
144 |
+
def stabilize_video_using_csv(video_file, csv_file, zoom=1.0, vertical_only=False, output_file=None):
|
145 |
"""
|
146 |
Stabilizes the input video using motion data from the CSV file.
|
147 |
+
If vertical_only is True, only vertical motion is corrected (horizontal displacement is ignored).
|
148 |
"""
|
149 |
start_time = time.time()
|
150 |
print(f"[INFO] Starting stabilization using CSV: {csv_file}")
|
|
|
184 |
frame = zoomed_frame[start_y:start_y+height, start_x:start_x+width]
|
185 |
|
186 |
dx, dy = motion_data.get(frame_idx, (0, 0))
|
187 |
+
if vertical_only:
|
188 |
+
# If only vertical stabilization is desired, ignore horizontal motion.
|
189 |
+
dx = 0
|
190 |
transform = np.array([[1, 0, dx],
|
191 |
[0, 1, dy]], dtype=np.float32)
|
192 |
stabilized_frame = cv2.warpAffine(frame, transform, (width, height))
|
|
|
202 |
print(f"[INFO] Stabilized video saved to: {output_file} in {elapsed:.2f} seconds")
|
203 |
return output_file
|
204 |
|
205 |
+
def process_video_ai(video_file, zoom, vertical_only):
|
206 |
"""
|
207 |
Gradio interface function:
|
208 |
- Generates motion data (CSV) from the input video using an AI model (RAFT if available, else Farneback).
|
209 |
- Stabilizes the video based on the generated motion data.
|
210 |
+
- If vertical_only is True, only vertical stabilization is applied.
|
211 |
|
212 |
Returns:
|
213 |
Tuple containing the original video file path, the stabilized video file path, and log output.
|
|
|
221 |
|
222 |
print("[INFO] Starting AI-powered video processing...")
|
223 |
csv_file = generate_motion_csv(video_file)
|
224 |
+
stabilized_path = stabilize_video_using_csv(video_file, csv_file, zoom=zoom, vertical_only=vertical_only)
|
225 |
print("[INFO] Video processing complete.")
|
226 |
logs = log_buffer.getvalue()
|
227 |
return video_file, stabilized_path, logs
|
|
|
229 |
# Build the Gradio UI.
|
230 |
with gr.Blocks() as demo:
|
231 |
gr.Markdown("# AI-Powered Video Stabilization")
|
232 |
+
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 accordingly.")
|
233 |
|
234 |
with gr.Row():
|
235 |
with gr.Column():
|
236 |
video_input = gr.Video(label="Input Video")
|
237 |
zoom_slider = gr.Slider(minimum=1.0, maximum=2.0, step=0.1, value=1.0, label="Zoom Factor")
|
238 |
+
vertical_checkbox = gr.Checkbox(label="Vertical Stabilization Only", value=False)
|
239 |
process_button = gr.Button("Process Video")
|
240 |
with gr.Column():
|
241 |
original_video = gr.Video(label="Original Video")
|
|
|
244 |
|
245 |
process_button.click(
|
246 |
fn=process_video_ai,
|
247 |
+
inputs=[video_input, zoom_slider, vertical_checkbox],
|
248 |
outputs=[original_video, stabilized_video, logs_output]
|
249 |
)
|
250 |
|