VapourSynth经过四十多个版本的更新,滤镜已经丰富。但Avisynth时代留下了诸多的教程,似乎仍是VapourSynth无法比拟的。
因此,我试着将前辈们一些用avs写的教程迁移到vs上,希望能够给大家做一点微小的贡献。
有什么错误的地方还请大家指正~
默认import如下内容。
1 2 3 4 5 import vapoursynth as vs core = vs.get_core()import mvsfunc as mvfimport havsfunc as haf
NR de-banding思路
avs脚本出处:https://www.nmm-hd.org/newbbs/viewtopic.php?f=7&t=1495#p12163 作者:mawen1250
NR de-banding(去色带)思路,可以降低去色带的力度、提升效果。基本的思路是先扫去噪点层,再做去色带,做完后再把噪点层加回来。
其中NR指noise reduction,降噪的意思,很多处理都可以使用降噪做预处理,以提升效果。
avs脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 last = last nr16 = last.Dither_removegrain16(11 , 11 ).Dither_removegrain16(20 , 0 ) noise = last.Dither_sub16(nr16, y=3 , u=3 , v=3 , dif=True ) nr16 = last.Dither_sub16(noise, y=3 , u=3 , v=3 , dif=True ) last = nr16 last = last.f3kdb(16 , 40 , 40 , 40 , 0 , 0 , input_mode=1 , output_mode=1 ).Dither_limit_dif16(last, ref=nr16, thr=0.30 , elast=2.5 , y=3 , u=3 , v=3 ) last = last.Dither_add16(noise, y=3 , u=3 , v=3 , dif=True ) last
vs脚本 1 2 3 4 5 6 7 8 9 10 11 12 nr16 = core.rgvs.RemoveGrain(src16, [11 ,11 ]).rgvs.RemoveGrain([20 ,0 ]) noise = core.std.MakeDiff(src16, nr16, planes=[0 ,1 ,2 ]) nr16 = core.std.MakeDiff(src16, noise, planes=[0 ,1 ,2 ]) deband = core.f3kdb.Deband(nr16, 16 ,40 ,40 ,40 ,0 ,0 , output_depth=16 ) deband = mvf.LimitFilter(deband, nr16, thr=0.30 , elast=2.5 , planes=[0 ,1 ,2 ]) deband = core.std.MergeDiff(deband, noise, planes=[0 ,1 ,2 ])
在此基础上更复杂一点的用法。做完de-banding后,不把噪点全部加回来,而是对噪点层降噪。这就是SBR降噪的思路。
当然,如果是用KNLMeansCL这类降噪滤镜扫噪点层,在参数不太高的情况下,本身对画面的破坏就已经很小。如果想做降噪,可以不把噪点层加回来。
Chroma Shift的处理
avs脚本出处:https://www.nmm-hd.org/newbbs/viewtopic.php?f=7&t=1483&p=12144#p12144 作者:mawen1250
Chroma Shift(色度偏移)的处理。关于色度偏移,可以看一下mawen1250前辈的这个帖子 和EleonoreMizo前辈为fmtconv写的Doc 中resample
函数的部分。
avs脚本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 U_Horizontal_Shift = -0.25 U_Vertical_Shift = 0 V_Horizontal_Shift = -0.25 V_Vertical_Shift = 0 Y = last U = UToY8() V = VToY8() U = U.Spline16Resize(U.Width(), U.Height(), U_Horizontal_Shift, U_Vertical_Shift) V = V.Spline16Resize(V.Width(), V.Height(), V_Horizontal_Shift, V_Vertical_Shift) YToUV(U, V, Y)
vs脚本 1 2 3 4 5 6 7 8 9 10 U_Horizontal_Shift = -0.25 U_Vertical_Shift = 0 V_Horizontal_Shift = -0.25 V_Vertical_Shift = 0 result = core.fmtc.resample(src, src.width, src.height, sx=[0 , U_Horizontal_Shift, V_Horizontal_Shift], sy=[0 , U_Vertical_Shift, V_Vertical_Shift], planes=[2 ,3 ,3 ])
Chroma Bleeding的处理
avs脚本出处:https://www.nmm-hd.org/newbbs/viewtopic.php?f=7&t=1587&p=12668#p12651 作者:mawen1250
Chroma Bleeding(色度溢出)的处理。详情可以点开上面的链接看一下原帖,mawen1250前辈做了说明。主要是用了AWarpSharp2系列的滤镜,以亮度平面为mask,将色度平面中溢出的部分砍掉。这也很好理解,多出来的就砍掉嘛~
顺带一提,收线也可用这个滤镜。道理类似,“收”就是砍的嘛~
avs脚本 脚本是8bit YUV420输入,先升至16bit YUV444,再降至8bit YUV444处理色度溢出,继而升至16bit YUV444与未修正色度溢出的16bit YUV444源比较,最后保持16bit YUV444输出。
(mawen1250前辈的教程写于2015年2月,avs版AWarpSharp2在2018年3月更新的v2.0.0版中添加了16bit支持,上述反复升降位深的做法已不必要)
1 2 3 4 5 6 7 8 9 10 11 nnedi3_resize16(lsb_in=False , lsb=True , output="YV24" , ratiothr=2.25 , kernel_u="Bicubic" , a1=0.6 , a2=0.4 ) src16 = last DitherPost(mode=-1 ) warpe = ConvertToYV12().aSobel(128 , 1 ).aBlur(1 , 1 , 1 ) epp = YToUV(UToY().awarp(warpe, 6 , 1 ), VToY().awarp(warpe, 6 , 1 ), last) Dither_limit_dif16(src16, epp.U16(), thr=1.0 , elast=2 , y=2 , u=3 , v=3 )
vs脚本 这里使用了dubhater前辈的AWarpSharp2 移植,由于支持高位深,所以全程在16bit下处理。
在脚本的最后用mvf.LimitFilter
做了限制,这是照抄mawen1250前辈的avs脚本。但avs脚本做限制是为了保留未处理部分的16bit精度(如前面所说,在avs版AWarpSharp2支持16bit前,不得不反复升降位深,这会带来精度的损失),在全程16bit处理的情况下,这个限制是否有必要,值得思考。唔..我太笨了,就是这样
1 2 3 4 5 6 7 8 9 10 11 src16 = mvf.Depth(src, 16 ) src16 = core.fmtc.resample(src16, src.width, src.height, kernel='bicubic' , a1=0.6 , a2=0.4 , css='444' ) warpe = mvf.GetPlane(core.warp.ASobel(src16, 128 , 1 ).warp.ABlur(1 , 1 , 1 ), plane=0 ) fixU = core.warp.AWarp(mvf.GetPlane(src16, plane=1 ), warpe, depth=6 , chroma=0 ) fixV = core.warp.AWarp(mvf.GetPlane(src16, plane=2 ), warpe, depth=6 , chroma=0 ) epp = core.std.ShufflePlanes([src16, fixU, fixV], planes=[0 ,0 ,0 ], colorfamily=vs.YUV) result = mvf.LimitFilter(src16, epp, thr=1.0 , elast=2.0 , planes=[1 ,2 ])
如果不想保持16bit YUV444输出,而是输出一般的16bit YUV420,则在进行上述处理后,再用fmtc.resample
缩放即可。降低分辨率通常推荐用Spline(样条采样)系列中的spline36
,fmtc.resample
的默认参数就是它。
1 result = core.fmtc.resample(result, src.width, src.height, kernel='spline36' , css='420' )
当然,如果是以16bit YUV420输出,将mvf.LimitFilter
的限制放到缩放后,将未拉伸色度平面的输入源与降回16bit YUV420的处理结果比较,可能会更好。因为这样多少限制了色度平面拉伸与缩小过程的损失。(我口胡的,不要打我呀~
后记 本来想打两个波浪线买一下萌,忘了markdown语法,结果变成了下面那个样子,太真实了。
(未完待续~~我才不会鸽的~)