Open PlutoNameless opened 1 year ago
I have tried to create a method myself, but since it needs to be based on CSV results, it will need to go through two video Detectors scans before outputting the image results, so I expect this feature to be officially supported
This should definitely be possible, but you can achieve this relatively quickly with the new API. For example, to save an image every 50 frames:
from scenedetect import detect, open_video, ContentDetector
import cv2
video_path = 'video.mp4'
scene_list = detect(video_path, ContentDetector())
video = open_video(video_path)
dist_between_images = 50
for scene_num, (start_time, end_time) in enumerate(scene_list):
curr_pos = start_time
image_num = 1
while curr_pos <= end_time:
video.seek(curr_pos)
frame = video.read()
if frame is False:
break
cv2.imwrite('Scene-%03d-%04d.jpg' % (scene_num + 1, image_num), frame)
image_num += 1
if curr_pos + dist_between_images > end_time:
break
curr_pos += dist_between_images
I'm open to any PRs that add this functionality, but in the meantime the above code snippet should be a good starting point for your use case. Also note that you can also use ffmpeg
to save every N frames.
If this is to be added officially, I would propose that the number of images be specified as a range of (min images, max images) to be saved per scene, and optionally the desired spacing (which if omitted, is calculated automatically based on the shortest and longest scenes). Lastly, to fulfill the original request, we could allow num_images
to be set to zero, in which case only the desired spacing would be used when outputting frames.
I noticed when analyzing the CSV logs that each scene has a different number of Length frames, but currently only a uniform number of output images for the scene can be controlled uniformly using the save-image -n parameter. This results in some scenes having only single-digit frames but still outputting more images, while some scenes have hundreds of frames and not enough images to cover them. Is it possible to control this with a parameter based on the number of Length frames per scene, for example, one image per 8 frames per scene.