Guest User

Untitled

a guest
Apr 5th, 2026
220
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.95 KB | None | 0 0
  1. import vapoursynth as vs
  2.  
  3. core = vs.core
  4.  
  5.  
  6. def _expr(clips: vs.VideoNode | list[vs.VideoNode], expr: str | list[str]) -> vs.VideoNode:
  7. """Expr — prefers llvmexpr → akarin → cranexpr → std."""
  8. if hasattr(core, "llvmexpr"):
  9. return core.llvmexpr.Expr(clips, expr)
  10. if hasattr(core, "akarin"):
  11. return core.akarin.Expr(clips, expr)
  12. if hasattr(core, "cranexpr"):
  13. return core.cranexpr.Expr(clips, expr)
  14. raise RuntimeError(
  15. "AntiRingLR requires akarin, llvmexpr, or cranexpr — "
  16. "none found. Install akarin, llvmexpr or cranexpr into your VS plugins folder."
  17. )
  18.  
  19.  
  20. def AntiRingLR(
  21. cl: vs.VideoNode,
  22. planes: str = "all",
  23. weightL: float = 0.25,
  24. offsetL: int = 1,
  25. weightR: float = 0.25,
  26. offsetR: int = 1,
  27. knee: float = 0.7,
  28. pr2: float = 0.5,
  29. pr3: float = 0.5,
  30. ) -> vs.VideoNode:
  31. """
  32. Hans' Ringing Remover — VapourSynth port.
  33. Output format always matches input format.
  34.  
  35. Parameters
  36. ----------
  37. cl : Input clip.
  38. planes : "luma", "chroma", or "all".
  39. weightL : Left-side correction intensity (0.15 – 0.7; 0.0 = inactive).
  40. offsetL : Left-side distance from edge (1 – 3).
  41. weightR : Right-side correction intensity.
  42. offsetR : Right-side distance from edge (1 – 3).
  43. knee : Softness of the on/off curve (0.2 – 1.5).
  44. pr2 : Protection for radius-2 signal components (0.0 – 1.5).
  45. pr3 : Protection for radius-3 signal components (0.0 – 1.5).
  46. """
  47.  
  48.  
  49.  
  50. fmt_in = cl.format
  51. is_gray = fmt_in.color_family == vs.GRAY
  52. work_fmt = vs.GRAYS if is_gray else vs.YUV444PS
  53.  
  54. cl_f = core.resize.Bicubic(cl, format=work_fmt)
  55.  
  56. pr2_coeff = pr2 * 0.36
  57. pr3_coeff = pr3 * 0.3
  58. scale = 10.0 / knee
  59. bias = 0.5 * knee
  60.  
  61. s128 = 128.0 / 255.0
  62. s64 = 64.0 / 255.0
  63. s127 = 127.0 / 255.0
  64.  
  65. luma_L = (
  66. "x[2,0] x[1,0] - dup * 0.75 * "
  67. "x[1,0] x - dup * + "
  68. "x x[-1,0] - dup * + "
  69. "x[-1,0] x[-2,0] - dup * 0.75 * + sqrt "
  70. )
  71.  
  72. prot_L = (
  73. f"x[3,0] x[1,0] - dup * 0.66 * x[2,0] x[0,0] - dup * + "
  74. f"x[1,0] x[-1,0] - dup * + x[0,0] x[-2,0] - dup * 0.66 * + sqrt {pr2_coeff} * - "
  75. f"x[3,0] x[0,0] - dup * 0.5 * x[2,0] x[-1,0] - dup * + "
  76. f"x[1,0] x[-2,0] - dup * + x[0,0] x[-3,0] - dup * 0.66 * + sqrt {pr3_coeff} * - "
  77. )
  78.  
  79. sigmoid_correct_L = (
  80. f"{scale} / {bias} - 0.0 max "
  81. f"dup 1.0 - swap 1.0 + / 1.0 + {s128} * 1.0 min "
  82. f"x[{offsetL},0] x[{2 + offsetL},0] - * {weightL} * -{s64} max {s127} min "
  83. )
  84.  
  85. luma_R = (
  86. "x[2,0] x[1,0] - dup * 0.75 * "
  87. "x[1,0] x - dup * + "
  88. "x x[-1,0] - dup * + "
  89. "x[-1,0] x[-2,0] - dup * 0.75 * + sqrt "
  90. )
  91.  
  92. prot_R = (
  93. f"x[-3,0] x[-1,0] - dup * 0.66 * x[-2,0] x[0,0] - dup * + "
  94. f"x[-1,0] x[1,0] - dup * + x[0,0] x[2,0] - dup * 0.66 * + sqrt {pr2_coeff} * - "
  95. f"x[-3,0] x[0,0] - dup * 0.5 * x[-2,0] x[1,0] - dup * + "
  96. f"x[-1,0] x[2,0] - dup * + x[0,0] x[3,0] - dup * 0.66 * + sqrt {pr3_coeff} * - "
  97. )
  98.  
  99. sigmoid_correct_R = (
  100. f"{scale} / {bias} - 0.0 max "
  101. f"dup 1.0 - swap 1.0 + / 1.0 + {s128} * 1.0 min "
  102. f"x[{-offsetR},0] x[{-2 - offsetR},0] - * {weightR} * -{s64} max {s127} min + x + "
  103. )
  104.  
  105. expr = (
  106. luma_L + prot_L + sigmoid_correct_L
  107. + luma_R + prot_R + sigmoid_correct_R
  108. )
  109.  
  110. do_luma = planes in ("luma", "all")
  111. do_chroma = planes in ("chroma", "all")
  112.  
  113. expr_y = expr if do_luma else "x"
  114. expr_u = expr if do_chroma else "x"
  115. expr_v = expr if do_chroma else "x"
  116. expr_list = [expr_y] if is_gray else [expr_y, expr_u, expr_v]
  117.  
  118. result = _expr(cl_f, expr_list)
  119.  
  120. return core.resize.Bicubic(result, format=fmt_in)
  121.  
  122.  
  123. def AntiRingLRUD(
  124. cl: vs.VideoNode,
  125. planes: str = "all",
  126. weightL: float = 0.25,
  127. offsetL: int = 1,
  128. weightR: float = 0.25,
  129. offsetR: int = 1,
  130. knee: float = 0.7,
  131. pr2: float = 0.5,
  132. pr3: float = 0.5
  133. ) -> vs.VideoNode:
  134. """
  135. Hans' Ringing Remover — horizontal + vertical pass.
  136. Applies AntiRingLR twice: once normally (fixes left/right ringing),
  137. and once on a 90°-rotated clip (fixes up/down ringing).
  138. """
  139.  
  140. # Pass 1 — horizontal ringing
  141. result = AntiRingLR(cl, planes=planes,
  142. weightL=weightL, offsetL=offsetL,
  143. weightR=weightR, offsetR=offsetR,
  144. knee=knee, pr2=pr2, pr3=pr3)
  145.  
  146. # Pass 2 — vertical ringing via 90° rotation
  147. rotated = core.std.Transpose(result)
  148. rotated = AntiRingLR(rotated, planes=planes,
  149. weightL=weightL, offsetL=offsetL,
  150. weightR=weightR, offsetR=offsetR,
  151. knee=knee, pr2=pr2, pr3=pr3)
  152. result = core.std.Transpose(rotated)
  153.  
  154. return result
Advertisement
Add Comment
Please, Sign In to add comment