Guest User

Vapoursynth SCDetect

a guest
May 14th, 2026
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.44 KB | None | 0 0
  1. def SCDetect(clip: vs.VideoNode, threshold: float = 0.1, plane: int = 0) -> vs.VideoNode:
  2. """
  3. Scene change detection with _SceneChangePrev/_SceneChangeNext frame properties.
  4. Uses core.misc.SCDetect if available (plane=0 only), otherwise falls back to
  5. a std.PlaneStats-based reimplementation.
  6.  
  7. Args:
  8. clip : Input clip
  9. threshold : Scene change threshold (default: 0.1, must be 0.0–1.0)
  10. plane : Plane to analyze; only honoured in fallback path —
  11. misc.SCDetect always uses plane 0
  12.  
  13. Returns:
  14. Clip with _SceneChangePrev and _SceneChangeNext frame properties set.
  15. """
  16. if not isinstance(clip, vs.VideoNode):
  17. raise vs.Error('SCDetect: this is not a clip')
  18. if not (0.0 <= threshold <= 1.0):
  19. raise vs.Error('SCDetect: threshold must be between 0.0 and 1.0')
  20. if clip.num_frames < 2:
  21. raise vs.Error('SCDetect: clip must have more than one frame')
  22.  
  23. if hasattr(core, 'misc') and plane == 0:
  24. if clip.format.color_family == vs.RGB:
  25. sc = clip.resize.Point(format=vs.GRAY8, matrix_s='709')
  26. sc = core.misc.SCDetect(sc, threshold=threshold)
  27.  
  28. def _copy_props(n: int, f: list[vs.VideoFrame]) -> vs.VideoFrame:
  29. fout = f[0].copy()
  30. fout.props['_SceneChangePrev'] = f[1].props['_SceneChangePrev']
  31. fout.props['_SceneChangeNext'] = f[1].props['_SceneChangeNext']
  32. return fout
  33.  
  34. return clip.std.ModifyFrame(clips=[clip, sc], selector=_copy_props)
  35.  
  36. return core.misc.SCDetect(clip, threshold=threshold)
  37.  
  38. # prev_stats[n] = diff(frame_{n-1}, frame_n) → SceneChangePrev
  39. # next_stats[n] = diff(frame_n, frame_{n+1}) → SceneChangeNext
  40. prev_shifted = clip.std.DuplicateFrames(0).std.Trim(last=clip.num_frames - 1)
  41. prev_stats = core.std.PlaneStats(prev_shifted, clip, plane=plane)
  42. next_stats = core.std.PlaneStats(clip, clip.std.Trim(first=1), plane=plane)
  43.  
  44. def _set_sc_props(n: int, f: list[vs.VideoFrame]) -> vs.VideoFrame:
  45. fout = f[0].copy()
  46. fout.props['_SceneChangePrev'] = int(float(f[1].props.get('PlaneStatsDiff', 0.0)) > threshold)
  47. fout.props['_SceneChangeNext'] = int(float(f[2].props.get('PlaneStatsDiff', 0.0)) > threshold)
  48. return fout
  49.  
  50. return clip.std.ModifyFrame(
  51. clips=[clip, prev_stats, next_stats],
  52. selector=_set_sc_props
  53. )
Advertisement
Add Comment
Please, Sign In to add comment