View Full Version : ChromaReconstructor v3.0: restore 420/422 to (almost) native 444


feisty2
26th December 2015, 17:00
function ChromaReconstructor(clip src, int "radius", float "str", int "hipass", int "mode", bool "wild")
{
radius = default(radius, 32)
str = default(str, 6.4)
hipass = default(hipass, 6)
mode = default(mode, 0)
wild = default(wild, True)
w = src.width
h = src.height / 2
ref = wild ? src.ConvertToY8() : src.ConvertToY8().KNLMeansCL(0, radius, 0, False, 1, pow(1.464968620512209618455732713658, str), lsb_inout=True)
srcU = src.UToY8()
srcV = src.VToY8()
src8 = YToUV(srcU, srcV, ref).Ditherpost(mode=-1)
up2x = src8.nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnRight().nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnLeft()
up4x = up2x.nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnRight().nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnLeft()
up16 = up4x.Dither_convert_8_to_16()
Luma = up16.ConvertToY8()
U = up16.UToY8()
V = up16.VtoY8()
Unew = wild ? KNLMeansCL(U, 0, radius, 0, False, 1, str, Luma, lsb_inout=True) : interpolation(Luma, U, 2, str)
Unew = wild ? Unew : interpolation(Luma, Unew, 4, str)
Unew = wild ? Unew : interpolation(Luma, Unew, 8, str)
Unew = wild ? Unew : interpolation(Luma, Unew, 16, str)
Unew = wild ? Unew : interpolation(Luma, Unew, 32, str)
Unew = Unew.Dither_resize16nr(w, h, src_left=-1.5, src_top=-1.5, kernel="spline", taps=6)
Vnew = wild ? KNLMeansCL(V, 0, radius, 0, False, 1, str, Luma, lsb_inout=True) : interpolation(Luma, V, 2, str)
Vnew = wild ? Vnew : interpolation(Luma, Vnew, 4, str)
Vnew = wild ? Vnew : interpolation(Luma, Vnew, 8, str)
Vnew = wild ? Vnew : interpolation(Luma, Vnew, 16, str)
Vnew = wild ? Vnew : interpolation(Luma, Vnew, 32, str)
Vnew = Vnew.Dither_resize16nr(w, h, src_left=-1.5, src_top=-1.5, kernel="spline", taps=6)
UHi = (mode == 1) ? Dither_sub16(Unew, gauss_h(Unew, hipass), dif=True) : Dither_sub16(Unew, gauss(Unew, hipass), dif=True)
VHi = (mode == 1) ? Dither_sub16(Vnew, gauss_h(Vnew, hipass), dif=True) : Dither_sub16(Vnew, gauss(Vnew, hipass), dif=True)
UFinal = Dither_add16(srcU, UHi, dif=True)
VFinal = Dither_add16(srcV, VHi, dif=True)
return YToUV(UFinal, VFinal, src.ConvertToY8())
}

function interpolation(clip luma, clip "chroma", int "radius", float "str")
{
exp_c0 = 1.060417282747435920994529352433
exp_c1 = pow(1.070339301855046091743224243341, 32)
weight = pow(exp_c0, radius) / exp_c1
ref0 = Dither_lut16(chroma, "x "+string(weight)+" *")
ref1 = Dither_lut16(luma, "x 1.0 "+string(weight)+" - *")
ref = Dither_add16(ref0, ref1, dif=False)
return KNLMeansCL(chroma, 0, radius, 0, False, 1, str, ref, lsb_inout=True)
}

function gauss(clip src, int "p")
{
p = default(p, 30)
w = src.width
h = src.height / 2
upsmp = Dither_resize16(src, w * 2, h * 2, kernel="gauss", a1=100)
return Dither_resize16(upsmp, w, h, kernel="gauss", a1=p)
}

function gauss_h(clip src, int "p")
{
p = default(p, 30)
w = src.width
h = src.height / 2
upsmp = Dither_resize16(src, w * 2, h, kernel="gauss", a1=100)
return Dither_resize16(upsmp, w, h, kernel="gauss", a1=p)
}


vaporsynth version: https://github.com/IFeelBloated/BlockMatchingToolkit/blob/master/BMToolkit.py (named "fulltonative")

no support to 8bits anymore, stacked 16bits vid is required!!!

just convert 420/422 to 444 with any regular resampling filter, bicubic, spline, kind of stuff
and apply this filter, chroma planes will be reconstructed to 444 with high frequencies from luma (luma serves as the weighting reference to NLMeans both chroma planes)

demos:
special pattern
source
http://i.imgur.com/Icqh01Q.png

converttoyv12()
converttoyv24()

http://i.imgur.com/Q1VyILy.png

converttoyv12()
converttoyv24()
Dither_convert_8_to_16()
ChromaReconstructor()
ditherpost(mode=-1)

http://i.imgur.com/lbP1r9B.png

on bluray quality level vids

##rule6##
converttoyv24()
utoy8()

http://i.imgur.com/ru1CgYl.png

##rule6##
converttoyv24()
Dither_convert_8_to_16()
ChromaReconstructor()
ditherpost(mode=-1)
utoy8()

http://i.imgur.com/iz1Ck3i.png

on (awesome) DVD quality level vids

##rule6##
converttoyv24()
utoy8()

http://i.imgur.com/AtwFKkM.png

##rule6##
converttoyv24()
Dither_convert_8_to_16()
ChromaReconstructor()
ditherpost(mode=-1)
utoy8()

http://i.imgur.com/WZ6luCN.png

on (shitty) DVD quality level vids

##rule6##
converttoyv24()
utoy8()

http://i.imgur.com/P211BNe.png

##rule6##
converttoyv24()
Dither_convert_8_to_16()
ChromaReconstructor(hipass=12)
ditherpost(mode=-1)
utoy8()

http://i.imgur.com/dkYiM19.png

on 4:2:2 vids (mastertape or whatever)

##rule6##
converttoyv24()
utoy8()

http://i.imgur.com/wmBcAUE.png

##rule6##
converttoyv24()
Dither_convert_8_to_16()
ChromaReconstructor(hipass=8, mode=1)
ditherpost(mode=-1)
utoy8()

http://i.imgur.com/ggqdBeF.png

when luma is not stable enough to rebuild chroma (common in cartoon-related cases)

##rule6##
converttoyv24()

http://i.imgur.com/7s6FJYv.png

##rule6##
converttoyv24()
utoy8()

http://i.imgur.com/witbZTI.png

##rule6##
converttoyv24()
Dither_convert_8_to_16()
ChromaReconstructor(hipass=12, wild=False)
ditherpost(mode=-1)

http://i.imgur.com/mbAgDcS.png

##rule6##
converttoyv24()
Dither_convert_8_to_16()
ChromaReconstructor(hipass=12, wild=False)
ditherpost(mode=-1)
utoy8()

http://i.imgur.com/uUyD9Xv.png
LOG:
v2.0: major update, much better quality and a lot slower, LOL
v2.1: so I realized that hardcore kind of real sharp chroma doesn't look so good, and v2.1 gives a softer and more natural look
v2.2: new parameter "mode", mode=0 for 4:2:0 and mode=1 (vertical filtering disabled) for 4:2:2
v2.2.1 fixed a stupid copy-paste typo
v3.0 major update, new parameter "hipass" allows you to manipulate the strength of the high frequency extraction, a new less aggressive (and a lot slower) method could be enabled when luma is not stable enough (set "wild" to False)

Mounir
26th December 2015, 21:44
I get an error: "Repair: only planar color spaces supported" any idea ?

Reel.Deel
26th December 2015, 22:12
I get an error: "Repair: only planar color spaces supported" any idea ?

You need RgTools (https://github.com/tp7/RgTools/releases).

AzraelNewtype
26th December 2015, 22:21
In case anybody wants to see what this is doing without having to scroll back and forth between two gray images, or worse actually move their eyes between the two, inviting differences in the monitor to cause issues. (http://screenshotcomparison.com/comparison/155771)

Mounir
27th December 2015, 00:30
You need RgTools (https://github.com/tp7/RgTools/releases).

Thanks, now that i load rgtool i get another error:
"mt_makediff unsupported colorspace..masktools support planar yuv"..

StainlessS
27th December 2015, 00:48
Daft question but what colorspace are you using ? (YUY2, EDIT: Needs planar now, no YUY2 support I think, sadly.
Not sure, think does not even support v2.6 Planar colorspaces)

Reel.Deel
27th December 2015, 01:15
Thanks, now that i load rgtool i get another error:
"mt_makediff unsupported colorspace..masktools support planar yuv"..

If the colorspace is YUY2 then ConvertToYV16(). Also make sure you're using MaskTools2 for AviSynth 2.6 (https://github.com/tp7/masktools/releases).

Daft question but what colorspace are you using ? (YUY2, EDIT: Needs planar now, no YUY2 support I think, sadly)

No big deal, conversion between YV16 and YUY2 is fast and lossless.

StainlessS
27th December 2015, 01:22
Oh, rgtools does support v2.6 Planar (I did originally suggest convert to YV16, then changed my mind).
If people are going to 'update' a plug, should always support at least same colorspace and functions as in old one (unless good reason not to).
rg, does not I think support all functions.

Reel.Deel
27th December 2015, 01:34
If people are going to 'update' a plug, should always support at least same colorspace and functions as in old one (unless good reason not to).

Here's some good reasons: http://avisynth.nl/index.php/AviSynth%2B#Stop_YUY2


rg, does not I think support all functions.
RgTools only includes the most popular filters from the RemoveGrain package (RemoveGrain, Repair, and the Clense family). The original one has a few other other filters, fortunately, no one really uses them.

StainlessS
27th December 2015, 02:06
Here's some good reasons
I whole heatedly agree, IF, YUY2 is officially deprecated (I would like to propose YV411 be also included here, [lets not even think about YUV9]).
OK, to import YV411, but lets not have filters be expected to support it.

fortunately, no one really uses them.
But you do get a bit stuck in a knot when you do need to use them, back to old version plugin, and the awful, if and buts that come with that.

feisty2
27th December 2015, 06:59
okay, this whole "reconstructed native Hi-Res chroma guided by high frequencies from luma" is technically hacky and unstable, and has a small possibility leading to ugly artifacts tho the filter was carefully designed to avoid crap like that, I've tested it on about 50 different movie clips and have not yet found any "it just goes south" case, other test results and suggestions are welcome

Sparktank
27th December 2015, 10:34
Hmmmm.

Would this be more for SD sources?
Your default for converttoyv24() is the defaults, which is Rec601.

If I wanted to convert, per se, Scream BD (Rec.709) to a 720p encode or even an SD encode, I can see this helping.
The examples given are very nice on an SD source.

I'll run some tests on various sources.
A few DVD's (one pro, one int).
A BD or so.

feisty2
27th December 2015, 10:41
Hmmmm.

Would this be more for SD sources?
Your default for converttoyv24() is the defaults, which is Rec601.

it's for any not 4:4:4 vid, at any resolution, sd, hd, even 4k or 8k, long as it's been chroma subsampled
yv12/yv16 - yv24 conversion is pure "resizing", has nothing to do with matrix

Sparktank
27th December 2015, 11:19
: thumbsup :

I like the improvement in the comparisons provided.

Mounir
27th December 2015, 11:33
Also make sure you're using MaskTools2 for AviSynth 2.6 (https://github.com/tp7/masktools/releases).

It seems i needed masktools2 for avs 2.6 thanks !

MysteryX
27th December 2015, 15:12
I just tried this at the beginning of my script to upgrade SD to HD, and really can't see any difference...


AviSource(file, audio=True, pixel_type="YV12")
ConvertToYV24()
ChromaReconstructor()
KNLMeansCL(D=0, A=2, h=3, cmode=true, device_type="GPU", device_id=1)
Double="""edi_rpow2(2, nns=4, cshift="Spline16Resize", Threads=2)"""
SuperRes(1, 0.85, 0, Double, MatrixIn="601")
ConvertToYV12()
InterFrame(Cores=8, Tuning="Smooth", NewNum=60000, NewDen=1001, GPU=true)
Double="""edi_rpow2(2, nns=4, cshift="BicubicResize", a1=-.6, a2=0, lsb=true, fwidth=940, fheight=720, Threads=2)"""
SuperRes(1, 0.85, 0, Double, lsb_upscale=true)


And it just occurred to me. Since chroma needs to be doubled when converting YV12 to YV24... why can't we use NNEDI3 for this? Or how can I do NNEDI3 chroma upsampling?

Also, does ConvertToYV24() fix the chroma shift?

feisty2
27th December 2015, 15:21
Chroma sub sampling wouldn't have existed if you can tell a huge difference between yv24 and yv12 on photo like images
Upscaling chroma with nnedi is technically incorrect for nnedi was trained for regular images, not "difference".
And even if it works, it wouldn't have the "native" hi res kind of high quality

feisty2
27th December 2015, 15:31
By the way, you destroyed everything when you converted yv24 back to yv12 for what exactly?
I don't think you get what this filter is used for

MysteryX
27th December 2015, 16:31
There are two times where I need to convert back to YV12: before calling InterFrame, and before encoding at the end.

There are also other times where I need to convert to YV24 and perform operations in that space or in the 16-bit RGB space.

I thought it might avoid losing chroma quality several times, but apparently it doesn't do much in this scenario.

However, I think I'll replace ConvertToYV24() with ConvertToYV24(chromaresample="Spline16"). That does a difference.

feisty2
27th December 2015, 16:41
this thing is useless when
1. The video quality is crappy, luma is not good enough to guide chroma
2. You have to convert back to 4:2:0/4:2:2 somewhere in the script after applying this
3. You are not going to encode at 4:4:4

And seems like you got all 3 of them covered...

feisty2
27th December 2015, 16:46
Spline16 for chroma upscaling??!
No comment..

MysteryX
27th December 2015, 16:53
this thing is useless when
1. The video quality is crappy, luma is not good enough to guide chroma
2. You have to convert back to 4:2:0/4:2:2 somewhere in the script after applying this
3. You are not going to encode at 4:4:4

And seems like you got all 3 of them covered...
:)

Spline16 for chroma upscaling??!
No comment..
You think the default Bicubic is better? Any detail you can give on this? Just a very quick test seemed to look better with Spline16, and too sharp with Spline36, although the difference is small.

By the way, I'm curious about something. ResizeX fixes a small chroma shift error that is caused by the internal resizers. I suppose ConvertToYV24 doesn't fix that error in the same way that ResizeX does?

feisty2
27th December 2015, 16:56
Spline16 is an over sharpening (unbalanced) kernel
And should never be used

MysteryX
27th December 2015, 17:44
Spline16 is an over sharpening (unbalanced) kernel
And should never be used
Most people use it for NNEDI3 sub-pixel correction.

bxyhxyh
27th December 2015, 18:43
Most people use it for NNEDI3 sub-pixel correction.

I think he meant Spline16 is too sharp for upsampling the chroma, not center shift correction.

CkJ
27th December 2015, 21:07
Or how can I do NNEDI3 chroma upsampling?
nnedi3_rpow2(rfactor=2, cshift="").utoy8/vtoy8

I use eedi3 instead of nnedi3 for chroma upsampling
function ChromaReconstructor(clip src, int "a", float "h")
{
a = default(a, 32)
h = default(h, 6.4)
Luma = src.ConvertToY8()
src2 = src.eedi3_rpow2(rfactor=2, cshift="bilinearresize")
U = src2.UToY8()
V = src2.VtoY8()
Unew = U.KNLMeansCL(d=0, a=a, s=0, h=h, rclip=Luma).Repair(U, 1)
Vnew = V.KNLMeansCL(d=0, a=a, s=0, h=h, rclip=Luma).Repair(V, 1)
UHi = mt_makediff(Unew, blur(Unew, 1.58).blur(1.58))
VHi = mt_makediff(Vnew, blur(Vnew, 1.58).blur(1.58))
UFinal = mt_adddiff(U, UHi)
VFinal = mt_adddiff(V, VHi)
return YToUV(UFinal, VFinal, Luma)
}

converttoyv24
utoy8
http://i.imgbox.com/wb5ak1lH.png
ChromaReconstructor
utoy8
http://i.imgbox.com/TIzAojuc.png
Original (yv12)
http://i.imgbox.com/LIed3Nq6.png
ChromaReconstructor (yv24)
http://i.imgbox.com/ljKMaE1N.png

The red has big difference. :)

feisty2
27th December 2015, 23:47
Yeah, now you've got a reason to encode at 4:4:4.:devil:

Desbreko
28th December 2015, 00:17
By the way, I'm curious about something. ResizeX fixes a small chroma shift error that is caused by the internal resizers. I suppose ConvertToYV24 doesn't fix that error in the same way that ResizeX does?
The internal ConvertTo functions don't cause chroma shift like the resize functions do.

Edit:

nnedi3_rpow2(rfactor=2, cshift="").utoy8/vtoy8
Upsampling the chroma this way will result in a chroma shift, by the way, because you're not accounting for the YV12 chroma being left-aligned. To do it right, you need to correct the shift with an external resize instead of using the rpow2 function's cshift, like this:

# YV12 source
u = UToY8().edi_rpow2(2, edi="nnedi3").Spline36Resize(Width(),Height(),0,-0.5)
v = VToY8().edi_rpow2(2, edi="nnedi3").Spline36Resize(Width(),Height(),0,-0.5)
merge = YToUV(u,v,last)

Normally when upsampling left-aligned YV12 chroma to get YV24, you'd use a src_left shift of 0.25, but that gets doubled and canceled out by the image doubling and its -0.5 center shift.

CkJ
28th December 2015, 13:16
Normally when upsampling left-aligned YV12 chroma to get YV24, you'd use a src_left shift of 0.25, but that gets doubled and canceled out by the image doubling and its -0.5 center shift.
Thanks, but I don't understand why src_left shift gets doubled.
Where do I can download the edi plugin? Nnedi3 and eedi3 don't support for y8.

Edit: I found the download link for edi_rpow2 here (http://forum.doom9.org/showthread.php?t=147695&page=27#post1738351).

MysteryX
28th December 2015, 18:23
Nnedi3 and eedi3 don't support for y8.
The latest release of NNEDI3 supports Y8.

ChiDragon
28th December 2015, 20:25
It seems to be the same idea as chroma bandwidth expansion (http://forum.doom9.org/showthread.php?t=167712), so could this be used with captured analog sources like VHS or LaserDisc?

So far I tried with a VHS sample but all I'm seeing are added artifacts. I also tried halving the horizontal resolution with LanczosResize(360,480) before the ConvertToYV24 and filter call.

Desbreko
28th December 2015, 23:37
Thanks, but I don't understand why src_left shift gets doubled.
Because when you double the size of the chroma without maintaining its image center (that is, without using cshift correction in the rpow2 function), it doubles the offset between the luma and chroma centers. Likewise, if you were to use rfactor=4, the offset would be quadrupled, giving you 0.25*4-0.5 = 0.5 for the src_left shift.

hydra3333
30th December 2015, 03:13
In case anybody wants to see what this is doing without having to scroll back and forth between two gray images, or worse actually move their eyes between the two, inviting differences in the monitor to cause issues. (http://screenshotcomparison.com/comparison/155771)

Thank you. Do you have instructions on how to do that ? It is a significantly helpful approach to visualising differences.

feisty2
30th December 2015, 08:28
@ChiDragon
try the latest version, I know nothing about analog stuff, so nothing for sure..

CkJ
30th December 2015, 10:42
That's weird, I tried version 2.0 but nothing happen, no different even on u/v plane. And the speed is super super ..... super slow :devil:

feisty2
30th December 2015, 11:35
That's weird, I tried version 2.0 but nothing happen, no different even on u/v plane. And the speed is super super ..... super slow :devil:

post ur script

AzraelNewtype
30th December 2015, 11:41
Thank you. Do you have instructions on how to do that ? It is a significantly helpful approach to visualising differences.

Do what exactly? Go to screenshotcomparison.com and upload files?

CkJ
30th December 2015, 11:59
post ur script

DGDecode_mpeg2source("")
crop(2,34,-2,-34)
http://i.imgbox.com/pFyfIZgE.png
DGDecode_mpeg2source("")
crop(2,34,-2,-34)
converttoyv24
utoy8
http://i.imgbox.com/n80UBBZC.png

function ChromaReconstructor(clip src, int "radius", float "str")
{
radius = default(radius, 32)
str = default(str, 6.4)
w = src.width
h = src.height / 2
src8 = src.Ditherpost(mode=-1)
up2x = src8.nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnRight().nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnLeft()
up4x = up2x.nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnRight().nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnLeft()
up16 = up4x.Dither_convert_8_to_16()
Luma = up16.ConvertToY8()
U = up16.UToY8()
V = up16.VtoY8()
Unew = U.KNLMeansCL(0, radius, 0, False, 1, str, Luma, lsb_inout=True).Dither_resize16(w, h, src_left=-1.25, src_top=-1.25, kernel="cubic", a1=-1.0, a2=0.0)
Vnew = V.KNLMeansCL(0, radius, 0, False, 1, str, Luma, lsb_inout=True).Dither_resize16(w, h, src_left=-1.25, src_top=-1.25, kernel="cubic", a1=-1.0, a2=0.0)
UHi = Dither_sub16(Unew, Dither_Removegrain16(Unew, 20).Dither_Removegrain16(20), dif=True)
VHi = Dither_sub16(Vnew, Dither_Removegrain16(Vnew, 20).Dither_Removegrain16(20), dif=True)
UFinal = Dither_add16(src.UToY8(), UHi, dif=True)
VFinal = Dither_add16(src.VToY8(), VHi, dif=True)
return YToUV(UFinal, VFinal, src.ConvertToY8())
}
DGDecode_mpeg2source("")
crop(2,34,-2,-34)
converttoyv24()
Dither_convert_8_to_16()
ChromaReconstructor()
ditherpost(mode=-1)
utoy8()
http://i.imgbox.com/rdrvWXTC.png

feisty2
30th December 2015, 13:02
ImageSource("orig.png")
function ChromaReconstructor(clip src, int "radius", float "str")
{
radius = default(radius, 32)
str = default(str, 6.4)
w = src.width
h = src.height / 2
src8 = src.Ditherpost(mode=-1)
up2x = src8.nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnRight().nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnLeft()
up4x = up2x.nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnRight().nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnLeft()
up16 = up4x.Dither_convert_8_to_16()
Luma = up16.ConvertToY8()
U = up16.UToY8()
V = up16.VtoY8()
Unew = U.KNLMeansCL(0, radius, 0, False, 1, str, Luma, lsb_inout=True).Dither_resize16(w, h, src_left=-1.25, src_top=-1.25, kernel="cubic", a1=-1.0, a2=0.0)
Vnew = V.KNLMeansCL(0, radius, 0, False, 1, str, Luma, lsb_inout=True).Dither_resize16(w, h, src_left=-1.25, src_top=-1.25, kernel="cubic", a1=-1.0, a2=0.0)
UHi = Dither_sub16(Unew, Dither_Removegrain16(Unew, 20).Dither_Removegrain16(20), dif=True)
VHi = Dither_sub16(Vnew, Dither_Removegrain16(Vnew, 20).Dither_Removegrain16(20), dif=True)
UFinal = Dither_add16(src.UToY8(), UHi, dif=True)
VFinal = Dither_add16(src.VToY8(), VHi, dif=True)
return YToUV(UFinal, VFinal, src.ConvertToY8())
}
converttoyv24()
Dither_convert_8_to_16()
ChromaReconstructor()
ditherpost(mode=-1)
utoy8()

http://i.imgur.com/cyqwwTB.png
works here, update your plugins

Georgel
30th December 2015, 16:13
I got into this thread because you posted in madVR thread, but this looks very nice!

Still, do you think that it would be possible to use Chroma reconstructor in real time? I mean, it seems like it needs a lot of processing, and madVR alone in good settings makes like 70% of GPU usage.

feisty2
30th December 2015, 16:17
I got into this thread because you posted in madVR thread, but this looks very nice!

Still, do you think that it would be possible to use Chroma reconstructor in real time? I mean, it seems like it needs a lot of processing, and madVR alone in good settings makes like 70% of GPU usage.

maybe... like reduce radius from 32 to 4, apply 2x supersampling instead of 4x, and lower some nnedi parameters like nns....
I don't know for sure, that's why I'm asking :D

huhn
31st December 2015, 04:16
is nnedi3 replaceable with super xBR?

feisty2
31st December 2015, 04:22
is nnedi3 replaceable with super xBR?

You could even replace nnedi3 with non-ring spline kind of regular and fast resizers, but I don't know how much it will affect the quality, think I'll do a test and report back

MysteryX
31st December 2015, 04:25
madVR has super-xbr chroma upscaling option

However, its current implementation only supports YV12, YV24, RGB24 and RGB32. It doesn't run on Y8 clips; although you could just run it anyway and discard the other planes.

huhn
31st December 2015, 05:00
You could even replace nnedi3 with non-ring spline kind of regular and fast resizers, but I don't know how much it will affect the quality, think I'll do a test and report back

super xBR is kind of free compared to nnedi3. so realtime doesn't sound unreal anymore.

but this doesn't change the fact that all needed plugins for this avisynth script needs to be ported to a shader language and that sounds like a lot of work.

feisty2
31st December 2015, 05:02
@huhn
a faster working version without nnedi3

function ChromaReconstructor_faster(clip src, int "radius", float "str")
{
radius = default(radius, 16)
str = default(str, 6.4)
w = src.width
h = src.height / 2
ref = src.ConvertToY8().KNLMeansCL(0, radius, 0, False, 1, pow(1.464968620512209618455732713658, str), lsb_inout=True)
srcU = src.UToY8()
srcV = src.VToY8()
src8 = YToUV(srcU, srcV, ref)
sup = src8.Dither_resize16nr(w*2, h*2, src_left=0, src_top=0, kernel="spline", taps=6)
Luma = sup.ConvertToY8()
U = sup.UToY8()
V = sup.VtoY8()
Unew = U.KNLMeansCL(0, radius, 0, False, 1, str, Luma, lsb_inout=True).Dither_resize16nr(w, h, src_left=0, src_top=0, kernel="spline", taps=6)
Vnew = V.KNLMeansCL(0, radius, 0, False, 1, str, Luma, lsb_inout=True).Dither_resize16nr(w, h, src_left=0, src_top=0, kernel="spline", taps=6)
UHi = Dither_sub16(Unew, Dither_Removegrain16(Unew, 20).Dither_Removegrain16(20), dif=True)
VHi = Dither_sub16(Vnew, Dither_Removegrain16(Vnew, 20).Dither_Removegrain16(20), dif=True)
UFinal = Dither_add16(srcU, UHi, dif=True)
VFinal = Dither_add16(srcV, VHi, dif=True)
return YToUV(UFinal, VFinal, src.ConvertToY8())
}


so the bottleneck of speed is not nnedi3, it's the large radius nlmeans that slows everything down, but reducing the radius will greatly blow the quality...:(

feisty2
31st December 2015, 05:20
some compares

source

##rule6##
converttoyv24()
utoy8()

http://i.imgur.com/csxO9IQ.png

chromareconstructor

##rule6##
converttoyv24()
Dither_convert_8_to_16()
ChromaReconstructor()
ditherpost(mode=-1)
utoy8()

http://i.imgur.com/pufHliV.png

chromareconstructor_faster

##rule6##
converttoyv24()
Dither_convert_8_to_16()
ChromaReconstructor_faster()
ditherpost(mode=-1)
utoy8()

http://i.imgur.com/fIztg02.png

bilateral

##rule6##
converttoyv24()
Dither_convert_8_to_16()
utoy8().Dither_bilateral16(converttoy8(),radius=32, thr=6.4, flat=0.00, wmin=0.0, subspl=0)
ditherpost(mode=-1)

http://i.imgur.com/wXKZbju.png

feisty2
31st December 2015, 15:11
update: vaporsynth version

Dreamland
31st December 2015, 23:12
nnedi3 is veeeeery slow in my Z97 and I5 4690k processor on SD video

feisty2
1st January 2016, 17:43
nnedi3 is veeeeery slow in my Z97 and I5 4690k processor on SD video

Always simple and easy and no sweat to discard stuff, but hard and complicated to get them back, that's just the price you have to pay to get back the long lost full sampled chroma from some incomplete copy

Dreamland
1st January 2016, 19:55
This is only my report not criticism ..I know is very hard to make good scripts for Avisinth/Vapoursinth

feisty2
2nd January 2016, 08:47
This is only my report not criticism ..I know is very hard to make good scripts for Avisinth/Vapoursinth

well, I didn't take that as criticism, just saying, it always takes a lot to restore what has been lost, sigh, I wish chroma subsampling dead immediately (as that old obsolete design from the analog era is a piece of plain junk in the digital world, lossy compression slays chroma subsampling).

MysteryX
2nd January 2016, 15:54
well, I didn't take that as criticism, just saying, it always takes a lot to restore what has been lost, sigh, I wish chroma subsampling dead immediately (as that old obsolete design from the analog era is a piece of plain junk in the digital world, lossy compression slays chroma subsampling).
YV12 chroma subsampling is designed to increase compressability.

Are you saying that this isn't true anymore?

I'm thinking of x264-10bit... it gives HIGHER quality because compressability is a greater factor than the available data.

feisty2
2nd January 2016, 16:03
YV12 chroma subsampling is designed to increase compressability.

Are you saying that this isn't true anymore?

I'm thinking of x264-10bit... it gives HIGHER quality because compressability is a greater factor than the available data.

chroma subsampling was designed to reduce the bandwidth of analog videos
the concept of "bandwidth" does not exist in the digital world, "bitrate" takes over, and lossy compression works hell better than simply shrinking the resolution (of chroma planes) to reduce the bitrate.

MysteryX
2nd January 2016, 16:41
How do you use x264 or x265 to encode in YV24 format? At that point... YUV itself doesn't make sense, can you encode straight in RGB?

Reel.Deel
2nd January 2016, 16:46
Encoding YUV 4:4:4 is still more efficient than RGB.

sneaker_ger
2nd January 2016, 16:54
x265: input format = output format
x264: --output-csp i444

BakaProxy
3rd January 2016, 03:10
>radius=32
Is this really how you wanna live your life?
Browsing doom9 and nmm-hd all day making worthless/witty comments, wasting other people their time by requesting worthless parameters.
Then one day you manage to make something remotely interesting only to disappoint everyone even further.
Like if I need to be really honest with you this is just overdoing it and even the results look mediocre.
Don't you think it is time to stop and go outside, think about what you're doing.
In the end this is all just a hobby and we can all be happy if anyone ever uses nnedi or alike for something professional.
If you want to make something, even if it is for yourself or it is to give something back to the community, make it worthwhile or at least useful.

I wish you and everyone who might stumble upon this post a happy new year.

feisty2
3rd January 2016, 03:26
>radius=32
Is this really how you wanna live your life?
Browsing doom9 and nmm-hd all day making worthless/witty comments, wasting other people their time by requesting worthless parameters.
Then one day you manage to make something remotely interesting only to disappoint everyone even further.
Like if I need to be really honest with you this is just overdoing it and even the results look mediocre.
Don't you think it is time to stop and go outside, think about what you're doing.
In the end this is all just a hobby and we can all be happy if anyone ever uses nnedi or alike for something professional.
If you want to make something, even if it is for yourself or it is to give something back to the community, make it worthwhile or at least useful.

I wish you and everyone who might stumble upon this post a happy new year.

about the "radius=32" thing, I'd say do a test by yourself, maybe a=32 is just simply useless for general denoising but in this particular case, it is required, reduce it to 16, the quality seems a bit lower but okay still, reduce it to 8, and everything starts to go to hell,
about other comments, no one's forcing you to use it anyway so, if you don't like it, then don't use it, simple like that, that's all I'm gonna say

feisty2
3rd January 2016, 03:46
and if you have a better way of doing it (improve the quality of 42x to 444 conversion)
I'm all ears..

wonkey_monkey
3rd January 2016, 12:21
Is this really how you wanna live your life?

Who threw you a peanut? What business is it of yours if it is?

Browsing doom9 and nmm-hd all day making worthless/witty comments

I suggest you re-read your own comment in light of this statement.

For what it's worth, I've been following this thread with mild interest. While I think the filter has limited use, and I don't see myself ever using it, I can appreciate what it does from a technical point of view.

Don't you think it is time to stop and go outside, think about what you're doing.

Again, read your own post. You're being insulting and condescending for no reason other than to be insulting and condescending. If this thread insults your lofty intelligence so much, just don't read it.

I fully expect both my post and yours to be deleted, since they are the only ones in this thread which contribute nothing of any interest to the world of video processing.

BakaProxy
3rd January 2016, 15:20
Then explain to me: why is radius 32 preferred in this particular case?
And why does everything go south by lowering the radius?
I won't take "because it looks good" for an answer.
What purpose does nlmeans have in this particular case if it isn't denoising?
Maybe there are more efficient kernels for this script, who knows?

feisty2
3rd January 2016, 15:33
That's complicated, the main reason for "radius = 32" is supersampling, the same amount of actual signal got diluted to a larger resolution so larger search radius is required, think "radius = 32" on a 4x supersampled clip as "radius = 8" at the original size, the kernel is actually not nlmeans, with similarity window of nlmeans set to 0, the kernel is actually a bilateral-like filter (without the distance weighting), it's used to convey high frequencies from luma to chroma planes

feisty2
3rd January 2016, 15:44
It looks mediocre to you anyway so, why even bother to ask how it works...

BakaProxy
3rd January 2016, 16:30
I didn't say that it doesn't have potential, I'm just pointing out that your current implementation is nowhere near practical.
If you can figure out some way to make this worthwhile and still render at acceptable speed then you maybe have made something interesting.
Like can't you do the super sampling outside of nlmeans with spline,bilinear,.... or possibly create a small c plugin to replace the nlmeans "hack" you're currently using (because this is definitely not how knlmeanscl is supposed to be used) to speed things up and possibly get better results, just in overall more efficient.

And why do I bother? Because I care for you, Feisty2, my sweet prince. ;)

MysteryX
3rd January 2016, 17:55
feisty2, you have an interesting concept that brought up a great discussion. I had never thought of doing YV24 encoding before, and it's a good idea in my case, with or without this.

Now... the current implementation's performance is absolutely not usable, but the concept is good. We'll have to find a way to reproduce those results "by design" instead of "by luck". There has to be a way to implement a C plugin that would do this nicely. It for sure will bring up some ideas for either yourself or others to work on.

MysteryX
4th January 2016, 19:58
x265: input format = output format
x264: --output-csp i444
I'm trying to do it with FFMPEG.

"--output-csp i444" gives "Unrecognized option 'output-csp'"

"-profile:v high444 -pix_fmt yuv444p" works libx264 but it still says "converting clip to YV12" and "Warning: data is not aligned! This can lead to a speedloss"

"-profile:v high444 -pix_fmt yuv444p" with libx265, however, says Undefined constant or missing '(' in 'high444'

How do you do 444 encoding with FFMPEG?

MysteryX
5th January 2016, 17:12
ah... I was piping through avs2yuv and was missing -csp I444. Now it works. Comparing results.

MysteryX
5th January 2016, 19:00
About encoding to 4:4:4... x265 works good enough to replace x264 according to my tests. However, 4:2:2 and 4:4:4 encoding aren't yet ready. It says you must add "-strict experimental" to use it anyway, and the encoding crashed on me.

As for what would provide the best result to upscale Chroma, it might be better to implement a solution that starts from the original YV12 data and work from it to upscale it, instead of taking already-converted YV24 data and trying to process it.

feisty2
7th January 2016, 16:16
v2.2: new parameter "mode", mode=0 for 4:2:0 and mode=1 (vertical filtering disabled) for 4:2:2

wonkey_monkey
7th January 2016, 17:20
As for what would provide the best result to upscale Chroma, it might be better to implement a solution that starts from the original YV12 data and work from it to upscale it, instead of taking already-converted YV24 data and trying to process it.

It does start from the original YV12 data. I don't think there's anything "invalid" about the first step being to convert to YV24, even if it is "lossy" in a way that, say, 8-bit to 16-bit isn't. The chroma needs to be resited anyway - it's not like any of the "original" chroma pixels can survive in-place.

Overdrive80
9th January 2016, 00:38
On special pattern, the chroma restaured picture has halo on colon, is it normal for limitations on conversion, isn't??

Thanks for you work.

jinkazuya
9th January 2016, 07:33
Just wonder how to use the script? Whenever I tried using it, error message always popped up stating "There is no function named KNLMeansCL.dll" Then I located this within the website and found it but when I tried to reload it again, another error message popped up saying "The module was not found, library missing?" Here is the unfinished basic avisynth script


LoadPlugin("C:\Users\Jinkazuya\Desktop\MeGui\tools\dgindex\DGDecode.dll")
DGDecode_mpeg2source("C:\Users\Jinkazuya\Desktop\Encoded Videos\01\VIDEO_TS\VTS_01_1.d2v", cpu=4, info=3)
LoadPlugin("C:\Users\Jinkazuya\Desktop\MeGui\tools\avisynth_plugin\ColorMatrix.dll")
LoadPlugin("C:\Program Files (x86)\AviSynth 2.5\plugins\RgTools.dll")
Import("C:\Program Files (x86)\AviSynth 2.5\plugins\ChromaReconstructor.avs")

ColorMatrix(hints=true, threads=0)
#deinterlace
crop( 4, 0, -10, 0)

LanczosResize(640,480) # Lanczos (Sharp)
#denoise

converttoyv12()
converttoyv24()
Dither_convert_8_to_16()
ChromaReconstructor(16)

Groucho2004
9th January 2016, 10:22
Just wonder how to use the script? Whenever I tried using it, error message always popped up stating "There is no function named KNLMeansCL.dll" Then I located this within the website and found it but when I tried to reload it again, another error message popped up saying "The module was not found, library missing?"
You're most likely missing the "Visual C++ Redistributable Package for Visual Studio 2013". See the first post in the KNLMeansCL thread (http://forum.doom9.org/showthread.php?t=171379).

jinkazuya
9th January 2016, 16:37
You're most likely missing the "Visual C++ Redistributable Package for Visual Studio 2013". See the first post in the KNLMeansCL thread (http://forum.doom9.org/showthread.php?t=171379).

Yes. I do have this package installed in my computer.

feisty2
14th January 2016, 10:18
v3.0 major update, new parameter "hipass" allows you to manipulate the strength of the high frequency extraction, a new less aggressive (and a lot slower) method could be enabled when luma is not stable enough (set "wild" to False)

ispano
16th January 2016, 23:48
Wanted to say a quick thx feisty for your work on this. I'm super happy with the results in madvr and the fact I won't need to re-encode in 444. :)

De-M-oN
17th January 2016, 23:42
Spline16 is an over sharpening (unbalanced) kernel

Are you sure you're not confuse it with Spline64?

Because 16 is rather a soft scaler.

http://svn.int64.org/viewvc/int64/resamplehq/doc/kernels.html
__

Could this help with my problem?
http://forum.doom9.org/showthread.php?t=172647

I mean: If it can fill up the gaps caused by the nearest neighbor chroma scaling again with color ( I dont mind bloating it up back to RGB, I just dont want the colorless pixels) so I thought your plugin could maybe apply the interpolation by upsampling it in???

wonkey_monkey
18th January 2016, 00:37
How fast is ChromaReconstructor, approximately?

I'm without a proper computer right now, so a) I can't try it for myself and b) I've been thinking about all different kinds of filters while I can't do any work on anything. If it's fast, then no need for me to continue thinking what I'm thinking.

Are_
18th January 2016, 01:01
I didn't really test this version, but somewhat in the order of seconds per frame.

Reel.Deel
18th January 2016, 01:12
How fast is ChromaReconstructor, approximately?

Too slow to be practical, with default settings on full HD I get 0.024 fps and 0.096 fps on 960x540.

SSH4
21st January 2016, 04:39
Is this script must work in Avisynth+ r1576?

ChromaReconstructor_faster work, at least result different from source. Eedi version (without LSB) from this thread work too.

But script from first post do nothing.

All scripts tested on source PNG from first post.

caiyuwei
23rd January 2016, 20:16
Can anyone please help me to re-up support 8bits version?

bxyhxyh
23rd January 2016, 21:41
Can anyone please help me to re-up support 8bits version?

Calling Dither_convert_8_to_16() before you call ChromaReconstructor() and call Ditherpost(mode=6) after that will do the trick

caiyuwei
24th January 2016, 02:07
Calling Dither_convert_8_to_16() before you call ChromaReconstructor() and call Ditherpost(mode=6) after that will do the trick

Thank you so much for your experience.
By the way, I got error "There is no function named KNLMeansCL"

I'm using Avisynth+ r1825 and KNLMeansCL v0.6 :(

bxyhxyh
24th January 2016, 11:23
If your KNLMeansCL correctly loaded. (Loaded in script or placed in plugins directory)

It is maybe similar issue to this (https://www.doom9.org/showthread.php?p=1737277#post1737277)

StainlessS
24th January 2016, 12:14
Here same link as above post, but without any security warning ('untrusted domain' or something like that).
http://forum.doom9.org/showthread.php?p=1737277#post1737277

EDIT: If you just remove 's' from 'https:\\' you get a 404, Not Found.

caiyuwei
25th January 2016, 08:05
If your KNLMeansCL correctly loaded. (Loaded in script or placed in plugins directory)

It is maybe similar issue to this (https://www.doom9.org/showthread.php?p=1737277#post1737277)

Here same link as above post, but without any security warning ('untrusted domain' or something like that).
http://forum.doom9.org/showthread.php?p=1737277#post1737277

EDIT: If you just remove 's' from 'https:\\' you get a 404, Not Found.

Thank you so much. I installed already but it seems didn't work :(

StainlessS
25th January 2016, 19:46
I'm using Avisynth+ r1825 and KNLMeansCL v0.6

There are a certain number of requirements in 1st post of KNLMeansCL (for current version), you might want to
post what you have installed that does fill requirements for your v0.6 (and also post documented requisites for that version).
Also, might post why you are using old version (is current no longer supported by your setup ?).

caiyuwei
26th January 2016, 03:03
There are a certain number of requirements in 1st post of KNLMeansCL (for current version), you might want to
post what you have installed that does fill requirements for your v0.6 (and also post documented requisites for that version).
Also, might post why you are using old version (is current no longer supported by your setup ?).

I updated the newest version, however, it didn't work so I changed to older version as Requirements

http://forum.doom9.org/showthread.php?t=171379

StainlessS
26th January 2016, 06:22
Well if neither version worked, you are more likely to get assistance for current version. (I've never used either myself).

By the way, I got error "There is no function named KNLMeansCL"

You might like to say how you are loading plugin, autoload in plugins dir ?

Also get Dependency Walker, and run it on the KNLMeansCL dll. http://www.dependencywalker.com/
And try Groucho2004 AVSInfo tool. http://forum.doom9.org/showthread.php?t=170647

poisondeathray
31st January 2016, 05:47
Thanks for this feisty2

I cannot reproduce your results in the 1st post with the "special pattern" image - was that from an earlier version or maybe using different settings? I'm getting more halos now with v3.0. I could have sworn it looked better with an earlier version, or maybe something got buggered up with my plugins

SSH4
1st February 2016, 09:57
Thanks for this feisty2

I cannot reproduce your results in the 1st post with the "special pattern" image - was that from an earlier version or maybe using different settings? I'm getting more halos now with v3.0. I could have sworn it looked better with an earlier version, or maybe something got buggered up with my plugins

Also can't reproduce 1st post.
Using Avisinth+ all plugins separately work well. But not in this script.

Looks like problem in this "dark magic" with loooooooong numbers and ternary operators.

feisty2
1st February 2016, 10:29
Thanks for this feisty2

I cannot reproduce your results in the 1st post with the "special pattern" image - was that from an earlier version or maybe using different settings? I'm getting more halos now with v3.0. I could have sworn it looked better with an earlier version, or maybe something got buggered up with my plugins

all default settings

ImageSource("Icqh01Q.png")
converttoyv12()
converttoyv24()
Dither_convert_8_to_16()
ChromaReconstructor()
ditherpost(mode=-1)

http://i.imgur.com/ASph430.png

ImageSource("Icqh01Q.png")
converttoyv12()
converttoyv24()
Dither_convert_8_to_16()
ChromaReconstructor()
ditherpost(mode=-1)
utoy8()

http://i.imgur.com/9kL7Tsp.png

ImageSource("Icqh01Q.png")
converttoyv12()
converttoyv24()
Dither_convert_8_to_16()
ChromaReconstructor()
ditherpost(mode=-1)
vtoy8()

http://i.imgur.com/1phIBXz.png

feisty2
1st February 2016, 10:54
Is this script must work in Avisynth+ r1576?

ChromaReconstructor_faster work, at least result different from source. Eedi version (without LSB) from this thread work too.

But script from first post do nothing.

All scripts tested on source PNG from first post.

dunno about that, knlmeanscl is sometimes a little bit unstable, I actually encountered real crazy weird crap like,
you see, I didn't name parameters like "radius" and "str" from the beginning, I used to name them "a" and "h" just like in knlmeanscl, so it was like this


function ChromaReconstructor(clip src, int "a", float "h", int "hipass", int "mode", bool "wild")
{
a = default(a, 32)
h = default(h, 6.4)
hipass = default(hipass, 6)
mode = default(mode, 0)
wild = default(wild, True)
w = src.width
h = src.height / 2
ref = wild ? src.ConvertToY8() : src.ConvertToY8().KNLMeansCL(0, radius, 0, False, 1, pow(1.464968620512209618455732713658, str), lsb_inout=True)
srcU = src.UToY8()
srcV = src.VToY8()
src8 = YToUV(srcU, srcV, ref).Ditherpost(mode=-1)
up2x = src8.nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnRight().nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnLeft()
up4x = up2x.nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnRight().nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnLeft()
up16 = up4x.Dither_convert_8_to_16()
Luma = up16.ConvertToY8()
U = up16.UToY8()
V = up16.VtoY8()
Unew = wild ? KNLMeansCL(U, 0, a, 0, False, 1, h, Luma, lsb_inout=True) : interpolation(Luma, U, 2, h)
Unew = wild ? Unew : interpolation(Luma, Unew, 4, h)
Unew = wild ? Unew : interpolation(Luma, Unew, 8, h)
Unew = wild ? Unew : interpolation(Luma, Unew, 16, h)
Unew = wild ? Unew : interpolation(Luma, Unew, 32, h)
Unew = Unew.Dither_resize16nr(w, h, src_left=-1.25, src_top=-1.25, kernel="spline", taps=6)
Vnew = wild ? KNLMeansCL(V, 0, a, 0, False, 1, h, Luma, lsb_inout=True) : interpolation(Luma, V, 2, h)
Vnew = wild ? Vnew : interpolation(Luma, Vnew, 4, h)
Vnew = wild ? Vnew : interpolation(Luma, Vnew, 8, h)
Vnew = wild ? Vnew : interpolation(Luma, Vnew, 16, h)
Vnew = wild ? Vnew : interpolation(Luma, Vnew, 32, h)
Vnew = Vnew.Dither_resize16nr(w, h, src_left=-1.25, src_top=-1.25, kernel="spline", taps=6)
UHi = (mode == 1) ? Dither_sub16(Unew, gauss_h(Unew, hipass), dif=True) : Dither_sub16(Unew, gauss(Unew, hipass), dif=True)
VHi = (mode == 1) ? Dither_sub16(Vnew, gauss_h(Vnew, hipass), dif=True) : Dither_sub16(Vnew, gauss(Vnew, hipass), dif=True)
UFinal = Dither_add16(srcU, UHi, dif=True)
VFinal = Dither_add16(srcV, VHi, dif=True)
return YToUV(UFinal, VFinal, src.ConvertToY8())
}


everything is the same except the name of 2 parameters changed, and it gave me like no nothing, and I traced back the problem to

Unew = wild ? KNLMeansCL(U, 0, a, 0, False, 1, h, Luma, lsb_inout=True) : interpolation(Luma, U, 2, h)


and here's the magic part :confused:
I replaced "a" and "h" with default values, so


Unew = wild ? KNLMeansCL(U, 0, 32, 0, False, 1, 6.4, Luma, lsb_inout=True) : interpolation(Luma, U, 2, h)

worked without any problem!!

so wtf?! I ended up using different names for "a" and "h"...

guess you are facing the similar problem

feisty2
1st February 2016, 11:10
function test1(clip src, int "a", float "h")
{
a = default(a, 32)
h = default(h, 6.4)
w = src.width
h = src.height / 2
ref = src.ConvertToY8()
srcU = src.UToY8()
srcV = src.VToY8()
src8 = YToUV(srcU, srcV, ref).Ditherpost(mode=-1)
up2x = src8.nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnRight().nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnLeft()
up4x = up2x.nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnRight().nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnLeft()
up16 = up4x.Dither_convert_8_to_16()
Luma = up16.ConvertToY8()
U = up16.UToY8()
V = up16.VtoY8()
Unew = KNLMeansCL(U, 0, a, 0, False, 1, h, Luma, lsb_inout=True)
return Unew.ditherpost(mode=-1)
}

function test2(clip src, int "radius", float "str")
{
radius = default(radius, 32)
str = default(str, 6.4)
w = src.width
h = src.height / 2
ref = src.ConvertToY8()
srcU = src.UToY8()
srcV = src.VToY8()
src8 = YToUV(srcU, srcV, ref).Ditherpost(mode=-1)
up2x = src8.nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnRight().nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnLeft()
up4x = up2x.nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnRight().nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnLeft()
up16 = up4x.Dither_convert_8_to_16()
Luma = up16.ConvertToY8()
U = up16.UToY8()
V = up16.VtoY8()
Unew = KNLMeansCL(U, 0, radius, 0, False, 1, str, Luma, lsb_inout=True)
return Unew.ditherpost(mode=-1)
}

ImageSource("ASph430.png")
converttoyv12()
converttoyv24()
Dither_convert_8_to_16()
stackvertical(test1(),test2())


http://i.imgur.com/b30Ijqn.png

!??

feisty2
1st February 2016, 13:07
h = default(h, 6.4)
...
h = src.height / 2


ah!! stupid me, always doing mindless things like this, thx for ur help HolyWu

then, @SSH4
I seriously don't know what went wrong when you were trying it.. :(

poisondeathray
1st February 2016, 16:21
Still can't reproduce it... :(

All plugins working separately. Even tried vanilla avisynth 2.6 x86 , switching knlmeanscl versions (0.6.11 vs. 0.7.4), dither 1.27.2

Can I ask what version of NNEDI3 you are using ? There are several versions floating around

poisondeathray
1st February 2016, 16:36
I think it was the NNEDI3 version. I was using an older version. With 0.9.4.20 - It looks a lot closer now :o

poisondeathray
1st February 2016, 19:36
(sorry third post in a row!)

Is the vpy version any faster, and I cannot find the vpy version in your github link ?

SSH4
2nd February 2016, 04:09
then, @SSH4
I seriously don't know what went wrong when you were trying it.. :(

Found main problem in old (NNEDI 0.9.4)
So changed to 0.9.4.20 from "Port of NNEDI under new v2.6 AVS API" http://forum.doom9.org/showthread.php?t=170083

But anyway, result is different from your test/tes1 results.

http://105.imagebam.com/download/_h5bBZbx4nYKFrmaUKWwLw/46286/462856161/Icqh01Q000000%282%29.png

This what i have on

orig=last.converttoyv24()
converttoyv12()
converttoyv24()

Dither_convert_8_to_16()
ChromaReconstructor()
ditherpost(mode=-1)
StackVertical(orig,last)

http://113.imagebam.com/download/FG-V7tezgF99knSWEytQSA/46286/462852511/Icqh01Q000000.png

feisty2
2nd February 2016, 08:32
(sorry third post in a row!)

Is the vpy version any faster, and I cannot find the vpy version in your github link ?

removed it cuz it was kinda unstable, will add it back when it's ready
it's no way faster, actually slower maybe...
but it features some extra quality (full 32bits floating point precision vs 8/16 bits hybrid precision) over the avisynth version

feisty2
4th February 2016, 09:36
@poisondeathray
@SSH4
try the vaporsynth version if you guys couldn't get the avisynth version to work
vaporsynth implement requires input to be 4:4:4 at 32bits precision (floating point)

poisondeathray
4th February 2016, 21:28
@poisondeathray
@SSH4
try the vaporsynth version if you guys couldn't get the avisynth version to work
vaporsynth implement requires input to be 4:4:4 at 32bits precision (floating point)

I got the avisynth version to work properly, I reported it a few posts back the the problem (at least for me) was the NNEDI3 version. My problem initially looked similar to SSH4's screenshots in post 102, but he said he already switched out the NNED3I version

I'll give the vapoursynth version a go later this week, thanks again for your efforts

SSH4
12th February 2016, 09:56
Well, well, well... Who's that boy?

I got it!

U = up16.UToY8()
but why ?
Unew = wild ? KNLMeansCL(U, 0, radius, 0, False, 1, str, Luma, lsb_inout=True) : interpolationZ(Luma, U, 2, str)
the same with V

D**n, this take me some days for understand :D

@feisty2 if U and V is 8bit why you want 16bit input?

Set lsb_inout=False is making all work as in your original and latest example.

1)Source
2)Source->YV12->YV24
3)Reconstructed

http://113.imagebam.com/download/kpdJWUtE3sua-JaHGfzFmQ/46470/464696064/Icqh01Q000000.png


Oh. May be your Ditherpost(mode=-1) inside script and some converttoX8 broke your 16bit idea.

Or. May be you "fine-tune" your own dither.avsi ?

musicvideos4k
15th August 2016, 21:00
I installed everything properly, the KNLMeansCL installed and DLL's too. I use W10 x64, though im using Avisynth 2.60MT and with 32bit plugins.

I load the script ( even copied the first post examples ) and all i get is "invalid arguments for KNLMeansCL" Line blah blah blah"

It doesn't matter if the script is empty with just the video clip source and the ChromaReconstructor basic script, it always says invalid arguments for KNLMeansCL.

I have the avsi installed, dll's working, opencl.dll in system32 and SysWOW64...

The thing just doesn't wanna work.

My Specs are i7 4770k, z97, 2x8gb ddr3 2400, W10.

raffriff42
15th August 2016, 23:30
There has been a change in KNLMeansCL's function signature since ChromaReconstructor_faster was posted (http://forum.doom9.org/showthread.php?p=1751574#post1751574).
I get an "invalid arguments" error with the latest KNLMeansCL (0.7.6), but not with an older version (0.6.2)
Here's ChromaReconstructor_faster, modified to work with the new KNLMeansCL signature:function ChromaReconstructor_faster(clip src, int "radius", float "str")
{
radius = default(radius, 16)
str = default(str, 6.4)
w = src.width
h = src.height / 2
#ref = src.ConvertToY8().KNLMeansCL(0, radius, 0, False, 1, pow(1.464968620512209618455732713658, str), lsb_inout=True)
ref = src.ConvertToY8().KNLMeansCL(0, radius, 0, pow(1.464968620512209618455732713658, str), False, 1, lsb_inout=True)
srcU = src.UToY8()
srcV = src.VToY8()
src8 = YToUV(srcU, srcV, ref)
sup = src8.Dither_resize16nr(w*2, h*2, src_left=0, src_top=0, kernel="spline", taps=6)
Luma = sup.ConvertToY8()
U = sup.UToY8()
V = sup.VtoY8()
#Unew = U.KNLMeansCL(0, radius, 0, False, 1, str, Luma, lsb_inout=True).Dither_resize16nr(w, h, src_left=0, src_top=0, kernel="spline", taps=6)
#Vnew = V.KNLMeansCL(0, radius, 0, False, 1, str, Luma, lsb_inout=True).Dither_resize16nr(w, h, src_left=0, src_top=0, kernel="spline", taps=6)
Unew = U.KNLMeansCL(0, radius, 0, str, False, 1, rclip=Luma, lsb_inout=True).Dither_resize16nr(w, h, src_left=0, src_top=0, kernel="spline", taps=6)
Vnew = V.KNLMeansCL(0, radius, 0, str, False, 1, rclip=Luma, lsb_inout=True).Dither_resize16nr(w, h, src_left=0, src_top=0, kernel="spline", taps=6)
UHi = Dither_sub16(Unew, Dither_Removegrain16(Unew, 20).Dither_Removegrain16(20), dif=True)
VHi = Dither_sub16(Vnew, Dither_Removegrain16(Vnew, 20).Dither_Removegrain16(20), dif=True)
UFinal = Dither_add16(srcU, UHi, dif=True)
VFinal = Dither_add16(srcV, VHi, dif=True)
return YToUV(UFinal, VFinal, src.ConvertToY8())
}

musicvideos4k
16th August 2016, 00:07
There has been a change in KNLMeansCL's function signature since ChromaReconstructor_faster was posted (http://forum.doom9.org/showthread.php?p=1751574#post1751574).
I get an "invalid arguments" error with the latest KNLMeansCL (0.7.6), but not with an older version (0.6.2)
Here's ChromaReconstructor_faster, modified to work with the new KNLMeansCL signature:function ChromaReconstructor_faster(clip src, int "radius", float "str")
{
radius = default(radius, 16)
str = default(str, 6.4)
w = src.width
h = src.height / 2
#ref = src.ConvertToY8().KNLMeansCL(0, radius, 0, False, 1, pow(1.464968620512209618455732713658, str), lsb_inout=True)
ref = src.ConvertToY8().KNLMeansCL(0, radius, 0, pow(1.464968620512209618455732713658, str), False, 1, lsb_inout=True)
srcU = src.UToY8()
srcV = src.VToY8()
src8 = YToUV(srcU, srcV, ref)
sup = src8.Dither_resize16nr(w*2, h*2, src_left=0, src_top=0, kernel="spline", taps=6)
Luma = sup.ConvertToY8()
U = sup.UToY8()
V = sup.VtoY8()
#Unew = U.KNLMeansCL(0, radius, 0, False, 1, str, Luma, lsb_inout=True).Dither_resize16nr(w, h, src_left=0, src_top=0, kernel="spline", taps=6)
#Vnew = V.KNLMeansCL(0, radius, 0, False, 1, str, Luma, lsb_inout=True).Dither_resize16nr(w, h, src_left=0, src_top=0, kernel="spline", taps=6)
Unew = U.KNLMeansCL(0, radius, 0, str, False, 1, rclip=Luma, lsb_inout=True).Dither_resize16nr(w, h, src_left=0, src_top=0, kernel="spline", taps=6)
Vnew = V.KNLMeansCL(0, radius, 0, str, False, 1, rclip=Luma, lsb_inout=True).Dither_resize16nr(w, h, src_left=0, src_top=0, kernel="spline", taps=6)
UHi = Dither_sub16(Unew, Dither_Removegrain16(Unew, 20).Dither_Removegrain16(20), dif=True)
VHi = Dither_sub16(Vnew, Dither_Removegrain16(Vnew, 20).Dither_Removegrain16(20), dif=True)
UFinal = Dither_add16(srcU, UHi, dif=True)
VFinal = Dither_add16(srcV, VHi, dif=True)
return YToUV(UFinal, VFinal, src.ConvertToY8())
}

I have tried it and i get constant CL_MEM_OBJECT errors, allocation and run out of memory ( error is linked to KNLMeansCL , again )

Looks like the new release needs fix, do you know where to get the old version that works?

raffriff42
16th August 2016, 00:22
all versions are here:
https://github.com/Khanattila/KNLMeansCL/releases

musicvideos4k
16th August 2016, 00:59
all versions are here:
https://github.com/Khanattila/KNLMeansCL/releases

I will try. It looks like having a lot of Avsi could make Avisynth memory maxed out, even if i do not call a specific avsi ? Maybe that's whats going on with my machine.

flacattack
5th December 2016, 03:49
I have cartoon material that I am trying to use with this set to wild=false. It works just fine when using wild=true, but when i set it to false:
mt_lutxy : unsupported colorspace.masktools only support planar YUN colorspaces (YV12, YV16, YV24)
(dither.avsi, line 1178)
(dither.avsi, line 1153)
(chromareconstructor.avsi, line 43)
(chromareconstructor.avsi, line 20)

Anyone else get this error before?

tuanden0
28th March 2017, 10:02
I get an "invalid arguments" error with the latest KNLMeansCL 1.0.2
Can someone help me?

rsd2015
8th September 2017, 06:22
I know this is an old thread, but can some kind and wise person correct the KNLMeansCL syntax in line 8 of the ChromaReconstructor_faster script so that the script works with the latest version of KNLMeansCL, 1.10?

OvejaNegra
11th November 2017, 06:04
id did some changes and it's working for me with last version:

function ChromaReconstructor(clip src, int "radius", float "str", int "hipass", int "mode", bool "wild")
{
radius = default(radius, 32)
str = default(str, 6.4)
hipass = default(hipass, 6)
mode = default(mode, 0)
wild = default(wild, True)
w = src.width
h = src.height / 2
ref = wild ? src.ConvertToY8() : src.ConvertToY8().KNLMeansCL(0, radius, 0, channels="Y", wmode=1, pow(1.464968620512209618455732713658, str), stacked=True,device_type="gpu",device_id=1,info=false)
srcU = src.UToY8()
srcV = src.VToY8()
src8 = YToUV(srcU, srcV, ref).Ditherpost(mode=-1)
up2x = src8.nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnRight().nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnLeft()
up4x = up2x.nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnRight().nnedi3(field=1, dh=True, nns=4, qual=2, etype=1, nsize=0).TurnLeft()
up16 = up4x.Dither_convert_8_to_16()
Luma = up16.ConvertToY8()
U = up16.UToY8()
V = up16.VtoY8()
Unew = wild ? KNLMeansCL(U, 0, radius, 0, channels="Y", wmode=1, str, rclip=luma, stacked=True,device_type="gpu",device_id=1,info=false) : interpolation(Luma, U, 2, str)
Unew = wild ? Unew : interpolation(Luma, Unew, 4, str)
Unew = wild ? Unew : interpolation(Luma, Unew, 8, str)
Unew = wild ? Unew : interpolation(Luma, Unew, 16, str)
Unew = wild ? Unew : interpolation(Luma, Unew, 32, str)
Unew = Unew.Dither_resize16nr(w, h, src_left=-1.5, src_top=-1.5, kernel="spline", taps=6)
Vnew = wild ? KNLMeansCL(V, 0, radius, 0, channels="Y", wmode=1, str, rclip=luma, stacked=True,device_type="gpu",device_id=1,info=false) : interpolation(Luma, V, 2, str)
Vnew = wild ? Vnew : interpolation(Luma, Vnew, 4, str)
Vnew = wild ? Vnew : interpolation(Luma, Vnew, 8, str)
Vnew = wild ? Vnew : interpolation(Luma, Vnew, 16, str)
Vnew = wild ? Vnew : interpolation(Luma, Vnew, 32, str)
Vnew = Vnew.Dither_resize16nr(w, h, src_left=-1.5, src_top=-1.5, kernel="spline", taps=6)
UHi = (mode == 1) ? Dither_sub16(Unew, gauss_h(Unew, hipass), dif=True) : Dither_sub16(Unew, gauss(Unew, hipass), dif=True)
VHi = (mode == 1) ? Dither_sub16(Vnew, gauss_h(Vnew, hipass), dif=True) : Dither_sub16(Vnew, gauss(Vnew, hipass), dif=True)
UFinal = Dither_add16(srcU, UHi, dif=True)
VFinal = Dither_add16(srcV, VHi, dif=True)
return YToUV(UFinal, VFinal, src.ConvertToY8())
}


function ChromaReconstructor_faster(clip src, int "radius", float "str")
{
radius = default(radius, 16)
str = default(str, 6.4)
w = src.width
h = src.height / 2
#ref = src.ConvertToY8().KNLMeansCL(0, radius, 0, channels="Y", 1, pow(1.464968620512209618455732713658, str), stacked=True,device_type="gpu",device_id=1,info=false)
ref = src.ConvertToY8().KNLMeansCL(0, radius, 0, pow(1.464968620512209618455732713658, str), channels="Y", wmode=1, stacked=True,device_type="gpu",device_id=1,info=false)
srcU = src.UToY8()
srcV = src.VToY8()
src8 = YToUV(srcU, srcV, ref)
sup = src8.Dither_resize16nr(w*2, h*2, src_left=0, src_top=0, kernel="spline", taps=6)
Luma = sup.ConvertToY8()
U = sup.UToY8()
V = sup.VtoY8()
#Unew = U.KNLMeansCL(0, radius, 0, channels="Y", wmode=1, str, Luma, stacked=True,device_type="gpu",device_id=1,info=false).Dither_resize16nr(w, h, src_left=0, src_top=0, kernel="spline", taps=6)
#Vnew = V.KNLMeansCL(0, radius, 0, channels="Y", wmode=1, str, Luma, stacked=True,device_type="gpu",device_id=1,info=false).Dither_resize16nr(w, h, src_left=0, src_top=0, kernel="spline", taps=6)
Unew = U.KNLMeansCL(0, radius, 0, str, channels="Y", wmode=1, rclip=Luma, stacked=True,device_type="gpu",device_id=1,info=false).Dither_resize16nr(w, h, src_left=0, src_top=0, kernel="spline", taps=6)
Vnew = V.KNLMeansCL(0, radius, 0, str, channels="Y", wmode=1, rclip=Luma, stacked=True,device_type="gpu",device_id=1,info=false).Dither_resize16nr(w, h, src_left=0, src_top=0, kernel="spline", taps=6)
UHi = Dither_sub16(Unew, Dither_Removegrain16(Unew, 20).Dither_Removegrain16(20), dif=True)
VHi = Dither_sub16(Vnew, Dither_Removegrain16(Vnew, 20).Dither_Removegrain16(20), dif=True)
UFinal = Dither_add16(srcU, UHi, dif=True)
VFinal = Dither_add16(srcV, VHi, dif=True)
return YToUV(UFinal, VFinal, src.ConvertToY8())
}


function interpolation(clip luma, clip "chroma", int "radius", float "str")
{
exp_c0 = 1.060417282747435920994529352433
exp_c1 = pow(1.070339301855046091743224243341, 32)
weight = pow(exp_c0, radius) / exp_c1
ref0 = Dither_lut16(chroma, "x "+string(weight)+" *")
ref1 = Dither_lut16(luma, "x 1.0 "+string(weight)+" - *")
ref = Dither_add16(ref0, ref1, dif=False)
return KNLMeansCL(chroma, 0, radius, 0, channels="Y", wmode=1, str, rclip=ref, stacked=True,device_type="gpu",device_id=1,info=false)
}

function gauss(clip src, int "p")
{
p = default(p, 30)
w = src.width
h = src.height / 2
upsmp = Dither_resize16(src, w * 2, h * 2, kernel="gauss", a1=100)
return Dither_resize16(upsmp, w, h, kernel="gauss", a1=p)
}

function gauss_h(clip src, int "p")
{
p = default(p, 30)
w = src.width
h = src.height / 2
upsmp = Dither_resize16(src, w * 2, h, kernel="gauss", a1=100)
return Dither_resize16(upsmp, w, h, kernel="gauss", a1=p)
}


change device_type="gpu",device_id=1 and enable disable info to see if your main GPU is doing the work ( and not the Intel OpenCL, that will be slow)

real.finder
5th April 2020, 21:56
here VS port to avs with more things https://forum.doom9.org/showpost.php?p=1906550&postcount=120

work with 8-16 bits and float

Sparktank
6th April 2020, 00:16
here VS port to avs with more things https://pastebin.com/40QXjAE4

work with 8-16 bits and float

Thanks! Will check it out!

FranceBB
6th April 2020, 02:50
here VS port to avs with more things https://pastebin.com/40QXjAE4

work with 8-16 bits and float

When you declared sisphbd you actually used the AvsPlusVersionNumber > 2294, however in AviSynth+ 3.5 (r3106, 3.5, i386) (3.5.0.0) when I try to compile it says "I don't know what AVSPlusVersionNumber means". When was that command implemented in the AVS core?
Anyway, I set it to some bogus value in order for it to always return true


sisphbd = 3500 > 2294


and it got me pass that, but now it's saying that there's no function called sh_padding which you used to pad


pad = fast > -1 ? src.sh_padding (4, 4, 4, 4) : src


but I can't find any filter which actually has sh_padding. Am I missing something?

real.finder
6th April 2020, 03:01
When you declared sisphbd you actually used the AvsPlusVersionNumber > 2294, however in AviSynth+ 3.5 (r3106, 3.5, i386) (3.5.0.0) when I try to compile it says "I don't know what AVSPlusVersionNumber means". When was that command implemented in the AVS core?
Anyway, I set it to some bogus value in order for it to always return true


sisphbd = 3500 > 2294


and it got me pass that, but now it's saying that there's no function called sh_padding which you used to pad


pad = fast > -1 ? src.sh_padding (4, 4, 4, 4) : src


but I can't find any filter which actually has sh_padding. Am I missing something?

in My Avisynth Stuff there are this :)

note:- Zs_RF_Shared.avsi (https://github.com/realfinder/AVS-Stuff/raw/master/avs%202.5%20and%20up/Zs_RF_Shared.avsi) (Shared Functions and utility V1.05 or up) is needed

real.finder
6th April 2020, 12:02
update for clean up things https://github.com/realfinder/AVS-Stuff/raw/master/avs%202.6%20and%20up/scaled444tonative.avsi

also now work with YUVA