Skip to content

Dynamically adjust the number of output images of the scene #280

Open

Description

@PlutoNameless

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.

Activity

  1. PlutoNameless commented on Aug 1, 2022

    @PlutoNameless
    Author

    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

  2. Breakthrough commented on Aug 1, 2022

    @Breakthrough
    Owner

    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.

  3. Deepchavda007 commented on Dec 1, 2023

    @Deepchavda007

    ray-so-export

  4. Rober1208 commented on Oct 21, 2026

    @Rober1208

    I'd like to implement this. Here's my plan, based on your proposal above. Does it look right before I open a PR?

    • Add -i/--interval DURATION to save-images (interval in the config file and in save_images()). It accepts the same formats as -m/--frame-margin: frames, seconds (1.5s) or a timecode.
    • With --interval, each scene gets floor(scene length / DURATION) + 1 images, spread the same way as today: first and last frame included, frame margin respected. Short scenes get fewer images, long scenes more.
    • --min-images and --max-images (default 1 and no limit) clamp that count per scene, which covers the (min, max) range you suggested.
    • Without --interval, -n/--num-images works exactly as now.

    I'd leave out computing the interval automatically from the shortest and longest scenes for now, since I'm not sure which rule would suit most videos. It could be added later.

    One question: would you rather have -n act as the maximum when --interval is set, instead of a separate --max-images?

  5. Breakthrough commented on Oct 22, 2026

    @Breakthrough
    Owner

    SGTM! Perhaps we should make -n mutually exclusive with -i to avoid the issue of specifying both together. One last thought: should we make it a single argument so --interval takes 1, 2, or 3 args? That way you can set only duration, duration with min. num of images, and duration w/ both min and max set. Thoughts?

    The approach you outlined sounds great though, feel free to get something up and do some local testing first to see what works best. Happy to iterate on this in a PR when you get one up, thank you.

  6. Rober1208 commented on Oct 22, 2026

    @Rober1208

    Thanks! Opened #588. I went with your single-argument idea. Click options can't take a variable number of values, so MIN and MAX follow DURATION after commas: -i 2s, -i 2s,3, -i 2s,3,10, or -i 2s,,10 to set only MAX. The config file takes the same format. -n and -i are mutually exclusive, both on the command line and in the config file. If separate --min-images/--max-images options read better once you try it, I can switch.

  7. Breakthrough commented on Oct 23, 2026

    @Breakthrough
    Owner

    Based on your analysis in the PR I think perhaps the single arg idea isn't ideal. Thanks for giving it a try though!

    We'll go with exactly what you originally proposed in #280 (comment) above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions