Log in

View Full Version : Color banding and noise removal


Pages : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 [15] 16 17 18 19 20 21 22 23

Sparktank
7th July 2013, 18:01
Just popped in to tell you how much I love finding this filter!
It's worked magic for downscaling my BD's to DVD.
Still learning a lot of what it has to offer but the skies and walls have never looked so much better.
Thank you for your hard work and looking forward to any updates in the future. :)

cretindesalpes
4th August 2013, 19:08
Dither 1.23.0 (http://forum.doom9.org/showthread.php?p=1386559#post1386559):

dfttest 1.9.4: Compatibility with the new Avisynth 2.6 colorspaces, excepted Y8.
Partial implementation of the BT.2020 color conversions. Only the non-constant luminance matrix is implemented.
Optimized Dither_merge16 for SSE2.
Fixed the radiusc type in GradFun3 (int), so it now should work correctly in Avisynth 2.6 alpha 4.
Fixed a bug in Dither_merge16 affecting the chroma of YV12 clips with luma=true. Thanks to tp7 for reporting these issues.

Yellow_
15th August 2013, 13:37
I'll check later when at my machine, but does the dfttest 1.9.4 compatibility fix with 2.6 color spaces perhaps solve the problem I was having that I PM'd you about a while ago and mentioned here http://forum.doom9.org/showpost.php?p=1632471&postcount=696, which would be great news. :-)

martin53
30th August 2013, 19:26
Dither 1.23.0
Cretindesalpes,
thanks for that great package!

I am unsure if lines 381, 382 of dither.avsi should read
scale_y = (tv_range) ? (219.0 / 255.0) : 1.0
scale_uv = (tv_range) ? (112.0 / 255.0) : 0.5
to produce a proper float result?:confused:
Also, in dither.html, in the dither_convert_rgb_to_yuv description: I think tv_range defines the output clip pixel range.

StainlessS
30th August 2013, 20:23
(219 / 255.0)

The less precise variable will be coerced to the same format as the more precise variable, eg int 219 will be converted to Float 219.0.
So eg Float(219) / 255, or 219.0 / 255, or 219 / Float(255), or 219 / 255.0, all same result.
EDIT: Probably exactly the same in all programming languages (but there may be exceptions).
Also in eg C, char + int, char would be promoted to type int before addition, and results in int.

cretindesalpes
31st August 2013, 15:33
martin53:

As StainlessS said, these int should be promoted to float.
You’re right about the tv_range in the doc, I just fixed it. Thank you for reporting it.

Overdrive80
26th October 2013, 23:02
@cretindesalpes Actually, I´m using mvtools2 mod for you from ditherpack. I have tested MdegrainN with bad results, as it introduces blocking artifacts. Screenshots:

Source (DVD):
http://imageshack.us/a/img811/4026/c9md.png

MDegrainN:


original=last
aa=antialiasing
prefiltrado= denoiser_spatial

tr = 5 # Temporal radius

super = MSuper (prefiltrado)
multi_vec = MAnalyse (super, multi=true, delta=tr,dct=10)
prefiltrado.MDegrainN (super, multi_vec, tr, thSAD=400,thSADC=200, thSAD2=250,lsb=true,
\thSADC2=200).ditherpost(mode=2)

gradfun3()

http://imageshack.us/a/img594/7236/w06p.png

MDegrain3:


original=last
aa=antialiasing
prefiltrado= denoiser_spatial

super=Msuper(prefiltrado)

backward_vec3 = MAnalyse(super, isb = true, delta = 3, overlap=4,search=4)
backward_vec2 = MAnalyse(super, isb = true, delta = 2, overlap=4,search=4)
backward_vec1 = MAnalyse(super, isb = true, delta = 1, overlap=4,search=4)

forward_vec1 = MAnalyse(super, isb = false, delta = 1, overlap=4,search=4)
forward_vec2 = MAnalyse(super, isb = false, delta = 2, overlap=4,search=4)
forward_vec3 = MAnalyse(super, isb = false, delta = 3, overlap=4,search=4)

prefiltrado.MDegrain3(super,backward_vec1,forward_vec1,backward_vec2,forward_vec2,backward_vec3,forward_vec3,
\thSAD=370,plane=4,lsb=true).ditherpost(mode=2)

gradfun3()

http://imageshack.us/a/img27/4458/yf1q.png

I hope this is useful and you can fix. Greetings.

cretindesalpes
27th October 2013, 09:43
Overdrive80:
Indeed, the blocking shown in your example is typical from an overlap parameter left to its default value (0).

*
* *

Dither 1.24.0 (http://forum.doom9.org/showthread.php?p=1386559#post1386559):

Added all modes up to 24 to Dither_removegrain16, thanks to tp7. Most of them are SSE2-optimised.
Added modes 15–18 to Dither_repair16 (not optimised for SSE2).

Overdrive80
27th October 2013, 13:57
For comparison, users should control the variables as few as possible. In your instance, you did not set either dct, overlap, search in MAnalyse or thSAD, thSADC, thSAD2, thSADC2 in MDegrain to the same value in both scripts, and that confuses people.

I dont said that was a comparative. I did say that MdegrainN did introduce blocking artefacts, is that all.

@Cretindesalpes Ok, I gonna review it. Thanks.

sqrt(9801)
3rd January 2014, 18:12
Hi.

I've been using Dither quite a bit lately as a replacement for ResampleHQ, and I've stumbled upon what looks like a bug with Dither_resize16.

For example, this script
BlankClip(width=1024, height=1024, pixel_type="Y8")

Dither_convert_8_to_16
Dither_resize16(32, 32, kernel="spline36")
DitherPost(mode=6)
throws an unknown exception (tested with Avisynth 2.6a5 and Avisynth+ r1561).
It works when using Dither_resize16 with another kernel like Bicubic, Spline16, or Lanczos (with taps=2 or less), but the issue reappears when downsampling further.

Does anyone else have this problem, or is my PC ready for the scrap heap ? (I am using Win7 x86, btw)

Dogway
3rd January 2014, 19:27
I do, I've been experiencing this issue for several years but cretindesalpes never cared for it. This is why I never got to downsample HD to SD using Dither_resize16().

feisty2
5th January 2014, 14:08
I dont said that was a comparative. I did say that MdegrainN did introduce blocking artefacts, is that all.

@Cretindesalpes Ok, I gonna review it. Thanks.

don't use "dct" other than "0" or "5" for mdegrain, it will produce blocking artifacts

cretindesalpes
5th January 2014, 14:23
sqrt(9801), dogway:
Extreme downsampling ratios in both directions (32x is big) are likely to fail, yes. I’m not sure how to fix it. Please bear with me, I’m not perfect. But you can do it in several steps (1024 → 256 → 32). However, downsampling from HD to SD should work without any problem, I use it daily. And it’s wrong I don’t care, I don’t know where you read this. It’s just I don’t know what to do and haven’t an infinite time to think about every issue.

Dogway
5th January 2014, 16:45
I had crashes on my new system as well, for speed purposes I ended up using bicubic with Dither_resize16(), but let me confirm again with spline36. Normally these HD->SD scripts are so simple (denoise+resize) that I can exclude the RAM/buffer being the culprit, either way I will use MP_Pipeline next time which uses cores on a better fashion, and then be dead sure.

Boulder
5th January 2014, 17:56
Out of interest, are there any differences between "Dither_convert_8_to_16() - Dither_resize16(x,y) - Ditherpost(mode=-1)" and ResampleHQ(x,y) ? Using Dither seems to be somewhat faster.

cretindesalpes
5th January 2014, 21:51
IIRC ResampleHQ always resizes in linear RGB colorspace. So there are at least two more conversions involved.

Boulder
5th January 2014, 22:11
But in real-life applications like encoding to a lossless format after the resize operation, "a meaningless edge"?

foxyshadis
6th January 2014, 23:44
Well, linear downsampling is VERY different from gamma-corrected resampling. Highlights are kept more accurately with linear, with gamma they're darkened. The smaller you go the darker it gets. Too bad you have to choose between that or dithering here.

mawen1250
21st January 2014, 06:06
When I use some expression like this, it gives me unexpected result.
Dither_lut16(" x 32768 <= x x 32768 - ? ")
While this one works correctly.
Dither_lut16(" x 32768 <= x x 32768 - ? ")

After checking Functions in dither.avsi, I reallized that Dither_lut16 replaces " x " in <str> with <repstr>, so it doesn't deal with " x x " correctly.
Dither_replace_string is only used by Dither_lut16 so I think it can be fixed like this:
Function Dither_replace_string (string str, string findstr, string repstr)
{
strl = LCase (str)
findstrl = LCase (findstr)
lenf = StrLen (findstr)

pos = FindStr (strl, findstrl)
rep = (pos <= 0) ? "" : LeftStr (str, pos-1) + repstr + Dither_replace_string (MidStr (str, pos + lenf - 1), findstr, repstr)

return ((pos <= 0) ? str : rep)
}

spawnbsd
21st January 2014, 08:32
cretindesalpes, any chance we can get a 64bit build of dither tools ? Now that Avisynth+ is taking off and has a 64bit build available, 64bit is starting to look like a viable option again.

StainlessS
21st January 2014, 12:24
@mawen1250,
dither-1.24.0.zip contains this mod which seems to work OK

Function Dither_replace_string (string str, string findstr, string repstr)
{
strl = LCase (str)
findstrl = LCase (findstr)
lenf = StrLen (findstr)

pos = FindStr (strl, findstrl)
pos2 = (pos <= 0) ? 1 : pos # EDIT: seems superflous
rep = (pos <= 0) ? "" : LeftStr (str, pos-1) + repstr + Dither_replace_string (MidStr (str, pos + lenf), findstr, repstr)

return ((pos <= 0) ? str : rep)
}


EDIT: On comparing with your version, the "pos2 = (pos <= 0) ? 1 : pos" line in v1.24.0 seems superflous.
Your version with the added '-1' causes Avisynth halt without producng clip or error message and is not working as you expected.
EDIT: Your version keeps trying to replace the same string over and over again, until it runs out of stack.

EDIT: This

colorbars

Function Dither_replace_string (string str, string findstr, string repstr)
{
strl = LCase (str)
findstrl = LCase (findstr)
lenf = StrLen (findstr)

pos = FindStr (strl, findstrl)
# pos2 = (pos <= 0) ? 1 : pos
rep = (pos <= 0) ? "" : LeftStr (str, pos-1) + repstr + Dither_replace_string (MidStr (str, pos + lenf), findstr, repstr)

return ((pos <= 0) ? str : rep)
}

S = " x 32768 <= x x 32768 - ? "
F=" x "
R=" 123 "
O=Dither_replace_string(S,F,R)
RT_DebugF("%s\n%s",S,O)
S2 = " x 32768 <= x x 32768 - ? "
O2=Dither_replace_string(S2,F,R)
RT_DebugF("%s\n%s",S2,O2)

return Last


Produces this:

00000013 72.02262115 [1948] RT_DebugF: x 32768 <= x x 32768 - ?
00000014 72.02263641 [1948] RT_DebugF: 123 32768 <= 123 x 32768 - ? # Problem
00000015 72.03427887 [1948] RT_DebugF: x 32768 <= x x 32768 - ?
00000016 72.03430176 [1948] RT_DebugF: 123 32768 <= 123 123 32768 - ? # OK


AMENDED as per Gavino post below.

Gavino
21st January 2014, 13:03
S2 = " x 32768 <= x x 32768 - ? "
O2=Dither_replace_string(S,F,R)
RT_DebugF("%s\n%s",S2,O2)
Shouldn't this be S2?

Try F=" x " R=" 123 " and you will see the issue mawen1250 is talking about.

Gavino
21st January 2014, 14:12
EDIT: Your version keeps trying to replace the same string over and over again, until it runs out of stack.
Only if the search string is a single character.
I think his point is that the way the function is used in Dither_lut16, both the search and replacement strings always have added spaces, so his fix works.

StainlessS
21st January 2014, 15:54
Thank you big G, you got me there.
As omission of space could cause problem, how bout this:



colorbars

Function Dither_replace_string_MOD (string str, string findstr, string repstr) {
strl = LCase (str) # case independent for FindStr
findstrl = LCase (findstr) #
lenf = StrLen (findstr)
pos = FindStr (strl, findstrl)
lenr = Strlen(repstr)
# Below string comparison 'RightStr(repstr,1) == LeftStr(findstr,1)' is case insignificant
# If last char in replace matches 1st char in find, then
# we replace with all but last char of replace, and re-search remainder but with prepended first char of replace.
rep = (pos <= 0)
\ ? ""
\ : (lenf>1 && lenr>1 && RightStr(repstr,1) == LeftStr(findstr,1))
\ ? LeftStr (str, pos-1) + LeftStr(repstr,lenr-1) + Dither_replace_string_MOD (RightStr(repstr,1)
\ + MidStr (str, pos + lenf), findstr, repstr)
\ : LeftStr (str, pos-1) + repstr + Dither_replace_string_MOD (MidStr (str, pos + lenf), findstr, repstr)
return ((pos <= 0) ? str : rep)
}

S1 = " x 32768 <= x x 32768 - ? "
F=" x "
R=" ABC "
O1=Dither_replace_string_MOD(S1,F,R)
RT_DebugF("S1='%s' : F='%s' R='%s'\nO1='%s'\n",S1,F,R,O1)
R="ABC"
O2=Dither_replace_string_MOD(S1,F,R)
RT_DebugF("S1='%s' : F='%s' R='%s'\nO2='%s\n",S1,F,R,O2)

S2 = " x 32768 <= x x 32768 - ? "
F=" x "
R=" ABC "
O3=Dither_replace_string_MOD(S2,F,R)
RT_DebugF("S2='%s' : F='%s' R='%s'\nO3='%s\n",S2,F,R,O3)
R="ABC"
O4=Dither_replace_string_MOD(S2,F,R)
RT_DebugF("S2='%s' : F='%s' R='%s'\nO4='%s\n",S2,F,R,O4)
return Last



00000005 2.31286550 [2940] RT_DebugF: S1=' x 32768 <= x x 32768 - ? ' : F=' x ' R=' ABC '
00000006 2.31392574 [2940] RT_DebugF: O1=' ABC 32768 <= ABC ABC 32768 - ? '
00000007 2.31412077 [2940] RT_DebugF:
00000008 2.33118415 [2940] RT_DebugF: S1=' x 32768 <= x x 32768 - ? ' : F=' x ' R='ABC'
00000009 2.37454796 [2940] RT_DebugF: O2='ABC32768 <=ABCABC32768 - ?
00000010 2.37459588 [2940] RT_DebugF:
00000011 2.39530826 [2940] RT_DebugF: S2=' x 32768 <= x x 32768 - ? ' : F=' x ' R=' ABC '
00000012 2.39533472 [2940] RT_DebugF: O3=' ABC 32768 <= ABC ABC 32768 - ?
00000013 2.39536095 [2940] RT_DebugF:
00000014 2.40840435 [2940] RT_DebugF: S2=' x 32768 <= x x 32768 - ? ' : F=' x ' R='ABC'
00000015 2.41166806 [2940] RT_DebugF: O4='ABC32768 <=ABCx 32768 - ?
00000016 2.41172385 [2940] RT_DebugF:

so long as repstr surounded by space, no problems.
Not much testing but seems to work. Spot any problems Gavino ?

PS, Whatever happend to the 'quick reply' spell checker when I was on 'vacation' ???

EDIT:
This causes silent crash in Mawen1250 mod, no error message, could be hard to trace bug

S1 = " x 32768 <= x x 32768 - ? "
F="x"
R="A"
O1=Dither_replace_string(S1,F,R)


but not above mod which produces this


00000005 2.15423131 [2144] RT_DebugF: S1=' x 32768 <= x x 32768 - ? ' : F='x' R='A'
00000006 2.15425491 [2144] RT_DebugF: O1=' A 32768 <= A A 32768 - ? '

mawen1250
22nd January 2014, 05:02
The original Dither_replace_string works correctly for pure linear string replacement, but it is only used in Dither_lut16, while the string replacement in Dither_lut16 is somewhat meant to be non-linear...
So the modified Dither_replace_string should be renamed to something like Dither_expr_replace_string IMO.

cretindesalpes
22nd January 2014, 11:30
Because there isn’t currently any operator starting with the letter "x", I think replacing " x" instead of " x " in Dither_lut16_expr() is a simpler solution.

cretindesalpes
2nd March 2014, 09:37
Dither 1.25.0 (http://forum.doom9.org/showthread.php?p=1386559#post1386559):
Added a 64-bit version. Source code projects ported to MSVC 2012.
Added modes 5–10 to Dither_repair16.
Added ref clip to GradFun3.
The order of the luma, y, u and v parameters in Dither_merge16 is now the same as in Dither_merge16_8. The documentation has been fixed accordingly.
Slight speed improvement in Dither_srgb_display when there is no resizing nor gamma correction.
Fixed a problem in Dither_lut16 with expressions containing two consecutive “x” arguments.
Fixed artefacts (overflow occuring when input pixels are close to 0) and inaccuracy in mode 20 of Dither_removegrain16.
Edit: important bug found. Please use the version 1.25.1 instead.

tormento
2nd March 2014, 11:10
Added a 64-bit version. Source code projects ported to MSVC 2012.
Do you plan to release x64 version for other dll in the package too?

cretindesalpes
2nd March 2014, 13:44
Do you mean avstp.dll? Most likely not. With this 64-bit version, I’m supporting AviSynth+, not the old 64-bit AviSynth which is abandoned. Avs+ already has frame-based multi-threading capabilities, and I’ll probably make avstp use its internal thread pool interface in the future.

tormento
2nd March 2014, 15:07
Do you mean avstp.dll?
And MVTools too.

mawen1250
3rd March 2014, 00:49
It seems plane copy of Dither_merge16 is broken in 1.25.0.

cretindesalpes
3rd March 2014, 22:11
Damn! Your’re right. Fixed in Dither 1.25.1 (http://forum.doom9.org/showthread.php?p=1386559#post1386559)

DeathAngelBR
5th March 2014, 21:41
Just wondering... is this the expected encode speed for a Q8400 and 4GB RAM?

(avstp.dll is in the autoload plugin folder)

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

setmemorymax(512)

LoadPlugin("D:\Edição de video\MeGUI\tools\dgavcindex\DGAVCDecode.dll")
LoadPlugin("D:\Arquivos de programas\AviSynth 2.5\plugins\removegrain\RemoveGrainSSE2.dll")
LoadPlugin("D:\Arquivos de programas\AviSynth 2.5\plugins\removegrain\RepairSSE2.dll")
LoadPlugin("D:\Arquivos de programas\AviSynth 2.5\plugins\removegrain\RSharpenSSE2.dll")
LoadPlugin("D:\Arquivos de programas\AviSynth 2.5\plugins\outros\mt_masktools-26.dll")
LoadPlugin("D:\Arquivos de programas\AviSynth 2.5\plugins\outros\AddGrainC.dll")
LoadPlugin("D:\Arquivos de programas\AviSynth 2.5\plugins\outros\dither.dll")
Import("D:\Arquivos de programas\AviSynth 2.5\plugins\outros\dither.avs")

AVCSource("I:\BDMV Symphogear G Vol. 2\BDMV\STREAM\00003.dga")
spline64resize(1280,720)
dither_convert_8_to_16()
gradfun3(lsb_in=true,lsb=true,smode=2)
dither_out()

cretindesalpes
5th March 2014, 23:24
No idea. If you want to check the speed of the script, use AVSMeter. If you want to check the speed of x264, keep only AVCSource + resize and use 10bit-x264 with 8-bit input.

spawnbsd
6th March 2014, 20:01
And MVTools too.

@ cretindesalpes, any chance we'll get a 64bit mvtools build as well ?

cretindesalpes
7th March 2014, 08:34
Not right now. This is a serious beast, and I have things to finish before (porting dfttest and eedi3 to 64-bits/VS/Avs+/high bit depth). But I plan to work on it. I think Myrsloik and tp7 are already poking it too.

feisty2
7th March 2014, 13:14
are you planning on porting nnedi3 to high bit depth too?

Bernardd
9th March 2014, 10:16
Hello

When I try Martin53's AWB function, i get error " Unable to call Dither_convert_yuv_to_rgb(). Required dither package 1.23.0 or higher installed ? http://forum.doom9.org/showthread.php?p=1386559"

I have writted this short script for checking

LoadPlugin("C:\RT_Stats_25&26_dll_v1.30_20131219\Avisynth26\RT_Stats26.dll")
LoadPlugin("C:\dither-1.25.1\win32\dither.dll")
assert(RT_FunctionExist("""Dither_convert_yuv_to_rgb"""), "Unable to call Dither_convert_yuv_to_rgb().")
return last

I get the same error. I use avisynth 2.60A5 (CVS 20130920, ICL 10).

What is missing ?

Thanks

the_weirdo
9th March 2014, 10:58
@Bernardd:

Function Dither_convert_yuv_to_rgb is implemented as a script function in dither.avsi, so you need to import dither.avsi or have it in autoload folder.

Bernardd
9th March 2014, 12:08
@ the_weirdo :

Thanks for your quick answer. It is ok now.

cretindesalpes
11th March 2014, 08:44
are you planning on porting nnedi3 to high bit depth too?
No, other people took charge of it, I’ll leave it to them.

Overdrive80
23rd April 2014, 00:25
One dude, how I can use below script with dither, for use high-bitdepth in his processing. Thanks.


ColorYUV( gain_y=-10, off_y=0, gamma_y=-8, cont_y=0,\
gain_u=4, off_u=0.0, gamma_U=-5, cont_u=0,\
gain_v=-4, off_v=0.0, gamma_v=-5, cont_v=0)

cretindesalpes
1st May 2014, 19:52
Overdrive80:

The code below should emulate ColorYUV in 16 bits:
Dither_convert_8_to_16 ()
Dither_lut16 (
\ yexpr=coloryuv_to_expr16 (-10, 0, -8, 0),
\ uexpr=coloryuv_to_expr16 ( 4, 0, 0, 0),
\ vexpr=coloryuv_to_expr16 ( -4, 0, 0, 0),
\ y=3, u=3, v=3)
DitherPost ()

Function coloryuv_to_expr16 (float gain, float off, float gamma, float cont)
{
pscale = 256.0
vscale = 65536
a = String ((gain + pscale) / pscale)
c = String ((cont ) / pscale)
o = String (off)
g = String (pscale / (gamma + pscale))
v = String (vscale)
h = String (vscale / 2)

e = "x "+a+" * x "+h+" - "+c+" * + "+o+" + "+v+" / "+g+" ^ "+v+" *"

return (e)
}

Set gamma_u and gamma_v to 0, they are ignored in the original ColorYUV.

Overdrive80
2nd May 2014, 02:43
Thanks for your answer. ^^

jackoneill
10th May 2014, 13:33
No, other people took charge of it, I’ll leave it to them.

Who did?

Uh, seems the line cretindesalpes was quoting didn't come through. It was about someone porting nnedi3 to 16 bit.

Popwax
15th May 2014, 17:07
I think patched dfttest-1.9.4 have a bug handling "plane" parameters from "nfile" or "nstring".
In "vi_src.width >> vi.GetPlaneWidthSubsampling (b);", maybe we should use "1<<b" instead of "b" here.

Lenchik
17th May 2014, 08:53
Is it possible to resize using a Sigmoidal Colorspace (http://www.imagemagick.org/Usage/resize/#resize_sigmoidal) with Dither package?

cretindesalpes
20th May 2014, 10:54
Popwax:

Yes you’re right, there’s something like this to fix it. I’ll work on it when back home.

Lenchik:

Yes it’s possible, it’s just a LUT and its inverse to add. I will probably add sigmoid curves in a next release.

Motenai Yoda
30th May 2014, 20:56
Sorry, but this is right?
Function Dither_lut16_expr (string expr, bool gmsb)
{
# We use spaces to enclose " x" because we don't want operators
# like "max" or "exp" to have their "x" replaced…
repstr = (gmsb) ? " x 256 * y + " : " y 256 * x + "
expr = Dither_replace_string (" " + expr, " x", repstr)
part = Dither_expr_part (gmsb)
expr = expr + part

return (expr)
}

what's the meaning? doesn't use lsb as msb and viceversa?

cretindesalpes
30th May 2014, 22:47
Yes, it’s to cancel the swap between the LSB and MSB input clips in the mt_lutxy parameters when processing the LSB output. I don’t remember exactly why it was needed but I think it’s to simplify the handling of the y, u and v plane parameters.