头像
Evalyn
帖子: 17
注册时间: 2014-07-19 20:49

Contra-Sharpen mod —— EP锐化/还原用脚本(v0.2.5解决ringing问题)

Avisynth下雯姐的CSMOD的移植版本。
真是EP到吐血..

v0.2.5对应新版CSmod 3.7 + CSmod16 1.6移植
CSMOD v0.2.5 with README.zip
(11.6 KiB) 下载 489 次
v0.2.3更新一处bug,修正在处理chroma的情况下,temporal limit时 chromamv = False 导致报错的问题。
以及原来temporal limit部分的一处逻辑问题

v0.2.4修正edgemask mode -5/-7/5 下存在的edgethr scale问题,现在edgethr均为8bit scale。
v0.2.5修复内置函数clamp一处错误,修正一处逻辑错误导致limit结果异常,从而引起ringing严重的问题

如果后面没有功能性更新的话
(估计也不会有
大概只会有小版本号的迭代用于修正潜在的bug...
欢迎回报捉虫 \\QwQ//

多的话我就不写了,有什么问题参考雯姐原来的帖子

VS版的特性为:仅支持YUV(或灰阶)输入,支持8~16bit INT输入,支持YV12与YV24。其他色彩空间未测试。
(实际上,如果不处理Chroma的话,YUV Colorfamily应该都是支持的。并且在ss_w * ss_h <= 3.0625时,即使处理Chroma应该也没有什么问题)
2.5版的锐化强度基本与avs版一致,不过,使用时还是请留意一下。(尤其是直接改写脚本时
速度方面,相比AVS提速较为明显。框多时应该很快。
► 显示剧情透露 SpeedTest By 舒书好@VCB-S
我就主要写一下与AVS的3.4+1.3版本相比,VS版本的CSMOD v0.2有哪些改动...

替偷懒的雯姐写一下v0.2的Changelog。

1. 参数 ss_hq 从bool 改为 int[0~2]
## 0:当横纵方向的supersample倍数乘积小于3.0625,即(ss_w*ss_h < 3.0625)时,使用non-ringing Spline64Resize做supersampling,否则使用nnedi3(pscrn=2)做supersampling。
## 1:一直使用nnedi3(pscrn=1)做supersampling,慢,但效果好一些。
## 2:一直使用nnedi3(pscrn=2)做supersampling,比1快很多,提升大概2-3倍。
(pscrn=0几乎没啥意义,太慢了。。)

2. 增加参数 showmask[bool]
是否输出内部mask,用于调试或者其他用途,默认False。
► 显示剧情透露 内置edgemask mode一览表
3. 移除参数 ssoutc[bool]
如果以supersample分辨率输出(ssout=True),且不处理UV(chroma = False),则UV平面默认会用non-ringing Spline64Resize修正到对应分辨率后一起输出。
# 但注意!如果以supersampling分辨率输出且处理Chroma,则你需要自己承担可能的Chroma shift风险。这个下面详细解释。

4. 加入灰阶支持
可直接处理Y8,Y16等。
同时如果不处理Chroma,内部将以灰阶处理,UV会被完全Copy。可以快大概10%。

5. 参数 secure 从 bool 改为 float[0~255]
Threshold(on an 8-bit scale) to avoid banding & oil painting (or face wax) effect of sharpening, set 0 to disable it.(from LSFmod)

5. 增加参数 preset[str]
预设有:
very fast
faster【Default if source[clip] is defined】
fast
medium【Default if source[clip] is not defined】
slow
slower
very slow
noise(细噪点)
grain(颗粒噪点)
detail(细节)
和CSmod1.6相比,去除了deband预设以及相关参数,因为可以用参数filter_ss自定义实现一样的效果。
预设非常快,建议降到very slow使用。

6. 增加参数 nr[bool]
控制是否在Spline64Resize时使用non-ringing算法,与预设有关。

7. 增加参数 sspre[bool]
True则在supersample分辨率下做pre-filter,False则在原分辨率下做pre-filter。
默认False,除非已经定义了filter_ss参数。
► 显示剧情透露 内置pre-filtering mode一览表
8. 增加参数 limitsrc[bool]
控制是否在时域以及空域稳定上使用source clip作为参照。

请注意下另一个参数 limit 的生效条件!
limit参数,控制是否依据source clip对filtered clip做Repair(3x3邻域像素限制),只在(Defined(source) || Defined(filter_ss) || usepasf) == True时有效。

类似的thr / thrc 参数并没有这个限制,并且 thr / thrc 的取值范围均为 0-255 ( 8bit scale )!
► 显示剧情透露 可能的Chroma shift风险 When "ssout=True"

代码: 全选

# 参数 "ssmethod" 的使用示例
import vapoursynth as vs
import nnedi3_resample as nnrs
import CSMOD as cs

core = vs.get_core()

def SSMethod(clip):
	ss_w = 2	# scale ratio in horizon
	ss_h = 2	# scale ratio in vertical
	width = clip.width		# source width
	height = clip.height	# source height

	clip = nnrs.nnedi3_resample(clip, width * ss_w, height * ss_h, nnrs=3)
		
	return clip
	# using nnedi3_resample as internal supersample method.
	# (No chroma placement issue when "ssout=True")

src = core.lsmas.LWLibavSource('xxx.mp4')
cs = cs.CSMOD(src, ssmethod=SSMethod, ss_w=2, ss_h=2, ssout=True)
# you should keep scale ratio set correctly

cs.set_output()
► 显示剧情透露 How to reproduce "preset=deband" using param "filter_nr"

代码: 全选

# 参数 "filter_nr" 的使用示例
import vapoursynth as vs
import CSMOD as cs

core = vs.get_core()

def deband(clip):
	clip = core.f3kdb.Deband(clip)		
	return clip
# you can also define a AA processing in supersample resolution with "filter_ss" param here

src = core.lsmas.LWLibavSource('xxx.mp4')
cs = cs.CSMOD(src, filter_nr=deband)


cs.set_output()
其他自定义参数 "kernel","filter_ss" 的定义与使用方法与 "filter_nr" 相同。
► 显示剧情透露 内置unsharp kernel一览表
但自定义参数 "Smode" 仍然是可以string型定义一个逆波兰表达式,
可定义预设 [1]Linear , [2]Non-linear , [3]Non-linear 2(from LSFmod Smode=5) 之外的sharpen mode。
上次由 Evalyn 在 2016-01-27 19:17,总共编辑 24 次。
► 显示剧情透露 欢迎各路姐姐前来照顾萝莉
头像
Evalyn
帖子: 17
注册时间: 2014-07-19 20:49

Re: Contra-Sharpen mod —— EP锐化/还原用脚本,VS移植版

已更新v0.2.1
► 显示剧情透露 欢迎各路姐姐前来照顾萝莉
TodyYDDY
帖子: 14
注册时间: 2015-12-15 23:13

Re: Contra-Sharpen mod —— EP锐化/还原用脚本,VS移植版

VS版比AVS版的CSMOD16强度高不少,是不是因为主要是基于CSMOD移植的?(AVS版COMOD参数基本一样的情况下强度也是明显高于CSMOD16,脚本太复杂,原因不明)。

报告一个BUG:chroma=True的时候会报错。或者是我不会用,请菊苣指教。
另外,maskmode=2的时候edge也会被锐化, maskmode=1的时候反而不会(或者不明显?)。不过py脚本的merge部分目测是对的(不会python,说错了莫见怪)。

Failed to evaluate the script:
Python exception: Analyse: super clip does not contain needed colour data.
Traceback (most recent call last):
File "src\cython\vapoursynth.pyx", line 1484, in vapoursynth.vpy_evaluateScript (src\cython\vapoursynth.c:26808)
File "D:/Encode/Speed/01.vpy", line 71, in <module>
drs16 = cs.CSMOD(dr16, src16, chroma=False, edgemode=0, preblur=-2, strength=80)
File "C:\Python\lib\site-packages\vapoursynth\CSMOD.py", line 1192, in CSMOD
f1v = core.mv.Analyse(super=sMVS,blksize=blksize,search=search,searchparam=searchparam,pelsearch=pelsearch,isb=False,chroma=chroma,truemotion=truemotion,_global=MVglobal,overlap=overlap,dct=DCT)
File "src\cython\vapoursynth.pyx", line 1376, in vapoursynth.Function.__call__ (src\cython\vapoursynth.c:25123)
vapoursynth.Error: Analyse: super clip does not contain needed colour data.


vpy脚本:

import vapoursynth as vs
import nnedi3_resample as nnrs
import havsfunc as haf
import mvsfunc as mvf
import os
import functools
import CSMOD as cs

core = vs.get_core(accept_lowercase=True, threads=6)
core.max_cache_size = 10000

srcPath = r'D:\Encode\Speed\01.d2v'
src = core.d2v.Source(srcPath, threads=1)
src = core.vivtc.VDecimate(core.vivtc.VFM(src, order=1, mode=3, mchroma=True, cthresh=9, mi=80, chroma=True))

def conditionalDeint(n, f, orig, deint):
if f.props._Combed:
return deint
else:
return orig

deint = core.tdm.TDeintMod(src, order=1, edeint=core.nnedi3.nnedi3(src, field=1))
combProps = core.tdm.IsCombed(src)
src = core.std.FrameEval(src, functools.partial(conditionalDeint, orig=src, deint=deint), combProps).std.CropRel(8, 8, 0, 0)

src16 = mvf.Depth(src, depth=16)

dh16 = haf.DeHalo_alpha(src16, rx=2.0, ry=2.0, darkstr=0.5, brightstr=1.0, lowsens=30, highsens=100, ss=1.5)
dh16 = haf.HQDeringmod(src16, p=dh16, mrad=3, msmooth=3, incedge=False, mthr=60, minp=1, sharp=0, drrep=13, thr=10., elast=2., darkthr=1.0, planes=[0], show=False)

dr16 = haf.HQDeringmod(dh16, mrad=2, msmooth=2, incedge=False, mthr=100, minp=1, nrmode=2, sharp=0, drrep=13, thr=8., elast=2., darkthr=2, planes=[0], show=False)

b1 = mvf.BM3D(dr16 , sigma=[12,0,0], radius1=0, profile1="lc")
b2 = core.knlm.KNLMeansCL(dr16 , d=0, a=4, s=2, h=7, device_type="GPU")

drdiff1 = core.std.MakeDiff(dr16, b1, [0])
drdiff2 = core.std.MakeDiff(dr16, b2, [0])
drdiff16 = core.std.Expr([drdiff1,drdiff2], ["x y > x y ?","",""], vs.YUV420P16)

b16 = core.std.MakeDiff(dr16, drdiff16, [0])

omask = haf.HQDeringmod(src16, mrad=3, msmooth=2, incedge=False, mthr=80, minp=0, show=True)
imask = haf.HQDeringmod(src16, mrad=1, msmooth=1, incedge=False, mthr=80, minp=0, show=True)
drmask = core.std.Expr([omask, imask], ['x {peak} y - * {peak} /'.format(peak=(1 << 16) - 1)])

dr16 = haf.HQDeringmod(dr16, ringmask=drmask, p=b16, sharp=0, drrep=13, thr=8., elast=2., darkthr=1.5, planes=[0], show=False)

drs16 = cs.CSMOD(dr16, src16, chroma=True, edgemode=0, preblur=-2, strength=70)
final = haf.HQDeringmod(drs16, mrad=2, msmooth=2, incedge=False, mthr=70, minp=1, nrmode=2, sharp=0, drrep=13, thr=4., elast=2., darkthr=1., planes=[0], show=False)

final.set_output()
头像
Evalyn
帖子: 17
注册时间: 2014-07-19 20:49

Re: Contra-Sharpen mod —— EP锐化/还原用脚本,VS移植版

TodyYDDY 写了:VS版比AVS版的CSMOD16强度高不少,是不是因为主要是基于CSMOD移植的?(AVS版COMOD参数基本一样的情况下强度也是明显高于CSMOD16,脚本太复杂,原因不明)。

报告一个BUG:chroma=True的时候会报错。或者是我不会用,请菊苣指教。
另外,maskmode=2的时候edge也会被锐化, maskmode=1的时候反而不会(或者不明显?)。不过py脚本的merge部分目测是对的(不会python,说错了莫见怪)。
► 显示剧情透露 Failed to evaluate the script:
► 显示剧情透露 vpy脚本:
首先感谢报错,在temporal limit部分,误把俩chromamv写成了chroma,导致这俩设定真值不同时出现冲突报错...已修正。
手残没得救,debug时又顺手发现 tcanny mask 模式下俩特殊变量名写错...
不过脚本的确是大多参照CSMOD写的,CSMOD16只是参考了部分功能以及预设。锐化强度自己注意一下就行(死)。

然后maskmode问题,应该是edgemode?并没有maskmode这个参数。。(倒是有edgemask用于选择不同的mask generate mode,同时edgethr用于tweak edgemask threshold)

我测试了下,也做了diff比对,maskedmerge是没有问题的,在edgemode=2(仅处理non-edge)时也出现了edge被锐化现象,很可能是因为mask保护力度不足引起的。你没有指定预设,但指定了source clip,那么预设默认是faster,此时默认的是edgemask=1【Same as edgemaskHQ=False in LSFmod(min/max)】,对线条保护力度不是很强。可以选择用其他的edgemask。
雯姐也调侃说他并不会用这些然并卵的内置mask(逃)。
我在主楼补充了内部的mask模式,或者干脆自己导入一个外部做过binarize的mask clip,注意位深和输入clip相同就行。
► 显示剧情透露 欢迎各路姐姐前来照顾萝莉
头像
mawen1250
核心会员
核心会员
帖子: 670
注册时间: 2011-07-24 20:33

Re: Contra-Sharpen mod —— EP锐化/还原用脚本,VS移植版

CSmod16我最早写出来时就发现强度明显高于CSmod,当时不知道为啥,所以把默认的strength调低了。
后来偶然发现Dither_lut16的表达式解析"x x"时有问题,这直接影响了Smode里的非线性映射的结果,也是为什么强度偏高(实际上如果锐化后不做限制,高频处直接会锐化成一坨白点+黑点,这也是发现了这个bug的原因),于是报告给了dither作者,并在之后的版本修复了这个问题——那么结果是之后由于CSmod16的默认strength比较低,锐化强度也就低了——这个默认值在前些天更新的CSmod16 v1.6里也修改回100了,不知道TodyYDDY说的锐化强度问题是不是这个原因。
TodyYDDY
帖子: 14
注册时间: 2015-12-15 23:13

Re: Contra-Sharpen mod —— EP锐化/还原用脚本,VS移植版

mawen1250 写了:CSmod16我最早写出来时就发现强度明显高于CSmod,当时不知道为啥,所以把默认的strength调低了。
后来偶然发现Dither_lut16的表达式解析"x x"时有问题,这直接影响了Smode里的非线性映射的结果,也是为什么强度偏高(实际上如果锐化后不做限制,高频处直接会锐化成一坨白点+黑点,这也是发现了这个bug的原因),于是报告给了dither作者,并在之后的版本修复了这个问题——那么结果是之后由于CSmod16的默认strength比较低,锐化强度也就低了——这个默认值在前些天更新的CSmod16 v1.6里也修改回100了,不知道TodyYDDY说的锐化强度问题是不是这个原因。
soga,感謝解答。
TodyYDDY
帖子: 14
注册时间: 2015-12-15 23:13

Re: Contra-Sharpen mod —— EP锐化/还原用脚本,VS移植版

# 5: tcanny mask(less sensitive to noise)
elif edgemask == 5:
edgemask = core.tcanny.TCanny(srcfinal, sigma=tcannysigma, mode=1, planes=0)
mt = "x "+str(edgethr*0.5)+" <= 0 x "+str(edgethr*0.5)+" - 2.4 pow ?"
edgemask = core.std.Expr(edgemask,[mt] if GRAYS else [mt,""])
edgemask = core.rgvs.RemoveGrain(edgemask,[20 if HD else 11] if GRAYS else [20 if HD else 11,0])
edgemask = core.std.Inflate(edgemask,planes=0)

貌似edgethr要乘255? 昨天试验edgemask=5, edgethr=10000结果才正常;默认几十showmask=True几乎全屏白色。
头像
Evalyn
帖子: 17
注册时间: 2014-07-19 20:49

Re: Contra-Sharpen mod —— EP锐化/还原用脚本,VS移植版

TodyYDDY 写了:# 5: tcanny mask(less sensitive to noise)
elif edgemask == 5:
edgemask = core.tcanny.TCanny(srcfinal, sigma=tcannysigma, mode=1, planes=0)
mt = "x "+str(edgethr*0.5)+" <= 0 x "+str(edgethr*0.5)+" - 2.4 pow ?"
edgemask = core.std.Expr(edgemask,[mt] if GRAYS else [mt,""])
edgemask = core.rgvs.RemoveGrain(edgemask,[20 if HD else 11] if GRAYS else [20 if HD else 11,0])
edgemask = core.std.Inflate(edgemask,planes=0)

貌似edgethr要乘255? 昨天试验edgemask=5, edgethr=10000结果才正常;默认几十showmask=True几乎全屏白色。
原来设计是这样的,mask部分无需16bit精度。
如果源位深高于8bit,会将mask前的prefinal clip全部降到8bit再框mask,可以精简不少位深自适应的Expr,同时小幅度提升部分mask mode下的速度。

代码: 全选

prefinal = Depth(prefinal,8)
但我忘了几个tcanny mask模式使用的是特殊的srcfianl clip。所以如果指定的source clip是16bit时就会出现上述问题,即必须指定edgethr为16bit scale才行。
感谢提醒,已修正scale问题。现在edgethr均为8bit scale。
► 显示剧情透露 欢迎各路姐姐前来照顾萝莉
TodyYDDY
帖子: 14
注册时间: 2015-12-15 23:13

Re: Contra-Sharpen mod —— EP锐化/还原用脚本,VS移植版

貌似limit,Tlimit,Slimit,Tovershoot,Sovershoot等限制参数对结果没什么影响?
算法弱,看脚本只能了解大致处理过程 {:cat_5}

回到 “VapourSynth”