Log in

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


Pages : [1] 2 3

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