View Full Version : Dogway's Filters Packs
Dogway
11th July 2021, 18:07
I use sorting networks (http://users.telenet.be/bertdobbelaere/SorterHunter/sorting_networks.html#N8L19D6). Right now I'm trying to port (kinda done), Adaptive Median (http://avisynth.nl/index.php/AdaptiveMedian) by VC Mohan checking the source file, the concept is easy but costly in terms of performance. In any case I'm doing this for the literature so I can have all the algos and how they look in one right place.
wonkey_monkey
11th July 2021, 18:17
Hmm. Neat but mindboggling (the sorting networks I mean).
wonkey_monkey
11th July 2021, 21:22
Fully optimsed undot2 - 40% faster! :eek:
x[-1,1] x[1,1] dup1 dup1 min swap2 max
x[0,1] x[-1,0] dup1 dup1 min swap2 max
x[1,0] x[0,-1] dup1 dup1 min swap2 max
x[-1,-1] x[1,-1] dup1 dup1 min swap2 max
swap7 swap1 swap3 dup1 dup1 min swap2 max
swap5 swap1 swap3 dup1 dup1 min swap2 max
swap6 swap1 swap2 dup1 dup1 min swap2 max
swap4 swap1 swap7 dup1 dup1 min swap2 max
swap3 swap1 swap2 max
swap6 dup1 dup1 min swap2 max
swap4 swap1 swap5 dup1 dup1 min swap2 max
swap3 swap1 swap2 min
swap4 dup1 dup1 min swap2 max
swap3 swap1 swap2 dup1 dup1 min swap2 max
swap5 swap1 swap3 min
swap2 swap1 swap3 max
swap2 min
swap2 max
x swap2 swap1
clip
This now makes it nearly 18x faster than the equivalent non-SIMD C++ plugin on my computer.
Dogway
12th July 2021, 13:05
I tested the undot2 and I got a 10% performance increase, from 317fps (old dup1 dup1 syntax) to 343fps. VERY nice!.
I'm trying to understand the new syntax, I think I got it but got some issues. I wonder why in the first swap3 line you only compute max? Is this to save a comparison check? Following you do a swap6 so you end with A F (I name them to keep track) on the stack and do a min, max when it should be A C.
Stack state after swap3 line:
C F
E G
H D
A B
As an exercise I'm doing the simple undot1:
"x[-1,1] A^ x[0,1] B^ x[1,1] C^ x[-1,0] D^ x[1,0] E^ x[-1,-1] F^ x[0,-1] G^ x[1,-1] H^ "
"x[0,0] A B min C min D min E min F min G min H min A B max C max D max E max F max G max H max clip"
And this was my attempt which doesn't match one to one (and it's slower):
x[0,0] x[-1,1] x[0,1] x[1,1] x[-1,0] x[1,0] x[-1,-1] x[0,-1] x[1,-1]
swap7 swap1 swap6 dup1 dup1 min swap2 max
swap5 dup swap2 min swap5 max
swap1 swap3 dup swap2 max swap4 min
dup1 min swap3 max
dup1 max swap2 min
swap2 dup1 max swap2 min
swap2 dup1 max swap2 min swap clip
EDIT: yikes, I borked it at dup. Edit above but still no match.
wonkey_monkey
12th July 2021, 18:17
I'm trying to understand the new syntax, I think I got it but got some issues. I wonder why in the first swap3 line you only compute max? Is this to save a comparison check?
Yes, the result of a min here would never be used so it's preferable not to do it (otherwise it would need to be popped at the end).
Following you do a swap6 so you end with A F (I name them to keep track) on the stack and do a min, max when it should be A C.
Because there's no min calculation, A ends up being removed from the stack entirely. The max changes the stack from "C F E G H D A B" to "C F E G H D B", then on the next line swap6 turns this into "B F E G H D C", ready for C and D to be compared (both min and max, since both are required).
wonkey_monkey
12th July 2021, 21:06
Can you give this tool a try?
https://horman.net/expr_sort.php
Select a network from the dropdown, then choose which sorted elements you want (e.g. for undot2, elements 1 and 6), select an ordering for the selected elements to be left on the stack, then hit submit.
Copy the contents of the left box and replace each [#] with an unsorted element (e.g. a pixel reference).
Dogway
13th July 2021, 09:06
Woow, so awesome! Saves a lot of time specially for 25 inputs. The problem is except for low inputs it's slower! I do think there's more to it than meets the eye. Following some reasoning.
I think there are some unwritten rules for Expr to optimize performance. I will try list those that come to mind.
Multiplication is faster than division. "x 0.5 *" > "x 2 /"
For better precision calculate the reciprocal within Expr, constants are directly stored so they are reused. "x 1 3 / *" > "x 0.333333333 * "
Ternaries are very slow, try to replace them with min|max when possible. "x y max" > "x y > x y ?"
Dragging stack elements lowers performance. "x 0.5 - x *" > "x x 0.5 - *"
dupn lowers performance for higher "n"
more?
I need to set those into stone to decide what optimization route to go forward with ExTools.
I think the problem with 25 inputs is number 4. swapping might be a free operation but performance suffers because Expr likes continuous operations on the stack. You can see this clearly with the example in my above post, simply swap the location of "x" to the correct stack position and it increases performance by 10%. "x" or "x[0,0]" doesn't make a change (at all).
x[0,-1] x[1,-1]
x[1,0] x[-1,-1]
x[1,1] x[-1,0]
x[-1,1] x[0,1] dup1 dup1 min swap2 max
swap3 dup1 swap2 min swap3 max
swap1 dup1 swap2 max swap2 min
swap3 dup1 swap2 max swap3 min
swap1 dup1 swap2 min swap2 max
swap2 dup1 swap2 min swap2 max
swap2 dup1 swap2 min swap2 max
x swap2 swap1 clip
The degree to which dragging elements behind impacts performance is not yet defined. For example.
old new
"x {th} > 255 scaleb x ?" > "x dup {th} > 255 scaleb swap1 swap2 ?"
old = 471 + 473 + 479 + 474 + 465 + 482 + 481 = 475 mean = 474 median = 1883 (470.75) 50%p
new = 471 + 469 + 486 + 481 + 464 + 468 + 485 = 474.85 mean = 471 median = 1872 (468) 50%p
Another example, each one stacked 3 times to augment difference.
sat=-0.2
Expr("", Format("x A^ 1 {sat} - A * {sat} range_max A - * + ")) # 297 298 297
Expr("", Format("1 {sat} - x dup swap2 * range_max swap1 swap2 - {sat} * +") ) # 294 299 293
As one can see the improvement of not using variables is not clear cut.
So my suggestion for median5 (or long sorting networks) is to bring stack elements to the front from time to time (after 1 or 2 layers).
wonkey_monkey
13th July 2021, 10:08
The problem is except for low inputs it's slower!
Slower than what?
Dogway
13th July 2021, 19:34
Slower than this (https://github.com/Dogway/Avisynth-Scripts/blob/03ac23f8c7241e390598540038e96871b33e7304/ExTools.avsi#L825).
Tried with this, but didn't help, it needs some manual work.
mode == "median5"? "x[-2,2] x[-1,2] dup1 dup1 min swap2 max
x[0,2] x[1,2] dup1 dup1 min swap2 max
x[2,2] x[-2,1] dup1 dup1 min swap2 max
x[-1,1] x[0,1] dup1 dup1 min swap2 max
x[1,1] x[2,1] dup1 dup1 min swap2 max
x[-2,0] x[-1,0] dup1 dup1 min swap2 max
x[0,0] x[1,0] dup1 dup1 min swap2 max
x[2,0] x[-2,-1] dup1 dup1 min swap2 max
x[-1,-1] x[0,-1] dup1 dup1 min swap2 max
x[1,-1] x[2,-1] dup1 dup1 min swap2 max
x[-2,-2] x[-1,-2] dup1 dup1 min swap2 max
x[0,-2] x[1,-2] dup1 dup1 min swap2 max
swap23 swap1 swap19 dup1 dup1 min swap2 max
swap21 swap1 swap3 dup1 dup1 min swap2 max
swap22 swap1 swap18 dup1 dup1 min swap2 max
swap17 swap1 swap7 dup1 dup1 min swap2 max
swap15 swap1 swap19 dup1 dup1 min swap2 max
swap13 swap1 swap9 dup1 dup1 min swap2 max
swap11 swap1 swap5 dup1 dup1 min swap2 max
swap20 swap1 swap2 dup1 dup1 min swap2 max
swap10 swap1 swap4 dup1 dup1 min swap2 max
swap8 swap1 swap12 dup1 dup1 min swap2 max
swap6 swap1 swap16 dup1 dup1 min swap2 max
swap14 swap1 swap23 dup1 dup1 min swap2 max
swap3 swap1 swap19 dup1 dup1 min swap2 max
swap18 swap1 swap2 dup1 dup1 min swap2 max
N@ P@ D@ O@ U@ E@ S@ L@ M@ R@ V@ J@ K@ X@ F@ Q@ C@ T@ G@ I@ Y@ A@ B@ H@
(...)
wonkey_monkey
13th July 2021, 20:33
I wonder if Expr's built-in spilling of values, when they don't fit on the stack, is slower than saving them to variables for some reason.
There is a fault somewhere in yours though - I checked it with random pixel values and it didn't give the correct median.
Dogway
13th July 2021, 20:52
Yes I know, I revised it several times but didn't find the culprit. The same with undot1 as stated above (https://forum.doom9.org/showthread.php?p=1947344#post1947344). Might not be my fault who knows.
I think it might also be a matter of dragging behind stack elements as explained above with simple expressions. The following is also very slow, I guess popping them out fixes the issue:
x[-2,2] x[-1,2] dup1 dup1 min swap2 max
x[0,2] x[1,2] dup1 dup1 min swap2 max
x[2,2] x[-2,1] dup1 dup1 min swap2 max
x[-1,1] x[0,1] dup1 dup1 min swap2 max
x[1,1] x[2,1] dup1 dup1 min swap2 max
x[-2,0] x[-1,0] dup1 dup1 min swap2 max
x[0,0] x[1,0] dup1 dup1 min swap2 max
x[2,0] x[-2,-1] dup1 dup1 min swap2 max
x[-1,-1] x[0,-1] dup1 dup1 min swap2 max
x[1,-1] x[2,-1] dup1 dup1 min swap2 max
x[-2,-2] x[-1,-2] dup1 dup1 min swap2 max
x[0,-2] x[1,-2] dup1 dup1 min swap2 max
N^ P^ D^ O^ U^ E^ S^ L^ M^ R^ V^ J^ K^ X^ F^ Q^ C^ T^ G^ I^ Y^ A^ B^ H^
M
EDIT: Above 12 stack elements it starts to bog down.
wonkey_monkey
13th July 2021, 20:57
Mine (median5) is faster if you set optSingleMode = true :D Yours does not benefit :(
Unfortunately knowing whether or not to switch it on is probably a black art and may not even be the same from computer to computer. Are you on x86 or x64?
Edit: actually thinking about it, if it's faster on one computer it should be faster on any computer with the same architecture (x86 or x64). It's to do with how many registers are available. Yours gained some speed by keeping more registers free, but lost some due to storing and loading variables. I'm still a little surprised at how close they are though.
When I eventually write my new RPN compiler I plan on including automatic profiling so it should always make the correct choices of such features.
Dogway
13th July 2021, 23:02
That one is outdated actually :rolleyes:, I think this might be faster (if we ignore the output difference):
x[-2,2] A^ x[-1,2] B^ x[0,2] C^ x[1,2] D^ x[2,2] E^ x[-2,1] F^ x[-1,1] G^ x[0,1] H^ x[1,1] I^ x[2,1] J^ x[-2,0] K^ x[-1,0] L^ x[0,0] M^
x[1,0] N^ x[2,0] O^ x[-2,-1] P^ x[-1,-1] Q^ x[0,-1] R^ x[1,-1] S^ x[2,-1] T^ x[-2,-2] U^ x[-1,-2] V^ x[0,-2] X^ x[1,-2] Y^ x[2,-2] Z^
A C dup1 dup1 min AA^ max CC^ B I dup1 dup1 min BB^ max II^ D S dup1 dup1 min DD^ max SS^ E R dup1 dup1 min EE^ max RR^ F U dup1 dup1 min FF^ max UU^ G T dup1 dup1 min GG^ max TT^ H J dup1 dup1 min HH^ max JJ^ K L dup1 dup1 min KK^ max LL^ M N dup1 dup1 min MM^ max NN^ O Q dup1 dup1 min OO^ max QQ^ P X dup1 dup1 min PP^ max XX^ V Y dup1 dup1 min VV^ max YY^
AA DD dup1 dup1 min A^ max D^ BB PP dup1 dup1 min B^ max P^ CC SS dup1 dup1 min C^ max S^ EE MM dup1 dup1 min E^ max M^ FF VV dup1 dup1 min F^ max V^ GG KK dup1 dup1 min G^ max K^ HH OO dup1 dup1 min H^ max O^ II XX dup1 dup1 min I^ max X^ JJ QQ dup1 dup1 min J^ max Q^ LL TT dup1 dup1 min L^ max T^ NN RR dup1 dup1 min N^ max R^ UU YY dup1 dup1 min U^ max Y^
A E dup1 dup1 min AA^ max EE^ B H dup1 dup1 min BB^ max HH^ C N dup1 dup1 min CC^ max NN^ D M dup1 dup1 min DD^ max MM^ F G dup1 dup1 min FF^ max GG^ I O dup1 dup1 min II^ max OO^ J P dup1 dup1 min JJ^ max PP^ K V dup1 dup1 min KK^ max VV^ L U dup1 dup1 min LL^ max UU^ Q X dup1 dup1 min QQ^ max XX^ R S dup1 dup1 min RR^ max SS^ T Y dup1 dup1 min TT^ max YY^
AA FF dup1 dup1 min A^ max F^ CC LL dup1 dup1 min C^ max L^ DD GG dup1 dup1 min D^ max G^ EE KK dup1 dup1 min E^ max K^ HH QQ dup1 dup1 min H^ max Q^ II JJ dup1 dup1 min I^ max J^ MM VV dup1 dup1 min M^ max V^ NN TT dup1 dup1 min N^ max T^ OO PP dup1 dup1 min O^ max P^ RR UU dup1 dup1 min R^ max U^ SS YY dup1 dup1 min S^ max Y^
C H dup1 dup1 min CC^ max HH^ G J dup1 dup1 min GG^ max JJ^ I LL dup1 dup1 min II^ max L^ O Z dup1 dup1 min OO^ max ZZ^ S V dup1 dup1 min SS^ max VV^
D II dup1 dup1 min DD^ max I^ HH K dup1 dup1 min H^ max KK^ LL M dup1 dup1 min L^ max MM^ N OO dup1 dup1 min NN^ max O^ P VV dup1 dup1 min PP^ max V^ SS U dup1 dup1 min S^ max UU^ X ZZ dup1 dup1 min XX^ max Z^
E NN dup1 dup1 min EE^ max N^ KK Q dup1 dup1 min K^ max QQ^ L PP dup1 dup1 min LL^ max P^ S Z dup1 dup1 min SS^ max ZZ^ T XX dup1 dup1 min TT^ max X^
BB EE dup1 dup1 min B^ max E^ I LL dup1 dup1 min II^ max L^ JJ TT dup1 dup1 min J^ max T^ N R dup1 dup1 min NN^ max RR^ O SS dup1 dup1 min OO^ max S^ QQ UU dup1 dup1 min Q^ max U^ Y ZZ dup1 dup1 min YY^ max Z^
A B dup1 dup1 min AA^ max BB^ E F dup1 dup1 min EE^ max FF^ GG NN dup1 dup1 min G^ max N^ J OO dup1 dup1 min JJ^ max O^ K RR dup1 dup1 min KK^ max R^ MM Q dup1 dup1 min M^ max QQ^ S T dup1 dup1 min SS^ max TT^ U V dup1 dup1 min UU^ max VV^ X YY dup1 dup1 min XX^ max Y^
CC G dup1 dup1 min C^ max GG^ DD EE dup1 dup1 min D^ max E^ FF N dup1 dup1 min F^ max NN^ H JJ dup1 dup1 min HH^ max J^ M SS dup1 dup1 min MM^ max S^ P R dup1 dup1 min PP^ max RR^ QQ TT dup1 dup1 min Q^ max T^ UU XX dup1 dup1 min U^ max X^ VV Y dup1 dup1 min V^ max YY^
BB C dup1 dup1 min B^ max CC^ F II dup1 dup1 min FF^ max I^ GG HH dup1 dup1 min G^ max H^ J KK dup1 dup1 min JJ^ max K^ L NN dup1 dup1 min LL^ max N^ O PP dup1 dup1 min OO^ max P^ RR U dup1 dup1 min R^ max UU^ V X dup1 dup1 min VV^ max XX^
B D dup1 dup1 min BB^ max DD^ CC E dup1 dup1 min C^ max EE^ FF G dup1 dup1 min F^ max GG^ H LL dup1 dup1 min HH^ max L^ I JJ dup1 dup1 min II^ max J^ K N dup1 dup1 min KK^ max NN^ MM OO dup1 dup1 min M^ max O^ P Q min PP^ R S min RR^
J M max MM^ KK L max LL^ NN O min N^ PP RR min P^ LL MM max M^ N P min NN^ M NN min MM^
MM
I don't mind doing manual profiling this time, well it's what I've doing for 2 months anyway, haha.
wonkey_monkey
14th July 2021, 00:08
Yup, faster for me too. What did you change? The ordering of swaps within each layer?
kedautinh12
14th July 2021, 04:42
I think need keep output same result cause it will affect whole scripts when just replace some functions. Example: you was replaced blur(.6) with RemoveGrain(1) in Framerateconverter.avsi cause it's only faster but MysteryX said it will make artifact when mask larger
Dogway
14th July 2021, 10:47
I just removed unnecessary checks for the last 2 layers. Anyway I will revise it one more time this time with regex so I don't do any mistake.
Today mainly will be profiling and optimizing, if lucky I can release this evening.
@kedautinh12: Yes, these are only drafts. I still haven't updated MIX/EX mods to latest ExTools, it happened that removegrain(12) or blur is not true gaussian but a weighted mean. blur(0.6) was implemented recently as a bare convolution. I also want to optimize Expr with latest tricks but most likely will leave untouched as shown here (https://forum.doom9.org/showthread.php?p=1947419#post1947419).
EDIT: By the way undot was:
x[0,-1] x[1,-1]
x[1,0] x[-1,-1]
x[1,1] x[-1,0]
x[-1,1] x[0,1] dup1 dup1 min swap2 max
swap3 dup swap2 min swap3 max
swap1 dup swap2 max swap2 min
swap3 dup swap2 max swap3 min
swap1 dup swap2 min swap2 max
swap2 dup swap2 min swap2 max
swap2 dup swap2 min swap2 max
x swap2 swap1 clip
It still slower than the old min max succession so I post it here just for reference. I also fixed median5 (an LL^ variable was mistyped) and also weightedp. Overall good optimizations going forward.
wonkey_monkey
14th July 2021, 20:18
Can you check if this is faster for median5? It was for me. It uses the second 25-item network instead of the first, which is apparently more Expr-friendly:
Expr(optsinglemode = true, "
x[-2,2] x[-1,2] dup1 dup1 min swap2 max
x[0,2] x[1,2] dup1 dup1 min swap2 max
x[2,2] x[-2,1] dup1 dup1 min swap2 max
x[-1,1] x[0,1] dup1 dup1 min swap2 max
x[1,1] x[2,1] dup1 dup1 min swap2 max
x[-2,0] x[-1,0] dup1 dup1 min swap2 max
x[0,0] x[1,0] dup1 dup1 min swap2 max
x[2,0] x[-2,-1] dup1 dup1 min swap2 max
x[-1,-1] x[0,-1] dup1 dup1 min swap2 max
x[1,-1] x[2,-1] dup1 dup1 min swap2 max
x[-2,-2] x[-1,-2] dup1 dup1 min swap2 max
x[0,-2] x[1,-2] dup1 dup1 min swap2 max
swap23 swap1 swap19 dup1 dup1 min swap2 max
swap21 swap1 swap3 dup1 dup1 min swap2 max
swap22 swap1 swap18 dup1 dup1 min swap2 max
swap17 swap1 swap7 dup1 dup1 min swap2 max
swap15 swap1 swap19 dup1 dup1 min swap2 max
swap13 swap1 swap9 dup1 dup1 min swap2 max
swap11 swap1 swap5 dup1 dup1 min swap2 max
swap20 swap1 swap2 dup1 dup1 min swap2 max
swap10 swap1 swap4 dup1 dup1 min swap2 max
swap8 swap1 swap12 dup1 dup1 min swap2 max
swap6 swap1 swap16 dup1 dup1 min swap2 max
swap14 swap1 swap23 dup1 dup1 min swap2 max
swap3 swap1 swap19 dup1 dup1 min swap2 max
swap18 swap1 swap2 dup1 dup1 min swap2 max
swap7 swap1 swap23 dup1 dup1 min swap2 max
swap21 swap1 swap15 dup1 dup1 min swap2 max
swap9 swap1 swap5 dup1 dup1 min swap2 max
swap4 swap1 swap20 dup1 dup1 min swap2 max
swap12 swap1 swap22 dup1 dup1 min swap2 max
swap11 swap1 swap13 dup1 dup1 min swap2 max
swap16 swap1 swap19 dup1 dup1 min swap2 max
swap8 swap1 swap10 dup1 dup1 min swap2 max
swap14 swap1 swap17 dup1 dup1 min swap2 max
swap6 swap1 swap3 dup1 dup1 min swap2 max
swap2 swap1 swap20 max
swap14 swap1 swap9 dup1 dup1 min swap2 max
swap4 swap1 swap3 dup1 dup1 min swap2 max
swap17 swap1 swap18 dup1 dup1 min swap2 max
swap21 swap1 swap12 dup1 dup1 min swap2 max
swap8 swap1 swap15 dup1 dup1 min swap2 max
swap20 swap1 swap19 dup1 dup1 min swap2 max
swap11 swap1 swap10 dup1 dup1 min swap2 max
swap2 swap1 swap7 dup1 dup1 min swap2 max
swap5 swap1 swap9 dup1 dup1 min swap2 max
swap13 x[2,-2] dup1 dup1 min swap2 max
swap7 swap1 swap20 dup1 dup1 min swap2 max
swap16 swap1 swap22 dup1 dup1 min swap2 max
swap9 swap1 swap11 dup1 dup1 min swap2 max
swap5 swap1 swap20 dup1 dup1 min swap2 max
swap2 swap1 swap21 dup1 dup1 min swap2 max
swap12 swap1 swap6 dup1 dup1 min swap2 max
swap14 swap1 swap7 min
swap22 swap1 swap20 dup1 dup1 min swap2 max
swap18 swap1 swap10 max
swap11 swap1 swap18 dup1 dup1 min swap2 max
swap13 swap1 swap20 dup1 dup1 min swap2 max
swap16 swap1 swap3 dup1 dup1 min swap2 max
swap7 swap1 swap18 dup1 dup1 min swap2 max
swap6 swap1 swap4 dup1 dup1 min swap2 max
swap15 swap1 swap19 dup1 dup1 min swap2 max
swap2 swap1 swap3 max
swap15 swap1 swap7 dup1 dup1 min swap2 max
swap16 swap1 swap18 dup1 dup1 min swap2 max
swap5 swap1 swap9 dup1 dup1 min swap2 max
swap2 swap1 swap4 dup1 dup1 min swap2 max
swap14 swap1 swap20 dup1 dup1 min swap2 max
swap11 swap1 swap7 dup1 dup1 min swap2 max
swap8 swap1 swap15 max
swap16 swap1 swap4 dup1 dup1 min swap2 max
swap11 swap1 swap8 dup1 dup1 min swap2 max
swap2 swap1 swap15 dup1 dup1 min swap2 max
swap12 swap1 swap19 dup1 dup1 min swap2 max
swap3 swap1 swap14 dup1 dup1 min swap2 max
swap6 swap1 swap13 dup1 dup1 min swap2 max
swap7 swap1 swap10 min
swap17 swap1 swap14 max
swap14 swap1 swap6 dup1 dup1 min swap2 max
swap15 swap1 swap12 dup1 dup1 min swap2 max
swap7 swap1 swap17 dup1 dup1 min swap2 max
swap3 swap1 swap9 dup1 dup1 min swap2 max
swap11 swap1 swap8 dup1 dup1 min swap2 max
swap6 swap1 swap10 dup1 dup1 min swap2 max
swap5 swap1 swap16 min
swap3 min
swap10 swap1 swap7 max
swap12 swap1 swap6 dup1 dup1 min swap2 max
swap14 swap1 swap11 max
swap9 swap1 swap3 dup1 dup1 min swap2 max
swap4 swap1 swap12 dup1 dup1 min swap2 max
swap7 swap1 swap3 min
swap4 swap1 swap7 min
swap8 swap1 swap7 max
swap8 swap1 swap9 max
swap9 swap1 swap8 dup1 dup1 min swap2 max
swap5 swap1 swap2 dup1 dup1 min swap2 max
swap8 swap1 swap4 min
swap2 swap1 swap5 min
swap5 swap1 swap7 max
swap3 max
swap5 min
swap3 swap1 swap2 min
swap3 max
swap2 min
min
")
Dogway
14th July 2021, 20:40
It runs at 74fps, more or less like my post above, but I went and optimized it further (https://github.com/Dogway/Avisynth-Scripts/blob/791b96fd58522901bb376e4bc36dbdfe694eadd3/ExTools.avsi#L824)and now it runs at 87fps
I already profiled all the modes and should be running at optimal speeds, I'm not sure it's possible to squeeze more out of it. For ex_edge I don't think I will be doing anything, they run pretty fast already.
I tried to do some dup swap thing in some functions like ex_merge, ex_makeadddiff and so, but I don't think they improve performance, if any it kinda feel slower (minimal but still). For ex_binarize smooth mode it was a tie, not sure what to think but left it updated with the new syntax. Tomorrow I will profile GradePack (ex_contrast and ex_levels).
By the way, for anyone reading, rebased MIX/EX mods with latest ExTools.
wonkey_monkey
14th July 2021, 20:56
Try this. I got 25% more out of it than my previous one (note that it does NOT use OptSingleMode):
Expr("
x[-2,-2] x[-2,-1] dup1 dup1 min A^ max C^
x[-2,0] x[-2,1] dup1 dup1 min B^ max I^
x[-2,2] x[-1,-2] dup1 dup1 min D^ max S^
x[-1,-1] x[-1,0] dup1 dup1 min E^ max R^
x[-1,1] x[-1,2] dup1 dup1 min F^ max U^
x[0,-2] x[0,-1] dup1 dup1 min G^ max T^
x[0,0] x[0,1] dup1 dup1 min H^ max J^
x[0,2] x[1,-2] dup1 dup1 min K^ max L^
x[1,-1] x[1,0] dup1 dup1 min M^ max N^
x[1,1] x[1,2] dup1 dup1 min O^ max Q^
x[2,-2] x[2,-1] dup1 dup1 min P^ max W^
x[2,0] x[2,1] dup1 dup1 min V^ max X^
A D dup1 dup1 min A^ max D^
B P dup1 dup1 min B^ max P^
C S dup1 dup1 min C^ max S^
E M dup1 dup1 min E^ max M^
F V dup1 dup1 min F^ max V^
G K dup1 dup1 min G^ max K^
H O dup1 dup1 min H^ max O^
I W dup1 dup1 min I^ max W^
J Q dup1 dup1 min J^ max Q^
L T dup1 dup1 min L^ max T^
N R dup1 dup1 min N^ max R^
U X dup1 dup1 min U^ max X^
A E dup1 dup1 min A^ max E^
B H dup1 dup1 min B^ max H^
C N dup1 dup1 min C^ max N^
D M dup1 dup1 min D^ max M^
F G dup1 dup1 min F^ max G^
I O dup1 dup1 min I^ max O^
J P dup1 dup1 min J^ max P^
K V dup1 dup1 min K^ max V^
L U dup1 dup1 min L^ max U^
Q W dup1 dup1 min Q^ max W^
R S dup1 dup1 min R^ max S^
T X dup1 dup1 min T^ max X^
A F max F^
C L dup1 dup1 min C^ max L^
D G dup1 dup1 min D^ max G^
E K dup1 dup1 min E^ max K^
H Q dup1 dup1 min H^ max Q^
I J dup1 dup1 min I^ max J^
M V dup1 dup1 min M^ max V^
N T dup1 dup1 min N^ max T^
O P dup1 dup1 min O^ max P^
R U dup1 dup1 min R^ max U^
S X dup1 dup1 min S^ max X^
C H dup1 dup1 min C^ max H^
G J dup1 dup1 min G^ max J^
I L dup1 dup1 min I^ max L^
O x[2,2] dup1 dup1 min O^ max Y^
S V dup1 dup1 min S^ max V^
D I max I^
H K dup1 dup1 min H^ max K^
L M dup1 dup1 min L^ max M^
N O dup1 dup1 min N^ max O^
P V dup1 dup1 min P^ max V^
S U dup1 dup1 min S^ max U^
W Y dup1 dup1 min W^ max Y^
E N dup1 dup1 min E^ max N^
K Q dup1 dup1 min K^ max Q^
L P dup1 dup1 min L^ max P^
S Y dup1 dup1 min S^ max Y^
T W dup1 dup1 min T^ max W^
B E max E^
I L dup1 dup1 min I^ max L^
J T dup1 dup1 min J^ max T^
N R dup1 dup1 min N^ max R^
O S dup1 dup1 min O^ max S^
Q U dup1 dup1 min Q^ max U^
X Y min X^
E F max F^
G N dup1 dup1 min G^ max N^
J O dup1 dup1 min J^ max O^
K R dup1 dup1 min K^ max R^
M Q dup1 dup1 min M^ max Q^
S T dup1 dup1 min S^ max T^
U V min U^
W X min W^
C G max G^
F N dup1 dup1 min F^ max N^
H J dup1 dup1 min H^ max J^
M S dup1 dup1 min M^ max S^
P R dup1 dup1 min P^ max R^
Q T min Q^
U W min U^
F I max I^
G H max H^
J K dup1 dup1 min J^ max K^
L N dup1 dup1 min L^ max N^
O P dup1 dup1 min O^ max P^
R U min R^
H L max L^
I J max J^
K N dup1 dup1 min K^ max N^
M O dup1 dup1 min M^ max O^
P Q min P^
R S min R^
J M max M^
K L max L^
N O min N^
P R min P^
L M max
N P min
min
")
I think there is still some work to be done. I'll update my online tool at some point as it now inserts automatic pixel references (when it can) and also has a variable-ised output option.
wonkey_monkey
14th July 2021, 21:08
Made a couple of optimisations to the above post. I won't edit it further to avoid confusion.
Dogway
14th July 2021, 21:09
Yes I got like 2 or 3 more fps (82fps) vs mine (79fps, CPU now is in lazy state). It's like an optimized version of the variable syntax.
EDIT: woow so fast (your edit), now 94fps vs 85fps
EDIT2: I mainly use 5x5 sorting networks for median5 and adaptive, but I'm thinking on adding it also to weighted 50% percentile, because it kinda makes more sense there than 3x3, although output wasn't what I expected...
wonkey_monkey
14th July 2021, 21:58
I'm realising just now that although these sorting networks are optimised for sorting, they are not necessarily optimised for finding. My generator makes the best optimisation it can out of them (mathematically speaking), but it can lead to non-optimal results. This may only affect odd-numbered networks. I'll continue to investigate.
Dogway
14th July 2021, 22:35
Thanks for the effort. Probably there might be finding algos (https://www.geeksforgeeks.org/searching-algorithms/) around but I didn't research that. In any case you can use reverse elimination as we have been doing.
Dogway
19th July 2021, 14:52
@wonkey_monkey: I could achieve a 5% improvement in median5 by realizing that my median algo was the same than undot4 (clip to closest). This requires one less input for the sorting network.
I'm also adding vertical median, matching verticalcleaner mode=1.
"x[0,1] x[0,-1] dup1 dup1 max swap2 min x swap2 clip"
Didn't have much luck with mode=2 (source code reads intelligible for me). I tried to apply the description:
Let b1, b2, c, t1, t2 be a vertical sequence of pixels. The center pixel c is to be modified in terms of the 4 neighbours. For simplicity let us assume that b2 <= t1. Then in mode 1, c is clipped with respect to b2 and t1, i.e. c is replaced by max(b2, min(c, t1)). In mode 2 the clipping intervall is widened, i.e. mode 2 is more conservative than mode 1. If b2 > b1 and t1 > t2, then c is replaced by max(b2, min(c, max(t1,d1) )), where d1 = min(b2 + (b2 - b1), t1 + (t1 - t2)). In other words, only if the gradient towards the center is positive on both clipping ends, then the upper clipping bound may be larger. If b2 < b1 and t1 < t2, then c is replaced by max(min(b2, d2), min(c, t1)), where d2 = max(b2 - (b1 - b2), t1 - (t2 - t1)). In other words, only if the gradient towards the center is negative on both clipping ends, then the lower clipping bound may be smaller.
But didn't yield the expected result, so played with the expression a bit and got a close match.
x[0,2] T2^ x[0,1] T1^
x[0,-2] B1^ x[0,-1] B2^
B2 B1 > T1 T2 > & B2 B2 B1 - + T1 T1 T2 - + min T1 ? MA^
B2 B1 < T1 T2 < & B2 B1 B2 - - T1 T2 T1 - - max B2 ? MI^
x B1 MA min x T1 max max T1 MI max x min B2 max clip
Could you take a look at it? not sure where it might be failing. I will also add temporal median.
###################
On another note, I'm also developing a dot crawl dechecker filter. I will make use of your fantastic kernel here (https://forum.doom9.org/showthread.php?p=1751654#post1751654), but that will be the last discretion of three, SAD, spatial match and temporal match.
About SAD I'm not sure how to implement it, per block or per pixel.
Per pixel(?)
a=selectevery(1,0)
b=selectevery(1,-1)
Expr(a,b,"x[1,1] XA^ x[1,0] XB^ x[1,-1] XC^ x[-1,1] XD^ x[-1,0] XE^ x[-1,-1] XF^ x[0,1] XG^ x[0,-1] XH^
y[1,1] YA^ y[1,0] YB^ y[1,-1] YC^ y[-1,1] YD^ y[-1,0] YE^ y[-1,-1] YF^ y[0,1] YG^ y[0,-1] YH^
XA YA - abs XB YB - abs XC YB - abs XD YB - abs XE YE - abs XF YF - abs XG YG - abs XH YH - abs + + + + + + + ","")
EDIT: By the way mt_motion(last, thy1=0,thy2=255,tht=255,U=-128,V=-128) pretty much matches the next
thSAD=300 / 7.111
Expr(a,b,"x[1,1] XA^ x[1,0] XB^ x[1,-1] XC^ x[-1,1] XD^ x[-1,0] XE^ x[-1,-1] XF^ x[0,1] XG^ x[0,-1] XH^
y[1,1] YA^ y[1,0] YB^ y[1,-1] YC^ y[-1,1] YD^ y[-1,0] YE^ y[-1,-1] YF^ y[0,1] YG^ y[0,-1] YH^
XA YA - abs XB YB - abs XC YB - abs XD YB - abs XE YE - abs XF YF - abs XG YG - abs XH YH - abs + + + + + + + 8 / W@ 9 * {thSAD} scalef < 0 W ?","")
wonkey_monkey
19th July 2021, 16:48
I think you might have overlooked the part which says "For simplicity let us assume that b2 <= t1" although that whole description is pretty opaque to me.
Dogway
20th July 2021, 21:39
Thanks. Found a source I could read.
ExTools updated to v4.0.
-ex_median() new modes; vertical medians (ported from verticalcleaner), temporal medians (medianT and medianT5) and spatio-temporal medians (medianST, ML3D, ML3Dex, and BDM). Some modes overlap to Clense and MedianBlur.
-ex_kawase(), add logarithmic multipass
-ex_repair(), port half the modes from removegrain repair()
-ex_smooth(), 2 small bugfixes
Dogway
22nd July 2021, 17:18
ExTools updated to v4.1.
-ex_bilateral() new filter. Performs (much) slower than Dither_bilateral16() not sure why since it's just a few operators (Edit: yes, exp operator is uber slow, pow is slower though). Anyhow the output is cleaner and HBD native (and includes a dejaggie arg). Won't make a SmoothGrad filter unless the speed issue is solved.
-ex_median() new mode MMF. Fixed weightedp (for real)
Dogway
22nd July 2021, 23:38
ExTools updated to v4.2.
-ex_median() new modes; SixNN (6 Nearest-Neighbours), PML (Planar Multi-Level), and removegrain modes 26 and 27. I plan to implement Kalman motion estimation (if possible) to avoid using mvtools.
-ex_bilateral() optimized a bit, still runs at around 93fps mainly due to the exp operator.
I will be uploading to OP a comparison chart for all the modes in a few minutes.
tormento
23rd July 2021, 10:11
ExTools updated to v4.2.
Would you mind to create a greyscale mode for SMDegrain and, if needed, ExTools?
With old movies, where more intensive filtering is required, I tried some times ago to set plane=0, chroma=false but I had worst results, mostly with higher bitrate when encoding, than leaving on "color mode".
Boulder
23rd July 2021, 10:51
Greyscale() at the end of your script would do the same if those two parameters already bypass any chroma processing for speedups.
tormento
23rd July 2021, 13:39
Greyscale() at the end of your script would do the same if those two parameters already bypass any chroma processing for speedups.
Not so easy...
Dogway
23rd July 2021, 20:37
If the clip doesn't have colors then the UV planes should be mostly blank, so analyzing vectors from them looks like a bad idea.
At least for ExTools you can set UV=1 and chroma planes will be copied, I would need to check out SMDegrain but I think it does the same. I have yet to rework the Contrasharpening area, there are at least three methods for antiringing that I have to study, closely related to limiting so I also need to assess spatial and temporal limiting, it's not my forte so it will take some time.
real.finder
23rd July 2021, 21:06
If the clip doesn't have colors then the UV planes should be mostly blank, so analyzing vectors from them looks like a bad idea.
yes I told him this back then https://forum.doom9.org/showthread.php?p=1917477#post1917477
tormento
24th July 2021, 10:55
yes I told him this back then https://forum.doom9.org/showthread.php?p=1917477#post1917477
But I couldn't find a solution. Have some tries and tell me.
real.finder
24th July 2021, 11:06
But I couldn't find a solution. Have some tries and tell me.
remove UV with ConvertToY/ConvertToY8 after source call and you are safe and you should get more speed as well
Dogway
24th July 2021, 16:24
If the grain is very high solutions have been given before. You can try with this (https://forum.doom9.org/showthread.php?p=1911107#post1911107). It's the feature I've been long wanting to implement to SMDegrain.
Dogway
25th July 2021, 18:12
ExTools updated to v4.3.
-ex_kawase() fixed a stupid mistake and added 2 new modes, fibonacci and tribonacci sequence.
-ex_repair() implemented 4 temporal repair modes, this replaces TemporalRepair from RGTools which by the way, is broken.
GradePack updated to v2.5.
-ex_glow() new filter to add glow, 2 modes fibonacci and tribonacci, it's very slow, is not optimized, only for proof of concept.
I also updated OP with a ranking benchmarks of all the modes (ex_median, blurs and ex_edge). I want to upload also a comparison chart for all blend modes.
Dogway
27th July 2021, 00:17
ExTools updated to v4.4.
-ex_smartblur(). Filter for blurring similar to Photoshop's filter. Less gentle blur than ex_bilateral() but much faster.
-ex_median() new mode EMF (Extended Median Filter)
-ex_vinverse() removed the monolithic script and included into ExTools with some additional updates.
-ex_boxblur() updated "weighted" mode weights to use binomial coefficients. Now it should match ex_blur() (but faster) and removegrain(12), blur(), etc
QTGMC updated to v3.5 based on 3.382s
Practically same speed for 8-bits (even with Expr unsupported LUT based calculations) and about 15% to 20% more performant for HBD. See OP for benchmarks.
Changelog:
- Replaced masktools2 with Expr calls via ExTools pack wrappers (except mt_merge)
- Merged redundant expressions
- Replaced blurs and medians with ExTools equivalents
- Replaced Vinverse_avsi() with ex_vinverse() (HBD) and vinverse() (8bit)
- Removed Dither support
- Formatting and small optimizations
I also want to post a list of all the median filters I could find. They happen to be much more than I thought, so I'm not including them all, although people can help out if interested to make a good library, despite some of them protected under a paywall or not possible with Expr expressions (recursions, etc)
From all of them the ones I'm interested most are: IDBA, TSND, RAA, ADKI, and AUTMF.
Convolution algorithms:
# ATMF - Asymmetric Trimmed Median Filter
# SMF - Switching Median Filter
# WMF - Weighted Median Filter
# CWMF - Center Weighted Median Filter
# DWMF - Directional Weighted Median Filter
# MDWMF - Modified Directional Weighted Median Filter
# RWMF - Recursive Weighted Median Filter
# PSMF - Progressive Switching Median Filter
# SMF-BDND - Switching Median Filter with Boundary Discriminative Noise Detection
# BDSMF - Boundary Discriminative Switching Median Filtering
# DBF - Decision Based Filter
# DBA - Decision Based Algorithm Median Filter
# DBA2 - Decision Based Algorithm 2 Median Filter
# MDBUTMF - Modified Decision Based Un-symmetric Trimmed Median Filter
# DBUTMF - Decision Based Un-symmetric Trimmed Median Filter
# ACWMF - Adaptive Center Weighted Median Filter
# NID - New Impulse Detector
# AMF - Adaptive Median Filter
# FUF - Fuzzy Filter
# UF -
# ADKI - Adaptive Decision based Kriging Interpolation
# IMF - Improved adaptive Median Filter ( Ha et al. (2016))
# IAMF - Improved Adaptive Median Filtering ( (Wang and Li, 2010))
# SAMF - Selective Adaptive Median Filter
# MDBSMF - Multiple Decision Based Switching Median Filter
# TSMF/TSF - Tri-State Median Filter
# NTSMF - New Tri-State Switching Median Filter
# NASMF - Noise Adaptive Soft-switching Median Filter
# FRMF - Fuzzy Rule-based Median Filtering
# RAA - Removal of salt and pepper an Adaptive Approach
# IDBA - Improved decision based algorithm
# HFFLND - Hybrid Filter and Fuzzy Logic Noise Detector
# NSPF - New Salt and Pepper Filter. (Biswal and Bohi, 2013)
# FEMF - Fast and Efficient Median Filter
# AMF-LPD - Adaptive Median Filtering on Local Pixel Distribution
# SSMF - Sorted Switching Median Filter
# TSND - Two-Stage Noise Detector
# IEMF - Improved Extremum and Median value Filter
# ADPSMF - Absolute Difference based Progressive Switching Median Filter
# IMFA - Improved Median Filtering Algorithm
# MBDND - Modified Boundary Discriminative Noise Detection
# MSSMF - Multistate Switching Median Filter
# RVINE - Random Valued Impulse Noise Elimination
# RVINENF - Random Valued Impulse Noise Elimination using Neural Filter
# RVINENFF - Random Valued Impulse Noise Elimination using Neuro-Fuzzy Filter
# EPF - Edge Preserving Filter
# NBPPFT - Neural Based Post Processing Filtering Technique
# FTPHR - Filtering Technique for Preserving Homogeneous Region
# FTPHRAER - Filtering Technique for Preserving Homogeneous Region and Edge Region
# FTHCDI - Filtering Technique for Highly Corrupted Digital Images
# CNFT - Combined Neural based Filtering Technique
# FFBPAMNEM1- Feed Forward Back Propagation Algorithm for Multiple Noise Elimination Method 1
# FFBPAMNEM2- Feed Forward Back Propagation Algorithm for Multiple Noise Elimination Method 2
# ANFIS - Adaptive Neuro-fuzzy Inference System
# HNFF - Hybrid Neuro-Fuzzy Filter
# TSHNFF1 - Two Stage Hybrid Neuro-Fuzzy Filter 1
# TSHNFF2 - Two Stage Hybrid Neuro-Fuzzy Filter 2
# MNENFF1 - Multiple Noise Elimination using Neuro-Fuzzy Filter 1
# MNENFF2 - Multiple Noise Elimination using Neuro-Fuzzy Filter 2
# INEDI1 - Intelligent Network for Enhancing Digital Images 1
# INEDI2 - Intelligent Network for Enhancing Digital Images 2
# BF - Bilateral Filter
# FBF - Fuzzy Bilateral Filter
# INR - Impulse Noise Reduction
# FRINR - Fuzzy Random Impulse Noise Reduction
# FRINRM - Fuzzy Random Impulse Noise Reduction Method
# FIDRM - Fuzzy Impulse noise Detection and Reduction Method
# FIDRMC - Fuzzy Impulse noise Detection and Reduction Method for Color Images
# HFRMC - Histogram-based Fuzzy Restoration Method for Color Images
# FISF - Fuzzy Inference System Filter
# AUTMF - Adaptive Unsymmetrical Trim-Based Morphological Filter
# MMEM - Minimum-Maximum Exclusive Mean Filter
# DBA - Decision-Based Asymmetrical trimmed median filter
# FRF - Fuzzy Rank-ordered Filter
# LABSVMF - cieLAB Switching Vector Median Filter
# FCG - Fuzzy Color preserving Gaussian filter
# Non Linear (for RGB images)
# VMF - Vector Median Filter
# TVMF - Trimmed Vector Median Filter
# EVMF - Extended Vector Median Filter
# FMVMF - Fast Modified Vector Median Filter
# FSVF - Fast Similarity Vector Filter
# DVMF - Directional Vector Median Filter
# GVMF - Generalized Vector Median Filter
# RCVMF - Rank Conditioned Vector Median Filter
# RCTVMF - Rank Conditioning and Threshold Vector Median Filter
# CLMMF - Crossing Level Median Mean Filter
# VDF - Vector Directional Filter
# BVDF - Basic Vector Directional Filter
# GVDF - Generalized Vector Directional Filter
# DDF - Directional Distance Filter
# WVMF - Weighted Vector Median Filter
# TWVMF - Trimmed Weighted Vector Median Filter
# EXWVMF - Extended Weighted Vector Median Filter
# ROWVMF - Rank Order Weighted Vector Median Filter
# WVDF - Weighted Vector Directional Filters
# GA WVDF - Genetic Algorithm Weighted Vector Directional Filter
# CWVMF - Center-Weighted Vector Median Filter
# AVMF - Adaptive Vector Median filter
# ABVDF - Adaptive Basic Vector Directional Filter
# MSVMAF - Multiclass Support Vector Machine based Adaptive Filter
# ATCC - Adaptive Threshold and Color Correction
# RSVF/RSVMF- Robust Switching Vector Filter
# AMMF - Adaptive Marginal Median filter
# MSMF - Modified Switching Median Filter
# RSDDF - Robust Switching Directional Distance filter
# ACWVMF - Adaptive Center-Weighted Vector Median Filter
# ARWSF - Adaptive rank weighted switching filter
# PGA - Peer Group Averaging
# PGSF - Peer Group Switching Filter
# MPG - Modified Peer Group
# PGVF - Peer Group Vector Filter
# FPGF - Fast Peer Group Filters
# NPGF - Novel Peer Group Filter
# FWAF - Fuzzy Weighted Average Filter
# FVMF - Fuzzy Vector Median Filter
# FVDF - Fuzzy Vector Directional Filter
# FOVF - Fuzzy Ordered Vector Filter
# FHF - Fuzzy Hybrid Filter
# ANNF - Adaptive Nearest-Neighbor Filter
# ANNMF - Adaptive Nearest-Neighbor Multichannel Filter
# AHMF - Adaptive Hybrid Multichannel Filter
# FIDRM - Fuzzy Impulse Detection and Reduction Method
# VMRHF - Vector Median Rational Hybrid filter
# SAHVF - Structure-Adaptive Hybrid Vector Filter
# SWAV - Structure Weighted Average Filter
# SVMF - Sigma Vector Median Filter
# SBVDF - Sigma Basic Vector Directional Filter
# SDDF - Sigma Directional Distance Filter
# ASVMF - Adaptive Sigma Vector Median Filter
# ASBVDF - Adaptive Sigma Basic Vector Directional Filter
# ASDDF - Adaptive Sigma Directional Distance Filter
# ASVMF - Adaptive Sigma Vector Median Filter
# EVMF - Entropy Vector Median Filter
# QSF - Quaternion Switching Filter
# QVMF - Quaternion Vector Median Filter
# QSVMF - Quaternion Switching Vector Median Filter
Dogway
30th July 2021, 10:49
ExTools updated to v4.5.
-ex_median() ported spatio-temporal DeGrainMedian modes
-ex_repair() ported repair(16)
Logo updated to v12.0.
For some reason I couldn't load DeGrainMedian with MP_Pipeline win32 mode so I couldn't double check if the output matched, nor benchmark it against. The filter is slowish but I'm not sure how to optimize it further.
I also wanted to port GrapeSmooth but closed source it seems.
I'm also still porting Adaptive Sharpen, I came to a little halt so may ask later for some help.
real.finder
30th July 2021, 11:56
For some reason I couldn't load DeGrainMedian with MP_Pipeline
there are https://github.com/Asd-g/AviSynth-vsDeGrainMedian
kedautinh12
30th July 2021, 12:14
I also wanted to port GrapeSmooth but closed source it seems.
I'm also still porting Adaptive Sharpen, I came to a little halt so may ask later for some help.
Ask Asd-g for port from Vapoursynth
real.finder
30th July 2021, 12:21
Ask Asd-g for port from Vapoursynth
Adaptive Sharpen vs link? I didn't find it, they say that Adaptive Sharpen is better than CAS
Dogway
30th July 2021, 12:29
there are https://github.com/Asd-g/AviSynth-vsDeGrainMedian
woow, great, source is much more readable. Besides I got my algos wrong, I think I borked them at last minute trying to fix a stupid issue before uploading.
I'm porting this (https://forum.doom9.org/showthread.php?t=172131)Adaptive Sharpen. Currently I'm stuck at local minima and maxima.
Since I cannot do recursion in Expr I deployed a small script to determine what the string ends being, but it "crashes" (endless loop?). I'm looking into porting this version first, optimize, then port this (https://gist.github.com/igv/8a77e4eb8276753b54bb94c1c50c317e) further optimized version, and if possible adapt it to turn it into Adaptive Contrasharpen. Also I don't like how they want to sharpen in linear or sigmoid gamma, sharpen should be performed in gamma light.
Reference. (https://github.com/bacondither/Adaptive-sharpen/blob/0da6654e464c4136e3a68d80f5cd3bd7563762b9/shaders/Adaptive-sharpen%20-%20Pass%20two.hlsl#L204)
luma0 = "luma0 " luma12 = "luma12 "
luma1 = "luma1 " luma13 = "luma13 "
luma2 = "luma2 " luma14 = "luma14 "
luma3 = "luma3 " luma15 = "luma15 "
luma4 = "luma4 " luma16 = "luma16 "
luma5 = "luma5 " luma17 = "luma17 "
luma6 = "luma6 " luma18 = "luma18 "
luma7 = "luma7 " luma19 = "luma19 "
luma8 = "luma8 " luma20 = "luma20 "
luma9 = "luma9 " luma21 = "luma21 "
luma10 = "luma10 " luma22 = "luma22 "
luma11 = "luma11 " luma23 = "luma23 "
luma24 = "luma24 "
for (i = 0, 2, 1)
{
temp=""
for (j = 0, 23-i, 2)
{
jp = j+1
temp = Eval(Format("luma{j}"))
Eval(Format(""" luma{j} = + string(luma{j}) + string(luma{jp}) + " min " """))
Eval(Format(""" luma{jp} = + string(temp) + string(luma{jp}) + " max " """))
}
for (jj = 24-i, i+1, -2)
{
temp = Eval(Format("luma{i}"))
Eval(Format(""" luma{i} = + string(luma{i}) + string(luma{jj}) + " min " """))
Eval(Format(""" luma{jj} = + string(temp) + string(luma{jj}) + " max " """))
jl = 24-i
js = jj-1
temp = Eval(Format("luma{jl}"))
Eval(Format(""" luma{jl} = + string(luma{jl}) + string(luma{js}) + " max " """))
Eval(Format(""" luma{js} = + string(temp) + string(luma{js}) + " min " """))
}
}
subtitle(last,luma1,size=10)
CAS is unsharp mask based as many other sharpeners, they mainly differ on how to avoid ringing, Adaptive Sharpen is another sharpening flavour. At some point I will try to compare all of them and do some evaluation. There's also Smart Sharp, qUINT sharp, NLM Sharp, there are some interesting *.mp4 guy sharpeners as well and I don't forget Plum by feisty2.
kedautinh12
30th July 2021, 12:32
Adaptive Sharpen vs link? I didn't find it, they say that Adaptive Sharpen is better than CAS
Sr, i think it's Vapoursynth filter
real.finder
30th July 2021, 12:42
Dogway, maybe it's better to make it a plugin? you can make it only with C/C++ code and then asked another person to add optimized asm code for speed up if you can't do asm codes
Dogway
30th July 2021, 13:14
Updated DeGrainMedian modes. Actually it wasn't my fault, I really have to go through hoops to make the algos work with the variables bugs.
Yes, plugin should be really easy for people into C, mostly 1:1 port. I'm also doing this for learning though (ex mods) and library, while mix mods are speed oriented. I'm not sure if after 6 years nobody tackled Adaptive Sharpen, it might be lack of interest or maybe hard to implement, I don't know. In any case if you want to go HD or UHD sharpening you might need to apply high sigma blurs which are only fast on frequency domain, I doubt scaling down, blur (kawase?) then up is faster than that.
real.finder
30th July 2021, 13:35
feisty2 said that new c++ is easy like scripting, maybe you can try use last c++ with GCC and C api of avs/avs+
Dogway
30th July 2021, 13:43
Yes, I have that in the back of my mind. GCC is lightweight, anyway I don't think writing asm is easy.
Actually I just wanted to make a few filters ExTools and TransformsPack and get going since I have an VR I bought 2 months ago and still haven't barely opened (need to install Win10/11, blabla, sloth).
tormento
31st July 2021, 12:17
remove UV with ConvertToY/ConvertToY8 after source call and you are safe and you should get more speed as well
My script:
SetMemoryMax()
SetFilterMTMode("DEFAULT_MT_MODE", 2)
LoadPlugin("D:\Eseguibili\Media\DGDecNV\DGDecodeNV.dll")
DGSource("F:\In\1_44 Harvey\harvey.dgi",ct=0,cb=0,cl=232,cr=232)
ConvertToY()
SMDegrain (tr=4, thSAD=400, trymany=true, refinemotion=true, contrasharp=false, PreFilter=4, truemotion=true, plane=0, chroma=false)
Prefetch(6)
Error:
Script error: syntax error
(D:/Programmi/Media/AviSynth+/plugins64/ExTools-4.5b~Dogway.avsi, line 1246, column 0)
(F:\In\1_44 Harvey\harvey_Y16.avs, line 3)
(F:\In\1_44 Harvey\harvey_Y16_temp\harvey_Y16_source.avs, line 1)
ExTools4.5b is buggish. With 4.4 it works ok.
P.S: How can I get the equivalent of color 16 bit on 4:0:0? 8 bit is enough for greyscale?
Dogway
1st August 2021, 00:19
Thanks, updated, it was a stupid typo.
You can improve denoising with HBD.
ConvertToY()
Convertbits(16)
By the way, the above iterator sample was as expected a sorting algo, so good to know another tool for the toolbox. The error dialog was for subtitle(), instead I wrote out the output to a file. Now Adaptive Sharpen is in debug phase.
vBulletin® v3.8.11, Copyright ©2000-2026, vBulletin Solutions Inc.