Nodes/ComfyUI-Sharp-Selector/2. Sharp Frame Selector
ComfyUI Node

2. Sharp Frame Selector

Keep only the sharp frames — either the top N, or one per scene

By ethanfel·Created 8 months ago·Updated 6 months ago· 2
2. Sharp Frame Selector
  • images
  • scores
  • selected_images
  • count
selection_method
batch_size24
batch_buffer0
num_frames10
min_sharpness0.0

SharpFrameSelector is the other half of the SharpFrames duo in ethanfel/ComfyUI-Sharp-Selector. SharpnessAnalyzer scores your batch; this node does something about it. Feed it the images and their scores and it returns only the sharp ones - in the order you can actually use.

There are two ways to pick, and they solve different problems. That choice is the whole point of the node.

The two selection methods

  • best_n - rank every frame by score, keep the top num_frames globally. This is the "keep the 10 sharpest frames from this whole clip" option. Output is sorted back into timeline order, not score order, so the clip's structure survives.
  • batched - walk the batch in windows of batch_size, and inside each window keep the single sharpest frame (if it clears min_sharpness). You get even temporal coverage: one representative frame per scene chunk instead of ten frames from the same stretch. This is the one you want when your goal is a varied dataset, because a global top-10 can all come from the same two seconds.

batch_buffer only matters for batched: it's how many frames the window skips between chunks, so windows don't overlap when your input is heavily oversampled. The stepping math is batch_size + batch_buffer, and the buffer is the fix this pack shipped to stop consecutive windows from double-counting the same sharp region.

min_sharpness is the floor filter. Any frame scoring below it is dropped in both modes. Default is 0, which means "keep everything," so it only does something if you've looked at real scores and picked a threshold.

Inputs and outputs that matter

  • Inputs: images, scores (from SharpnessAnalyzer), selection_method, batch_size, batch_buffer, num_frames, min_sharpness.
  • Outputs: selected_images (the reduced IMAGE batch) and count (an INT - how many frames survived, handy for logging or routing).

Gotchas worth knowing

  • If nothing clears the threshold, you get a black frame. The code returns a single 1×H×W tensor of zeros with count = 0 rather than an empty batch. It won't crash your workflow - which is the problem. A silent black frame can end up in a training set or get cheerfully upscaled. Watch that count.
  • Length mismatch is handled by truncation. If images and scores disagree on length, the selector silently cuts both to the shorter. The analyzer always produces one score per frame, so this only bites if you wire in a different batch than the one you scored.
  • The SHARPNESS_SCORES type is pack-private. The selector only accepts the analyzer's output. Don't try to hand it a scores list from another pack - the wire won't connect.

Install and dependencies

ComfyUI Manager (search "ComfyUI-Sharp-Selector") or:

cd ComfyUI/custom_nodes
git clone https://github.com/ethanfel/ComfyUI-Sharp-Selector

Dependencies are just opencv-python and numpy (in requirements.txt), then restart. No model downloads anywhere in this pack. The typical spot for this node: after AnimateDiff or an img2img pass, before your FaceDetailer or upscaler, so you never waste a second pass on frames that were never going to survive it anyway.

CategorySharpFrames

Inputs (7)

NameTypeDefaultDescription
imagesIMAGE
scoresSHARPNESS_SCORES
selection_methodCOMBO2 options: batched, best_n
batch_sizeINT241–10000
batch_bufferINT00–10000
num_framesINT101–10000
min_sharpnessFLOAT0.00–10000

Outputs (2)

NameTypeDescription
selected_imagesIMAGE
countINT