Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage

Reply
 
Thread Tools Search this Thread Display Modes
Old 9th September 2004, 23:02   #1  |  Link
Vectrangle
Registered User
 
Join Date: Sep 2004
Location: Byron Bay, Australia
Posts: 20
FastLineDarken() - the name says it all

- it's fast (yv12lutxy is godly, thank you!)
- it darkens lines
- it thins lines (optional, slower) <-- new in 1.3
- it doesn't ever touch edges, owing to a nifty little line masking method that occurred to me a few days ago, all you have to do is subtract(expand.inpand)

Motivation for this function was that someone told me they used mftoon for line darkening, which is like using a tank to take your kids to school... it's overkill, it's slow, and it has nasty side effects So I wrote this little function as a better faster alternative

EDIT: Updated post to include latest version

Here is a download link (right click -> save as), or you can copy/paste the code into a file yourself:

Code:
######################
# FastLineDarken 1.3 #
######################
#
# Written by Vectrangle, last update 12 Sept 04
#
#  * requires masktools 1.5.1 -- http://jourdan.madism.org/~manao/
#  * requires yv12 input
#
# Usage is FastLineDarken(strength, luma_cap, threshold, thinning),
#   named parameters are supported eg FastLineDarken(thinning=0)
# 
# Note that you must import this avs into your script using import("...\FastLineDarken 1.3.avs")
#
# Parameters are:
#  strength (integer)  - Line darkening amount, 0-256. Default 48. Represents the _maximum_ amount
#                        that the luma will be reduced by, weaker lines will be reduced by
#                        proportionately less.
#  luma_cap (integer)  - value from 0 (black) to 255 (white), used to stop the darkening
#                        determination from being 'blinded' by bright pixels, and to stop grey
#                        lines on white backgrounds being darkened. Any pixels brighter than
#                        luma_cap are treated as only being as bright as luma_cap. Lowering
#                        luma_cap tends to reduce line darkening. 255 disables capping. Default 191.
#  threshold (integer) - any pixels that were going to be darkened by an amount less than
#                        threshold will not be touched. setting this to 0 will disable it, setting
#                        it to 4 (default) is recommended, since often a lot of random pixels are
#                        marked for very slight darkening and a threshold of about 4 should fix
#                        them. Note if you set threshold too high, some lines will not be darkened
#  thinning (integer)  - optional line thinning amount, 0-256. Setting this to 0 will disable it,
#                        which is gives a _big_ speed increase. Note that thinning the lines will
#                        inherently darken the remaining pixels in each line a little. Default 24.
#
# Changelog:
#  1.3  - added ability to thin lines, now runs much slower unless thinning=0. Changed the defaults (again)
#  1.2  - huge speed increase using yv12lutxy =)
#       - weird darkening issues gone (they were caused by yv12layer)
#       - show option no longer available due to optimizations. Use subtract() instead
#  1.1  - added luma_cap option
#  1.0  - initial release
#


function FastLineDarken( clip c, int "strength", int "luma_cap", int "threshold", int "thinning") {
	str = string(default(strength, 48) /128.)
	lum = string(default(luma_cap, 191))
	thr = string(default(threshold, 4))
	thinning = default(thinning,24)
	thn = string(thinning /16.)
	exin=c.expand().inpand()
	diff = yv12lutxy(c,exin,yexpr="y "+lum+" < y "+lum+" ? x "+thr+" + > x y "\
		+lum+" < y "+lum+" ? - 0 ? 127 +",uexpr="x",vexpr="x")
	linemask = yv12lut(diff.inpand(),"x 127 - "+thn+" * 255 +")\
		.yv12convolution("1 1 1","1 1 1",y=3,u=0,v=0)
	thick = yv12lutxy(c, exin, yexpr="y "+lum+" < y "+lum+" ? x "+thr+" + > x y "\
		+lum+" < y "+lum+" ? - 0 ? "+str+" * x +",uexpr="x",vexpr="x")
	thin = yv12lutxy(c.expand(),diff,yexpr="x y 127 - "+str+" 1 + * +")
	return (thinning == 0) ? thick : maskedmerge(thin,thick,linemask,y=3,u=2,v=2)
}
Enjoy! Comments appreciated

Last edited by Vectrangle; 12th September 2004 at 11:54.
Vectrangle is offline   Reply With Quote
Old 10th September 2004, 00:40   #2  |  Link
Zarxrax
Registered User
 
Zarxrax's Avatar
 
Join Date: Dec 2001
Location: Concord, NC
Posts: 1,168
Very nice filter! I never used mftoon both because of the slow speed and I don't like the look it gives the video. This is a VERY good solution for darkening lines in anime! Thank you!
Zarxrax is offline   Reply With Quote
Old 10th September 2004, 01:56   #3  |  Link
Vectrangle
Registered User
 
Join Date: Sep 2004
Location: Byron Bay, Australia
Posts: 20
Glad you like it! I did the easy part though -- most of the credit should go to kurosu and Manao for writing masktools, I couldn't have done it without that excellent (even if slightly buggy) plugin ^^ Also I owe thanks to Didee for thinking up yv12lutxy, and inspiring me to use it when I read through LimitedSharpen for ideas

Btw luma_cap is an experimental parameter, I'm not sure what a 'good' default value would be, which is why I left it at 255. For myself I'm using FastLineDarken(50,190) but I'll haven't played around with it much yet.

also in the comments where I suggest using subtract(fastlinedarken).levels(0,0.2,127,0,255,false), I should have said:
fastlinedarken.subtract(last).levels(0,0.2,127,0,255,false)

this should give you a good idea of which parts of the frame were darkened. (try doing this and then setting threshold to 0, and you'll see why I had to add the threshold option in ^^)

My favourite part about avisynth scripting is the times when the more I work on solving a problem, the shorter and simpler my script becomes, FastLineDarken is a good example
Vectrangle is offline   Reply With Quote
Old 10th September 2004, 16:40   #4  |  Link
Paced
Registered User
 
Join Date: Dec 2003
Posts: 194
Wow, nice work Vectrangle, this is exactly what I was looking for, and it works like a charm
Paced is offline   Reply With Quote
Old 11th September 2004, 02:12   #5  |  Link
Vectrangle
Registered User
 
Join Date: Sep 2004
Location: Byron Bay, Australia
Posts: 20
Yeah so far everyone I've shown it to seems to appreciate it

Can anyone suggest any improvements? I can't personally, I think it's good the way it is now. It's such a simple little script there's not really a whole lot to improve anyway

So, time to move on to my next project
Vectrangle is offline   Reply With Quote
Old 11th September 2004, 09:00   #6  |  Link
AS
Registered User
 
Join Date: Jan 2002
Posts: 76
Improvement? Sure. This filter also thickens the edges, so it'd be nice to be able to thin the edges again without using warpsharp (warpsharp modifies the whole frame).
AS is offline   Reply With Quote
Old 11th September 2004, 18:21   #7  |  Link
Vectrangle
Registered User
 
Join Date: Sep 2004
Location: Byron Bay, Australia
Posts: 20
hmm I assume you mean lines, rather than edges? In theory fastlinedarken should never touch edges, and this has been true in practice for me too.

FastLineDarken doesn't really 'thicken' the edges per se, since it only darkens parts that are already dark, however this does give an overal visual appearance of a thicker line.

If you wanted the lines to have the same amount of 'visual impact' as the original, you would want to darken _and_ thin (ideally the average luma of the image should remain the same, I think). As I said in my first post mftoon can do this but FastLineDarken highly simplified algorithm cannot.

Personally I never saw it as a problem because I didn't see the point in thinning lines, but I'm quite new to serious encoding (I have mucked around a tiny bit with encoding over the last couple years, but I only _really_ got into it a couple weeks ago) and am open to new ideas ^^ So since you have requested it I will see if I can add this functionality, but without compromising the speed for those users wishing only to darken (since I think thinning will be a lot slower).

I'll get back to you tomorrow... just got back from a party and need to sleep. Thanks for the suggestion though, I always enjoy a new challenge
Vectrangle is offline   Reply With Quote
Old 11th September 2004, 22:49   #8  |  Link
AS
Registered User
 
Join Date: Jan 2002
Posts: 76
Hi, I want to apologise if I sounded rude and unenthusiastic. I actually like this alot and will probably use it in all my encode from now on. Thanks

Quote:
hmm I assume you mean lines, rather than edges?
Well, it's actually more common to coin it as ' edges ' rather than 'lines'. But that's minor terminology we don't need to concern about. Yes, we're talking about the same thing

I deliberately taken these pics at strength =256 to exaggerate the differences.

Original




filtered




Looking at the edges on the shirts, I think they're (slightly) thickened.


Quote:
Personally I never saw it as a problem because I didn't see the point in thinning lines...
Indeed, most of the time it's quite beneficial. But because now it's actually darkened, those slight imperfection -- those jags along the edge -- is also amplified.In this case, a very low thinning would disguise this.

However, these are quite minor and indeed I agree with most of what you said.

While looking around, I found potentially a bigger problem:

original




filtered




Look at the third strip/belt, slightly right and down a bit from middle of the pic, you will see two white lines with a very thin gap in between. After applying the filter, it gets treated as an edge and darkened!

While the cap is taken at strength = 256, the problem does persist but does depending on strength. At default strength, the effect is quite minimal and can be forgotten.

So all in all, if you ever got around doing the edge thinning part,it might be preferrable as a standalone filter, as it might come handy for other purpose as well (ie, side-effects that are benefitial)

Last edited by AS; 11th September 2004 at 22:51.
AS is offline   Reply With Quote
Old 11th September 2004, 23:44   #9  |  Link
Vectrangle
Registered User
 
Join Date: Sep 2004
Location: Byron Bay, Australia
Posts: 20


Quote:
Originally posted by AS Hi, I want to apologise if I sounded rude and unenthusiastic.
Not at all, the more problems you can find, the better! That's the great thing about sharing your script with others, someone will always see things that you didn't

However I think the issues you had can be aleviated significantly by tweaking the other parameters! My recommended values in my comments were only after brief testing, so please play around with them

Quote:
Looking at the edges on the shirts, I think they're (slightly) thickened.
Using strength=255 is an excellent idea, you can clearly see what the filter is doing. What happens is that any dot (unfortunately my method thinks dots are lines too) or part of a line that is only _slightly_ darker than surrounds will be darkened too, but only slightly (in proportion to how much darker they are). Normally this wouldn't be noticed, but with such a huge strengthing it becomes obvious that the slightly darker pixels that occur either side of a line, and normally not considered part of the line by your eye (in the original picture) are darkened, thus thickening the line. also you can see that some noise specks are darkened too.

This is what the threshold parameter is for! It will ignore these pixels that are only slightly darker. Try turning it up to 10 or even higher, and see how it goes. In my comments in the script I say to leave it at 1, but clearly I was wrong! (although if you try it you will see that threshold=1 is a lot better than threshold=0)

[EDIT]After a quick test I realized 10 is probably too high, as it stops darkening some of the weaker lines. I think a threshold of around 4, with some line thinning, will ultimately be the best option. Please play around with threshold and tell me what you think

Quote:
Indeed, most of the time it's quite beneficial. But because now it's actually darkened, those slight imperfection -- those jags along the edge -- is also amplified.In this case, a very low thinning would disguise this.
I'm working on the thinning idea, but it's a much more complicated process than darkening I did find a quick and cheap little thinning method, but I'm not sure how well it will work. I'll post it later for you to test

Quote:
Look at the third strip/belt, slightly right and down a bit from middle of the pic, you will see two white lines with a very thin gap in between. After applying the filter, it gets treated as an edge and darkened!
Aha! This is a problem I forsaw already, even though I hadn't seen an actual example of it until you found this one (pats self on back ^^). My fear that this would occur is the reason I added the luma_cap parameter, if you lower luma_cap then your problem should go away

Quote:
So all in all, if you ever got around doing the edge thinning part,it might be preferrable as a standalone filter, as it might come handy for other purpose as well (ie, side-effects that are benefitial)
I will probably include just a 'quick and simple' thinning algorithm into FastLineDarken, that can be turned on through a parameter, and then work on making a more accurate (and definately slower) line thinner for stand alone use.

So yeah to summarize, try increasing threshold and lowering luma_cap, and if you find good values for both please post them

Last edited by Vectrangle; 11th September 2004 at 23:55.
Vectrangle is offline   Reply With Quote
Old 12th September 2004, 01:07   #10  |  Link
Vectrangle
Registered User
 
Join Date: Sep 2004
Location: Byron Bay, Australia
Posts: 20
Ahh well, the idea I had for a method of 'quick' line thinning sucked IMO. It doesn't thin much, and looks to me like it creates a little haloing in some places (not very noticable, but still bad).

You're welcome to try it out though, maybe it doesn't suck as much as I think:
Code:
Removed, due to release of 1.3 with better algorithm :)
The good news is at least that with thinning set to 0 it runs at essentially the same speed as before (in theory anyway)

Last edited by Vectrangle; 12th September 2004 at 03:51.
Vectrangle is offline   Reply With Quote
Old 12th September 2004, 04:06   #11  |  Link
Vectrangle
Registered User
 
Join Date: Sep 2004
Location: Byron Bay, Australia
Posts: 20
Yay, I found a much better way to thin the lines! Took me a while to implement and speed optimize it, but it's all done and version 1.3 is released (I edited my original post, please get it from there)

The thinning algorithm is relatively complicated compared to just darkening, so unfortunately the script runs a fair bit slower (but still much faster than mftoon of course ). However if all you want to do is darken, then setting thinning=0 will still run at the same speed as before

Please test it out and tell me what you think, in the mean time here's a quick comparison:


(btw the blurryness of my source is because it's recovered from a field blended PAL dvd, I don't have any NTSC dvds -_-)
Vectrangle is offline   Reply With Quote
Old 12th September 2004, 08:27   #12  |  Link
AS
Registered User
 
Join Date: Jan 2002
Posts: 76
Hi, the thinning part works great, just as expected

Thanks
AS is offline   Reply With Quote
Old 13th September 2004, 06:09   #13  |  Link
ChronoCross
Does it really matter?
 
ChronoCross's Avatar
 
Join Date: Jun 2004
Location: Chicago, IL
Posts: 1,542
interesting script. fast and does what it says it does. Excellent work. I will give it a try on quite a few different anime's and report back if I find any errors.
ChronoCross is offline   Reply With Quote
Old 13th September 2004, 08:31   #14  |  Link
Vectrangle
Registered User
 
Join Date: Sep 2004
Location: Byron Bay, Australia
Posts: 20
Thanks for the feedback

However it was just pointed out to me that the thinning algorithm doesn't thin all parts of the lines by the same amount, and it's especially apparant on thin lines. Also sometimes it gets 'confused' and thinks some dark areas are the edge of a line that actually aren't, and will lighten them.

So yeah be careful of that, and try to keep the thinning parameter low, or use none at all, ie FastLineDarken(thinning=0)

I'm working on a better way of thinning that doesn't have these problems , I'll post again when I have it worked out
Vectrangle is offline   Reply With Quote
Old 14th September 2004, 01:05   #15  |  Link
ChronoCross
Does it really matter?
 
ChronoCross's Avatar
 
Join Date: Jun 2004
Location: Chicago, IL
Posts: 1,542
I had a question. since I don't really have too many good non anime dVD's would someone like to test this on non-anime sources and see what it does? Just curious. Thanks
ChronoCross is offline   Reply With Quote
Old 15th September 2004, 06:08   #16  |  Link
Vectrangle
Registered User
 
Join Date: Sep 2004
Location: Byron Bay, Australia
Posts: 20
It would probably do very little and any effects it did have would look weird :P
Vectrangle is offline   Reply With Quote
Old 24th February 2005, 18:09   #17  |  Link
cypher_soundz
Gold Member
 
cypher_soundz's Avatar
 
Join Date: Jan 2002
Location: United Republic Of Cypher_Soundz (U_ROC)...hehehe
Posts: 647
Trying to use this script gives me a layer of green. Any idea what i'm doing wrong?
[EDIT]
I'm playing the avs script in media player classic.
[/EDIT]


Script:
Code:
# PLUGINS
LoadPlugin("C:\PROGRA~1\Autorv10\SOFTS\AVSFILE\DGDECODE.DLL")
LoadPlugin("C:\PROGRA~1\Autorv10\SOFTS\AVSFILE\deen.DLL")
LoadPlugin("C:\PROGRA~1\Autorv10\SOFTS\AVSFILE\asharp.DLL")
LoadPlugin("C:\PROGRA~1\GordianKnot\AviSynthPlugins\decomb.dll")
LOadPlugin("Masktools.dll")
import("FastLineDarken.avs")
#
# LIMIT MEMORY USE
SetMemoryMax(768)
#
# VIDEO SOURCE
Mpeg2Source("D:\street fighter\SF2.d2v", cpu=4)
FieldDeinterlace()

crop(12,62,688,432,true)
#

deen("a2d",2,5,5)
deen("a3d",1,5,5)

LanczosResize(640,368)

asharp(1,2.5)


FastLineDarken()
Masktools verison:

Regards
cyph
__________________
http://img207.echo.cx/img207/2203/cyphtag0eg.gif
I Love it when a plan comes together!

cypher_soundz


Windows XP| 2GB ECC DDR 2100 ram| 160gb WD 7200rpm 40gb seagate 7200rpm |40gb seagate 7200rpm | Dual 2400MP X1 ;) [L5 mod]| MSI K7D| ATI radeon 9800 PRO 128MB tv-out/dv-out | Hauppauge WinTV PVR 350| Samsung dvd (firmware:612-B) | NEC 1300 dvd+r



.

Last edited by cypher_soundz; 24th February 2005 at 18:28.
cypher_soundz is offline   Reply With Quote
Old 24th February 2005, 21:47   #18  |  Link
Manao
Registered User
 
Join Date: Jan 2002
Location: France
Posts: 2,856
The script on this page isn't correct : everytime yv12lutxy is used, you have to add the parameters : u=2, v=2

Also, you can update your masktools version to the latest : 1.5.6, which you can get there : http://manao4.free.fr/
Manao is offline   Reply With Quote
Old 25th February 2005, 13:40   #19  |  Link
cypher_soundz
Gold Member
 
cypher_soundz's Avatar
 
Join Date: Jan 2002
Location: United Republic Of Cypher_Soundz (U_ROC)...hehehe
Posts: 647
Great thankyou Manao everything is working fine now.
I will update masktools also, . thankyou for the help.

I will post the edited version below incase some one wants to use
Code:
######################
# FastLineDarken 1.3 #
######################
#
# Written by Vectrangle, last update 12 Sept 04
#
#  * requires masktools 1.5.1 -- http://jourdan.madism.org/~manao/
#  * requires yv12 input
#
# Usage is FastLineDarken(strength, luma_cap, threshold, thinning),
#   named parameters are supported eg FastLineDarken(thinning=0)
# 
# Note that you must import this avs into your script using import("...\FastLineDarken 1.3.avs")
#
# Parameters are:
#  strength (integer)  - Line darkening amount, 0-256. Default 48. Represents the _maximum_ amount
#                        that the luma will be reduced by, weaker lines will be reduced by
#                        proportionately less.
#  luma_cap (integer)  - value from 0 (black) to 255 (white), used to stop the darkening
#                        determination from being 'blinded' by bright pixels, and to stop grey
#                        lines on white backgrounds being darkened. Any pixels brighter than
#                        luma_cap are treated as only being as bright as luma_cap. Lowering
#                        luma_cap tends to reduce line darkening. 255 disables capping. Default 191.
#  threshold (integer) - any pixels that were going to be darkened by an amount less than
#                        threshold will not be touched. setting this to 0 will disable it, setting
#                        it to 4 (default) is recommended, since often a lot of random pixels are
#                        marked for very slight darkening and a threshold of about 4 should fix
#                        them. Note if you set threshold too high, some lines will not be darkened
#  thinning (integer)  - optional line thinning amount, 0-256. Setting this to 0 will disable it,
#                        which is gives a _big_ speed increase. Note that thinning the lines will
#                        inherently darken the remaining pixels in each line a little. Default 24.
#
# Changelog:
#  1.3  - added ability to thin lines, now runs much slower unless thinning=0. Changed the defaults (again)
#  1.2  - huge speed increase using yv12lutxy =)
#       - weird darkening issues gone (they were caused by yv12layer)
#       - show option no longer available due to optimizations. Use subtract() instead
#  1.1  - added luma_cap option
#  1.0  - initial release
#


function FastLineDarken( clip c, int "strength", int "luma_cap", int "threshold", int "thinning") {
	str = string(default(strength, 48) /128.)
	lum = string(default(luma_cap, 191))
	thr = string(default(threshold, 4))
	thinning = default(thinning,24)
	thn = string(thinning /16.)
	exin=c.expand().inpand()
	diff = yv12lutxy(c,exin,yexpr="y "+lum+" < y "+lum+" ? x "+thr+" + > x y "\
		+lum+" < y "+lum+" ? - 0 ? 127 +",uexpr="x",vexpr="x",u=2, v=2)
	linemask = yv12lut(diff.inpand(),"x 127 - "+thn+" * 255 +")\
		.yv12convolution("1 1 1","1 1 1",y=3,u=0,v=0)
	thick = yv12lutxy(c, exin, yexpr="y "+lum+" < y "+lum+" ? x "+thr+" + > x y "\
		+lum+" < y "+lum+" ? - 0 ? "+str+" * x +",uexpr="x",vexpr="x",u=2, v=2)
	thin = yv12lutxy(c.expand(),diff,yexpr="x y 127 - "+str+" 1 + * +",u=2, v=2)
	return (thinning == 0) ? thick : maskedmerge(thin,thick,linemask,y=3,u=2,v=2)
}
Regards
cyph
__________________
http://img207.echo.cx/img207/2203/cyphtag0eg.gif
I Love it when a plan comes together!

cypher_soundz


Windows XP| 2GB ECC DDR 2100 ram| 160gb WD 7200rpm 40gb seagate 7200rpm |40gb seagate 7200rpm | Dual 2400MP X1 ;) [L5 mod]| MSI K7D| ATI radeon 9800 PRO 128MB tv-out/dv-out | Hauppauge WinTV PVR 350| Samsung dvd (firmware:612-B) | NEC 1300 dvd+r



.

Last edited by cypher_soundz; 25th February 2005 at 13:42.
cypher_soundz is offline   Reply With Quote
Old 25th February 2005, 17:11   #20  |  Link
Prettz
easily bamboozled user
 
Prettz's Avatar
 
Join Date: Sep 2002
Location: Atlanta
Posts: 373
This filter looks like it could really help the anime Metropolis, which has extremely problematic cel borders. I'll test it as soon as I have time (which won't be soon, unfortunately).
Prettz is offline   Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 14:30.


Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.