The video-to-image converter isn't hard to write in Python, as many libraries are already around. Instead, I added order and science order, as each check between a list of structures from frame 1 to the last frame. So in scene 1, we have no structure in the list. We first add the first one and get its mean value to add that to an array. Then we go through each frame and add the new mean to append that array, but before that, we check each previous frame added to that scene. If it's above a difference of 30, we reset the array list and set that one in the next scene.
import cv2
import os
# Open the MP4 file
video = cv2.VideoCapture('video.mp4')
# Get the frame count and FPS of the video
frame_count = int(video.get(cv2.CAP_PROP_FRAME_COUNT))
fps = int(video.get(cv2.CAP_PROP_FPS))
# Create a directory to store the JPEG images
output_dir = 'images'
if not os.path.exists(output_dir):
os.makedirs(output_dir)
# Loop through the frames and save each one as a JPEG image
current_scene = 0
current_scene_frame_count = 0
prev_frames = []
scene_dir = ''
for i in range(frame_count):
ret, frame = video.read()
if not ret:
break
# Compute the color difference between the current frame and all previous frames in the same scene
if len(prev_frames) == 0:
color_diff = 0
else:
color_diff = sum(cv2.absdiff(frame, prev_frame).mean() for prev_frame in prev_frames) / len(prev_frames)
# If the color difference is above a threshold, start a new scene
if color_diff > 30:
current_scene += 1
current_scene_frame_count = 0
# Create a directory for the scene
scene_dir = os.path.join(output_dir, f'scene_{current_scene:04d}')
os.makedirs(scene_dir, exist_ok=True)
# Clear the previous frames buffer
prev_frames.clear()
# Save the frame as a JPEG image in the current scene directory
if scene_dir:
filename = os.path.join(scene_dir, f'frame_{current_scene_frame_count:04d}.jpg')
resized_frame = cv2.resize(frame, (854, 480))
cv2.imwrite(filename, resized_frame, [int(cv2.IMWRITE_JPEG_QUALITY), 80])
current_scene_frame_count += 1
prev_frames.append(frame)
# Print the progress as a percentage of the total frames, and clear the previous progress print
progress = (i + 1) / frame_count * 100
print(f'Processed {i + 1} frames out of {frame_count} ({progress:.2f}%) \n', end='\r', flush=True)
# Rename the files to include the frame index within each scene
for scene in os.listdir(output_dir):
if not scene.startswith('scene_'):
continue
scene_dir = os.path.join(output_dir, scene)
frames = os.listdir(scene_dir)
frames.sort()
for i, frame in enumerate(frames):
frame_path = os.path.join(scene_dir, frame)
frame_index = int(frame.split('.')[0].split('_')[-1])
new_filename = os.path.join(scene_dir, f'frame_{frame_index:04d}.jpg')
os.rename(frame_path, new_filename)
# Release the video file
video.release()
print("done")