Created
June 26, 2025 08:35
-
-
Save dgwyer/bfdcb8e7a2fd00e8d9edd08855419d60 to your computer and use it in GitHub Desktop.
Extract the first frame of a 1280x720 video, convert it to an image, then crop and resize both the image and original video to 480x3680
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cv2 | |
import os | |
from fractions import Fraction | |
import subprocess | |
# === Settings === | |
video_file = 'videos/video.mp4' | |
output_image_file = 'first_frame_clipped.jpg' | |
output_image_resized_file = 'first_frame_resized.jpg' | |
output_video_file = 'clipped_video.mp4' | |
target_aspect = Fraction(4, 3) | |
# === Setup Paths === | |
video_path = os.path.join(os.getcwd(), video_file) | |
print("Checking video path:", video_file) | |
print("Video file exists:", os.path.exists(video_path)) | |
# === Load Video === | |
cap = cv2.VideoCapture(video_path) | |
if not cap.isOpened(): | |
print("โ Failed to open video file.") | |
else: | |
success, frame = cap.read() | |
if success: | |
print("โ First frame captured successfully.") | |
height, width = frame.shape[:2] | |
aspect_fraction = Fraction(width, height).limit_denominator() | |
print(f"๐ Original Dimensions: {width} x {height}") | |
print(f"๐งฎ Original Aspect Ratio: {aspect_fraction.numerator}:{aspect_fraction.denominator}") | |
# === Calculate crop for 4:3 === | |
target_width = (height * target_aspect.numerator) // target_aspect.denominator | |
print(f"โ๏ธ Cropping to 4:3 โ New width: {target_width}") | |
x_start = (width - target_width) // 2 | |
x_end = x_start + target_width | |
cropped_frame = frame[:, x_start:x_end] | |
print(f"๐ธ Saved cropped frame as '{output_image_file}'") | |
cv2.imwrite(output_image_file, cropped_frame) | |
# === Resize image to half dimensions === | |
resized_frame = cv2.resize(cropped_frame, (target_width // 2, height // 2), interpolation=cv2.INTER_AREA) | |
cv2.imwrite(output_image_resized_file, resized_frame) | |
print(f"๐ผ๏ธ Saved resized image as '{output_image_resized_file}' ({target_width // 2} x {height // 2})") | |
# === Crop and scale video using ffmpeg === | |
ffmpeg_cmd = [ | |
'ffmpeg', | |
'-y', # auto overwrite | |
'-i', video_path, | |
'-filter:v', f'crop={target_width}:{height},scale={target_width // 2}:{height // 2}', | |
'-c:a', 'copy', | |
output_video_file | |
] | |
print(f"๐๏ธ Cropping and downscaling video to {target_width // 2} x {height // 2}...") | |
result = subprocess.run(ffmpeg_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) | |
if result.returncode == 0: | |
print(f"โ Cropped and scaled video saved as '{output_video_file}'") | |
else: | |
print("โ ffmpeg error:") | |
print(result.stderr) | |
# === Show final sizes and aspect ratios === | |
clipped_height, clipped_width = resized_frame.shape[:2] | |
clipped_aspect = Fraction(clipped_width, clipped_height).limit_denominator() | |
print(f"๐ผ๏ธ Final Image Size: {clipped_width} x {clipped_height}") | |
print(f"๐ฒ Final Image Aspect Ratio: {clipped_aspect.numerator}:{clipped_aspect.denominator}") | |
# === Confirm video size using ffprobe === | |
ffprobe_cmd = [ | |
'ffprobe', '-v', 'error', | |
'-select_streams', 'v:0', | |
'-show_entries', 'stream=width,height', | |
'-of', 'csv=p=0:s=x', | |
output_video_file | |
] | |
probe = subprocess.run(ffprobe_cmd, stdout=subprocess.PIPE, text=True) | |
if probe.returncode == 0: | |
vid_width, vid_height = map(int, probe.stdout.strip().split('x')) | |
vid_aspect = Fraction(vid_width, vid_height).limit_denominator() | |
print(f"๐ฌ Final Video Size: {vid_width} x {vid_height}") | |
print(f"๐๏ธ Final Video Aspect Ratio: {vid_aspect.numerator}:{vid_aspect.denominator}") | |
else: | |
print("โ ๏ธ Failed to get final video dimensions using ffprobe.") | |
else: | |
print("โ Failed to read the first frame.") | |
cap.release() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment