Log in

View Full Version : RGBAdapt v0.5 plugin 06 Dec 2018


Pages : 1 2 [3] 4

StainlessS
2nd September 2016, 07:09
Nice job Bernardd.

How did you deal with the subtitled text on the images ?
Some of Fred's images have similar Subtitles which make it impossible to exactly re-create the final images (you have to crop off the nuisance text
so as not to affect results, but then have different image).
To make things worse, you add more subtitles to the images, meaning more to crop off and less like original.
Can I suggest that you add black bar top or bottom and subtitle over that, so can easily be cropped leaving original intact.

It does not look like you treated the subtitles in any way special, so maybe that threw off your corrections a little (perhaps).

EDIT: Also would be nice if images were Portable Network Graphics, png format rather than jpg, so we have the exact image that
you worked with.

StainlessS
2nd September 2016, 10:02
Here, tiny function to add sub to clip, demo'ed using GamMac script.


#Imagesource("Avenue.png",end=0)
#Imagesource("BlueFish.png",end=0)
Imagesource("ClimbingFrame.png",end=0)
#Imagesource("Cup&Saucer.png",end=0)
#Imagesource("Deer.png",end=0)
#Imagesource("Elephants.png",end=0)
#Imagesource("Fish.png",end=0)
#Imagesource("GreenChurch.png",end=0)
#Imagesource("Lenna.png",end=0)
#Imagesource("LollipopLady.png",end=0)
#Imagesource("Parrot.png",end=0)
#Imagesource("Pool.png",end=0)
#Imagesource("Puppy.png",end=0)
#Imagesource("PyramidSkier.png",end=0)
#Imagesource("Singers.png",end=0)
#Imagesource("Tahiti.png",end=0)
#Imagesource("TajMahal.png",end=0)
#Imagesource("Train.png",end=0)
#Imagesource("Unwrapping.png",end=0)
#Imagesource("WalkInThePark.png",end=0)
#Imagesource("Matt_Greece_001.png",end=0)
#Imagesource("Matt_Greece_002.png",end=0)
#Imagesource("Matt_Greece_004.png",end=0)
#Imagesource("Matt_Greece_005.png",end=0)
#Imagesource("Matt_Greece_007.png",end=0)
#Imagesource("Matt_Greece_009.png",end=0)


Function Sub(clip c,string tit) {Return StackVertical(c,c.Blankclip(Height=20).SubTitle(tit))}

ConvertToRGB24

O=Last
LockChan = 1 # Chan for lock to Ave, 0=R, 1=G, 2=B
# -1 = Use LockVal below.
# -2 = LockVal=(RedAve+GrnAve+BluAve)/3.0 for LockVal.
# -3 = LockVal=Median(RedAve,GrnAve,BluAve)
Scale=1
RedMul = 1.0 # Required Ave multiplier for Red Channel, applied when requesting GuessGamma(reqAve*RedMul),
# Even applied when LockChan=-1.
GrnMul = 1.0 # Same for Green channel. GrnMul even applies when LockChan is Green Channel, etc for chans.
BluMul = 1.0 # Same for Blue channel. Allows tinkering/fine tuning.
th = 0.0
LockVal = 8.0 # Only valid if LockChan == -1
RngLim = 10.0
GamMax = 10.0
Show = False # Subtitles
Verb = 3

x=0
y=0
w=0
h=0

Scale=0
A=GamMac(LockChan=LockChan,LockVal=LockVal,RedMul=RedMul,GrnMul=GrnMul,BluMul=BluMul,Show=Show,Verbosity=Verb,Th=Th,SCALE=SCALE,
\ RngLim=RngLim,GamMax=GamMax,x=x,y=y,w=w,h=h)

#RedMul = 0.6 Grnmul = 0.7 blumul = 0.8
Scale=1
B=GamMac(LockChan=LockChan,LockVal=LockVal,RedMul=RedMul,GrnMul=GrnMul,BluMul=BluMul,Show=Show,Verbosity=Verb,th=th,SCALE=Scale,
\ RngLim=RngLim,GamMax=GamMax,x=x,y=y,w=w,h=h)

#RedMul = 0.5 Grnmul = 0.6 blumul = 1.1
Scale=2
C=GamMac(LockChan=LockChan,LockVal=LockVal,RedMul=RedMul,GrnMul=GrnMul,BluMul=BluMul,Show=Show,Verbosity=Verb,th=th,SCALE=Scale,
\ RngLim=RngLim,GamMax=GamMax,x=x,y=y,w=w,h=h)

TOP=StackHorizontal(Sub(O,"Original"),Sub(A,"Scale 0"))
BOT=StackHorizontal(Sub(B,"Scale 1"),Sub(C,"Scale 2"))
StackVertical(TOP,BOT)
return Last


https://s20.postimg.cc/6oi93qt19/climb_zpsqisfjser.png (https://postimg.cc/image/6bquxkard/)
Subtitled black bar is 20 pixels tall at bottom of frame.


Here, zip (~6MB) with script + about 26 png's, posted in this and other threads. http://www.mediafire.com/download/rdk5du4h3c114z4/GamMacSubs.zip

All pics with Subtitles cropped off (I did not bother including images with multiple subtitles).

Bernardd
2nd September 2016, 11:36
Hello StainlessS

Do you know Rt_Stats plugin is very very powerfull ? :thanks:

I use scrutinized aera to pass through subtitle

Thanks for your tip with BlankClip and Subtitle, but now it is same fast with AddBorder.

Three pictures to illustrate the new call script, that is posted after

http://img110.xooimage.com/files/6/b/9/grece1-aera-504afaa.png (http://letransfert.soforums.com/image/110/6/b/9/grece1-aera-504afaa.png.htm)

http://img110.xooimage.com/files/8/0/4/grece1-504b140.png (http://letransfert.soforums.com/image/110/8/0/4/grece1-504b140.png.htm)

http://img110.xooimage.com/files/7/0/f/grece2-504b00c.png (http://letransfert.soforums.com/image/110/7/0/f/grece2-504b00c.png.htm)

Bernardd
2nd September 2016, 11:39
Below the call script with subtitle not on picture


AVISource("C:\........\your_video.avi")
LoadPlugin("C:\.........\GRunT.dll")
LoadPlugin("C:\.........\RGBAdapt.dll")
LoadPlugin("C:\.........\RT_Stats26.dll")

# display tunings
comparison = true
show_scrutinized = true
show_info = false

# color space matrix tuning and specify the source rectangle under scrutiny
matrix = "Rec601"
x = 0.09
Y= 0.09
w = 0.09
h = 0.09

# autogain tunings
threshold = 0.10
autogain = true

# autocontraste tunings
autocont_strength = 1.0
luma_chroma = 0.0

# gamma process tunings
rpow = true
spow = true
pord = false

# bias tuning
bias = true

# If you use AvsPmod user sliders you can delete comment for follow lines

#~ [<separator="display tunings">]
#~ comparison = Select([<"show different settings - (false ou true) default = false = 0", 0, 1, 1>], false , true)
#~ show_scrutinized = Select([<"show scrutinized aera - (false ou true) default = false = 0", 0, 1, 0>], false , true)
#~ show_info = Select([<"show datas - (false ou true) default = false = 0", 0, 1, 0>], false , true)

#~ [<separator="color space matrix tuning and specify the source rectangle under scrutiny">]
#~ matrix = Select([<"color matrix - (Rec 601= 0 ou Rec 709 =1) = default = 0", 0, 1, 0>], "Rec601" , "Rec709")
#~ x = [<"ignore pixels on left - width percentage - default : 0.00", 0.00, 0.99, 0.09>]
#~ Y= [<"ignore pixels on top - heigth percentage - default : 0.00", 0.00, 0.99, 0.09>]
#~ w = [<"ignore pixels on right - width percentage - default : 0.00", 0.00, 0.99, 0.09>]
#~ h = [<"ignore pixels on bottom - heigth percentage - default : 0.00", 0.00, 0.99, 0.09>]

#~ [<separator="automatic white balance tunings">]

#~ [<separator="-------- autogain tunings">]
#~ threshold = [<"percentage for extreme pixels to be ignored - default : 0.10", 0.00, 1.00, 0.1>]
#~ autogain = Select([<"enable autogain process - (false or true) default = false = 0", 0, 1, 1>], false , true)

#~ [<separator="-------- autocontraste tunings">]
#~ autocont_strength = [<"enable and strength action auto-cont process (0.0 = desable 1.0 = full) - default : 1.0", 0.0, 1.0, 0.5>]
#~ luma_chroma = [<"channel luma vs chroma weigth adjust (0.0 = desable 1.0 = full) - default : 0.0", 0.0, 1.0, 0.2>]

#~ [<separator="-------- gamma process tunings">]

#~ rpow = Select([<"enable rpow process - (false or true) default = true = 0", 0, 1, 1>], false , true)
#~ spow = Select([<"enable spow process - (false or true) default = true = 0", 0, 1, 1>], false , true)
#~ pord = Select([<"Pord - (false = rpow before spow ) default = false = 0", 0, 1, 0>], false , true)

#~ [<separator="-------- bias tuning">]

#~ bias = Select([<"enable bias process - (false or true) default = false = 0", 0, 1, 1>], false , true)

output = RGBAdapt_auto_awb_process(matrix = matrix, show_scrutinized = show_scrutinized, show_info = show_info, x = x, y = y, w = w, h = h, \
threshold = threshold, autogain = autogain, luma_chroma = luma_chroma, \
autocont_strength = autocont_strength, rpow = rpow, spow = spow, pord = pord, bias = bias)

without_autocont_output = RGBAdapt_auto_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, \
threshold = threshold, autocont_strength = 0.0, luma_chroma = 0.0)\
.AddBorders(0, 20, 0, 0, color=$000000). Subtitle ("gain, rpow, spow and bias no auto cont")

bias_only = RGBAdapt_auto_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, \
threshold = threshold, autogain = false, autocont_strength = 0.0, luma_chroma = 0.0, rpow = false)\
.AddBorders(0, 20, 0, 0, color=$000000). Subtitle ("bias only (ColorYUV autowhite)")

gain_bias_only = RGBAdapt_auto_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, \
threshold = threshold, autocont_strength = 0.0, luma_chroma = 0.0, rpow = false)\
.AddBorders(0, 20, 0, 0, color=$000000). Subtitle ("gain and bias only")

whole = RGBAdapt_auto_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, luma_chroma = 0.0)\
.AddBorders(0, 20, 0, 0, color=$000000). Subtitle ("gain cont (default) rpow spow and bias")

compared_output = StackVertical(StackHorizontal(last .AddBorders(0, 20, 0, 0, color=$000000).Subtitle("original"),gain_bias_only, whole), \
StackHorizontal(bias_only, without_autocont_output, output .AddBorders(0, 20, 0, 0, color=$000000)\
. Subtitle ("user setting :" + " autocont : " + LeftStr(string(autocont_strength),3) + " luma vs chroma : " + LeftStr(string(luma_chroma),3))))

(!comparison) ? output : compared_output

return last


Bernard

Bernardd
2nd September 2016, 11:54
StainlessS

On your sample upper with GamMac, the wheel and car have near same color. With color restoration with ColorMill, the wheel are magenta and car brown.
With my script, with channel color conversion factor use, i can get a car with a little little brown tone. Have you observed the same result ?

Thanks

Bernard

StainlessS
4th September 2016, 00:15
Dont ask me about that, I've never been any good at color correction, I can spend hours tinkering and think, 'great job'.
Next day, argh, what a mess I made of that!!!.
I tend to push it too far and make it bad in opposite direction :(

Anyway, just changing BluMul in GamMac script makes side of carriage more brown, and wheel magenta (should probably be rust red).

Changed end of script as so (shows only two images), only changed BluMul to 0.93

#RedMul = 0.6 Grnmul = 0.7 blumul = 0.8
Scale=2
B=GamMac(LockChan=LockChan,LockVal=LockVal,RedMul=RedMul,GrnMul=GrnMul,BluMul=BluMul,Show=Show,Verbosity=Verb,th=th,SCALE=Scale,
\ RngLim=RngLim,GamMax=GamMax,x=x,y=y,w=w,h=h)

#RedMul = 0.5 Grnmul = 0.6 blumul = 1.1
Scale=2
RedMul=1.0 Grnmul=1.0 Blumul=0.93

C=GamMac(LockChan=LockChan,LockVal=LockVal,RedMul=RedMul,GrnMul=GrnMul,BluMul=BluMul,Show=Show,Verbosity=Verb,th=th,SCALE=Scale,
\ RngLim=RngLim,GamMax=GamMax,x=x,y=y,w=w,h=h)

#TOP=StackHorizontal(Sub(O,"Original"),Sub(A,"Scale 0"))
BOT=StackHorizontal(Sub(B,"Scale 2 : 1.00 1.00 1.00"),Sub(C,RT_String("Scale 2 : %.2f %.2f %.2f",Redmul,GrnMul,BluMul)))
#StackVertical(TOP,BOT)
BOT
return Last



The flesh tones are nowhere near as good as the RetroDisneyworld guys mod (probably easier with sliders but I dont use AvsPMod).

EDIT: The 'Night club singers' image comes out a lot darker in GamMac than RetroDisneyworld guys take, I would not be surprised
if GamMac actually got that more correct, it could well have been quite dark in that room, the Disney world guy makes it look like all the lights were on.
EDIT: Although there does seem to be a child in the audience, so could be either way.

EDIT: Or maybe RedMul=1.03 Grnmul=1.04 Blumul=0.9

videoFred
4th September 2016, 13:25
Dont ask me about that, I've never been any good at color correction, I can spend hours tinkering and think, 'great job'.
Next day, argh, what a mess I made of that!!!.
I tend to push it too far and make it bad in opposite direction :(

Sometimes, I want to correct colors from the real world hehe :p

But color correction is something you can learn by observing real colors. Especally flesh tones, vegetation and sky.


The flesh tones are nowhere near as good as the RetroDisneyworld guys mod (probably easier with sliders but I dont use AvsPMod).

What do you think about this: (subtitles added after filtering and histograms of cource)
http://www.super-8.be/Doom/disney_red_03.jpg

http://www.super-8.be/Doom/disney_red_02.jpg

http://www.super-8.be/Doom/disney_red_01.jpg

After GamMac, I adjusted red hue, yellow hue and cyan hue. Then, I did some RGB adjustments with RgbAdjust.

Talking about the Disney Guy... I do not find his postings here, does someone know where to find it?

Fred.

StainlessS
4th September 2016, 14:13
Better than I could do Fred :) (much better).

I think that in TmpGenc color correction, there was some kind of toggle button to set surrounding background Magenta (and perhaps Green), and then back to grey,
it helped to 'unskew' your color perception (which happens after staring at an image for some time).

Here is a Disney guys post, perhaps the one you search for:- http://forum.doom9.org/showthread.php?p=1745309#post1745309

And all posts by him (via Profile 'Find all posts by wdwms'):- http://forum.doom9.org/search.php?searchid=7695136
Last on-line 14 Dec 2015.

For single images, there is RGBAdjust_Graffer (with sliders), here:- http://forum.doom9.org/showthread.php?t=156774&highlight=coloryuv2

EDIT: Shekh has some kind of 6 axis rgb tweaker in his VirtualDub Mod 'vdfiltermod', here:- http://forum.doom9.org/showthread.php?t=172021

https://sourceforge.net/p/vdfiltermod/wiki/Home/attachment/sixaxis.png

EDIT: And here RgbAdapt() Graffer (this thread), much the same as RgbAdjust() but no Dither option (Added in Avisynth v2.6)
but with several additional options not available in RgbAdjust().
https://s20.postimg.cc/wxyq8spkt/Fishv3_zpsfjmoyerr.jpg (https://postimg.cc/image/yd0axiqnt/)

videoFred
4th September 2016, 15:02
Here is a Disney guys post, perhaps the one you search for:- http://forum.doom9.org/showthread.php?p=1745309#post1745309

Thank you! I did not find it in my own thread haha :D

Especially on this red films, GamMac is really a miracle filter.

Fred.

Bernardd
3rd October 2016, 19:11
Hello,

Below new script to make automatic white balance with RGBAdapt. First autogain wash the lights, second autocontrst amplify autogain process, very useful for big color cast but dangerous sometime.
After color correction in accordance with gray world theory. One correction with rpow and spow curves, one correction with bias curve. One of two or two together, it is function of video.

The function script is written in three parts to have the smaller scriptclip and so a faster script.

Script in following post

Bernardd
3rd October 2016, 19:17
The script call

AVISource("C:\ ......\ your video.avi")

LoadPlugin("C:\..........\GRunT.dll")
LoadPlugin("C:\..........\RGBAdapt.dll")
LoadPlugin("C:\..........\RT_Stats26.dll")

# display tunings
comparison = true
show_scrutinized = true
show_info = false

# color space matrix tuning and specify the source rectangle under scrutiny
matrix = "Rec601"
x = 0.09
Y= 0.09
w = 0.09
h = 0.09

# autogain tunings
threshold = 0.10
autogain = 1.0

# autocontraste tunings
autocont = 1.0

# gamma process tunings
rpow = 1.0
spow = 1.0
pord = false

# bias tuning
bias = 1.0

# If you use AvsPmod user sliders you can delete comment for follow lines

#~ [<separator="display tunings">]
#~ comparison = Select([<"show different settings - (false ou true) default = false = 0", 0, 1, 0>], false , true)
#~ show_scrutinized = Select([<"show scrutinized aera - (false ou true) default = false = 0", 0, 1, 0>], false , true)
#~ show_info = Select([<"show datas - (false ou true) default = false = 0", 0, 1, 0>], false , true)

#~ [<separator="color space matrix tuning - specify the source rectangle under scrutiny and percentage extreme pixels to ignore">]
#~ matrix = Select([<"color matrix - (Rec 601= 0 ou Rec 709 =1) = default = 0", 0, 1, 0>], "Rec601" , "Rec709")
#~ x = [<"ignore pixels on left - width percentage - default : 0.00", 0.00, 0.99, 0.09>]
#~ Y= [<"ignore pixels on top - heigth percentage - default : 0.00", 0.00, 0.99, 0.09>]
#~ w = [<"ignore pixels on right - width percentage - default : 0.00", 0.00, 0.99, 0.09>]
#~ h = [<"ignore pixels on bottom - heigth percentage - default : 0.00", 0.00, 0.99, 0.09>]
#~ threshold = [<"percentage for extreme pixels to be ignored - default : 0.10", 0.00, 1.00, 0.1>]

#~ [<separator="automatic white balance tunings">]

#~ [<separator="args autogain tunings">]
#~ autogain = [<"enable and strength autogain process - default = 1.0", 0.0, 1.0, 1.0>]

#~ [<separator="args autocontrast tunings">]
#~ autocont = [<"enable and strength autocont process - default = 1.0", 0.0, 1.0, 1.0>]

#~ [<separator="args gamma process tunings">]
#~ rpow =[<"enable and strength rpow process - default = 1.0", 0.0, 1.0, 1.0>]
#~ spow = [<"enable and strength spow process - default = 1.0", 0.0, 1.0, 1.0>]
#~ pord = Select([<"Pord - (false = rpow before spow ) default = false = 0", 0, 1, 0>], false , true)

#~ [<separator="free args bias tuning">]
#~ bias =[<"enable and strength bias process - default = 1.0", 0.0, 1.0, 1.0>]


output = RGBAdapt_awb_process(matrix = matrix, show_scrutinized = show_scrutinized, show_info = show_info, x = x, y = y, w = w, h = h, \
threshold = threshold, autogain = autogain, autocont = autocont,\
rpow = rpow, spow = spow, pord = pord, bias = bias)

without_autocont_output = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, \
threshold = threshold, autocont = 0.0)\
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("gain, rpow, spow and bias no auto cont"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " autogain strength : 1.0" + " autocont strength : 0.0" + \
"\n rpow strength : 1.0" + " spow strength : 1.0" + " pord : false" +\
"\n bias strength : 1.0" , lsp = 20)

bias_only = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, \
threshold = threshold, autogain = 0.0, autocont = 0.0, rpow = 0.0)\
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("bias only output near ColorYUV autowhite"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " autogain strength : 0.0" + " autocont strength : 0.0" + \
"\n rpow strength : 0.0" + " spow strength : 0.0" + " pord : false" +\
"\n bias strength : 1.0" , lsp = 20)

gain_bias_only = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, \
threshold = threshold, autocont = 0.0, rpow = 0.0)\
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("gain and bias only"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " autogain strength : 1.0" + " autocont strength : 0.0" + \
"\n rpow strength : 0.0" + " spow strength : 0.0" + " pord : false" +\
"\n bias strength : 1.0", lsp = 20)

all = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, threshold = threshold) \
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("gain cont rpow spow and bias"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " autogain strength : 1.0" + " autocont strength : 1.0" + \
"\n rpow strength : 1.0" + " spow strength : 1.0" + " pord : false" +\
"\n bias strength : 1.0" , lsp = 20)

compared_output = (!comparison) ? nop : StackVertical(StackHorizontal(last .AddBorders(0, 80, 0, 0, color=$000000).Subtitle("original"),gain_bias_only, all), \
StackHorizontal(bias_only, without_autocont_output, output .AddBorders(0, 80, 0, 0, color=$000000)\
. Subtitle ("user setting where all args are free" + \
"\n threshold : " + LeftStr(string(threshold),4) + " autogain strength : " + LeftStr(string(autogain),3) + " autocont strength : " + LeftStr(string(autocont),3) + \
"\n rpow strength : " + LeftStr(string(rpow),3) + " spow strength : " + LeftStr(string(spow),3) + " pord : " + string(pord) +\
"\n bias strength : " + LeftStr(string(bias),3) , lsp = 20)))

(!comparison) ? output : compared_output

Bernardd
3rd October 2016, 19:22
The script function part I


# ---------------------------- function script -------------------------------------

function RGBAdapt_awb_process(clip clip, string "matrix",bool "show_scrutinized", bool "show_info", float "x", float "y", float "w", float "h", \
float "threshold", float "autogain" , float "autocont", float "rpow", float "spow", bool "pord", float "bias")

{

#----------------------------------------------based on RGBADapt plugin ---------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.php?p=1681286#post1681286 #
#------------------------------------------------------------------------------------------------------------------------------------------------- #

#---------------------------------------------- need RT_Stats plugin ----------------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.php?p=1584313#post1584313 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #

#---------------------------------------------- need GRunT plugin ----------------------------------------------------------------------------#
# script author : Gavino http://forum.doom9.org/showthread.php?p=1157083#post1157083 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #

Assert(IsYV12(clip) || IsRGB(clip)," Input video colorspace must be YV12 or RGB, not YUV")
matrix = string(Default(matrix, "Rec601") ) # Color standard, Rec 601 or Rec 709
Assert(matrix == "Rec601" || matrix == "Rec709", """RGBAdapt_auto_awb: matrix "Rec601" or "Rec709"""")
show_scrutinized = Default(show_scrutinized, false) # show scrutinized aera or not, default false
show_info = Default(show_info, false) # show info or not, default false
x = float(Default(x,0.00)) #width percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(x>=0.00 && x <= 0.99,"RGBAdapt_auto_awb: x 0.00 -> 0.99")
y = float(Default(y,0.00)) #heignt percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(y>=0.00 && y <= 0.99,"RGBAdapt_auto_awb: y 0.00 -> 0.99")
w = float(Default(w,0.00)) #coords specify the source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(w>=0.00 && w <= 0.99,"RGBAdapt_auto_awb: w 0.00 -> 0.99")
Assert(x+w>=0.00 && x+w <= 0.99 ,"RGBAdapt_auto_awb: x+w 0.00 -> 0.99")
h = float(Default(h,0.00)) #coords specify the source rectangle under scrutiny , the default : x = y = h = w = 0.00 is full frame
Assert(h>=0.00 && h <= 0.99,"RGBAdapt_auto_awb: h 0.00 -> 0.99")
Assert(y+h>=0.00 && y+h <= 0.99 ,"RGBAdapt_auto_awb: x+w 0.00 -> 0.99")
threshold = Float(Default(threshold, 0.10)) # threshold arg of RT_Stats plugin
Assert(threshold>=0.00 && threshold <= 1.00,"RGBAdapt_auto_awb: threshold 0.00 -> 1.00")
autogain = Float(Default(autogain, 1.00)) # strength arg for automatic gain
Assert(autogain>=0.00 && autogain <= 1.00,"RGBAdapt_auto_awb: autogain 0.00 -> 1.00")
autocont = Float(Default(autocont, 1.00)) # strength arg for automatic contrast
Assert(autocont>=0.00 && autocont <= 1.00,"RGBAdapt_auto_awb: autocont 0.00 -> 1.00")
rpow = Float(Default(rpow, 1.00)) # strength arg for automatic rpow
Assert(rpow>=0.00 && rpow <= 1.00,"RGBAdapt_auto_awb: rpow 0.00 -> 1.00")
spow = Float(Default(spow, 1.00)) # strength arg for automatic spow
Assert(spow>=0.00 && spow <= 1.00,"RGBAdapt_auto_awb: spow 0.00 -> 1.00")
pord = Default(pord, false) # RGBAdapt pord arg
bias = Float(Default(bias, 1.00)) # strength arg for automatic bias
Assert(bias>=0.00 && bias <= 1.00,"RGBAdapt_auto_awb: bias 0.00 -> 1.00")

#---------- Convert to RGB color space

#---------- Specify the source rectangle under scrutiny

x = int(Width(clip) * x)
y = int(Height(clip) * y)
w = int(-Width(clip) * w)
h = int(-Height(clip) * h)

#--------- RGB color space process

RGB_clip = (!isRGB(clip)) ? ConvertToRGB24(clip, matrix=matrix) : clip

#--------- AWB process

ScriptClip(RGB_clip, """

#---------- First pass : autogain process for each channel

RT_RgbChanStats( RGB_clip, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+16)

# ------ detection BlankClip and condition to avoid division by 0

blanklip = RCS_MinMaxDiff_0 + RCS_MinMaxDiff_1 + RCS_MinMaxDiff_2

RCS_MinMaxDiff_0 = Max (RCS_MinMaxDiff_0, 0.01) RCS_MinMaxDiff_1 = Max (RCS_MinMaxDiff_1, 0.01) RCS_MinMaxDiff_2 = Max (RCS_MinMaxDiff_2, 0.01)

#---- autogain process

r_gain = 1 - (1 - float(255.0/RCS_MinMaxDiff_0)) * autogain
r_bias = - RCS_Min_0 * r_gain * autogain

g_gain = 1 - (1 - float(255.0/RCS_MinMaxDiff_1)) * autogain
g_bias = - RCS_Min_1 * g_gain * autogain


b_gain = 1 - (1 - float(255.0/RCS_MinMaxDiff_2)) * autogain
b_bias = - RCS_Min_2 * b_gain * autogain

ref = (RCS_Ave_0 * r_gain + r_bias + RCS_Ave_1 * g_gain + g_bias + RCS_Ave_2 * b_gain + b_bias)/3

#---- autocont process

r_cont = 1 - (1 - r_gain) * autocont
r_cont_max = RCS_Max_0 * r_gain + r_bias + (r_cont - 1) *(RCS_Max_0 - 128)

g_cont = 1 - (1 - g_gain) * autocont
g_cont_max = RCS_Max_1 * g_gain + g_bias + (g_cont - 1) *(RCS_Max_1 - 128)

b_cont = 1 - (1 - b_gain) * autocont
b_cont_max = RCS_Max_2 * b_gain + b_bias + (b_cont - 1) *(RCS_Max_2 - 128)

r_cont_bias = (255 - r_cont_max) * autocont
g_cont_bias = (255 - g_cont_max) * autocont
b_cont_bias = (255 - b_cont_max) * autocont

r_bias = r_bias + r_cont_bias
g_bias = g_bias + g_cont_bias
b_bias = b_bias + b_cont_bias

#---------- gamma curves and bias corrections process in accordance with gray world theory

#----------- RGB values calculation

r_gain_cont_ave = RCS_Ave_0 * r_gain + r_bias + (r_cont - 1) *(RCS_Ave_0 - 128)
g_gain_cont_ave = RCS_Ave_1 * g_gain + g_bias + (g_cont - 1) *(RCS_Ave_1 - 128)
b_gain_cont_ave = RCS_Ave_2 * b_gain + b_bias + (b_cont - 1) *(RCS_Ave_2 - 128)

#----------- RGB corrections values calcul

# In gray world theory, in YUV range, ref = 128, but in RGB range average of channel average values
# is better, with average of channel average value after autogain process the picture ligth is better

dr = ref - r_gain_cont_ave # gray world theory bias correction calcul
dg = ref - g_gain_cont_ave
db = ref - b_gain_cont_ave

#----- RGB correction with Rpow curve calcul

r_rpow = 1 - (1 - pow(4.0,dr/128.0)) * rpow
r_rpow = Min (4.0, Max (r_rpow, 0.1))
g_rpow = 1 - (1 - pow(4.0,dg/128.0)) * rpow
g_rpow = Min (4.0, Max (g_rpow, 0.1))
b_rpow = 1 - (1 - pow(4.0,db/128.0)) * rpow
b_rpow = Min (4.0, Max (b_rpow, 0.1))

#----------- RGB correction with Spow curve calcul

#------- Spow process is enable in default mode, spmid and pord args default values increase
#------- rpow process action, thus we get more color saturation but also more dark aeras.

r_spow = 1 - (1 - 1/r_rpow) * spow
r_spow = Min (4.0, Max (r_spow, 0.1))
g_spow = 1 - (1 - 1/g_rpow) * spow
g_spow = Min (4.0, Max (g_spow, 0.1))
b_spow = 1 - (1 - 1/b_rpow) * spow
b_spow = Min (4.0, Max (b_spow, 0.1))

r_spmid = (rpow == 0 || spow == 0) ? 0.5 : r_gain_cont_ave/255.0
r_spmid = Min (0.99, Max (r_spmid, 0.01))
g_spmid = (rpow == 0 || spow == 0) ? 0.5 : g_gain_cont_ave/255.0
g_spmid = Min (0.99, Max (g_spmid, 0.01))
b_spmid = (rpow == 0 || spow == 0) ? 0.5 : b_gain_cont_ave/255.0
b_spmid = Min (0.99, Max (b_spmid, 0.01))

#----------- RGB bias corrections calcul

r_bias = (r_bias + dr * bias)
r_bias = Min (512.0, Max (r_bias, -512.0))
g_bias = (g_bias + dg * bias)
g_bias = Min (512.0, Max (g_bias, -512.0))
b_bias = (b_bias + db * bias)
b_bias = Min (512.0, Max (b_bias, -512.0))

#------------ gain and cont in RGBadapt args range
r_gain = Min (8.0, Max (r_gain, -8.0))
g_gain = Min (8.0, Max (g_gain, -8.0))
b_gain = Min (8.0, Max (b_gain, -8.0))

r_cont = Min (8.0, Max (r_cont, -8.0))
g_cont = Min (8.0, Max (g_cont, -8.0))
b_cont = Min (8.0, Max (b_cont, -8.0))

RGBAdapt( RGB_clip, \
R_Bias = r_bias, R_Gain = r_gain, R_Cont = r_cont, R_RPow = r_rpow, R_Spow = r_spow, R_SPMid = r_spmid, R_Pord = pord,\
G_Bias = g_bias, G_Gain = g_gain, G_Cont = g_cont, G_RPow = g_rpow, G_Spow = g_spow, G_SPMid = g_spmid, G_Pord = pord,\
B_Bias = b_bias, B_Gain = b_gain, B_Cont = b_cont, B_RPow = b_rpow, B_Spow = b_spow, B_SPMid = b_spmid, B_Pord = pord)

(blanklip == 0) ? RGB_clip : last

#----------- variables are tuned in global mode for data display in following ScriptClip
global r_bias = (!show_info)? nop : r_bias global g_bias = (!show_info)? nop : g_bias global b_bias = (!show_info)? nop : b_bias
global r_gain = (!show_info)? nop : r_gain global g_gain = (!show_info)? nop : g_gain global b_gain = (!show_info)? nop : b_gain
global r_cont = (!show_info)? nop : r_cont global g_cont = (!show_info)? nop : g_cont global b_cont = (!show_info)? nop : b_cont
global r_rpow = (!show_info)? nop : r_rpow global g_rpow = (!show_info)? nop : g_rpow global b_rpow = (!show_info)? nop : b_rpow
global r_spow = (!show_info)? nop : r_spow global g_spow = (!show_info)? nop : g_spow global b_spow = (!show_info)? nop : b_spow
global r_spmid = (!show_info)? nop : r_spmid global g_spmid = (!show_info)? nop : g_spmid global b_spmid = (!show_info)? nop : b_spmid
global pord = (!show_info)? nop : pord global ref = ref

return last """, args = "RGB_clip, matrix, show_info, x, y, w , h, autogain, threshold, autocont, rpow, spow, pord, bias")


#--------- datas display process

(!show_info) ? last :\
ScriptClip(last, """

#---------- First pass : autogain process for each channel

RT_RgbChanStats( RGB_clip, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+16)

#----- extraction for gain/cont calculation and final display

r_Min = RCS_Min_0 g_min = RCS_Min_1 b_min = RCS_Min_2
r_Max = RCS_Max_0 g_max = RCS_Max_1 b_max = RCS_Max_2
r_MinmaxDiff = RCS_MinMaxDiff_0 g_minMaxDiff = RCS_MinMaxDiff_1 b_MinMaxDiff = RCS_MinMaxDiff_2
r_Ave = RCS_Ave_0 g_Ave = RCS_Ave_1 b_Ave = RCS_Ave_2

#--------- Final RGB values extraction for display

RT_RgbChanStats( last, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+8+16)

Subtitle("channels averages average : " + string((r_ave + g_ave + b_ave )/3)+\
"\n "+\
"\nRed values : "+\
"\nDeparture : " + " Average : " + String(r_Ave) + " Min/max : " + String(r_MinMaxDiff)\
+ " Min : " + String(r_Min)+ " Max : " + String(r_Max)+\
"\n R_bias : " + String(r_bias) + " R_gain : " + String(r_gain) + " R_cont : " + String(r_cont) +\
"\n R_rpow : " + String(r_rpow )+ " R_spow : " + String(r_spow) + " R_spmid : " + String(r_spmid)+\
"\nFinish : " + " Average : " + String(RCS_Ave_0) + " Min/max : " + String(RCS_MinMaxDiff_0)\
+ " Min : " + String(RCS_Min_0)+ " Max : " + String(RCS_Max_0)\
, y= float(height()/32.0), lsp= 20, text_color = $00FFFF00, halo_color = $00000000, size = float(height()/32.0))\
.Subtitle("Green values : "+\
"\nDeparture : "+ " Average : " + String(g_Ave) + " Min/max : " + String(g_MinMaxDiff)\
+ " Min : " + String(g_Min)+ " Max : " + String(g_Max)+\
"\n G_bias : " + String(g_bias) + " G_gain : " + String(g_gain) + " G_cont : " + String(g_cont)+\
"\n G_rpow : " + String(g_rpow) + " G_spow : " + String(g_spow) + " G_spmid : " + String(g_spmid) +\
"\nFinish : " + " Average : " + String(RCS_Ave_1) + " Min/max : " + String(RCS_MinMaxDiff_1)\
+ " Min : " + String(RCS_Min_1)+ " Max : " + String(RCS_Max_1)\
, y= 10 * float(height()/32.0), lsp= 20, text_color = $00FFFF00, halo_color = $00000000, size = float(height()/32.0))\
.Subtitle("Blue values : "+\
"\nDeparture : " + " Average : " + String(b_Ave) + " Min/max : " + String(b_MinMaxDiff)\
+ " Min : " + String(b_Min)+ " Max : " + String(b_Max)+\
"\n B_bias : " + String(b_bias) + " B_gain : " + String(b_gain)+ " B_cont : " + String(b_cont) +\
"\n B_rpow : " + String(b_rpow) + " B_spow : " + String(b_spow) + " B_spmid : " + String(b_spmid) +\
"\nFinish : " + " Average :" + String(RCS_Ave_2) + " Min/max : " + String(RCS_MinMaxDiff_2)\
+ " Min : " + String(RCS_Min_2)+ " Max : " + String(RCS_Max_2)+\
"\n "+\
"\nchannels averages average : " + string((RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2 )/3)\
, y = 17 * float(height()/32.0), lsp = 20, text_color = $00FFFF00, halo_color = $00000000, size = float(height()/32.0))

return last """, args = "RGB_clip, matrix, show_info, x, y, w , h, threshold")

Bernardd
3rd October 2016, 19:24
The script function part II



#-------- display scrutinized aera

scrutinized_green = (!show_scrutinized)? nop : BlankClip(RGB_clip, width = (Width(last)-x+w), height = (Height(last)-y+h), color=$00FF00)
scrutinized_white = (!show_scrutinized)? nop : Blankclip(RGB_clip, width = (Width(last)-x+w), height = (Height(last)-y+h), color=$FFFFFF)
scrutinized_int = (!show_scrutinized)? nop : Blankclip(RGB_clip, width = (Width(scrutinized_white)-4), height = (Height(scrutinized_white)-4),\
color=000000)

scrutinized_mask = (!show_scrutinized)? nop : Overlay(scrutinized_white, scrutinized_int, x=2, y=2, opacity=1.0, mode="multiply", greymask=true,\
ignore_conditional=false, pc_range=false)

scrutinized = (!show_scrutinized)? nop : Overlay(last, scrutinized_green, mask = scrutinized_mask, x=x, y=y, opacity=1.0, mode="blend", greymask=true,\
ignore_conditional=false, pc_range=false)

(!show_scrutinized)? last : scrutinized

#--------- End of RGB color space process

!isRGB(clip) ? ConvertToYV12(last, matrix=matrix) : last

}


And on YouTube scriptdemo on John Meyer's sample (http://forum.doom9.org/showthread.php?p=1780794#post1780794 )

https://youtu.be/9ewbXiM01uw

Bernard

Bernardd
5th October 2016, 11:38
Hello,
I apologize, i have a definition error in function call script. autogain, autocont, rpow, spow and bias are not bool but float. I have amended call script in post before this one.
Bernard

StainlessS
5th October 2016, 16:02
Yo Berni,


Subtitle("channels averages average : " + string((r_ave + g_ave + b_ave )/3)+\
"\n "+\
"\nRed values : "+\
"\nDeparture : " + " Average : " + String(r_Ave) + " Min/max : " + String(r_MinMaxDiff)\
+ " Min : " + String(r_Min)+ " Max : " + String(r_Max)+\
"\n R_bias : " + String(r_bias) + " R_gain : " + String(r_gain) + " R_cont : " + String(r_cont) +\
"\n R_rpow : " + String(r_rpow )+ " R_spow : " + String(r_spow) + " R_spmid : " + String(r_spmid)+\
"\nFinish : " + " Average : " + String(RCS_Ave_0) + " Min/max : " + String(RCS_MinMaxDiff_0)\
+ " Min : " + String(RCS_Min_0)+ " Max : " + String(RCS_Max_0)\
, y= float(height()/32.0), lsp= 20, text_color = $00FFFF00, halo_color = $00000000, size = float(height()/32.0))\
.Subtitle("Green values : "+\
"\nDeparture : "+ " Average : " + String(g_Ave) + " Min/max : " + String(g_MinMaxDiff)\
+ " Min : " + String(g_Min)+ " Max : " + String(g_Max)+\
"\n G_bias : " + String(g_bias) + " G_gain : " + String(g_gain) + " G_cont : " + String(g_cont)+\
"\n G_rpow : " + String(g_rpow) + " G_spow : " + String(g_spow) + " G_spmid : " + String(g_spmid) +\
"\nFinish : " + " Average : " + String(RCS_Ave_1) + " Min/max : " + String(RCS_MinMaxDiff_1)\
+ " Min : " + String(RCS_Min_1)+ " Max : " + String(RCS_Max_1)\
, y= 10 * float(height()/32.0), lsp= 20, text_color = $00FFFF00, halo_color = $00000000, size = float(height()/32.0))\
.Subtitle("Blue values : "+\
"\nDeparture : " + " Average : " + String(b_Ave) + " Min/max : " + String(b_MinMaxDiff)\
+ " Min : " + String(b_Min)+ " Max : " + String(b_Max)+\
"\n B_bias : " + String(b_bias) + " B_gain : " + String(b_gain)+ " B_cont : " + String(b_cont) +\
"\n B_rpow : " + String(b_rpow) + " B_spow : " + String(b_spow) + " B_spmid : " + String(b_spmid) +\
"\nFinish : " + " Average :" + String(RCS_Ave_2) + " Min/max : " + String(RCS_MinMaxDiff_2)\
+ " Min : " + String(RCS_Min_2)+ " Max : " + String(RCS_Max_2)+\
"\n "+\
"\nchannels averages average : " + string((RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2 )/3)\
, y = 17 * float(height()/32.0), lsp = 20, text_color = $00FFFF00, halo_color = $00000000, size = float(height()/32.0))


You could probably make life a bit easier by using RT_String() instead of all of the String() functions and '+' string concatenations.
Subtitle is a little awkward in that it would need to use '\\n' rather than just '\n' because RT_String would convert '\n' in format string to
a Chr(10) [but Subtitle actually wants '\n' literally, '\\n' the double backslash is escaped to a single '\n' as Subtitle requires.
Alternatively, you could just use '\n' which would be turned into Chr(10), and then use eg RT_StrReplace(S, Chr(10),"\n") to finally convert
back to '\n' strings.
If 2nd method used, then could also send S to RT_DebugF(S) prior to doing the string replace, or to RT_Subtitle instead.
Standard string conversion and concatenation is real tedious in Avisynth.

Bernardd
6th October 2016, 09:03
Hello StainlessS,

Thanks for the tip. I look your write script proposal.

Bernard

Bernardd
25th October 2016, 23:12
Hi StainlessS

Below a new version of my script.

In gray world theory, we compute a bias for increasing or decreasing average values at 128.
By the same way, for gamma correction, i compute now a rpow for increasing or decreasing average values to 128.
128 = pow(average value/255, 1/rpow)*255, thus rpow = log(average value/255)/log(128/255).

With this new rpow, results are near GamMac results.

In my script i get better results with average of channels averages values than with 128.

The script have, like the oldest versions, the following args : gain, cont, rpow, spow, pord and bias tunable args, but also
two boolean args to enable or desable automatic weitghed strength for cont and spow. With these two automatic
weigthed args enable, the default args give often good results.

In the following posts are first the call script, with AvsPmod user sliders opportunity
and after the function script.

Bernard

PS : i have done a little use of RT_String

Bernardd
25th October 2016, 23:12
The call script

AVISource("C:\.............\your video.avi")
LoadPlugin("C:\.............\GRunT.dll")
LoadPlugin("C:\.............\RGBAdapt.dll")
LoadPlugin("C:\.............\RT_Stats26.dll")

# display tunings
comparison = false
show_scrutinized = false
show_info = false

# color space matrix tuning and specify the source rectangle under scrutiny
matrix = "Rec601"
x = 0.09
Y= 0.09
w = 0.09
h = 0.09

# autogain tunings
threshold = 0.10
gain_strength = 1.0

# autocontraste tunings
auto_cont = true
cont_strength = 1.0

# gamma process tunings
auto_spow = true
rpow_strength = 1.0
spow_strength = 1.0
pord = false

# bias tuning
bias_strength = 1.0

# If you use AvsPmod user sliders you can delete comment for follow lines

#~ [<separator="display tunings">]
#~ comparison = Select([<"show different settings - (false ou true) default = false = 0", 0, 1, 0>], false , true)
#~ show_scrutinized = Select([<"show scrutinized aera - (false ou true) default = false = 0", 0, 1, 0>], false , true)
#~ show_info = Select([<"show datas - (false ou true) default = false = 0", 0, 1, 0>], false , true)

#~ [<separator="color space matrix tuning - specify the source rectangle under scrutiny and percentage extreme pixels to ignore">]
#~ matrix = Select([<"color matrix - (Rec 601= 0 ou Rec 709 =1) = default = 0", 0, 1, 0>], "Rec601" , "Rec709")
#~ x = [<"ignore pixels on left - width percentage - default : 0.00", 0.00, 0.99, 0.07>]
#~ Y= [<"ignore pixels on top - heigth percentage - default : 0.00", 0.00, 0.99, 0.07>]
#~ w = [<"ignore pixels on right - width percentage - default : 0.00", 0.00, 0.99, 0.07>]
#~ h = [<"ignore pixels on bottom - heigth percentage - default : 0.00", 0.00, 0.99, 0.07>]
#~ threshold = [<"percentage for extreme pixels to be ignored - default : 0.10", 0.00, 1.00, 0.1>]

#~ [<separator="automatic white balance tunings">]

#~ [<separator="gain_strengthargs tunings">]
#~ gain_strength = [<"enable and strength gain process - default = 1.0", 0.0, 1.0, 1.0>]

#~ [<separator="cont_strength args tunings - - cont arg can be free or automatic tunable">]
#~ auto_cont = Select([<"auto_cont - (auto weighted cont_strength ) default = true = 1", 0, 1, 1>], false , true)
#~ [<separator="----------- below free or automatic strength adjust">]
#~ cont_strength = [<"----------- enable and strength cont process - default = 1.0", 0.0, 1.0, 1.0>]

#~ [<separator="gamma process args tunings - - spow args can be free or automatic tunable">]
#~ auto_spow = Select([<"auto_spow - (auto weighted spow_strength) default = true = 1", 0, 1, 1>], false , true)
#~ [<separator="----------- below free or automatic strength adjust">]
#~ rpow_strength = [<"----------- enable and strength rpow process - default = 1.0", 0.0, 1.0, 1.0>]
#~ spow_strength = [<"----------- enable and strength spow process - default = 1.0", 0.0, 1.0, 1.0>]
#~ pord = Select([<"----------- pord - (false = rpow before spow ) default = false = 0", 0, 1, 0>], false , true)

#~ [<separator="free bias_strength args tuning">]
#~ bias_strength = [<"enable and strength bias process - default = 1.0", 0.0, 1.0, 1.0>]

output = RGBAdapt_awb_process(matrix = matrix, show_scrutinized = show_scrutinized, show_info = show_info, x = x, y = y, w = w, h = h, \
threshold = threshold, gain_strength = gain_strength, auto_cont = auto_cont,cont_strength = cont_strength, \
auto_spow = auto_spow,rpow_strength = rpow_strength, spow_strength = spow_strength, pord = pord, bias_strength = bias_strength)

without_cont_output = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, \
threshold = threshold, cont_strength = 0.0, auto_spow = false)\
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("gain, rpow_strength, spow_strength and bias process no cont and no auto mode for gamma"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " gain strength : 1.0" + " auto_cont : false cont strength : 0.0" + \
"\n auto_spow : false rpow strength : 1.0" + " spow strength : 1.0" + " pord : false" +\
"\n bias strength : 1.0" , lsp = 20)

bias_only = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, \
threshold = threshold, gain_strength = 0.0, cont_strength = 0.0, rpow_strength = 0.0)\
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("bias process only output near ColorYUV autowhite"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " gain strength : 0.0" + " auto_cont : false cont strength : 0.0" + \
"\n auto_spow : false rpow strength : 0.0" + " spow strength : 0.0" + " pord : false" +\
"\n bias strength : 1.0" , lsp = 20)

gain_bias_only = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, \
threshold = threshold, cont_strength = 0.0, rpow_strength = 0.0)\
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("gain and bias process only"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " gain strength : 1.0" + " auto_cont : false cont strength : 0.0" + \
"\n auto_spow : false rpow strength : 0.0" + " spow strength : 0.0" + " pord : false" +\
"\n bias strength : 1.0", lsp = 20)

gain_gamma_only = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, \
threshold = threshold, cont_strength = 0.0, auto_spow = false, bias_strength = 0.0) \
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("gain cont rpow and spow process but no bias process and no auto mode for cont and gamma"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " gain strength : 1.0" + " auto_cont : false cont strength : 0.0" + \
"\n auto_spow : false rpow strength : 1.0" + " spow strength : 1.0" + " pord : false" +\
"\n bias strength : 0.0" , lsp = 20)

all = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, threshold = threshold) \
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("gain cont rpow spow and bias process with auto mode for cont and gamma"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " gain strength : 1.0" + " auto_cont : true cont strength : 1.0" + \
"\n auto_spow : true rpow strength : 1.0" + " spow strength : 1.0" + " pord : false" +\
"\n bias strength : 1.0" , lsp = 20)

compared_output = (!comparison) ? nop : StackVertical(StackHorizontal(last.AddBorders(0, 80, 0, 0, color=$000000).Subtitle("original"),gain_bias_only, all), \
StackHorizontal(bias_only, gain_gamma_only, output .AddBorders(0, 80, 0, 0, color=$000000)\
. Subtitle ("user setting where all args are free" + \
"\n threshold : " + LeftStr(string(threshold),4) + " gain strength : " + LeftStr(string(gain_strength),3) + " auto_cont : " + string(auto_cont)+\
" cont strength : " + LeftStr(string(cont_strength),3) + \
"\n auto_spow : " + string(auto_spow) + " rpow strength : " + LeftStr(string(rpow_strength),3) +" spow strength : " + \
LeftStr(string(spow_strength),3) + " pord : " + string(pord) +\
"\n bias strength : " + LeftStr(string(bias_strength),3) , lsp = 20)))

(!comparison) ? output : compared_output

Bernardd
25th October 2016, 23:15
The function script part 1

# ---------------------------- function script -------------------------------------

function RGBAdapt_awb_process(clip clip, string "matrix",bool "show_scrutinized", bool "show_info", float "x", float "y", float "w", float "h", \
float "threshold", float "gain_strength" , bool "auto_cont", float "cont_strength", \
bool "auto_spow", float "rpow_strength", float "spow_strength", bool "pord", float "bias_strength")

{

#----------------------------------------------based on RGBADapt plugin ---------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.php?p=1681286#post1681286 #
#------------------------------------------------------------------------------------------------------------------------------------------------- #

#---------------------------------------------- need RT_Stats plugin ----------------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.php?p=1584313#post1584313 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #

#---------------------------------------------- need GRunT plugin ----------------------------------------------------------------------------#
# script author : Gavino http://forum.doom9.org/showthread.php?p=1157083#post1157083 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #

Assert(IsYV12(clip) || IsRGB(clip)," Input video colorspace must be YV12 or RGB, not YUV")
matrix = string(Default(matrix, "Rec601") ) # Color standard, Rec 601 or Rec 709
Assert(matrix == "Rec601" || matrix == "Rec709", """RGBAdapt_auto_awb: matrix "Rec601" or "Rec709"""")
show_scrutinized = Default(show_scrutinized, false) # show scrutinized aera or not, default false
show_info = Default(show_info, false) # show info or not, default false
x = float(Default(x,0.00)) #width percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(x>=0.00 && x <= 0.99,"RGBAdapt_auto_awb: x 0.00 -> 0.99")
y = float(Default(y,0.00)) #heignt percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(y>=0.00 && y <= 0.99,"RGBAdapt_auto_awb: y 0.00 -> 0.99")
w = float(Default(w,0.00)) #coords specify the source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(w>=0.00 && w <= 0.99,"RGBAdapt_auto_awb: w 0.00 -> 0.99")
Assert(x+w>=0.00 && x+w <= 0.99 ,"RGBAdapt_auto_awb: x+w 0.00 -> 0.99")
h = float(Default(h,0.00)) #coords specify the source rectangle under scrutiny , the default : x = y = h = w = 0.00 is full frame
Assert(h>=0.00 && h <= 0.99,"RGBAdapt_auto_awb: h 0.00 -> 0.99")
Assert(y+h>=0.00 && y+h <= 0.99 ,"RGBAdapt_auto_awb: x+w 0.00 -> 0.99")
threshold = Float(Default(threshold, 0.10)) # threshold arg of RT_Stats plugin
Assert(threshold>=0.00 && threshold <= 1.00,"RGBAdapt_auto_awb: threshold 0.00 -> 1.00")
gain_strength = Float(Default(gain_strength, 1.00)) # strength arg for gain
Assert(gain_strength>=0.00 && gain_strength <= 1.00,"RGBAdapt_auto_awb: gain_strength 0.00 -> 1.00")
auto_cont = Default(auto_cont, true) # auto weighted cont_strength arg
cont_strength = Float(Default(cont_strength, 1.00)) # strength arg for contrast
Assert(cont_strength>=0.00 && cont_strength <= 1.00,"RGBAdapt_auto_awb: cont_strength 0.00 -> 1.00")
auto_spow = Default(auto_spow, true) # auto weighted rpow_strength arg control by cont_strength arg
rpow_strength = Float(Default(rpow_strength, 1.00)) # strength arg for rpow
Assert(rpow_strength>=0.00 && rpow_strength <= 1.00,"RGBAdapt_auto_awb: rpow_strength 0.00 -> 1.00")
spow_strength = Float(Default(spow_strength, 1.00)) # strength arg for spow
Assert(spow_strength>=0.00 && spow_strength <= 1.00,"RGBAdapt_auto_awb: spow_strength 0.00 -> 1.00")
pord = Default(pord, false) # RGBAdapt pord arg
bias_strength = Float(Default(bias_strength, 1.00)) # strength arg for automatic bias_strength
Assert(bias_strength>=0.00 && bias_strength <= 1.00,"RGBAdapt_auto_awb: bias_strength 0.00 -> 1.00")

#---------- Specify the source rectangle under scrutiny

x = int(Width(clip) * x)
y = int(Height(clip) * y)
w = int(-Width(clip) * w)
h = int(-Height(clip) * h)

#--------- RGB color space process

RGB_clip = (!isRGB(clip)) ? ConvertToRGB24(clip, matrix=matrix) : clip

#--------- AWB process

ScriptClip(RGB_clip, """

#---------- First pass : gain process for each channel

RT_RgbChanStats( RGB_clip, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+16)

# ------ detection BlankClip and condition to avoid division by 0

blanklip = RCS_MinMaxDiff_0 + RCS_MinMaxDiff_1 + RCS_MinMaxDiff_2

RCS_MinMaxDiff_0 = Max (RCS_MinMaxDiff_0, 0.01) RCS_MinMaxDiff_1 = Max (RCS_MinMaxDiff_1, 0.01) RCS_MinMaxDiff_2 = Max (RCS_MinMaxDiff_2, 0.01)

#---- gain process

r_gain = 1 - (1 - float(255.0/RCS_MinMaxDiff_0)) * gain_strength
r_bias = - RCS_Min_0 * r_gain * gain_strength

g_gain = 1 - (1 - float(255.0/RCS_MinMaxDiff_1)) * gain_strength
g_bias = - RCS_Min_1 * g_gain * gain_strength


b_gain = 1 - (1 - float(255.0/RCS_MinMaxDiff_2)) * gain_strength
b_bias = - RCS_Min_2 * b_gain * gain_strength

#---- cont process

# Cont is dangerous, because it can overshoot light and dark, but it is necessary to help to find good correction for very big
# color cast. Thus bool auto_cont arg enable a automatic weighted autocont stength. I observe that picture do'nt need contraste is
# picture, which have a large histogram, which have min value near 0 et max value near 255, which have bigger min max diff value.
# But not it is simple, sometime the automatic weigthed autocont stength must be desable.

r_cont = (!auto_cont) ? 1 - (1 - r_gain) * cont_strength : 1 - (1 - r_gain) * cont_strength * (255.0 - RCS_MinMaxDiff_0)/255.0
r_cont_max = RCS_Max_0 * r_gain + r_bias + (r_cont - 1) *(RCS_Max_0 - 128)

g_cont = (!auto_cont) ? 1 - (1 - g_gain) * cont_strength : 1 - (1 - g_gain) * cont_strength * (255.0 - RCS_MinMaxDiff_1)/255.0
g_cont_max = RCS_Max_1 * g_gain + g_bias + (g_cont - 1) *(RCS_Max_1 - 128)

b_cont = (!auto_cont) ? 1 - (1 - b_gain) * cont_strength : 1 - (1 - b_gain) * cont_strength * (255.0 - RCS_MinMaxDiff_2)/255.0
b_cont_max = RCS_Max_2 * b_gain + b_bias + (b_cont - 1) *(RCS_Max_2 - 128)

r_cont_bias = (!auto_cont) ? (255 - r_cont_max) * cont_strength : \
(255 - r_cont_max) * cont_strength * (255.0 - RCS_MinMaxDiff_0)/255.0
g_cont_bias = (!auto_cont) ? (255 - g_cont_max) * cont_strength : \
(255 - g_cont_max) * cont_strength * (255.0 - RCS_MinMaxDiff_1)/255.0
b_cont_bias = (!auto_cont) ? (255 - b_cont_max) * cont_strength : \
(255 - b_cont_max) * cont_strength * (255.0 - RCS_MinMaxDiff_2)/255.0

#------------ gain and cont in RGBadapt args range

r_gain = Min (8.0, Max (r_gain, -8.0))
g_gain = Min (8.0, Max (g_gain, -8.0))
b_gain = Min (8.0, Max (b_gain, -8.0))

r_cont = Min (8.0, Max (r_cont, -8.0))
g_cont = Min (8.0, Max (g_cont, -8.0))
b_cont = Min (8.0, Max (b_cont, -8.0))

r_bias = r_bias + r_cont_bias
r_bias = Min (512.0, Max (r_bias, -512.0))
g_bias = g_bias + g_cont_bias
g_bias = Min (512.0, Max (g_bias, -512.0))
b_bias = b_bias + b_cont_bias
b_bias = Min (512.0, Max (b_bias, -512.0))

#---------- gamma curves corrections process in accordance with gray world theory

#----------- RGB values calculation

r_gain_cont_ave = RCS_Ave_0 * r_gain + r_bias + (r_cont - 1) *(RCS_Ave_0 - 128)
g_gain_cont_ave = RCS_Ave_1 * g_gain + g_bias + (g_cont - 1) *(RCS_Ave_1 - 128)
b_gain_cont_ave = RCS_Ave_2 * b_gain + b_bias + (b_cont - 1) *(RCS_Ave_2 - 128)

#----------- RGB gamma corrections values calcul

# In gray world theory, in YUV range, we increase or decrease average value to ref = 128.0, but in RGB range
# average of channel average values is better, with average of channel average value after gain process the
# picture ligth is better

# In gamma process, to incresae or decrease average value, we use gamma args. To find this gamma args, we
# solve this equation ref = pow(average value/255.0,1/gamma args)

# Gamma corrections are calculated with gain output, because is more refine than calculated with gain and cont output

ref = (RCS_Ave_0 * r_gain + r_bias + RCS_Ave_1 * g_gain + g_bias + RCS_Ave_2 * b_gain + b_bias)/3.0

r_rpow = 1 + (log((RCS_Ave_0 * r_gain + r_bias)/255.0)/log(ref/255.0) -1) * rpow_strength
r_rpow = Min (4.0, Max (r_rpow, 0.1))
g_rpow = 1 + (log((RCS_Ave_1* g_gain + g_bias)/255.0)/log(ref/255.0) - 1) * rpow_strength
g_rpow = Min (4.0, Max (g_rpow, 0.1))
b_rpow = 1 + (log((RCS_Ave_2 * b_gain + b_bias)/255.0)/log(ref/255.0) -1) * rpow_strength
b_rpow = Min (4.0, Max (b_rpow, 0.1))

#----------- RGB correction with spow curve calcul

#------- Spow process is enable in default mode, spmid and pord args default values increase
#------- rpow process action, thus we get more color saturation but also more dark aeras.
#------- Spow for rpow is like contrast for gain. Thus i use the same factor to get automatic
#------- weigthed spow arg

r_spow = (!auto_spow) ? 1 - (1 - 1/r_rpow) * spow_strength : \
1 - (1 - 1/r_rpow) * spow_strength * (255.0 - RCS_MinMaxDiff_0)/255.0
r_spow = Min (4.0, Max (r_spow, 0.1))
g_spow = (!auto_spow) ? 1 - (1 - 1/g_rpow) * spow_strength : \
1 - (1 - 1/g_rpow) * spow_strength * (255.0 - RCS_MinMaxDiff_1)/255.0
g_spow = Min (4.0, Max (g_spow, 0.1))
b_spow = (!auto_spow) ? 1 - (1 - 1/b_rpow) * spow_strength : \
1 - (1 - 1/b_rpow) * spow_strength * (255.0 - RCS_MinMaxDiff_2)/255.0
b_spow = Min (4.0, Max (b_spow, 0.1))

r_spmid = (r_spow == 1.0) ? 0.5 : (RCS_Ave_0 * r_gain + r_bias)/255.0
r_spmid = Min (0.99, Max (r_spmid, 0.01))
g_spmid = (g_spow == 1.0) ? 0.5 : (RCS_Ave_1* g_gain + g_bias)/255.0
g_spmid = Min (0.99, Max (g_spmid, 0.01))
b_spmid = (b_spow == 1.0) ? 0.5 : (RCS_Ave_2 * b_gain + b_bias)/255.0
b_spmid = Min (0.99, Max (b_spmid, 0.01))

#---------- bias corrections process in accordance with gray world theory

#----------- RGB bias corrections extraction and calcul

RGBAdapt( RGB_clip, \
R_bias = r_bias, R_Gain = r_gain, R_Cont = r_cont, R_rpow = r_rpow, R_spow = r_spow, R_SPMid = r_spmid, R_Pord = pord,\
G_bias = g_bias, G_Gain = g_gain, G_Cont = g_cont, G_rpow = g_rpow, G_spow = g_spow, G_SPMid = g_spmid, G_Pord = pord,\
B_bias = b_bias, B_Gain = b_gain, B_Cont = b_cont, B_rpow = b_rpow, B_spow = b_spow, B_SPMid = b_spmid, B_Pord = pord)

RT_RgbChanStats( LAST, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 16)

ref = (RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2)/3.0 # in RGB range ref is better 128.0 for Gray world theory correction

dr = ref - RCS_Ave_0
dg = ref - RCS_Ave_1
db = ref - RCS_Ave_2

r_bias = (r_bias + dr * bias_strength)
r_bias = Min (512.0, Max (r_bias, -512.0))

g_bias = (g_bias + dg * bias_strength)
g_bias = Min (512.0, Max (g_bias, -512.0))

b_bias = (b_bias + db * bias_strength)
b_bias = Min (512.0, Max (b_bias, -512.0))

RGBAdapt( RGB_clip, \
R_bias = r_bias, R_Gain = r_gain, R_Cont = r_cont, R_rpow = r_rpow, R_spow = r_spow, R_SPMid = r_spmid, R_Pord = pord,\
G_bias = g_bias, G_Gain = g_gain, G_Cont = g_cont, G_rpow = g_rpow, G_spow = g_spow, G_SPMid = g_spmid, G_Pord = pord,\
B_bias = b_bias, B_Gain = b_gain, B_Cont = b_cont, B_rpow = b_rpow, B_spow = b_spow, B_SPMid = b_spmid, B_Pord = pord)

(blanklip == 0) ? RGB_clip : last

#----------- variables strings are tuned in global mode for data display in following ScriptClip

global r_args = (!show_info)? nop : \
RT_String("\\n R_bias : %s R_gain : %s R_cont : %s \\n R_rpow : %s R_spow : %s R_spmid : %s",\
string(r_bias), string(r_gain), string(r_cont), string(r_rpow), string(r_spow), string(r_spmid),esc =1)
global g_args = (!show_info)? nop : \
RT_String("\\n G_bias : %s G_gain : %s G_cont : %s \\n G_rpow : %s G_spow : %s G_spmid : %s",\
string(g_bias), string(g_gain), string(g_cont), string(g_rpow), string(g_spow), string(g_spmid),esc =1)
global b_args = (!show_info)? nop : \
RT_String("\\n B_bias : %s B_gain : %s B_cont : %s \\n B_rpow : %s B_spow : %s B_spmid : %s",\
string(b_bias), string(b_gain), string(b_cont), string(b_rpow), string(b_spow), string(b_spmid),esc =1)

return last """, args = "RGB_clip, show_info, x, y, w , h, gain_strength, threshold, auto_cont, cont_strength, auto_spow, rpow_strength, spow_strength,"+\
"pord, bias_strength")

Bernardd
25th October 2016, 23:16
The function script part 2

#--------- datas display process

(!show_info) ? last :\
ScriptClip(last, """

#--------- start RGB values extraction for display

RT_RgbChanStats( RGB_clip, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+16)
start_ave = (RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2)/3.0
r_start = RT_String("\\nDeparture : Average : %s Min/max : %s Min : %s Max : %s",\
string(RCS_Ave_0), string(RCS_MinMaxDiff_0), string(RCS_Min_0), string(RCS_Max_0),esc =1)
g_start = RT_String("\\nDeparture : Average : %s Min/max : %s Min : %s Max : %s",\
string(RCS_Ave_1), string(RCS_MinMaxDiff_1), string(RCS_Min_1), string(RCS_Max_1),esc =1)
b_start = RT_String("\\nDeparture : Average : %s Min/max : %s Min : %s Max : %s",\
string(RCS_Ave_2), string(RCS_MinMaxDiff_2), string(RCS_Min_2), string(RCS_Max_2),esc =1)

#--------- final RGB values extraction for display

RT_RgbChanStats( last, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+8+16)

r_end = RT_String("\\nFinish : Average : %s Min/max : %s Min : %s Max : %s",\
string(RCS_Ave_0), string(RCS_MinMaxDiff_0), string(RCS_Min_0), string(RCS_Max_0),esc =1)
g_end = RT_String("\\nFinish : Average : %s Min/max : %s Min : %s Max : %s",\
string(RCS_Ave_1), string(RCS_MinMaxDiff_1), string(RCS_Min_1), string(RCS_Max_1),esc =1)
b_end = RT_String("\\nFinish : Average : %s Min/max : %s Min : %s Max : %s",\
string(RCS_Ave_2), string(RCS_MinMaxDiff_2), string(RCS_Min_2), string(RCS_Max_2),esc =1)

#-------- display

Subtitle("channels averages average : " + string(start_ave)+\
"\n\n" + "Red values : " + r_start + r_args + r_end +\
"\n\n" + "Green values : " + g_start + g_args + g_end+\
"\n\n" + "Blue values : " + b_start + b_args + b_end+\
"\n\n" + "channels averages average : " + string((RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2 )/3)\
,y = 20, lsp = 20, text_color = $00FFFF00, halo_color = $00000000, size = float(height()/32.0))

return last """, args = "RGB_clip, x, y, w , h, threshold")

#-------- display scrutinized aera

scrutinized_green = (!show_scrutinized)? nop : BlankClip(RGB_clip, width = (Width(last)-x+w), height = (Height(last)-y+h), color=$00FF00)
scrutinized_white = (!show_scrutinized)? nop : Blankclip(RGB_clip, width = (Width(last)-x+w), height = (Height(last)-y+h), color=$FFFFFF)
scrutinized_int = (!show_scrutinized)? nop : Blankclip(RGB_clip, width = (Width(scrutinized_white)-4), height = (Height(scrutinized_white)-4),\
color=000000)

scrutinized_mask = (!show_scrutinized)? nop : Overlay(scrutinized_white, scrutinized_int, x=2, y=2, opacity=1.0, mode="multiply", greymask=true,\
ignore_conditional=false, pc_range=false)

scrutinized = (!show_scrutinized)? nop : Overlay(last, scrutinized_green, mask = scrutinized_mask, x=x, y=y, opacity=1.0, mode="blend", greymask=true,\
ignore_conditional=false, pc_range=false)

(!show_scrutinized)? last : scrutinized

#--------- End of RGB color space process

!isRGB(clip) ? ConvertToYV12(last, matrix=matrix) : last

}

StainlessS
25th October 2016, 23:24
Nice job Bernardd,

Just a second suggestion (by all means ignore), but RT_Subtitle is way faster than regular subtitle and with built in formatting
just like RT_String. Probably not of any great concern if static Subtitle applied on full clip, but if using eg ScriptClip to apply
some changing text/metrics, then would be significantly faster. Align arg also works as in Avisynth standard Subtitle, but has 1 or two
extra args I think (also works in color, but not large text, see demo in RT_ AVS/FSel_&_Subtitle_Demo/).

fvisagie
26th October 2016, 05:01
Nice job Bernardd,

Just a second suggestion (by all means ignore), but RT_Subtitle is way faster than regular subtitle and with built in formatting
just like RT_String. Probably not of any great concern if static Subtitle applied on full clip, but if using eg ScriptClip to apply
some changing text/metrics, then would be significantly faster. Align arg also works as in Avisynth standard Subtitle, but has 1 or two
extra args I think (also works in color, but not large text, see demo in RT_ AVS/FSel_&_Subtitle_Demo/).

Further advantages of RT_Subtitle() are that it supports all AVS colourspaces, and uses less memory especially on longer files (when called from ScriptClip() at least).

Bernardd
26th October 2016, 23:42
Hi StainlessS

In following posts, new version of the script, only function script no the unchanged call script.

The changes are in the end :

the best "ref" for final bias process, i take anymore the average of channels averages values of last extraction,
but the average of channels averages values given by gain process.

a try of use RT_Subtitle. It is not perfect, because today i cannot find how adjust letter size. With SD material the text
finish out of the screen. have you a tips ? Perhaps i must change order of displayed datas.

Thanks

The function script part 1

# ---------------------------- function script -------------------------------------

function RGBAdapt_awb_process(clip clip, string "matrix",bool "show_scrutinized", bool "show_info", float "x", float "y", float "w", float "h", \
float "threshold", float "gain_strength" , bool "auto_cont", float "cont_strength", \
bool "auto_spow", float "rpow_strength", float "spow_strength", bool "pord", float "bias_strength")

{

#----------------------------------------------based on RGBADapt plugin ---------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.php?p=1681286#post1681286 #
#------------------------------------------------------------------------------------------------------------------------------------------------- #

#---------------------------------------------- need RT_Stats plugin ----------------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.php?p=1584313#post1584313 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #

#---------------------------------------------- need GRunT plugin ----------------------------------------------------------------------------#
# script author : Gavino http://forum.doom9.org/showthread.php?p=1157083#post1157083 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #

Assert(IsYV12(clip) || IsRGB(clip)," Input video colorspace must be YV12 or RGB, not YUV")
matrix = string(Default(matrix, "Rec601") ) # Color standard, Rec 601 or Rec 709
Assert(matrix == "Rec601" || matrix == "Rec709", """RGBAdapt_auto_awb: matrix "Rec601" or "Rec709"""")
show_scrutinized = Default(show_scrutinized, false) # show scrutinized aera or not, default false
show_info = Default(show_info, false) # show info or not, default false
x = float(Default(x,0.00)) #width percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(x>=0.00 && x <= 0.99,"RGBAdapt_auto_awb: x 0.00 -> 0.99")
y = float(Default(y,0.00)) #heignt percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(y>=0.00 && y <= 0.99,"RGBAdapt_auto_awb: y 0.00 -> 0.99")
w = float(Default(w,0.00)) #coords specify the source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(w>=0.00 && w <= 0.99,"RGBAdapt_auto_awb: w 0.00 -> 0.99")
Assert(x+w>=0.00 && x+w <= 0.99 ,"RGBAdapt_auto_awb: x+w 0.00 -> 0.99")
h = float(Default(h,0.00)) #coords specify the source rectangle under scrutiny , the default : x = y = h = w = 0.00 is full frame
Assert(h>=0.00 && h <= 0.99,"RGBAdapt_auto_awb: h 0.00 -> 0.99")
Assert(y+h>=0.00 && y+h <= 0.99 ,"RGBAdapt_auto_awb: x+w 0.00 -> 0.99")
threshold = Float(Default(threshold, 0.10)) # threshold arg of RT_Stats plugin
Assert(threshold>=0.00 && threshold <= 1.00,"RGBAdapt_auto_awb: threshold 0.00 -> 1.00")
gain_strength = Float(Default(gain_strength, 1.00)) # strength arg for gain
Assert(gain_strength>=0.00 && gain_strength <= 1.00,"RGBAdapt_auto_awb: gain_strength 0.00 -> 1.00")
auto_cont = Default(auto_cont, true) # auto weighted cont_strength arg
cont_strength = Float(Default(cont_strength, 1.00)) # strength arg for contrast
Assert(cont_strength>=0.00 && cont_strength <= 1.00,"RGBAdapt_auto_awb: cont_strength 0.00 -> 1.00")
auto_spow = Default(auto_spow, true) # auto weighted rpow_strength arg control by cont_strength arg
rpow_strength = Float(Default(rpow_strength, 1.00)) # strength arg for rpow
Assert(rpow_strength>=0.00 && rpow_strength <= 1.00,"RGBAdapt_auto_awb: rpow_strength 0.00 -> 1.00")
spow_strength = Float(Default(spow_strength, 1.00)) # strength arg for spow
Assert(spow_strength>=0.00 && spow_strength <= 1.00,"RGBAdapt_auto_awb: spow_strength 0.00 -> 1.00")
pord = Default(pord, false) # RGBAdapt pord arg
bias_strength = Float(Default(bias_strength, 1.00)) # strength arg for automatic bias_strength
Assert(bias_strength>=0.00 && bias_strength <= 1.00,"RGBAdapt_auto_awb: bias_strength 0.00 -> 1.00")

#---------- Specify the source rectangle under scrutiny

x = int(Width(clip) * x)
y = int(Height(clip) * y)
w = int(-Width(clip) * w)
h = int(-Height(clip) * h)

#--------- RGB color space process

RGB_clip = (!isRGB(clip)) ? ConvertToRGB24(clip, matrix=matrix) : clip

#--------- AWB process

ScriptClip(RGB_clip, """

#---------- First pass : gain process for each channel

RT_RgbChanStats( RGB_clip, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+16)

# ------ detection BlankClip and condition to avoid division by 0

blanklip = RCS_MinMaxDiff_0 + RCS_MinMaxDiff_1 + RCS_MinMaxDiff_2

RCS_MinMaxDiff_0 = Max (RCS_MinMaxDiff_0, 0.01) RCS_MinMaxDiff_1 = Max (RCS_MinMaxDiff_1, 0.01) RCS_MinMaxDiff_2 = Max (RCS_MinMaxDiff_2, 0.01)

#---- gain process

r_gain = 1 - (1 - float(255.0/RCS_MinMaxDiff_0)) * gain_strength
r_bias = - RCS_Min_0 * r_gain * gain_strength

g_gain = 1 - (1 - float(255.0/RCS_MinMaxDiff_1)) * gain_strength
g_bias = - RCS_Min_1 * g_gain * gain_strength


b_gain = 1 - (1 - float(255.0/RCS_MinMaxDiff_2)) * gain_strength
b_bias = - RCS_Min_2 * b_gain * gain_strength

#---- cont process

# Cont is dangerous, because it can overshoot light and dark, but it is necessary to help to find good correction for very big
# color cast. Thus bool auto_cont arg enable a automatic weighted autocont stength. I observe that picture do'nt need contraste is
# picture, which have a large histogram, which have min value near 0 et max value near 255, which have bigger min max diff value.
# But not it is simple, sometime the automatic weigthed autocont stength must be desable.

r_cont = (!auto_cont) ? 1 - (1 - r_gain) * cont_strength : 1 - (1 - r_gain) * cont_strength * (255.0 - RCS_MinMaxDiff_0)/255.0
r_cont_max = RCS_Max_0 * r_gain + r_bias + (r_cont - 1) *(RCS_Max_0 - 128)

g_cont = (!auto_cont) ? 1 - (1 - g_gain) * cont_strength : 1 - (1 - g_gain) * cont_strength * (255.0 - RCS_MinMaxDiff_1)/255.0
g_cont_max = RCS_Max_1 * g_gain + g_bias + (g_cont - 1) *(RCS_Max_1 - 128)

b_cont = (!auto_cont) ? 1 - (1 - b_gain) * cont_strength : 1 - (1 - b_gain) * cont_strength * (255.0 - RCS_MinMaxDiff_2)/255.0
b_cont_max = RCS_Max_2 * b_gain + b_bias + (b_cont - 1) *(RCS_Max_2 - 128)

r_cont_bias = (!auto_cont) ? (255 - r_cont_max) * cont_strength : \
(255 - r_cont_max) * cont_strength * (255.0 - RCS_MinMaxDiff_0)/255.0
g_cont_bias = (!auto_cont) ? (255 - g_cont_max) * cont_strength : \
(255 - g_cont_max) * cont_strength * (255.0 - RCS_MinMaxDiff_1)/255.0
b_cont_bias = (!auto_cont) ? (255 - b_cont_max) * cont_strength : \
(255 - b_cont_max) * cont_strength * (255.0 - RCS_MinMaxDiff_2)/255.0

#------------ gain and cont in RGBadapt args range

r_gain = Min (8.0, Max (r_gain, -8.0))
g_gain = Min (8.0, Max (g_gain, -8.0))
b_gain = Min (8.0, Max (b_gain, -8.0))

r_cont = Min (8.0, Max (r_cont, -8.0))
g_cont = Min (8.0, Max (g_cont, -8.0))
b_cont = Min (8.0, Max (b_cont, -8.0))

r_bias = r_bias + r_cont_bias
r_bias = Min (512.0, Max (r_bias, -512.0))
g_bias = g_bias + g_cont_bias
g_bias = Min (512.0, Max (g_bias, -512.0))
b_bias = b_bias + b_cont_bias
b_bias = Min (512.0, Max (b_bias, -512.0))

#---------- gamma curves corrections process in accordance with gray world theory

#----------- RGB values calculation

r_gain_cont_ave = RCS_Ave_0 * r_gain + r_bias + (r_cont - 1) *(RCS_Ave_0 - 128)
g_gain_cont_ave = RCS_Ave_1 * g_gain + g_bias + (g_cont - 1) *(RCS_Ave_1 - 128)
b_gain_cont_ave = RCS_Ave_2 * b_gain + b_bias + (b_cont - 1) *(RCS_Ave_2 - 128)

#----------- RGB gamma corrections values calcul

# In gray world theory, in YUV range, we increase or decrease average value to ref = 128.0, but in RGB range
# average of channel average values is better, with average of channel average value after gain process the
# picture ligth is better

# In gamma process, to incresae or decrease average value, we use gamma args. To find this gamma args, we
# solve this equation ref = pow(average value/255.0,1/gamma args)

# Gamma corrections are calculated with gain output, because is more refine than calculated with gain and cont output

ref = (RCS_Ave_0 * r_gain + r_bias + RCS_Ave_1 * g_gain + g_bias + RCS_Ave_2 * b_gain + b_bias)/3.0

r_rpow = 1 + (log((RCS_Ave_0 * r_gain + r_bias)/255.0)/log(ref/255.0) -1) * rpow_strength
r_rpow = Min (4.0, Max (r_rpow, 0.1))
g_rpow = 1 + (log((RCS_Ave_1* g_gain + g_bias)/255.0)/log(ref/255.0) - 1) * rpow_strength
g_rpow = Min (4.0, Max (g_rpow, 0.1))
b_rpow = 1 + (log((RCS_Ave_2 * b_gain + b_bias)/255.0)/log(ref/255.0) -1) * rpow_strength
b_rpow = Min (4.0, Max (b_rpow, 0.1))

#----------- RGB correction with spow curve calcul

#------- Spow process is enable in default mode, spmid and pord args default values increase
#------- rpow process action, thus we get more color saturation but also more dark aeras.
#------- Spow for rpow is like contrast for gain. Thus i use the same factor to get automatic
#------- weigthed spow arg

r_spow = (!auto_spow) ? 1 - (1 - 1/r_rpow) * spow_strength : \
1 - (1 - 1/r_rpow) * spow_strength * (255.0 - RCS_MinMaxDiff_0)/255.0
r_spow = Min (4.0, Max (r_spow, 0.1))
g_spow = (!auto_spow) ? 1 - (1 - 1/g_rpow) * spow_strength : \
1 - (1 - 1/g_rpow) * spow_strength * (255.0 - RCS_MinMaxDiff_1)/255.0
g_spow = Min (4.0, Max (g_spow, 0.1))
b_spow = (!auto_spow) ? 1 - (1 - 1/b_rpow) * spow_strength : \
1 - (1 - 1/b_rpow) * spow_strength * (255.0 - RCS_MinMaxDiff_2)/255.0
b_spow = Min (4.0, Max (b_spow, 0.1))

r_spmid = (r_spow == 1.0) ? 0.5 : (RCS_Ave_0 * r_gain + r_bias)/255.0
r_spmid = Min (0.99, Max (r_spmid, 0.01))
g_spmid = (g_spow == 1.0) ? 0.5 : (RCS_Ave_1* g_gain + g_bias)/255.0
g_spmid = Min (0.99, Max (g_spmid, 0.01))
b_spmid = (b_spow == 1.0) ? 0.5 : (RCS_Ave_2 * b_gain + b_bias)/255.0
b_spmid = Min (0.99, Max (b_spmid, 0.01))

#---------- bias corrections process in accordance with gray world theory

#----------- RGB bias corrections extraction and calcul

RGBAdapt( RGB_clip, \
R_bias = r_bias, R_Gain = r_gain, R_Cont = r_cont, R_rpow = r_rpow, R_spow = r_spow, R_SPMid = r_spmid, R_Pord = pord,\
G_bias = g_bias, G_Gain = g_gain, G_Cont = g_cont, G_rpow = g_rpow, G_spow = g_spow, G_SPMid = g_spmid, G_Pord = pord,\
B_bias = b_bias, B_Gain = b_gain, B_Cont = b_cont, B_rpow = b_rpow, B_spow = b_spow, B_SPMid = b_spmid, B_Pord = pord)

RT_RgbChanStats( LAST, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 16)

dr = ref - RCS_Ave_0 # better result with average of average values given by gain process
dg = ref - RCS_Ave_1
db = ref - RCS_Ave_2

r_bias = (r_bias + dr * bias_strength)
r_bias = Min (512.0, Max (r_bias, -512.0))

g_bias = (g_bias + dg * bias_strength)
g_bias = Min (512.0, Max (g_bias, -512.0))

b_bias = (b_bias + db * bias_strength)
b_bias = Min (512.0, Max (b_bias, -512.0))

RGBAdapt( RGB_clip, \
R_bias = r_bias, R_Gain = r_gain, R_Cont = r_cont, R_rpow = r_rpow, R_spow = r_spow, R_SPMid = r_spmid, R_Pord = pord,\
G_bias = g_bias, G_Gain = g_gain, G_Cont = g_cont, G_rpow = g_rpow, G_spow = g_spow, G_SPMid = g_spmid, G_Pord = pord,\
B_bias = b_bias, B_Gain = b_gain, B_Cont = b_cont, B_rpow = b_rpow, B_spow = b_spow, B_SPMid = b_spmid, B_Pord = pord)

(blanklip == 0) ? RGB_clip : last

#----------- variables strings are tuned in global mode for data display in following ScriptClip

global r_args1 = (!show_info)? nop : \
RT_String("\\n R_bias : %s R_gain : %s R_cont : %s \\n R_rpow : %s R_spow : %s R_spmid : %s",\
string(r_bias), string(r_gain), string(r_cont), string(r_rpow), string(r_spow), string(r_spmid),esc =1)
global g_args1 = (!show_info)? nop : \
RT_String("\\n G_bias : %s G_gain : %s G_cont : %s \\n G_rpow : %s G_spow : %s G_spmid : %s",\
string(g_bias), string(g_gain), string(g_cont), string(g_rpow), string(g_spow), string(g_spmid),esc =1)
global b_args1 = (!show_info)? nop : \
RT_String("\\n B_bias : %s B_gain : %s B_cont : %s \\n B_rpow : %s B_spow : %s B_spmid : %s",\
string(b_bias), string(b_gain), string(b_cont), string(b_rpow), string(b_spow), string(b_spmid),esc =1)

return last """, args = "RGB_clip, show_info, x, y, w , h, gain_strength, threshold, auto_cont, cont_strength, auto_spow, rpow_strength, spow_strength,"+\
"pord, bias_strength")


Bernard

Bernardd
26th October 2016, 23:44
The function script part 2

#--------- datas display process

(!show_info) ? last :\
ScriptClip(last, """

#--------- start RGB values extraction for display

RT_RgbChanStats( RGB_clip, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+16)
start_ave = (RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2)/3.0
r_start1 = RT_String("\\nDeparture : Average : %s Min/max : %s Min : %s Max : %s",\
string(RCS_Ave_0), string(RCS_MinMaxDiff_0), string(RCS_Min_0), string(RCS_Max_0),esc =1)
g_start1 = RT_String("\\nDeparture : Average : %s Min/max : %s Min : %s Max : %s",\
string(RCS_Ave_1), string(RCS_MinMaxDiff_1), string(RCS_Min_1), string(RCS_Max_1),esc =1)
b_start1 = RT_String("\\nDeparture : Average : %s Min/max : %s Min : %s Max : %s",\
string(RCS_Ave_2), string(RCS_MinMaxDiff_2), string(RCS_Min_2), string(RCS_Max_2),esc =1)

#--------- final RGB values extraction for display

RT_RgbChanStats( last, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+8+16)

r_end1 = RT_String("\\nFinish : Average : %s Min/max : %s Min : %s Max : %s",\
string(RCS_Ave_0), string(RCS_MinMaxDiff_0), string(RCS_Min_0), string(RCS_Max_0),esc =1)
g_end1 = RT_String("\\nFinish : Average : %s Min/max : %s Min : %s Max : %s",\
string(RCS_Ave_1), string(RCS_MinMaxDiff_1), string(RCS_Min_1), string(RCS_Max_1),esc =1)
b_end1 = RT_String("\\nFinish : Average : %s Min/max : %s Min : %s Max : %s",\
string(RCS_Ave_2), string(RCS_MinMaxDiff_2), string(RCS_Min_2), string(RCS_Max_2),esc =1)

#-------- display

RT_Subtitle("channels averages average : %s
\nRed value : %s %s %s
\nGreen values : %s %s %s
\nBlue values : %s %s %s
\nchannels averages average : %s",\
string(start_ave), r_start1, r_args1, r_end1, g_start1, g_args1, g_end1, b_start1, b_args1, b_end1,\
string((RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2 )/3),y = 20, esc = 2)

return last """, args = "RGB_clip, x, y, w , h, threshold")

#-------- display scrutinized aera

scrutinized_green = (!show_scrutinized)? nop : BlankClip(RGB_clip, width = (Width(last)-x+w), height = (Height(last)-y+h), color=$00FF00)
scrutinized_white = (!show_scrutinized)? nop : Blankclip(RGB_clip, width = (Width(last)-x+w), height = (Height(last)-y+h), color=$FFFFFF)
scrutinized_int = (!show_scrutinized)? nop : Blankclip(RGB_clip, width = (Width(scrutinized_white)-4), height = (Height(scrutinized_white)-4),\
color=000000)

scrutinized_mask = (!show_scrutinized)? nop : Overlay(scrutinized_white, scrutinized_int, x=2, y=2, opacity=1.0, mode="multiply", greymask=true,\
ignore_conditional=false, pc_range=false)

scrutinized = (!show_scrutinized)? nop : Overlay(last, scrutinized_green, mask = scrutinized_mask, x=x, y=y, opacity=1.0, mode="blend", greymask=true,\
ignore_conditional=false, pc_range=false)

(!show_scrutinized)? last : scrutinized

#--------- End of RGB color space process

!isRGB(clip) ? ConvertToYV12(last, matrix=matrix) : last

}

StainlessS
27th October 2016, 09:12
Bernardd, made a few mods, use as you will.


Added RT_String to Asserts.

Removed String from "String(Default(matrix, "Rec601"))", not necessary.

Changed eg "x>=0.00 && x <= 0.99" to "0.0 <= x <= 0.99" see http://forum.doom9.org/showthread.php?p=1783132#post1783132

Removed 'Float', eg (255.0/1) always float result. eg r_gain = 1 - (1 - (255.0/RCS_MinMaxDiff_0) * gain_strength

Converted RT_String "%s" string args to float "%f" (RT_String does conversion) eg
From:-
b_start1 = RT_String("\\nDeparture : Average : %s Min/max : %s Min : %s Max : %s",\
string(RCS_Ave_2), string(RCS_MinMaxDiff_2), string(RCS_Min_2), string(RCS_Max_2),esc =1)
To:-
b_start1 = RT_String("\\nDeparture : Average : %f Min/max : %f Min : %f Max : %f", RCS_Ave_2, RCS_MinMaxDiff_2, RCS_Min_2, RCS_Max_2,esc =1)

Added Global r_args2, etc.

Mod of Subtitle Stuff. (use RT_Subtitle if frame big enough, else use Subtitle).

part1

# ---------------------------- function script -------------------------------------

function RGBAdapt_awb_process(clip clip, string "matrix",bool "show_scrutinized", bool "show_info", float "x", float "y", float "w", float "h", \
float "threshold", float "gain_strength" , bool "auto_cont", float "cont_strength", \
bool "auto_spow", float "rpow_strength", float "spow_strength", bool "pord", float "bias_strength")

{

#----------------------------------------------based on RGBADapt plugin ---------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.ph...86#post1681286 #
#------------------------------------------------------------------------------------------------------------------------------------------------- #

#---------------------------------------------- need RT_Stats plugin ----------------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.ph...13#post1584313 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #

#---------------------------------------------- need GRunT plugin ----------------------------------------------------------------------------#
# script author : Gavino http://forum.doom9.org/showthread.ph...83#post1157083 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #
myName="RGBAdapt_awb_process: "
Assert(IsYV12(clip) || IsRGB(clip),RT_String("%sInput video colorspace must be YV12 or RGB, not YUV",myName))
matrix = Default(matrix, "Rec601") # Color standard, Rec 601 or Rec 709
Assert(matrix == "Rec601" || matrix == "Rec709",RT_String("%smatrix 'Rec601' or 'Rec709'('%s')",myName,matrix))
show_scrutinized = Default(show_scrutinized, false) # show scrutinized area or not, default false
show_info = Default(show_info, false) # show info or not, default false
x = float(Default(x,0.0)) #width percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= x <= 0.99,RT_String("%s0.0 <= x <= 0.99(%f)",myName,x))
y = float(Default(y,0.0)) #height percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= y <= 0.99,RT_String("%s0.0 <= y <= 0.99(%f)",myName,y))
w = float(Default(w,0.0)) #coords specify the source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= w <= 0.99,RT_String("%s0.0 <= w <= 0.99(%f)",myName,w))
Assert(0.0 <= (x+w) <= 0.99 ,RT_String("%s0.0 <= (x+w) <= 0.99(%f)",myName,x+w))
h = float(Default(h,0.0)) #coords specify the source rectangle under scrutiny , the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= h <= 0.99,RT_String("%s0.0 <= h <= 0.99(%f)",myName,h))
Assert(0.0 <= (y+h) <= 0.99 ,RT_String("%s0.0 <= (y+h) <= 0.99(%f)",myName,y+h))
threshold = Float(Default(threshold, 0.10)) # threshold arg of RT_Stats plugin
Assert(0.0 <= threshold <= 1.0,RT_String("%s0.0 <= threshold <= 1.0(%f)",myName,threshold))
gain_strength = Float(Default(gain_strength, 1.0)) # strength arg for gain
Assert(0.0 <= gain_strength <= 1.0,RT_String("%s0.0 <= gain_strength <= 1.0(%f)",myName,gain_strength))
auto_cont = Default(auto_cont, true) # auto weighted cont_strength arg
cont_strength = Float(Default(cont_strength, 1.0)) # strength arg for contrast
Assert(0.0 <= cont_strength <= 1.0,RT_String("%s0.0 <= cont_strength <= 1.0(%f)",myName,cont_strength))
auto_spow = Default(auto_spow, true) # auto weighted rpow_strength arg control by cont_strength arg
rpow_strength = Float(Default(rpow_strength, 1.0)) # strength arg for rpow
Assert(0.0 <= rpow_strength <= 1.0,RT_String("%s0.0 <= rpow_strength <= 1.0(%f)",myName,rpow_strength))
spow_strength = Float(Default(spow_strength, 1.0)) # strength arg for spow
Assert(0.0 <= spow_strength <= 1.0,RT_String("%s0.0 <= spow_strength <= 1.0(%f)",myName,spow_strength))
pord = Default(pord, false) # RGBAdapt pord arg
bias_strength = Float(Default(bias_strength, 1.0)) # strength arg for automatic bias_strength
Assert(0.0 <= bias_strength <= 1.0,RT_String("%s0.0 <= bias_strength <= 1.0(%f)",myName,bias_strength))

#---------- Specify the source rectangle under scrutiny

x = int(Width(clip) * x)
y = int(Height(clip) * y)
w = int(-Width(clip) * w)
h = int(-Height(clip) * h)

#--------- RGB color space process

RGB_clip = (!isRGB(clip)) ? ConvertToRGB24(clip, matrix=matrix) : clip

#--------- AWB process

ScriptClip(RGB_clip, """

#---------- First pass : gain process for each channel

RT_RgbChanStats( RGB_clip, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+16)

# ------ detection BlankClip and condition to avoid division by 0

blanklip = RCS_MinMaxDiff_0 + RCS_MinMaxDiff_1 + RCS_MinMaxDiff_2

RCS_MinMaxDiff_0 = Max (RCS_MinMaxDiff_0, 0.01) RCS_MinMaxDiff_1 = Max (RCS_MinMaxDiff_1, 0.01) RCS_MinMaxDiff_2 = Max (RCS_MinMaxDiff_2, 0.01)

#---- gain process

r_gain = 1 - (1 - (255.0/RCS_MinMaxDiff_0)) * gain_strength
r_bias = - RCS_Min_0 * r_gain * gain_strength

g_gain = 1 - (1 - (255.0/RCS_MinMaxDiff_1)) * gain_strength
g_bias = - RCS_Min_1 * g_gain * gain_strength


b_gain = 1 - (1 - (255.0/RCS_MinMaxDiff_2)) * gain_strength
b_bias = - RCS_Min_2 * b_gain * gain_strength

#---- cont process

# Cont is dangerous, because it can overshoot light and dark, but it is necessary to help to find good correction for very big
# color cast. Thus bool auto_cont arg enable a automatic weighted autocont stength. I observe that picture do'nt need contraste is
# picture, which have a large histogram, which have min value near 0 et max value near 255, which have bigger min max diff value.
# But not it is simple, sometime the automatic weigthed autocont stength must be desable.

r_cont = (!auto_cont) ? 1 - (1 - r_gain) * cont_strength : 1 - (1 - r_gain) * cont_strength * (255.0 - RCS_MinMaxDiff_0)/255.0
r_cont_max = RCS_Max_0 * r_gain + r_bias + (r_cont - 1) *(RCS_Max_0 - 128)

g_cont = (!auto_cont) ? 1 - (1 - g_gain) * cont_strength : 1 - (1 - g_gain) * cont_strength * (255.0 - RCS_MinMaxDiff_1)/255.0
g_cont_max = RCS_Max_1 * g_gain + g_bias + (g_cont - 1) *(RCS_Max_1 - 128)

b_cont = (!auto_cont) ? 1 - (1 - b_gain) * cont_strength : 1 - (1 - b_gain) * cont_strength * (255.0 - RCS_MinMaxDiff_2)/255.0
b_cont_max = RCS_Max_2 * b_gain + b_bias + (b_cont - 1) *(RCS_Max_2 - 128)

r_cont_bias = (!auto_cont) ? (255 - r_cont_max) * cont_strength : \
(255 - r_cont_max) * cont_strength * (255.0 - RCS_MinMaxDiff_0)/255.0
g_cont_bias = (!auto_cont) ? (255 - g_cont_max) * cont_strength : \
(255 - g_cont_max) * cont_strength * (255.0 - RCS_MinMaxDiff_1)/255.0
b_cont_bias = (!auto_cont) ? (255 - b_cont_max) * cont_strength : \
(255 - b_cont_max) * cont_strength * (255.0 - RCS_MinMaxDiff_2)/255.0

#------------ gain and cont in RGBadapt args range

r_gain = Min (8.0, Max (r_gain, -8.0))
g_gain = Min (8.0, Max (g_gain, -8.0))
b_gain = Min (8.0, Max (b_gain, -8.0))

r_cont = Min (8.0, Max (r_cont, -8.0))
g_cont = Min (8.0, Max (g_cont, -8.0))
b_cont = Min (8.0, Max (b_cont, -8.0))

r_bias = r_bias + r_cont_bias
r_bias = Min (512.0, Max (r_bias, -512.0))
g_bias = g_bias + g_cont_bias
g_bias = Min (512.0, Max (g_bias, -512.0))
b_bias = b_bias + b_cont_bias
b_bias = Min (512.0, Max (b_bias, -512.0))

#---------- gamma curves corrections process in accordance with gray world theory

#----------- RGB values calculation

r_gain_cont_ave = RCS_Ave_0 * r_gain + r_bias + (r_cont - 1) *(RCS_Ave_0 - 128)
g_gain_cont_ave = RCS_Ave_1 * g_gain + g_bias + (g_cont - 1) *(RCS_Ave_1 - 128)
b_gain_cont_ave = RCS_Ave_2 * b_gain + b_bias + (b_cont - 1) *(RCS_Ave_2 - 128)

#----------- RGB gamma corrections values calcul

# In gray world theory, in YUV range, we increase or decrease average value to ref = 128.0, but in RGB range
# average of channel average values is better, with average of channel average value after gain process the
# picture light is better

# In gamma process, to incresae or decrease average value, we use gamma args. To find this gamma args, we
# solve this equation ref = pow(average value/255.0,1/gamma args)

# Gamma corrections are calculated with gain output, because is more refine than calculated with gain and cont output

ref = (RCS_Ave_0 * r_gain + r_bias + RCS_Ave_1 * g_gain + g_bias + RCS_Ave_2 * b_gain + b_bias)/3.0

r_rpow = 1 + (log((RCS_Ave_0 * r_gain + r_bias)/255.0)/log(ref/255.0) -1) * rpow_strength
r_rpow = Min (4.0, Max (r_rpow, 0.1))
g_rpow = 1 + (log((RCS_Ave_1* g_gain + g_bias)/255.0)/log(ref/255.0) - 1) * rpow_strength
g_rpow = Min (4.0, Max (g_rpow, 0.1))
b_rpow = 1 + (log((RCS_Ave_2 * b_gain + b_bias)/255.0)/log(ref/255.0) -1) * rpow_strength
b_rpow = Min (4.0, Max (b_rpow, 0.1))

#----------- RGB correction with spow curve calcul

#------- Spow process is enable in default mode, spmid and pord args default values increase
#------- rpow process action, thus we get more color saturation but also more dark aeras.
#------- Spow for rpow is like contrast for gain. Thus i use the same factor to get automatic
#------- weigthed spow arg

r_spow = (!auto_spow) ? 1 - (1 - 1/r_rpow) * spow_strength : \
1 - (1 - 1/r_rpow) * spow_strength * (255.0 - RCS_MinMaxDiff_0)/255.0
r_spow = Min (4.0, Max (r_spow, 0.1))
g_spow = (!auto_spow) ? 1 - (1 - 1/g_rpow) * spow_strength : \
1 - (1 - 1/g_rpow) * spow_strength * (255.0 - RCS_MinMaxDiff_1)/255.0
g_spow = Min (4.0, Max (g_spow, 0.1))
b_spow = (!auto_spow) ? 1 - (1 - 1/b_rpow) * spow_strength : \
1 - (1 - 1/b_rpow) * spow_strength * (255.0 - RCS_MinMaxDiff_2)/255.0
b_spow = Min (4.0, Max (b_spow, 0.1))

r_spmid = (r_spow == 1.0) ? 0.5 : (RCS_Ave_0 * r_gain + r_bias)/255.0
r_spmid = Min (0.99, Max (r_spmid, 0.01))
g_spmid = (g_spow == 1.0) ? 0.5 : (RCS_Ave_1* g_gain + g_bias)/255.0
g_spmid = Min (0.99, Max (g_spmid, 0.01))
b_spmid = (b_spow == 1.0) ? 0.5 : (RCS_Ave_2 * b_gain + b_bias)/255.0
b_spmid = Min (0.99, Max (b_spmid, 0.01))

#---------- bias corrections process in accordance with gray world theory

#----------- RGB bias corrections extraction and calcul

RGBAdapt( RGB_clip, \
R_bias = r_bias, R_Gain = r_gain, R_Cont = r_cont, R_rpow = r_rpow, R_spow = r_spow, R_SPMid = r_spmid, R_Pord = pord,\
G_bias = g_bias, G_Gain = g_gain, G_Cont = g_cont, G_rpow = g_rpow, G_spow = g_spow, G_SPMid = g_spmid, G_Pord = pord,\
B_bias = b_bias, B_Gain = b_gain, B_Cont = b_cont, B_rpow = b_rpow, B_spow = b_spow, B_SPMid = b_spmid, B_Pord = pord)

RT_RgbChanStats( LAST, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 16)

dr = ref - RCS_Ave_0 # better result with average of average values given by gain process
dg = ref - RCS_Ave_1
db = ref - RCS_Ave_2

r_bias = (r_bias + dr * bias_strength)
r_bias = Min (512.0, Max (r_bias, -512.0))

g_bias = (g_bias + dg * bias_strength)
g_bias = Min (512.0, Max (g_bias, -512.0))

b_bias = (b_bias + db * bias_strength)
b_bias = Min (512.0, Max (b_bias, -512.0))

RGBAdapt( RGB_clip, \
R_bias = r_bias, R_Gain = r_gain, R_Cont = r_cont, R_rpow = r_rpow, R_spow = r_spow, R_SPMid = r_spmid, R_Pord = pord,\
G_bias = g_bias, G_Gain = g_gain, G_Cont = g_cont, G_rpow = g_rpow, G_spow = g_spow, G_SPMid = g_spmid, G_Pord = pord,\
B_bias = b_bias, B_Gain = b_gain, B_Cont = b_cont, B_rpow = b_rpow, B_spow = b_spow, B_SPMid = b_spmid, B_Pord = pord)

(blanklip == 0) ? RGB_clip : last

#----------- variables strings are tuned in global mode for data display in following ScriptClip

global r_args1 = (!show_info)? nop : RT_String(" R_bias=%7.3f : R_gain=%7.3f : R_cont =%7.3f",r_bias, r_gain, r_cont)
global r_args2 = (!show_info)? nop : RT_String(" R_rpow=%7.3f : R_spow=%7.3f : R_spmid=%7.3f",r_rpow,r_spow,r_spmid)

global g_args1 = (!show_info)? nop : RT_String(" G_bias=%7.3f : G_gain=%7.3f : G_cont =%7.3f",g_bias, g_gain, g_cont)
global g_args2 = (!show_info)? nop : RT_String(" G_rpow=%7.3f : G_spow=%7.3f : G_spmid=%7.3f",g_rpow, g_spow, g_spmid)

global b_args1 = (!show_info)? nop : RT_String(" B_bias=%7.3f : B_gain=%7.3f : B_cont =%7.3f",b_bias, b_gain, b_cont)
global b_args2 = (!show_info)? nop : RT_String(" B_rpow=%7.3f : B_spow=%7.3f : B_spmid=%7.3f",b_rpow, b_spow, b_spmid)

return last """, args = "RGB_clip, show_info, x, y, w , h, gain_strength, threshold, auto_cont, cont_strength, auto_spow, rpow_strength, spow_strength,"+\
"pord, bias_strength")

StainlessS
27th October 2016, 09:13
part 2


###########
###########
###########

#--------- datas display process

(!show_info) ? last :\
ScriptClip(last, """

#--------- start RGB values extraction for display

RT_RgbChanStats( RGB_clip, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+16)
start_ave = (RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2)/3.0
r_start1 = RT_String("Departure : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d",RCS_Ave_0, RCS_MinMaxDiff_0, RCS_Min_0, RCS_Max_0)
g_start1 = RT_String("Departure : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d",RCS_Ave_1, RCS_MinMaxDiff_1, RCS_Min_1, RCS_Max_1)
b_start1 = RT_String("Departure : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d",RCS_Ave_2, RCS_MinMaxDiff_2, RCS_Min_2, RCS_Max_2)

#--------- final RGB values extraction for display

RT_RgbChanStats( last, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+8+16)

r_end1 = RT_String("Finish : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d", RCS_Ave_0, RCS_MinMaxDiff_0, RCS_Min_0, RCS_Max_0)
g_end1 = RT_String("Finish : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d", RCS_Ave_1, RCS_MinMaxDiff_1, RCS_Min_1, RCS_Max_1)
b_end1 = RT_String("Finish : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d", RCS_Ave_2, RCS_MinMaxDiff_2, RCS_Min_2, RCS_Max_2)

#-------- display
CWID=65 CHIT=25 # display Width and Height in Subtitle characters
MinWid=CWID*10 MinHit=CHIT*20 # RT_Subtitle required width height in pixels (fixed font size is 10x20)
TooSmall=(Width<MinWid || Height<MinHit)

S=RT_String("\nchannels averages average : %f\n" +
\ "Red values :\n" +
\ "%s\n%s\n%s\n%s\n\n" +
\ "Green values :\n" +
\ "%s\n%s\n%s\n%s\n\n" +
\ "Blue values :\n" +
\ "%s\n%s\n%s\n%s\n\n" +
\ "channels averages average : %f",
\ start_ave,
\ r_start1, r_args1, r_args2, r_end1,
\ g_start1, g_args1, g_args2, g_end1,
\ b_start1, b_args1, g_args2, b_end1,
\ (RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2 )/3,Esc=(TooSmall)?0:1)

(TooSmall)
\ ? Subtitle(S,Font="Courier New",lsp=0,text_color=$00FFFF00,halo_color=$00000000,size=height/float(CHIT),Font_width=width/FloaT(CWID))
\ : RT_Subtitle("%s",S)

return last """, args = "RGB_clip, x, y, w , h, threshold")

###########
###########
###########

#-------- display scrutinized aera

scrutinized_green = (!show_scrutinized)? nop : BlankClip(RGB_clip, width = (Width(last)-x+w), height = (Height(last)-y+h), color=$00FF00)
scrutinized_white = (!show_scrutinized)? nop : Blankclip(RGB_clip, width = (Width(last)-x+w), height = (Height(last)-y+h), color=$FFFFFF)
scrutinized_int = (!show_scrutinized)? nop : Blankclip(RGB_clip, width = (Width(scrutinized_white)-4), height = (Height(scrutinized_white)-4),\
color=000000)

scrutinized_mask = (!show_scrutinized)? nop : Overlay(scrutinized_white, scrutinized_int, x=2, y=2, opacity=1.0, mode="multiply", greymask=true,\
ignore_conditional=false, pc_range=false)

scrutinized = (!show_scrutinized)? nop : Overlay(last, scrutinized_green, mask = scrutinized_mask, x=x, y=y, opacity=1.0, mode="blend", greymask=true,\
ignore_conditional=false, pc_range=false)

(!show_scrutinized)? last : scrutinized

#--------- End of RGB color space process

!isRGB(clip) ? ConvertToYV12(last, matrix=matrix) : last

}


Will use RT_Subtitle if frame big enough, else switch to SubTitle(used MonoSpaced font "Courier New") and font size will adjust to frame size.

EDIT: By the way, lsp adjusts EXTRA spacing for font, nearly always set as lsp=0.

Bernardd
27th October 2016, 09:49
Thanks StainlessS

First, I adopt your change. The script run always well and it is better for datas display.
Second, it is a pleasure to learn from one code writter master.

Bernard

StainlessS
27th October 2016, 10:02
Bernard


Average=%-7.3f : Min/max=%-3d


Formats 1st '%-7.3f' (float) arg to 7 characters (minimum) and left aligned ('-') with 3 character precision for fractional part.
'%-3d' format 3 character minimum for int args, left aligned ('%03d' would print eg '001' non significant zeros are printed)
Also eg '%1s', "True" would print only 1 character of string "True" ie "T".

Really powerful formatting options, see the Micro$oft link in docs for full info on formatting options (you can even supply eg precision as a data arg).

EDIT: eg "%-7.*f",4,PI would print "3.1416s" (* used for precision as data arg [where s is space]).
EDIT: Above in blue edited, was "3.146ss", oops.

EDIT: Changed this line (increased both by 1, avoid rounding error on small frames [font size can be a little too large @ eg 320x240]).

CWID=65 CHIT=25 # display Width and Height in Subtitle characters

StainlessS
27th October 2016, 14:05
Bernardd, another mod, use as you will.

Made multi-instance capable (but in the process managed to get rid of global variables, but now can use GScript If/Else etc).

/*
#----------------------------------------------based on RGBADapt plugin ---------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.php?t=170642 #
#------------------------------------------------------------------------------------------------------------------------------------------------- #

#---------------------------------------------- need RT_Stats plugin ----------------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.php?t=165479 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #

#---------------------------------------------- need GRunT plugin ----------------------------------------------------------------------------#
# plugin author : Gavino http://forum.doom9.org/showthread.php?t=139337 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #

#---------------------------------------------- need GScript plugin ----------------------------------------------------------------------------#
# plugin author : Gavino http://forum.doom9.org/showthread.php?t=147846 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #
*/

Function RGBAdapt_awb_process(clip clip, string "matrix",bool "show_scrutinized", bool "show_info", float "x", float "y", float "w", float "h",
\ float "threshold", float "gain_strength" , bool "auto_cont", float "cont_strength",
\ bool "auto_spow", float "rpow_strength", float "spow_strength", bool "pord", float "bias_strength") {
clip
myName="RGBAdapt_awb_process: "
Assert(RT_FunctionExist("RGBAdapt"),myName+"Essential RGBAdapt plugin installed, http://forum.doom9.org/showthread.php?t=170642")
Assert(RT_FunctionExist("GScriptClip"),myName+"Essential GRunT plugin installed, http://forum.doom9.org/showthread.php?t=139337")
Assert(RT_FunctionExist("GScript"),myName+"Essential GScript plugin installed, http://forum.doom9.org/showthread.php?t=147846")
Assert(IsYV12() || IsRGB(),RT_String("%sInput video colorspace must be YV12 or RGB, not YUV",myName))
matrix = Default(matrix, "Rec601") # Color standard, Rec 601 or Rec 709
Assert(matrix == "Rec601" || matrix == "Rec709",RT_String("%smatrix 'Rec601' or 'Rec709'('%s')",myName,matrix))
show_scrutinized = Default(show_scrutinized, false) # show scrutinized area or not, default false
show_info = Default(show_info, false) # show info or not, default false
x = float(Default(x,0.0)) #width percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= x <= 0.99,RT_String("%s0.0 <= x <= 0.99(%f)",myName,x))
y = float(Default(y,0.0)) #height percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= y <= 0.99,RT_String("%s0.0 <= y <= 0.99(%f)",myName,y))
w = float(Default(w,0.0)) #coords specify the source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= w <= 0.99,RT_String("%s0.0 <= w <= 0.99(%f)",myName,w))
Assert(0.0 <= (x+w) <= 0.99 ,RT_String("%s0.0 <= (x+w) <= 0.99(%f)",myName,x+w))
h = float(Default(h,0.0)) #coords specify the source rectangle under scrutiny , the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= h <= 0.99,RT_String("%s0.0 <= h <= 0.99(%f)",myName,h))
Assert(0.0 <= (y+h) <= 0.99 ,RT_String("%s0.0 <= (y+h) <= 0.99(%f)",myName,y+h))
threshold = Float(Default(threshold, 0.10)) # threshold arg of RT_Stats plugin
Assert(0.0 <= threshold <= 1.0,RT_String("%s0.0 <= threshold <= 1.0(%f)",myName,threshold))
gain_strength = Float(Default(gain_strength, 1.0)) # strength arg for gain
Assert(0.0 <= gain_strength <= 1.0,RT_String("%s0.0 <= gain_strength <= 1.0(%f)",myName,gain_strength))
auto_cont = Default(auto_cont, true) # auto weighted cont_strength arg
cont_strength = Float(Default(cont_strength, 1.0)) # strength arg for contrast
Assert(0.0 <= cont_strength <= 1.0,RT_String("%s0.0 <= cont_strength <= 1.0(%f)",myName,cont_strength))
auto_spow = Default(auto_spow, true) # auto weighted rpow_strength arg control by cont_strength arg
rpow_strength = Float(Default(rpow_strength, 1.0)) # strength arg for rpow
Assert(0.0 <= rpow_strength <= 1.0,RT_String("%s0.0 <= rpow_strength <= 1.0(%f)",myName,rpow_strength))
spow_strength = Float(Default(spow_strength, 1.0)) # strength arg for spow
Assert(0.0 <= spow_strength <= 1.0,RT_String("%s0.0 <= spow_strength <= 1.0(%f)",myName,spow_strength))
pord = Default(pord, false) # RGBAdapt pord arg
bias_strength = Float(Default(bias_strength, 1.0)) # strength arg for automatic bias_strength
Assert(0.0 <= bias_strength <= 1.0,RT_String("%s0.0 <= bias_strength <= 1.0(%f)",myName,bias_strength))
# ---------------------------- function script -------------------------------------
#---------- Specify the source rectangle under scrutiny

x = int(Width() * x)
y = int(Height() * y)
w = int(-Width() * w)
h = int(-Height() * h)

#--------- RGB color space process

(!isRGB()) ? ConvertToRGB24(matrix=matrix) : NOP

# Use same string at each frame.
Fmt=
\ "\nchannels averages average : %f\n\n" +
\ "Red values :\n" +
\ "Departure : Average=%7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d\n"+
\ " R_bias=%7.3f : R_gain =%7.3f : R_cont =%.3f\n"+
\ " R_rpow=%7.3f : R_spow =%7.3f : R_spmid=%.3f\n" +
\ "Finish : Average=%7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d\n" +
\ "\nGreen values :\n" +
\ "Departure : Average=%7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d\n"+
\ " G_bias=%7.3f : G_gain =%7.3f : G_cont =%.3f\n"+
\ " G_rpow=%7.3f : G_spow =%7.3f : G_spmid=%.3f\n" +
\ "Finish : Average=%7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d\n" +
\ "\nBlue values :\n" +
\ "Departure : Average=%7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d\n"+
\ " B_bias=%7.3f : B_gain =%7.3f : B_cont =%.3f\n"+
\ " B_rpow=%7.3f : B_spow =%7.3f : B_spmid=%.3f\n" +
\ "Finish : Average=%7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d\n" +
\ "\nchannels averages average : %f"

CWID=70 CHIT=23 # display Width and Height in Subtitle characters
MinWid=CWID*10 MinHit=CHIT*20 # RT_Subtitle required width height in pixels (fixed font size is 10x20)
TooSmall=(Width<MinWid || Height<MinHit)

#--------- AWB process

# ssS, NOTE, Args x,y,w,h to RGBAdapt_awb_process_Lo are Type Int
GSCript("""
Function RGBAdapt_awb_process_Lo(clip clp,bool show_info, int x, int y, int w, int h,
\ float threshold, float gain_strength , bool auto_cont, float cont_strength,
\ bool auto_spow, float rpow_strength, float spow_strength, bool pord, float bias_strength,String Fmt,Bool TooSmall,Int CWid,Int CHit) {
clp
n = current_frame # We dont actually use n for anything, I'll leave it here, maybe want to access eg n-1, ie RT_RgbChanStats(n=n-1)
#---------- First pass : gain process for each channel

Last.RT_RgbChanStats(x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+16)

# ssS, Leave RCS_ values as original (avoid repeat function call in Show_info), new variables without RCS_ prefix, avoid divide by zero
MinMaxDiff_0 = Max (RCS_MinMaxDiff_0, 0.01)
MinMaxDiff_1 = Max (RCS_MinMaxDiff_1, 0.01)
MinMaxDiff_2 = Max (RCS_MinMaxDiff_2, 0.01)

#---- gain process

r_gain = 1 - (1 - (255.0/MinMaxDiff_0)) * gain_strength
r_bias = - RCS_Min_0 * r_gain * gain_strength

g_gain = 1 - (1 - (255.0/MinMaxDiff_1)) * gain_strength
g_bias = - RCS_Min_1 * g_gain * gain_strength


b_gain = 1 - (1 - (255.0/MinMaxDiff_2)) * gain_strength
b_bias = - RCS_Min_2 * b_gain * gain_strength

#---- cont process

# Cont is dangerous, because it can overshoot light and dark, but it is necessary to help to find good correction for very big
# color cast. Thus bool auto_cont arg enable a automatic weighted autocont stength. I observe that picture do'nt need contraste is
# picture, which have a large histogram, which have min value near 0 et max value near 255, which have bigger min max diff value.
# But not it is simple, sometime the automatic weigthed autocont stength must be desable.

r_cont = (!auto_cont) ? 1 - (1 - r_gain) * cont_strength : 1 - (1 - r_gain) * cont_strength * (255.0 - MinMaxDiff_0)/255.0
r_cont_max = RCS_Max_0 * r_gain + r_bias + (r_cont - 1) *(RCS_Max_0 - 128)

g_cont = (!auto_cont) ? 1 - (1 - g_gain) * cont_strength : 1 - (1 - g_gain) * cont_strength * (255.0 - MinMaxDiff_1)/255.0
g_cont_max = RCS_Max_1 * g_gain + g_bias + (g_cont - 1) *(RCS_Max_1 - 128)

b_cont = (!auto_cont) ? 1 - (1 - b_gain) * cont_strength : 1 - (1 - b_gain) * cont_strength * (255.0 - MinMaxDiff_2)/255.0
b_cont_max = RCS_Max_2 * b_gain + b_bias + (b_cont - 1) *(RCS_Max_2 - 128)

r_cont_bias = (!auto_cont) ? (255 - r_cont_max) * cont_strength : (255 - r_cont_max) * cont_strength * (255.0 - MinMaxDiff_0)/255.0
g_cont_bias = (!auto_cont) ? (255 - g_cont_max) * cont_strength : (255 - g_cont_max) * cont_strength * (255.0 - MinMaxDiff_1)/255.0
b_cont_bias = (!auto_cont) ? (255 - b_cont_max) * cont_strength : (255 - b_cont_max) * cont_strength * (255.0 - MinMaxDiff_2)/255.0


EDIT: Your plugin links were broken, fixed.
EDIT: Updated, removed unnecessary multi-instance stuff, still multi-instance capable (no Globals)

StainlessS
27th October 2016, 14:06
Part 2



#------------ gain and cont in RGBadapt args range

r_gain = Min (8.0, Max (r_gain, -8.0))
g_gain = Min (8.0, Max (g_gain, -8.0))
b_gain = Min (8.0, Max (b_gain, -8.0))

r_cont = Min (8.0, Max (r_cont, -8.0))
g_cont = Min (8.0, Max (g_cont, -8.0))
b_cont = Min (8.0, Max (b_cont, -8.0))

r_bias = r_bias + r_cont_bias
r_bias = Min (512.0, Max (r_bias, -512.0))
g_bias = g_bias + g_cont_bias
g_bias = Min (512.0, Max (g_bias, -512.0))
b_bias = b_bias + b_cont_bias
b_bias = Min (512.0, Max (b_bias, -512.0))

#---------- gamma curves corrections process in accordance with gray world theory

#----------- RGB values calculation

r_gain_cont_ave = RCS_Ave_0 * r_gain + r_bias + (r_cont - 1) *(RCS_Ave_0 - 128)
g_gain_cont_ave = RCS_Ave_1 * g_gain + g_bias + (g_cont - 1) *(RCS_Ave_1 - 128)
b_gain_cont_ave = RCS_Ave_2 * b_gain + b_bias + (b_cont - 1) *(RCS_Ave_2 - 128)

#----------- RGB gamma corrections values calcul

# In gray world theory, in YUV range, we increase or decrease average value to ref = 128.0, but in RGB range
# average of channel average values is better, with average of channel average value after gain process the
# picture light is better

# In gamma process, to incresae or decrease average value, we use gamma args. To find this gamma args, we
# solve this equation ref = pow(average value/255.0,1/gamma args)

# Gamma corrections are calculated with gain output, because is more refine than calculated with gain and cont output

ref = (RCS_Ave_0 * r_gain + r_bias + RCS_Ave_1 * g_gain + g_bias + RCS_Ave_2 * b_gain + b_bias)/3.0

r_rpow = 1 + (log((RCS_Ave_0 * r_gain + r_bias)/255.0)/log(ref/255.0) -1) * rpow_strength
r_rpow = Min (4.0, Max (r_rpow, 0.1))
g_rpow = 1 + (log((RCS_Ave_1* g_gain + g_bias)/255.0)/log(ref/255.0) - 1) * rpow_strength
g_rpow = Min (4.0, Max (g_rpow, 0.1))
b_rpow = 1 + (log((RCS_Ave_2 * b_gain + b_bias)/255.0)/log(ref/255.0) -1) * rpow_strength
b_rpow = Min (4.0, Max (b_rpow, 0.1))

#----------- RGB correction with spow curve calcul

#------- Spow process is enable in default mode, spmid and pord args default values increase
#------- rpow process action, thus we get more color saturation but also more dark aeras.
#------- Spow for rpow is like contrast for gain. Thus i use the same factor to get automatic
#------- weigthed spow arg

r_spow = (!auto_spow) ? 1 - (1 - 1/r_rpow) * spow_strength : 1 - (1 - 1/r_rpow) * spow_strength * (255.0 - MinMaxDiff_0)/255.0
r_spow = Min (4.0, Max (r_spow, 0.1))
g_spow = (!auto_spow) ? 1 - (1 - 1/g_rpow) * spow_strength : 1 - (1 - 1/g_rpow) * spow_strength * (255.0 - MinMaxDiff_1)/255.0
g_spow = Min (4.0, Max (g_spow, 0.1))
b_spow = (!auto_spow) ? 1 - (1 - 1/b_rpow) * spow_strength : 1 - (1 - 1/b_rpow) * spow_strength * (255.0 - MinMaxDiff_2)/255.0
b_spow = Min (4.0, Max (b_spow, 0.1))

r_spmid = (r_spow == 1.0) ? 0.5 : (RCS_Ave_0 * r_gain + r_bias)/255.0
r_spmid = Min (0.99, Max (r_spmid, 0.01))
g_spmid = (g_spow == 1.0) ? 0.5 : (RCS_Ave_1* g_gain + g_bias)/255.0
g_spmid = Min (0.99, Max (g_spmid, 0.01))
b_spmid = (b_spow == 1.0) ? 0.5 : (RCS_Ave_2 * b_gain + b_bias)/255.0
b_spmid = Min (0.99, Max (b_spmid, 0.01))

#---------- bias corrections process in accordance with gray world theory

#----------- RGB bias corrections extraction and calcul
# ssS, Create and measure temp clip
TempC=Last.RGBAdapt(
\ R_bias = r_bias, R_Gain = r_gain, R_Cont = r_cont, R_rpow = r_rpow, R_spow = r_spow, R_SPMid = r_spmid, R_Pord = pord,
\ G_bias = g_bias, G_Gain = g_gain, G_Cont = g_cont, G_rpow = g_rpow, G_spow = g_spow, G_SPMid = g_spmid, G_Pord = pord,
\ B_bias = b_bias, B_Gain = b_gain, B_Cont = b_cont, B_rpow = b_rpow, B_spow = b_spow, B_SPMid = b_spmid, B_Pord = pord)

TempC.RT_RgbChanStats(x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 16,Prefix="TMP_")

dr = ref - TMP_Ave_0 # better result with average of average values given by gain process
dg = ref - TMP_Ave_1
db = ref - TMP_Ave_2

r_bias = (r_bias + dr * bias_strength)
r_bias = Min (512.0, Max (r_bias, -512.0))

g_bias = (g_bias + dg * bias_strength)
g_bias = Min (512.0, Max (g_bias, -512.0))

b_bias = (b_bias + db * bias_strength)
b_bias = Min (512.0, Max (b_bias, -512.0))

# ssS, now change for real
Last.RGBAdapt(
\ R_bias = r_bias, R_Gain = r_gain, R_Cont = r_cont, R_rpow = r_rpow, R_spow = r_spow, R_SPMid = r_spmid, R_Pord = pord,
\ G_bias = g_bias, G_Gain = g_gain, G_Cont = g_cont, G_rpow = g_rpow, G_spow = g_spow, G_SPMid = g_spmid, G_Pord = pord,
\ B_bias = b_bias, B_Gain = b_gain, B_Cont = b_cont, B_rpow = b_rpow, B_spow = b_spow, B_SPMid = b_spmid, B_Pord = pord)

if(show_info) {

#--------- final RGB values extraction for display
# ssS, Used different Prefix so as not to destroy original variables

Last.RT_RgbChanStats(x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+8+16,Prefix="FIN_")

#-------- display

S=RT_String(Fmt,
\ (RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2)/3.0,
\
\ RCS_Ave_0, RCS_MinMaxDiff_0, RCS_Min_0, RCS_Max_0,
\ r_bias, r_gain,r_cont,
\ r_rpow,r_spow,r_spmid,
\ FIN_Ave_0, FIN_MinMaxDiff_0, FIN_Min_0, FIN_Max_0,
\
\ RCS_Ave_1, RCS_MinMaxDiff_1, RCS_Min_1, RCS_Max_1,
\ g_bias, g_gain,g_cont,
\ g_rpow,g_spow,g_spmid,
\ FIN_Ave_1, FIN_MinMaxDiff_1, FIN_Min_1, FIN_Max_1,
\
\ RCS_Ave_2, RCS_MinMaxDiff_2, RCS_Min_2, RCS_Max_2,
\ b_bias,b_gain,b_cont,
\ b_rpow,b_spow,b_spmid,
\ FIN_Ave_2, FIN_MinMaxDiff_2, FIN_Min_2, FIN_Max_2,
\
\ (FIN_Ave_0 + FIN_Ave_1 + FIN_Ave_2 )/3,Esc=(TooSmall)?0:1)

(TooSmall)
\ ? Last.Subtitle(S,Font="Courier New",lsp=0,text_color=$00FFFF00,halo_color=$00000000,size=height/float(CHIT),Font_width=width/FloaT(CWID))
\ : Last.RT_Subtitle("%s",S)
} # end ShowInfo
Return Last
}
ARGS="show_info,x,y,w,h,threshold,gain_strength,auto_cont,cont_strength," +
\ "auto_spow,rpow_strength,spow_strength,pord,bias_strength,Fmt,TooSmall,CWid,CHit"
Last.GScriptClip("RGBAdapt_awb_process_Lo(last, "+ARGS+")", local=true, args=ARGS)
# ssS, Do border outside of Scriptclip.
if(show_scrutinized) {
#-------- display scrutinized area
scrutinized_green = Last.BlankClip(width = Last.Width-x+w, height = Last.Height-y+h, color=$00FF00)
scrutinized_white = scrutinized_green.Blankclip(color=$FFFFFF)
scrutinized_int = Last.Blankclip(width = scrutinized_white.Width-4, height = scrutinized_white.Height-4,color=000000)
scrutinized_mask = scrutinized_white.Overlay(scrutinized_int, x=2, y=2, opacity=1.0, mode="multiply", greymask=true,
\ ignore_conditional=false, pc_range=false)
Last.Overlay(scrutinized_green, mask = scrutinized_mask, x=x, y=y, opacity=1.0, mode="blend", greymask=true,
\ ignore_conditional=false, pc_range=false)
} # End show_scrutinized
Return Last
""")
Return (!isRGB) ? ConvertToYV12(last, matrix=matrix) : last
}

Bernardd
27th October 2016, 21:34
Thanks StainlessS

With your explanations an tips, i discover a new world. I shall study these new ways.

Bernard

Bernardd
7th November 2016, 19:03
Hello StainlessS,

To day, i have not kept your multi-instance capable amend, because i search now a easier use for the script. Thus i have worked only on user's inputs.

My auto white balance script has many parameters.
To help with the choice of combinations of these parameters, I introduced a "preset" mode
This new preset parameter can take the values:
3, default value, corresponding to the use of the gain, contrast weighted, rpow, spow weighted and bias
2, only gain, rpow and unweighted spow
1, only gain and bias
0, no presets, all parameters are freely adjustable

To help in the selection of presets, the comparison shows now 9 versions of Clip
top, from left to right
the original, gain and only rpow process, combination of gain, contrast, rpow, spow and bias without contrast weighting and without spow weighting
in the middle, from left to right
gain and bias, combination of gain rpow and unweighted spow, combination of gain, contrast, rpow, spow and bias with contrast weighting and with spow weighting
bottom, from left to right
bias only, combination of gain rpow and weighted spow, and last combination given by the operator settings

To facilitate comparison, the preset outputs are all aligned in the middle. This presentation is to assess the action of the contrast and weights
by comparing with the output displayed at the top or bottom. Note that all the combinations are not displayed, but I hope that this provision helps
find the most effective combination.

Three examples of this comparison. The images are from the John Meyer's demo clip

Perhaps preset 1

http://img.xooimage.com/files110/f/4/9/john-homme_2-50d7b8e.png

Perhaps the preset 2

http://img.xooimage.com/files110/3/b/4/john-sable_2-50d7b9e.png


Perhaps the preset 3

http://img.xooimage.com/files110/f/3/8/john-perroquet_2-50d7bb7.png

The script is in the following posts

Bernard

Bernardd
7th November 2016, 19:23
The call script


AVISource("C:\.............\your video.avi")
LoadPlugin("C:\.............\GRunT.dll")
LoadPlugin("C:\.............\RGBAdapt.dll")
LoadPlugin("C:\.............\RT_Stats26.dll")

# display tunings
comparison = true
show_scrutinized = true
show_info = false

# color space matrix tuning and specify the source rectangle under scrutiny
matrix = "Rec601"
x = 0.09
Y= 0.09
w = 0.09
h = 0.09

preset = 3

# autogain tunings
threshold = 0.10
gain_strength = 1.0

# autocontraste tunings
auto_cont = true
cont_strength = 1.0

# gamma process tunings
auto_spow = true
rpow_strength = 1.0
spow_strength = 1.0
pord = false

# bias tuning
bias_strength = 1.0

# If you use AvsPmod user sliders you can delete comment for follow lines

#~ [<separator="display tunings">]
#~ comparison = Select([<"show different settings - (false ou true) default = false = 0", 0, 1, 0>], false , true)
#~ show_scrutinized = Select([<"show scrutinized aera - (false ou true) default = false = 0", 0, 1, 0>], false , true)
#~ show_info = Select([<"show datas - (false ou true) default = false = 0", 0, 1, 0>], false , true)

#~ [<separator="color space matrix tuning - specify the source rectangle under scrutiny and percentage extreme pixels to ignore">]
#~ matrix = Select([<"color matrix - (Rec 601= 0 ou Rec 709 =1) = default = 0", 0, 1, 0>], "Rec601" , "Rec709")
#~ x = [<"ignore pixels on left - width percentage - default : 0.00", 0.00, 0.99, 0.07>]
#~ Y= [<"ignore pixels on top - heigth percentage - default : 0.00", 0.00, 0.99, 0.07>]
#~ w = [<"ignore pixels on right - width percentage - default : 0.00", 0.00, 0.99, 0.07>]
#~ h = [<"ignore pixels on bottom - heigth percentage - default : 0.00", 0.00, 0.99, 0.07>]
#~ threshold = [<"percentage for extreme pixels to be ignored - default : 0.10", 0.00, 1.00, 0.1>]

#~ [<separator="automatic white balance tunings">]

#~ [<separator="------------ first automatic white balance tunings with preset 1 - 2 or 3">]
#~ preset = Select([<"preset (free - gain+bias - gain+rpow+spow or all) default = 3", 0, 3, 3>], 0 , 1, 2, 3)

#~ [<separator="------------ second automatic white balance tunings with free args when preset 0">]
#~ [<separator="gain_strength args tunings">]
#~ gain_strength = [<"enable and strength gain process - default = 1.0", 0.0, 1.0, 1.0>]

#~ [<separator="cont strength args tunings - - cont arg can be free or automatic weighted tunable">]
#~ auto_cont = Select([<"auto_cont - (auto weighted cont strength ) default = true = 1", 0, 1, 1>], false , true)
#~ [<separator="----------- below free or automatic weighted strength adjust">]
#~ cont_strength = [<"----------- enable and strength cont process - default = 1.0", 0.0, 1.0, 1.0>]

#~ [<separator="gamma process args tunings">]
#~ rpow_strength = [<"enable and strength rpow process - default = 1.0", 0.0, 1.0, 1.0>]
#~ [<separator="----------- spow args can be free or automatic weighted tunable">]
#~ auto_spow = Select([<"----------- auto_spow - (auto weighted spow strength) default = true = 1", 0, 1, 1>], false , true)
#~ spow_strength = [<"----------- enable and strength spow process - default = 1.0", 0.0, 1.0, 1.0>]
#~ pord = Select([<"pord - (false = rpow before spow ) default = false = 0", 0, 1, 0>], false , true)

#~ [<separator="free bias_strength args tuning">]
#~ bias_strength = [<"enable and strength bias process - default = 1.0", 0.0, 1.0, 1.0>]

output = RGBAdapt_awb_process(matrix = matrix, show_scrutinized = show_scrutinized, show_info = show_info, x = x, y = y, w = w, h = h, \
threshold = threshold, preset = preset, gain_strength = gain_strength, auto_cont = auto_cont,cont_strength = cont_strength, \
auto_spow = auto_spow,rpow_strength = rpow_strength, spow_strength = spow_strength, pord = pord, bias_strength = bias_strength)

bias_only = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, \
threshold = threshold, gain_strength = 0.0, cont_strength = 0.0, rpow_strength = 0.0, preset = 0)\
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("bias process only output near ColorYUV autowhite"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " gain strength : 0.0" + " auto_cont : true cont strength : 0.0" + \
"\n rpow strength : 0.0" + " auto_spow : true spow strength : 0.0" + " pord : false" +\
"\n bias strength : 1.0" , lsp = 20)

gain_bias_only = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, \
threshold = threshold, cont_strength = 0.0, rpow_strength = 0.0, preset = 1)\
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("gain and bias process only"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " gain strength : 1.0" + " auto_cont : true cont strength : 0.0" + \
"\n rpow strength : 0.0" + " auto_spow : true spow strength : 0.0" + " pord : false" +\
"\n bias strength : 1.0 preset 1", lsp = 20)

gain_rpow_only = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, \
threshold = threshold, cont_strength = 0.0, spow_strength = 0.0, bias_strength = 0.0, preset = 0) \
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("gain rpow process but no cont, no spow and no bias process"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " gain strength : 1.0" + " auto_cont : true cont strength : 0.0" + \
"\n rpow strength : 1.0" + " auto_spow : true spow strength : 0.0" + " pord : false" +\
"\n bias strength : 0.0" , lsp = 20)

gain_rpow_spow_only = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, \
threshold = threshold, cont_strength = 0.0, auto_spow = true, bias_strength = 0.0, preset = 0) \
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("gain rpow and auto weighted spow process but no cont and no bias process"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " gain strength : 1.0" + " auto_cont : false cont strength : 0.0" + \
"\n rpow strength : 1.0" + " auto_spow : true spow strength : 0.0" + " pord : false" +\
"\n bias strength : 0.0" , lsp = 20)

gain_rpow_spow_only_without_auto = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, \
threshold = threshold, cont_strength = 0.0, auto_cont = false, auto_spow = false, bias_strength = 0.0, preset = 2) \
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("gain, rpow and spow process but no cont and no bias process and no auto weighted mode for spow"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " gain strength : 1.0" + " auto_cont : false cont strength : 0.0" + \
"\n rpow strength : 1.0" + " auto_spow : false spow strength : 1.0" + " pord : false" +\
"\n bias strength : 0.0 preset 2" , lsp = 20)


all = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, threshold = threshold)\
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("gain cont rpow spow and bias process with auto mode for cont and gamma"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " gain strength : 1.0" + " auto_cont : true cont strength : 1.0" + \
"\n rpow strength : 1.0" + " auto_spow : true spow strength : 1.0" + " pord : false" +\
"\n bias strength : 1.0 preset 3" , lsp = 20)

all_without_auto = (!comparison) ? nop : RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = false, x = x, y = y, w = w, h = h, threshold = threshold,\
auto_cont = false, auto_spow = false, preset = 0) \
.AddBorders(0, 80, 0, 0, color=$000000). Subtitle ("gain cont rpow spow and bias process with auto mode for cont and gamma"+ \
"\n threshold : " + LeftStr(string(threshold),4) + " gain strength : 1.0" + " auto_cont : false cont strength : 1.0" + \
"\n rpow strength : 1.0" + " auto_spow : false spow strength : 1.0" + " pord : false" +\
"\n bias strength : 1.0" , lsp = 20)

compared_output = (!comparison) ? nop : StackVertical(StackHorizontal(last.AddBorders(0, 80, 0, 0, color=$000000).Subtitle("original"),gain_rpow_only, all_without_auto), \
StackHorizontal(gain_bias_only,gain_rpow_spow_only_without_auto, all), \
StackHorizontal(bias_only, gain_rpow_spow_only, output .AddBorders(0, 80, 0, 0, color=$008000)\
. Subtitle ("user setting where all args are free and or preset number : " +string(preset) + \
"\n threshold : " + LeftStr(string(threshold),4) + " gain strength : " + LeftStr(string(gain_strength),3) + " auto_cont : " + string(auto_cont)+\
" cont strength : " + LeftStr(string(cont_strength),3) + \
"\n rpow strength : " + LeftStr(string(rpow_strength),3) +" auto_spow : " + string(auto_spow) + " spow strength : " + \
LeftStr(string(spow_strength),3) + " pord : " + string(pord) +\
"\n bias strength : " + LeftStr(string(bias_strength),3) , lsp = 20)))

(!comparison) ? output : compared_output

Bernardd
7th November 2016, 19:24
The function script part 1


# ---------------------------- function script -------------------------------------

function RGBAdapt_awb_process(clip clip, string "matrix",bool "show_scrutinized", bool "show_info", float "x", float "y", float "w", float "h", \
float "threshold", int "preset", float "gain_strength" , bool "auto_cont", float "cont_strength", \
bool "auto_spow", float "rpow_strength", float "spow_strength", bool "pord", float "bias_strength")

{
#----------------------------------------------based on RGBADapt plugin ---------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.php?t=170642 #
#------------------------------------------------------------------------------------------------------------------------------------------------#

#---------------------------------------------- need RT_Stats plugin -------------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.php?t=165479 #
#------------------------------------------------------------------------------------------------------------------------------------------------#

#---------------------------------------------- need GRunT plugin ----------------------------------------------------------------------------#
# plugin author : Gavino http://forum.doom9.org/showthread.php?t=139337 #
#-----------------------------------------------------------------------------------------------------------------------------------------------#

myName="RGBAdapt_awb_process: "
Assert(IsYV12(clip) || IsRGB(clip),RT_String("%sInput video colorspace must be YV12 or RGB, not YUV",myName))
matrix = Default(matrix, "Rec601") # Color standard, Rec 601 or Rec 709
Assert(matrix == "Rec601" || matrix == "Rec709",RT_String("%smatrix 'Rec601' or 'Rec709'('%s')",myName,matrix))
show_scrutinized = Default(show_scrutinized, false) # show scrutinized area or not, default false
show_info = Default(show_info, false) # show info or not, default false
x = float(Default(x,0.0)) #width percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= x <= 0.99,RT_String("%s0.0 <= x <= 0.99(%f)",myName,x))
y = float(Default(y,0.0)) #height percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= y <= 0.99,RT_String("%s0.0 <= y <= 0.99(%f)",myName,y))
w = float(Default(w,0.0)) #coords specify the source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= w <= 0.99,RT_String("%s0.0 <= w <= 0.99(%f)",myName,w))
Assert(0.0 <= (x+w) <= 0.99 ,RT_String("%s0.0 <= (x+w) <= 0.99(%f)",myName,x+w))
h = float(Default(h,0.0)) #coords specify the source rectangle under scrutiny , the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= h <= 0.99,RT_String("%s0.0 <= h <= 0.99(%f)",myName,h))
Assert(0.0 <= (y+h) <= 0.99 ,RT_String("%s0.0 <= (y+h) <= 0.99(%f)",myName,y+h))
threshold = Float(Default(threshold, 0.10)) # threshold arg of RT_Stats plugin
Assert(0.0 <= threshold <= 1.0,RT_String("%s0.0 <= threshold <= 1.0(%f)",myName,threshold))
gain_strength = Float(Default(gain_strength, 1.0)) # strength arg for gain
Assert(0.0 <= gain_strength <= 1.0,RT_String("%s0.0 <= gain_strength <= 1.0(%f)",myName,gain_strength))
auto_cont = Default(auto_cont, true) # auto weighted cont_strength arg
cont_strength = Float(Default(cont_strength, 1.0)) # strength arg for contrast
Assert(0.0 <= cont_strength <= 1.0,RT_String("%s0.0 <= cont_strength <= 1.0(%f)",myName,cont_strength))
auto_spow = Default(auto_spow, true) # auto weighted rpow_strength arg control by cont_strength arg
rpow_strength = Float(Default(rpow_strength, 1.0)) # strength arg for rpow
Assert(0.0 <= rpow_strength <= 1.0,RT_String("%s0.0 <= rpow_strength <= 1.0(%f)",myName,rpow_strength))
spow_strength = Float(Default(spow_strength, 1.0)) # strength arg for spow
Assert(0.0 <= spow_strength <= 1.0,RT_String("%s0.0 <= spow_strength <= 1.0(%f)",myName,spow_strength))
pord = Default(pord, false) # RGBAdapt pord arg
bias_strength = Float(Default(bias_strength, 1.0)) # strength arg for automatic bias_strength
Assert(0.0 <= bias_strength <= 1.0,RT_String("%s0.0 <= bias_strength <= 1.0(%f)",myName,bias_strength))
preset= Int(Default(preset, 3))
Assert(0 <= preset <= 3,RT_String("%s preset = 0,1, 2 or 3 ( no %d)",myName,preset))

#---------- Specify the source rectangle under scrutiny

x = int(Width(clip) * x)
y = int(Height(clip) * y)
w = int(-Width(clip) * w)
h = int(-Height(clip) * h)

#--------- RGB color space process

RGB_clip = (!isRGB(clip)) ? ConvertToRGB24(clip, matrix=matrix) : clip

#--------- AWB process

ScriptClip(RGB_clip, """

#---------- First pass : gain process for each channel

RT_RgbChanStats( RGB_clip, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+16)

# ------ detection BlankClip and condition to avoid division by 0

blanklip = RCS_MinMaxDiff_0 + RCS_MinMaxDiff_1 + RCS_MinMaxDiff_2

RCS_MinMaxDiff_0 = Max (RCS_MinMaxDiff_0, 0.01) RCS_MinMaxDiff_1 = Max (RCS_MinMaxDiff_1, 0.01) RCS_MinMaxDiff_2 = Max (RCS_MinMaxDiff_2, 0.01)

#---- gain process

gain_strength = (preset == 1) || (preset == 2) || (preset == 3) ? 1.0 : gain_strength

r_gain = 1 - (1 - (255.0/RCS_MinMaxDiff_0)) * gain_strength
r_bias = - RCS_Min_0 * r_gain * gain_strength

g_gain = 1 - (1 - (255.0/RCS_MinMaxDiff_1)) * gain_strength
g_bias = - RCS_Min_1 * g_gain * gain_strength


b_gain = 1 - (1 - (255.0/RCS_MinMaxDiff_2)) * gain_strength
b_bias = - RCS_Min_2 * b_gain * gain_strength

#---- cont process

# Cont is dangerous, because it can overshoot light and dark, but it is necessary to help to find good correction for very big
# color cast. Thus bool auto_cont arg enable a automatic weighted autocont stength. I observe that picture do'nt need contraste is
# picture, which have a large histogram, which have min value near 0 et max value near 255, which have bigger min max diff value.
# But not it is simple, sometime the automatic weigthed autocont stength must be desable.

cont_strength = (preset == 1) || (preset == 2) ? 0.0 : ((preset == 3) ? 1.0 : cont_strength)
auto_cont = (preset == 1) || (preset == 2) || (preset == 3) ? true : auto_cont

r_cont = (!auto_cont) ? 1 - (1 - r_gain) * cont_strength : 1 - (1 - r_gain) * cont_strength * (255.0 - RCS_MinMaxDiff_0)/255.0
r_cont_max = RCS_Max_0 * r_gain + r_bias + (r_cont - 1) *(RCS_Max_0 - 128)

g_cont = (!auto_cont) ? 1 - (1 - g_gain) * cont_strength : 1 - (1 - g_gain) * cont_strength * (255.0 - RCS_MinMaxDiff_1)/255.0
g_cont_max = RCS_Max_1 * g_gain + g_bias + (g_cont - 1) *(RCS_Max_1 - 128)

b_cont = (!auto_cont) ? 1 - (1 - b_gain) * cont_strength : 1 - (1 - b_gain) * cont_strength * (255.0 - RCS_MinMaxDiff_2)/255.0
b_cont_max = RCS_Max_2 * b_gain + b_bias + (b_cont - 1) *(RCS_Max_2 - 128)

r_cont_bias = (!auto_cont) ? (255 - r_cont_max) * cont_strength : \
(255 - r_cont_max) * cont_strength * (255.0 - RCS_MinMaxDiff_0)/255.0
g_cont_bias = (!auto_cont) ? (255 - g_cont_max) * cont_strength : \
(255 - g_cont_max) * cont_strength * (255.0 - RCS_MinMaxDiff_1)/255.0
b_cont_bias = (!auto_cont) ? (255 - b_cont_max) * cont_strength : \
(255 - b_cont_max) * cont_strength * (255.0 - RCS_MinMaxDiff_2)/255.0

#------------ gain and cont in RGBadapt args range

r_gain = Min (8.0, Max (r_gain, -8.0))
g_gain = Min (8.0, Max (g_gain, -8.0))
b_gain = Min (8.0, Max (b_gain, -8.0))

r_cont = Min (8.0, Max (r_cont, -8.0))
g_cont = Min (8.0, Max (g_cont, -8.0))
b_cont = Min (8.0, Max (b_cont, -8.0))

r_bias = r_bias + r_cont_bias
r_bias = Min (512.0, Max (r_bias, -512.0))
g_bias = g_bias + g_cont_bias
g_bias = Min (512.0, Max (g_bias, -512.0))
b_bias = b_bias + b_cont_bias
b_bias = Min (512.0, Max (b_bias, -512.0))

#---------- gamma curves corrections process in accordance with gray world theory

#----------- RGB values calculation

r_gain_cont_ave = RCS_Ave_0 * r_gain + r_bias + (r_cont - 1) *(RCS_Ave_0 - 128)
g_gain_cont_ave = RCS_Ave_1 * g_gain + g_bias + (g_cont - 1) *(RCS_Ave_1 - 128)
b_gain_cont_ave = RCS_Ave_2 * b_gain + b_bias + (b_cont - 1) *(RCS_Ave_2 - 128)

#----------- RGB gamma corrections values calcul

# In gray world theory, in YUV range, we increase or decrease average value to ref = 128.0, but in RGB range
# average of channel average values is better, with average of channel average value after gain process the
# picture light is better

# In gamma process, to incresae or decrease average value, we use gamma args. To find this gamma args, we
# solve this equation ref = pow(average value/255.0,1/gamma args)

# Gamma corrections are calculated with gain output, because is more refine than calculated with gain and cont output

ref = (RCS_Ave_0 * r_gain + r_bias + RCS_Ave_1 * g_gain + g_bias + RCS_Ave_2 * b_gain + b_bias)/3.0

rpow_strength = (preset == 1) ? 0.0 : ((preset == 2) || (preset == 3) ? 1.0 : rpow_strength)

r_rpow = 1 + (log((RCS_Ave_0 * r_gain + r_bias)/255.0)/log(ref/255.0) -1) * rpow_strength
r_rpow = Min (4.0, Max (r_rpow, 0.1))
g_rpow = 1 + (log((RCS_Ave_1* g_gain + g_bias)/255.0)/log(ref/255.0) - 1) * rpow_strength
g_rpow = Min (4.0, Max (g_rpow, 0.1))
b_rpow = 1 + (log((RCS_Ave_2 * b_gain + b_bias)/255.0)/log(ref/255.0) -1) * rpow_strength
b_rpow = Min (4.0, Max (b_rpow, 0.1))

#----------- RGB correction with spow curve calcul

#------- Spow process is enable in default mode, spmid and pord args default values increase
#------- rpow process action, thus we get more color saturation but also more dark aeras.
#------- Spow for rpow is like contrast for gain. Thus i use the same factor to get automatic
#------- weigthed spow arg

auto_spow = (preset == 2) ? false : ((preset == 1)|| (preset == 3) ? true : auto_spow)

r_spow = (!auto_spow) ? 1 - (1 - 1/r_rpow) * spow_strength : \
1 - (1 - 1/r_rpow) * spow_strength * (255.0 - RCS_MinMaxDiff_0)/255.0
r_spow = Min (4.0, Max (r_spow, 0.1))
g_spow = (!auto_spow) ? 1 - (1 - 1/g_rpow) * spow_strength : \
1 - (1 - 1/g_rpow) * spow_strength * (255.0 - RCS_MinMaxDiff_1)/255.0
g_spow = Min (4.0, Max (g_spow, 0.1))
b_spow = (!auto_spow) ? 1 - (1 - 1/b_rpow) * spow_strength : \
1 - (1 - 1/b_rpow) * spow_strength * (255.0 - RCS_MinMaxDiff_2)/255.0
b_spow = Min (4.0, Max (b_spow, 0.1))

r_spmid = (r_spow == 1.0) ? 0.5 : (RCS_Ave_0 * r_gain + r_bias)/255.0
r_spmid = Min (0.99, Max (r_spmid, 0.01))
g_spmid = (g_spow == 1.0) ? 0.5 : (RCS_Ave_1* g_gain + g_bias)/255.0
g_spmid = Min (0.99, Max (g_spmid, 0.01))
b_spmid = (b_spow == 1.0) ? 0.5 : (RCS_Ave_2 * b_gain + b_bias)/255.0
b_spmid = Min (0.99, Max (b_spmid, 0.01))

#---------- bias corrections process in accordance with gray world theory

#----------- RGB bias corrections extraction and calcul

RGBAdapt( RGB_clip, \
R_bias = r_bias, R_Gain = r_gain, R_Cont = r_cont, R_rpow = r_rpow, R_spow = r_spow, R_SPMid = r_spmid, R_Pord = pord,\
G_bias = g_bias, G_Gain = g_gain, G_Cont = g_cont, G_rpow = g_rpow, G_spow = g_spow, G_SPMid = g_spmid, G_Pord = pord,\
B_bias = b_bias, B_Gain = b_gain, B_Cont = b_cont, B_rpow = b_rpow, B_spow = b_spow, B_SPMid = b_spmid, B_Pord = pord)

RT_RgbChanStats( LAST, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 16)

dr = ref - RCS_Ave_0 # better result with average of average values given by gain process
dg = ref - RCS_Ave_1
db = ref - RCS_Ave_2

bias_strength = (preset == 1) || (preset == 3) ? 1.0 : ((preset == 2) ? 0.0 : bias_strength)

r_bias = (r_bias + dr * bias_strength)
r_bias = Min (512.0, Max (r_bias, -512.0))

g_bias = (g_bias + dg * bias_strength)
g_bias = Min (512.0, Max (g_bias, -512.0))

b_bias = (b_bias + db * bias_strength)
b_bias = Min (512.0, Max (b_bias, -512.0))

RGBAdapt( RGB_clip, \
R_bias = r_bias, R_Gain = r_gain, R_Cont = r_cont, R_rpow = r_rpow, R_spow = r_spow, R_SPMid = r_spmid, R_Pord = pord,\
G_bias = g_bias, G_Gain = g_gain, G_Cont = g_cont, G_rpow = g_rpow, G_spow = g_spow, G_SPMid = g_spmid, G_Pord = pord,\
B_bias = b_bias, B_Gain = b_gain, B_Cont = b_cont, B_rpow = b_rpow, B_spow = b_spow, B_SPMid = b_spmid, B_Pord = pord)

(blanklip == 0) ? RGB_clip : last

#----------- variables strings are tuned in global mode for data display in following ScriptClip

global r_args1 = (!show_info)? nop : RT_String(" R_bias=%7.3f : R_gain=%7.3f : R_cont =%7.3f",r_bias, r_gain, r_cont)
global r_args2 = (!show_info)? nop : RT_String(" R_rpow=%7.3f : R_spow=%7.3f : R_spmid=%7.3f",r_rpow,r_spow,r_spmid)

global g_args1 = (!show_info)? nop : RT_String(" G_bias=%7.3f : G_gain=%7.3f : G_cont =%7.3f",g_bias, g_gain, g_cont)
global g_args2 = (!show_info)? nop : RT_String(" G_rpow=%7.3f : G_spow=%7.3f : G_spmid=%7.3f",g_rpow, g_spow, g_spmid)

global b_args1 = (!show_info)? nop : RT_String(" B_bias=%7.3f : B_gain=%7.3f : B_cont =%7.3f",b_bias, b_gain, b_cont)
global b_args2 = (!show_info)? nop : RT_String(" B_rpow=%7.3f : B_spow=%7.3f : B_spmid=%7.3f",b_rpow, b_spow, b_spmid)

return last """, args = "RGB_clip, show_info, x, y, w , h, preset, gain_strength, threshold, auto_cont, cont_strength, auto_spow,"+\
"rpow_strength, spow_strength, pord, bias_strength")

Bernardd
7th November 2016, 19:24
The script end

#--------- datas display process

(!show_info) ? last :\
ScriptClip(last, """

#--------- start RGB values extraction for display

RT_RgbChanStats( RGB_clip, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+16)
start_ave = (RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2)/3.0
r_start1 = RT_String("Departure : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d",RCS_Ave_0, RCS_MinMaxDiff_0, RCS_Min_0, RCS_Max_0)
g_start1 = RT_String("Departure : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d",RCS_Ave_1, RCS_MinMaxDiff_1, RCS_Min_1, RCS_Max_1)
b_start1 = RT_String("Departure : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d",RCS_Ave_2, RCS_MinMaxDiff_2, RCS_Min_2, RCS_Max_2)

#--------- final RGB values extraction for display

RT_RgbChanStats( last, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+8+16)

r_end1 = RT_String("Finish : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d", RCS_Ave_0, RCS_MinMaxDiff_0, RCS_Min_0, RCS_Max_0)
g_end1 = RT_String("Finish : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d", RCS_Ave_1, RCS_MinMaxDiff_1, RCS_Min_1, RCS_Max_1)
b_end1 = RT_String("Finish : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d", RCS_Ave_2, RCS_MinMaxDiff_2, RCS_Min_2, RCS_Max_2)

#-------- display
CWID=65 CHIT=25 # display Width and Height in Subtitle characters
MinWid=CWID*10 MinHit=CHIT*20 # RT_Subtitle required width height in pixels (fixed font size is 10x20)
TooSmall=(Width<MinWid || Height<MinHit)

S=RT_String("\nchannels averages average : %f selected preset : %d\n" +
\ "Red values :\n" +
\ "%s\n%s\n%s\n%s\n\n" +
\ "Green values :\n" +
\ "%s\n%s\n%s\n%s\n\n" +
\ "Blue values :\n" +
\ "%s\n%s\n%s\n%s\n\n" +
\ "channels averages average : %f",
\ start_ave, preset,
\ r_start1, r_args1, r_args2, r_end1,
\ g_start1, g_args1, g_args2, g_end1,
\ b_start1, b_args1, g_args2, b_end1,
\ (RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2 )/3,Esc=(TooSmall)?0:1)

(TooSmall)
\ ? Subtitle(S,Font="Courier New",lsp=0,text_color=$00FFFF00,halo_color=$00000000,size=height/float(CHIT),Font_width=width/FloaT(CWID))
\ : RT_Subtitle("%s",S)

return last """, args = "RGB_clip, x, y, w , h, threshold, preset")

#-------- display scrutinized aera

scrutinized_green = (!show_scrutinized)? nop : BlankClip(RGB_clip, width = (Width(last)-x+w), height = (Height(last)-y+h), color=$00FF00)
scrutinized_white = (!show_scrutinized)? nop : Blankclip(RGB_clip, width = (Width(last)-x+w), height = (Height(last)-y+h), color=$FFFFFF)
scrutinized_int = (!show_scrutinized)? nop : Blankclip(RGB_clip, width = (Width(scrutinized_white)-4), height = (Height(scrutinized_white)-4),\
color=000000)

scrutinized_mask = (!show_scrutinized)? nop : Overlay(scrutinized_white, scrutinized_int, x=2, y=2, opacity=1.0, mode="multiply", greymask=true,\
ignore_conditional=false, pc_range=false)

scrutinized = (!show_scrutinized)? nop : Overlay(last, scrutinized_green, mask = scrutinized_mask, x=x, y=y, opacity=1.0, mode="blend", greymask=true,\
ignore_conditional=false, pc_range=false)

(!show_scrutinized)? last : scrutinized

#--------- End of RGB color space process

!isRGB(clip) ? ConvertToYV12(last, matrix=matrix) : last

}

Bernard

StainlessS
8th November 2016, 02:21
i have not kept your multi-instance capable amend

Dont know why not, you could have added an additional function to show preset windowed display, it is very handy to have GScript within your filter script.
But, your choice, may your god be with you ... Peace and love :)

EDIT: By all means have preset in the function, BUT, maybe another function for AvsPMod sliders use (Not a good idea to import that stuff into all instances of your plug, keep separate [also avoid having to edit the AvsPmod stuff Out/In, I'm assuming that AvsPmod
stuff does not have to be at main level]).

Bernardd
8th November 2016, 13:35
I have added an additional function to show preset windowed display, because all other args are not tunable when preset is not 0. It is a mark to explain why adjust one args can be uneffective.
Now i search the better use for the script. Thus when i have to do some correction, i prefer use a script method that i know a little. It is more easy for me.
I know, write with Gscript is not difficult, but it is new for me and now i am not ready. I search to solve one problem after the other.

With you, i am learning. Thanks :)
Bernard

StainlessS
8th November 2016, 15:51
Come on Bernardd, you dont have to be any kind of scripting wizard to use eg


if(something) {
Do_Something()
} else if(something_else) {
Do_Something_else()
} else {
Do_Otherwise()
}


a lot more convenient than lots of ternary conditions, you can include/exclude loads of lines all at once.

Bernardd
9th November 2016, 02:06
Hi StainlessS
You have right
I have saw the benefit of GScript, but now my problem is :
exists a new condition to get a more automatic process, and on which frame datas ?
Thus optimise the script is now a second priority for me.

If i find or if i do not find nothing, i shall come back with script with Gscript use.

Bernard

Bernardd
20th December 2016, 10:54
Hello StainlessS,

In following post is new version of my script.

Now with script, the user have three choices :
- output with gain, rpow and bias process (preset 1)
- output with gain, cont, rpow, spow and bias process (preset 2)
- output with automatic choice (preset 0)

The user must tune threshold arg of RgbChanStats for RGB min, max, and minmax diff values. It is very useful for
define gain effect power. But it is also necassary in automatic choice mode, because auto choice is based on minmax values.

These threshold is also important, because a frame with a big minmaxdiff value variation from next and previous frame will be
more light or more dark, we can observe this with a source like the frame 2111 of John Meyer's script demo sample
(http://forum.doom9.org/showthread.php?p=1780794#post1780794 )

To choice help, call script have a comparison mode to display original, basic coloryuv autowhite process, preset 1, preset 2
and selected preset clip versions.

The script uses now Gscript plugin, conditional line write are now more easy, but quote use is not so evident.
I have not follow the whole of your Gscript sample on my old script version. Thus i call Gscript fonction twice.
One to include Gscript in GScripClip and second to include GScriptClip in Gscript. With this way, i think it
is not optimised, but i understand that i do. If you can give me some explanations, i should be satisfied.

Thanks.

Bernard

Bernardd
20th December 2016, 10:59
Call script

AVISource("C:\.............\your video.avi")
LoadPlugin("C:\............\GRunT.dll")
LoadPlugin("C:\............\GScript.dll")
LoadPlugin("C:\............\RGBAdapt.dll")
LoadPlugin("C:\............\RT_Stats26.dll")

# display tunings
comparison = true
show_scrutinized = true
show_info = false

# color space matrix tuning and specify the source rectangle under scrutiny
matrix = "Rec601"
x = 0.10
Y= 0.10
w = 0.10
h = 0.10

#extreme pixels percentage to be ignored when datas extraction
threshold = 0.10

# automatic white balance preset tunings
preset = 0

# gamma process tuning
pord = false #pord args changes give similar results

# If you use AvsPmod user sliders you can delete comment for follow lines

#~ [<separator="display tunings">]
#~ comparison = Select([<"show different settings - (false ou true) default = false = 0", 0, 1, 1>], false , true)
#~ show_scrutinized = Select([<"show scrutinized aera - (false ou true) default = false = 0", 0, 1, 0>], false , true)
#~ show_info = Select([<"show datas - (false ou true) default = false = 0", 0, 1, 0>], false , true)

#~ [<separator="color space matrix tuning">]
#~ matrix = Select([<"color matrix - (Rec 601= 0 ou Rec 709 =1) = default = 0", 0, 1, 0>], "Rec601" , "Rec709")
#~ [<separator=""specify the source rectangle under scrutiny and percentage extreme pixels to ignore">]
#~ x = [<"ignore pixels on left - width percentage - default : 0.00", 0.00, 0.99, 0.07>]
#~ Y= [<"ignore pixels on top - heigth percentage - default : 0.00", 0.00, 0.99, 0.07>]
#~ w = [<"ignore pixels on right - width percentage - default : 0.00", 0.00, 0.99, 0.07>]
#~ h = [<"ignore pixels on bottom - heigth percentage - default : 0.00", 0.00, 0.99, 0.07>]
#~ [<separator=""specify the extreme pixels percentage to be ignored when datas extraction">]
#~ threshold = [<"percentage for extreme pixels to be ignored - default : 0.10", 0.00, 1.00, 0.05>]
#~ [<separator="automatic white balance preset tunings">]
#~ preset = Select([<"preset default = 0", 0, 2, 0>], 0 , 1, 2)
#~ pord = false # pord = Select([<"pord - (false = rpow before spow ) default = false = 0", 0, 1, 0>], false , true) # pord args changes give similar results

Gscript("""
output = RGBAdapt_awb_process(matrix = matrix, show_scrutinized = show_scrutinized, show_info = show_info, x = x, y = y, w = w, h = h, \
threshold = threshold, pord = pord, preset = preset)
if (!comparison) {output}
else {
if (!isRGB) {ColorYUV_AWB = ColorYUV(autowhite = true)}
else { colorYUV_AWB = ConvertToYV12(matrix=matrix).ColorYUV(autowhite = true).ConvertToRGB24(matrix=matrix)}


preset_1 = RGBAdapt_awb_process(matrix = matrix, show_scrutinized = false, show_info = show_info, x = x, y = y, w = w, h = h, \
threshold = 0.1, pord = pord, preset = 1)
preset_2 = RGBAdapt_awb_process(matrix = matrix, show_scrutinized = show_scrutinized, show_info = show_info, x = x, y = y, w = w, h = h, \
threshold = 0.1, pord = pord, preset = 2)
StackVertical(\
StackHorizontal(blankclip(last).AddBorders(0, 50, 0, 0, color=$000000),\
preset_1.AddBorders(0, 50, 0, 0, color=$000000). Subtitle ("gain rpow and bias process but no cont and no spow process"+ \
"\n threshold : 0.1 preset 1" , lsp = 20),\
preset_2.AddBorders(0, 50, 0, 0, color=$000000). Subtitle ("gain cont rpow spow and bias process"+ \
"\n threshold : 0.1 preset 2" , lsp = 20)),\
StackHorizontal(last.AddBorders(0, 0, 0, 50, color=$000000).Subtitle("original", y = height(last)),\
colorYUV_AWB.AddBorders(0, 0, 0, 50, color=$000000).Subtitle ("As a reminder, classical ColorYUV awb", y = height(last)),\
output.AddBorders(0, 0, 0, 50, color=$000000).Subtitle ("Selected output"+ "\n threshold : " + LeftStr(string(threshold),4) + \
" preset = " +string(preset), lsp = 20, y = height(last))))}
""")

Bernardd
20th December 2016, 11:05
Script function part 1

/*
#----------------------------------------------based on RGBADapt plugin ---------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.php?t=170642 #
#------------------------------------------------------------------------------------------------------------------------------------------------#

#---------------------------------------------- need RT_Stats plugin -------------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.php?t=165479 #
#------------------------------------------------------------------------------------------------------------------------------------------------#

#---------------------------------------------- need GRunT plugin ----------------------------------------------------------------------------#
# plugin author : Gavino http://forum.doom9.org/showthread.php?t=139337 #
#-----------------------------------------------------------------------------------------------------------------------------------------------#

#---------------------------------------------- need GScript plugin ----------------------------------------------------------------------------#
# plugin author : Gavino http://forum.doom9.org/showthread.php?t=147846 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #
*/

# ---------------------------- function script -------------------------------------

function RGBAdapt_awb_process(clip clip, string "matrix",bool "show_scrutinized", bool "show_info", float "x", float "y", float "w", float "h", \
float "threshold", int "preset", bool "pord")
{
myName="RGBAdapt_awb_process: "
Assert(RT_FunctionExist("RGBAdapt"),myName+"RGBAdapt plugin must be loaded, http://forum.doom9.org/showthread.php?t=170642")
Assert(RT_FunctionExist("GScriptClip"),myName+"GRunT plugin must be loaded, http://forum.doom9.org/showthread.php?t=139337")
Assert(RT_FunctionExist("GScript"),myName+"GScript plugin must be loaded, http://forum.doom9.org/showthread.php?t=147846")
Assert(IsYV12(clip) || IsRGB(clip),RT_String("%sInput video colorspace must be YV12 or RGB, not YUV",myName))
matrix = Default(matrix, "Rec601") # Color standard, Rec 601 or Rec 709
Assert(matrix == "Rec601" || matrix == "Rec709",RT_String("%smatrix 'Rec601' or 'Rec709'('%s')",myName,matrix))
show_scrutinized = Default(show_scrutinized, false) # show scrutinized area or not, default false
show_info = Default(show_info, false) # show info or not, default false
x = float(Default(x,0.0)) #width percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= x <= 0.99,RT_String("%s0.0 <= x <= 0.99(%f)",myName,x))
y = float(Default(y,0.0)) #height percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= y <= 0.99,RT_String("%s0.0 <= y <= 0.99(%f)",myName,y))
w = float(Default(w,0.0)) #coords specify the source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= w <= 0.99,RT_String("%s0.0 <= w <= 0.99(%f)",myName,w))
Assert(0.0 <= (x+w) <= 0.99 ,RT_String("%s0.0 <= (x+w) <= 0.99(%f)",myName,x+w))
h = float(Default(h,0.0)) #coords specify the source rectangle under scrutiny , the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= h <= 0.99,RT_String("%s0.0 <= h <= 0.99(%f)",myName,h))
Assert(0.0 <= (y+h) <= 0.99 ,RT_String("%s0.0 <= (y+h) <= 0.99(%f)",myName,y+h))
threshold = Float(Default(threshold, 0.10)) # threshold arg of RT_Stats plugin
Assert(0.0 <= threshold <= 1.0,RT_String("%s0.0 <= threshold <= 1.0(%f)",myName,threshold))
pord = Default(pord, false) # RGBAdapt pord arg, his changes give similar results
preset= Int(Default(preset, 0))
Assert(0 <= preset <= 2,RT_String("%s preset = 0,1 or 2 ( no %d)",myName,preset))

#---------- Specify the source rectangle under scrutiny

x = int(Width(clip) * x)
y = int(Height(clip) * y)
w = int(-Width(clip) * w)
h = int(-Height(clip) * h)

#--------- RGB color space process

RGB_clip = (!isRGB(clip)) ? ConvertToRGB24(clip, matrix=matrix) : clip

#----------------- technical string definition to avoid quote use errors with ScriptClip and Gscript mix

r_args1_string = " R_bias=%7.3f : R_gain=%7.3f : R_cont =%7.3f"
r_args2_string = " R_rpow=%7.3f : R_spow=%7.3f : R_spmid=%7.3f"

g_args1_string = " G_bias=%7.3f : G_gain=%7.3f : G_cont =%7.3f"
g_args2_string = " G_rpow=%7.3f : G_spow=%7.3f : G_spmid=%7.3f"

b_args1_string = " B_bias=%7.3f : B_gain=%7.3f : B_cont =%7.3f"
b_args2_string = " B_rpow=%7.3f : B_spow=%7.3f : B_spmid=%7.3f"
start_string = "Departure : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d"
end_string = "Finish : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d"
display_string = "\nchannels averages average : %f used preset : %-d\n" +
\ "Red values :\n"+
\ "%s\n%s\n%s\n%s\n\n"+
\ "Green values :\n"+
\ "%s\n%s\n%s\n%s\n\n"+
\ "Blue values :\n"+
\ "%s\n%s\n%s\n%s\n\n"+
\ "channels averages average : %f"
rt_string_format_string = "%s"
police_string = "Courier New"

#--------- AWB process

ScriptClip( RGB_clip,"""
Gscript("
#---------- First pass : gain process for each channel

RT_RgbChanStats( RGB_clip, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+16)

# ------ detection BlankClip and condition to avoid division by 0

blankclip = RCS_MinMaxDiff_0 + RCS_MinMaxDiff_1 + RCS_MinMaxDiff_2

RCS_MinMaxDiff_0 = Max (RCS_MinMaxDiff_0, 0.01) RCS_MinMaxDiff_1 = Max (RCS_MinMaxDiff_1, 0.01) RCS_MinMaxDiff_2 = Max (RCS_MinMaxDiff_2, 0.01)

#------ preset automatic selection

ave_ave = (RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2)/3.0
min_minmaxdiff = Min(RCS_MinMaxDiff_0, RCS_MinMaxDiff_1, RCS_MinMaxDiff_2)
if (preset == 0) {if (min_minmaxdiff < ave_ave) {preset = 2} else {preset = 1}}

#---- gain args calculation

r_gain = 255.0/RCS_MinMaxDiff_0 g_gain = 255.0/RCS_MinMaxDiff_1 b_gain = 255.0/RCS_MinMaxDiff_2
r_gain_bias = - RCS_Min_0 * r_gain g_gain_bias = - RCS_Min_1 * g_gain b_gain_bias = - RCS_Min_2 * b_gain

#---- cont args calculation

# Cont is dangerous, because it can overshoot light and dark, but it is necessary to help to find good correction for very big
# color cast. Thus it is desable for preset 1. It is enable for preset 2 with a automatic weighted autocont strength
# based on my tests results. I observe that picture do'nt need contraste is picture, which have a large histogram, which have
# min value near 0 et max value near 255, which have bigger min max diff value.

if (preset == 2) {r_cont = 1 + (r_gain - 1) * (255.0 - RCS_MinMaxDiff_0)/255.0
r_cont_max = RCS_Max_0 * r_gain + r_gain_bias + (r_cont - 1) *(RCS_Max_0 - 128)
r_cont_bias = (255 - r_cont_max) * (255.0 - RCS_MinMaxDiff_0)/255.0

g_cont = 1 + (g_gain - 1) * (255.0 - RCS_MinMaxDiff_1)/255.0
g_cont_max = RCS_Max_1 * g_gain + g_gain_bias + (g_cont - 1) *(RCS_Max_1 - 128)
g_cont_bias = (255 - g_cont_max) * (255.0 - RCS_MinMaxDiff_1)/255.0

b_cont =1 + (b_gain - 1) * (255.0 - RCS_MinMaxDiff_2)/255.0
b_cont_max = RCS_Max_2 * b_gain + b_gain_bias + (b_cont - 1) *(RCS_Max_2 - 128)
b_cont_bias = (255 - b_cont_max) * (255.0 - RCS_MinMaxDiff_2)/255.0 }

else { r_cont = 1.0 g_cont = 1.0 b_cont = 1.0
r_cont_bias = 0.0 g_cont_bias = 0.0 b_cont_bias = 0.0}

r_bias = r_gain_bias + r_cont_bias g_bias = g_gain_bias + g_cont_bias b_bias = b_gain_bias + b_cont_bias

#----gamma args calculation in accordance with gray world theory

# In gray world theory, in YUV range, we increase or decrease average value to ref = 128.0, but in RGB range
# ref = average of channel average values is better.
# With preset 2, average of channel average value after gain process without cont process give a better picture light.

# In gamma process, to incresae or decrease average value, we use gamma args. To find this gamma args, we
# solve this equation ref = pow(average value/255.0,1/gamma args)

ref = (RCS_Ave_0 * r_gain + r_gain_bias + RCS_Ave_1 * g_gain + g_gain_bias + RCS_Ave_2 * b_gain + b_gain_bias)/3.0

r_rpow = 1 + (log((RCS_Ave_0 * r_gain + r_gain_bias)/255.0)/log(ref/255.0) - 1)
r_rpow = Min (4.0, Max (r_rpow, 0.1))
g_rpow = 1 + (log((RCS_Ave_1 * g_gain + g_gain_bias)/255.0)/log(ref/255.0) - 1)
g_rpow = Min (4.0, Max (g_rpow, 0.1))
b_rpow = 1 + (log((RCS_Ave_2 * b_gain + b_gain_bias)/255.0)/log(ref/255.0) - 1)
b_rpow = Min (4.0, Max (b_rpow, 0.1))

# spow, spmid calculation, pord is operator choice

#------- Spow, spmid and pord args computed values increase rpow process action,
#------- thus we get more color saturation but also more dark aeras.
#------- Spow for rpow is like contrast for gain. Thus in preset 2, i do'nt use spow,
#------- an with preset 3, i use a factor to get automatic weigthed spow arg

if (preset == 2) { Ave_max = Max(RCS_Ave_0 * r_gain + r_gain_bias , \
Max(RCS_Ave_1 * g_gain + g_gain_bias, RCS_Ave_2 * b_gain + b_gain_bias))

r_spow = 1 + (1/r_rpow - 1) * (Ave_max - RCS_Ave_0 * r_gain - r_gain_bias)/Ave_max
g_spow = 1 + (1/g_rpow - 1) * (Ave_max - RCS_Ave_1 * g_gain - g_gain_bias)/Ave_max
b_spow = 1 + (1/b_rpow - 1) * (Ave_max - RCS_Ave_2 * b_gain - b_gain_bias)/Ave_max

r_spmid = (RCS_Ave_0 * r_gain + r_gain_bias)/255.0
g_spmid = (RCS_Ave_1* g_gain + g_gain_bias)/255.0
b_spmid = (RCS_Ave_2 * b_gain + b_gain_bias)/255.0 }

else { r_spow = 1.0 g_spow = 1.0 b_spow = 1.0
r_spmid = 0.5 g_spmid = 0.5 b_spmid = 0.5}

#--------- bias gain cont spow and spmid in RGBadapt args range

r_bias = Min (512.0, Max (r_bias, -512.0)) g_bias = Min (512.0, Max (g_bias, -512.0)) b_bias = Min (512.0, Max (b_bias, -512.0))
r_gain = Min (8.0, Max (r_gain, -8.0)) g_gain = Min (8.0, Max (g_gain, -8.0)) b_gain = Min (8.0, Max (b_gain, -8.0))
r_cont = Min (8.0, Max (r_cont, -8.0)) g_cont = Min (8.0, Max (g_cont, -8.0)) b_cont = Min (8.0, Max (b_cont, -8.0))
r_spow = Min (4.0, Max (r_spow, 0.1)) g_spow = Min (4.0, Max (g_spow, 0.1)) b_spow = Min (4.0, Max (b_spow, 0.1))
r_spmid = Min (0.99, Max (r_spmid, 0.01)) g_spmid = Min (0.99, Max (g_spmid, 0.01)) b_spmid = Min (0.99, Max (b_spmid, 0.01))

#---------- bias corrections in accordance with gray world theory

#----------- bias corrections extraction and calcul

RGBAdapt( RGB_clip, \
R_bias = r_bias, R_Gain = r_gain, R_Cont = r_cont, R_rpow = r_rpow, R_spow = r_spow, R_SPMid = r_spmid, R_Pord = pord,\
G_bias = g_bias, G_Gain = g_gain, G_Cont = g_cont, G_rpow = g_rpow, G_spow = g_spow, G_SPMid = g_spmid, G_Pord = pord,\
B_bias = b_bias, B_Gain = b_gain, B_Cont = b_cont, B_rpow = b_rpow, B_spow = b_spow, B_SPMid = b_spmid, B_Pord = pord)

RT_RgbChanStats( last, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 16)

# Ref for bias corrections is calculated with gain output, because is more light than calculated with gain cont and gamma output

dr = ref - RCS_Ave_0 dg = ref - RCS_Ave_1 db = ref - RCS_Ave_2
r_bias = (r_gain_bias + r_cont_bias + dr) g_bias = (g_gain_bias + g_cont_bias + dg) b_bias = (b_gain_bias + b_cont_bias + db)
r_bias = Min (512.0, Max (r_bias, -512.0)) g_bias = Min (512.0, Max (g_bias, -512.0)) b_bias = Min (512.0, Max (b_bias, -512.0))

#------------ AWB output with gain cont rpow spow and bias process in accordance with preset

RGBAdapt( RGB_clip, \
R_bias = r_bias, R_Gain = r_gain, R_Cont = r_cont, R_rpow = r_rpow, R_spow = r_spow, R_SPMid = r_spmid, R_Pord = pord,\
G_bias = g_bias, G_Gain = g_gain, G_Cont = g_cont, G_rpow = g_rpow, G_spow = g_spow, G_SPMid = g_spmid, G_Pord = pord,\
B_bias = b_bias, B_Gain = b_gain, B_Cont = b_cont, B_rpow = b_rpow, B_spow = b_spow, B_SPMid = b_spmid, B_Pord = pord)

(blankclip == 0) ? RGB_clip : last

#----------- variables strings are tuned in global mode for data display in following ScriptClip

if (show_info) { global preset = preset

global r_args1 = RT_String(r_args1_string,r_bias, r_gain, r_cont)
global r_args2 = RT_String(r_args2_string,r_rpow,r_spow,r_spmid)

global g_args1 = RT_String(g_args1_string,g_bias, g_gain, g_cont)
global g_args2 = RT_String(g_args2_string,g_rpow, g_spow, g_spmid)

global b_args1 = RT_String(b_args1_string,b_bias, b_gain, b_cont)
global b_args2 = RT_String(b_args2_string,b_rpow, b_spow, b_spmid) }

return last ")""", args = " RGB_clip, show_info, x, y, w , h, preset, threshold, pord,"+\
"r_args1_string, r_args2_string, g_args1_string, g_args2_string, b_args1_string, b_args2_string")

#--------- datas display process

Gscript(""" if (show_info) { ScriptClip(last,"

#--------- start RGB values extraction for display

RT_RgbChanStats( RGB_clip, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+16)
start_ave = (RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2)/3.0
r_start1 = RT_String(start_string,RCS_Ave_0, RCS_MinMaxDiff_0, RCS_Min_0, RCS_Max_0)
g_start1 = RT_String(start_string,RCS_Ave_1, RCS_MinMaxDiff_1, RCS_Min_1, RCS_Max_1)
b_start1 = RT_String(start_string,RCS_Ave_2, RCS_MinMaxDiff_2, RCS_Min_2, RCS_Max_2)

#--------- final RGB values extraction for display

RT_RgbChanStats( last, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+8+16)

r_end1 = RT_String(end_string, RCS_Ave_0, RCS_MinMaxDiff_0, RCS_Min_0, RCS_Max_0)
g_end1 = RT_String(end_string, RCS_Ave_1, RCS_MinMaxDiff_1, RCS_Min_1, RCS_Max_1)
b_end1 = RT_String(end_string, RCS_Ave_2, RCS_MinMaxDiff_2, RCS_Min_2, RCS_Max_2)

#-------- display
CWID=65 CHIT=25 # display Width and Height in Subtitle characters
MinWid=CWID*10 MinHit=CHIT*20 # RT_Subtitle required width height in pixels (fixed font size is 10x20)
TooSmall=(Width<MinWid || Height<MinHit)

S=RT_String(display_string,
\ start_ave, preset,
\ r_start1, r_args1, r_args2, r_end1,
\ g_start1, g_args1, g_args2, g_end1,
\ b_start1, b_args1, b_args2, b_end1,
\ (RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2 )/3, Esc=(TooSmall)?0:1)

(TooSmall)
\ ? Subtitle(S,Font=police_string,lsp=0,text_color=$00FFFF00,halo_color=$00000000,size=height/float(CHIT),Font_width=width/FloaT(CWID))
\ : RT_Subtitle(rt_string_format_string,S)

return last ", args = "RGB_clip, x, y, w , h, threshold,start_string, end_string, display_string, rt_string_format_string, police_string") }
else { return last }

Bernardd
20th December 2016, 11:06
Script function part 2

#-------- display scrutinized aera

if (show_scrutinized) {

scrutinized_green = BlankClip(RGB_clip, width = (Width(last)-x+w), height = (Height(last)-y+h), color=$00FF00)
scrutinized_white = Blankclip(RGB_clip, width = (Width(last)-x+w), height = (Height(last)-y+h), color=$FFFFFF)
scrutinized_int = Blankclip(RGB_clip, width = (Width(scrutinized_white)-4), height = (Height(scrutinized_white)-4),\
color=000000)

scrutinized_mask = Overlay(scrutinized_white, scrutinized_int, x=2, y=2, opacity=1.0, mode="multiply", greymask=true,\
ignore_conditional=false, pc_range=false)

scrutinized = Overlay(last, scrutinized_green, mask = scrutinized_mask, x=x, y=y, opacity=1.0, mode="blend", greymask=true,\
ignore_conditional=false, pc_range=false)

return scrutinized } """)

#--------- End of RGB color space process

!isRGB(clip) ? ConvertToYV12(last, matrix=matrix) : last
}

Bernardd
7th January 2017, 22:24
Happy new year for all

Below the last version of my script.

In this version i have deleted spow process, because after many tests, her efficiency was not proved.

The script have always technical args to display comparison, scrutinized area and computed datas. It have always the args to define scrutinized area
and threshold of RgbChanStats for RGB min, max, and minmax diff values. Default value can be enough, but it must be increase if you get a unhomogenous
process for several following frames.

Now the script computes one automatic white balance with gain, rpow and final bias process. For big color cast the script use also contrast process.
In automatic mode, the contrast use is enable if difference between max average channel value and min average channel value is bigger than threshold
(in color cast, one channel average value is often bigger thant the the two others). Automatic contrast use is only for big color cast, thus default threshold is 128.

Threshold_auto arg is used to define the contrast automatic toggle. When it is equal to 0, contrast is always enable, when it is equal to 255 contrast is always disable,
between 0 and 255, contrast is enabled if min max average valus diff is bigger than it.

I think that you can get a better automatic white balance with this combination, than with ColorYUV (autowhite = true). But perhaps you can found gain too strong.
The script have thus a gain strength arg to decrease and even to disable the gain. It have also a rpow strength arg and a bias strength arg to decrease and even to
disable these process.

In default mode, the script use combination of gain rpow and bias, but with these three last args you can make three other combination, gain only, gain and rpow,
gain and bias. To help to make a choice, on comparison display below the green line these three combinations are displayed.

The script have always a call part and a function part. These parts are in following posts.

Bernard

Bernardd
7th January 2017, 22:25
Call lines with AvsPMod usersliders opportunity, il you want.

AVISource("C:\.............\your video.avi")
LoadPlugin("C:\............\GRunT.dll")
LoadPlugin("C:\............\GScript.dll")
LoadPlugin("C:\............\RGBAdapt.dll")
LoadPlugin("C:\............\RT_Stats26.dll")

# display tunings
comparison = true
show_scrutinized = true
show_info = false

# color space matrix tuning and specify the source rectangle under scrutiny
matrix = "Rec601"
x = 0.10
Y= 0.10
w = 0.10
h = 0.10

#extreme pixels percentage to be ignored when datas extraction
threshold = 0.10

# automatic white balance preset tunings
threshold_auto = 128
gain_strength = 1.0
rpow_strength = 1.0
bias_strength = 1.0

# If you use AvsPmod user sliders you can delete comment for following lines

#~ [<separator="display tunings">]
#~ comparison = Select([<"show different settings - (false ou true) default = false = 0", 0, 1, 1>], false , true)
#~ show_scrutinized = Select([<"show scrutinized aera - (false ou true) default = false = 0", 0, 1, 0>], false , true)
#~ show_info = Select([<"show datas - (false ou true) default = false = 0", 0, 1, 0>], false , true)

#~ [<separator="color space matrix tuning">]
#~ matrix = Select([<"color matrix - (Rec 601= 0 ou Rec 709 =1) = default = 0", 0, 1, 0>], "Rec601" , "Rec709")
#~ [<separator=""specify the source rectangle under scrutiny and percentage extreme pixels to ignore">]
#~ x = [<"ignore pixels on left - width percentage - default : 0.00", 0.00, 0.99, 0.1>]
#~ Y= [<"ignore pixels on top - heigth percentage - default : 0.00", 0.00, 0.99, 0.1>]
#~ w = [<"ignore pixels on right - width percentage - default : 0.00", 0.00, 0.99, 0.1>]
#~ h = [<"ignore pixels on bottom - heigth percentage - default : 0.00", 0.00, 0.99, 0.1>]
#~ [<separator=""specify the extreme pixels percentage to be ignored when datas extraction">]
#~ threshold = [<"percentage for extreme pixels to be ignored - default : 0.10", 0.00, 1.00, 0.1>]
#~ [<separator="automatic white balance tunings">]
#~ threshold_auto = [<"threshold for enable cont process - default : 128", 0, 255, 128>]
#~ gain_strength = [<"gain strength - default : 1.0", 0.0, 1.0, 1.0>]
#~ rpow_strength = [<"rpow strength - default : 1.0", 0.0, 1.0, 1.0>]
#~ bias_strength = [<"final bias strength - default : 1.0", 0.0, 1.0, 1.0>]

Gscript("""
output = RGBAdapt_awb_process(matrix = matrix, show_scrutinized = show_scrutinized, show_info = show_info, x = x, y = y, w = w, h = h, threshold = threshold, \
gain_strength = gain_strength, rpow_strength = rpow_strength, bias_strength = bias_strength,threshold_auto = threshold_auto)
if (!comparison) {output}
else {
if (!isRGB) {ColorYUV_AWB = ColorYUV(autowhite = true)}
else { colorYUV_AWB = ConvertToYV12(matrix=matrix).ColorYUV(autowhite = true).ConvertToRGB24(matrix=matrix)}

without_contrast = RGBAdapt_awb_process(matrix = matrix, show_scrutinized = show_scrutinized, show_info = show_info, x = x, y = y, w = w, h = h, \
threshold_auto = 255)
with_contrast = RGBAdapt_awb_process(matrix = matrix, show_scrutinized = show_scrutinized, show_info = show_info, x = x, y = y, w = w, h = h, \
threshold_auto = 0)
gain_rpow = RGBAdapt_awb_process(matrix = matrix, show_scrutinized = show_scrutinized, show_info = show_info, x = x, y = y, w = w, h = h, \
threshold_auto = threshold_auto, bias_strength = 0.0)
gain_bias = RGBAdapt_awb_process(matrix = matrix, show_scrutinized = show_scrutinized, show_info = show_info, x = x, y = y, w = w, h = h, \
threshold_auto = threshold_auto, rpow_strength = 0.0)
only_gain = RGBAdapt_awb_process(matrix = matrix, show_scrutinized = show_scrutinized, show_info = show_info, x = x, y = y, w = w, h = h, \
threshold = 0.1, threshold_auto = threshold_auto, rpow_strength = 0.0, bias_strength = 0.0)
if (threshold_auto == 255) {contrast_label = "without contrast"} else {if (threshold_auto == 0) \
{contrast_label = "with contrast"} else {contrast_label = "contrast in accordance with threshold"}}

StackVertical(\
StackHorizontal(blankclip(last).AddBorders(0, 20, 0, 0, color=$000000),\
without_contrast.AddBorders(0, 20, 0, 0, color=$000000). Subtitle ("gain rpow and bias process without contrast"),\
with_contrast.AddBorders(0, 20, 0, 0, color=$000000). Subtitle ("gain rpow and bias process with contrast")),\
StackHorizontal(last.AddBorders(0, 0, 0, 20, color=$000000).Subtitle("original", y = height(last)),\
colorYUV_AWB.AddBorders(0, 0, 0, 20, color=$000000).Subtitle ("As a reminder, classical ColorYUV awb", y = height(last)),\
output.AddBorders(0, 0, 0, 20, color=$000000).Subtitle ("Selected output"+ " " +string(contrast_label), y = height(last))),\
StackHorizontal(only_gain.AddBorders(0, 0, 0, 20, color=$000000). Subtitle ("only gain "+ " " +string(contrast_label), y = height(last)),\
gain_bias.AddBorders(0, 0, 0, 20, color=$000000). Subtitle ("only gain and bias"+ " " +string(contrast_label), y = height(last)),\
gain_rpow.AddBorders(0, 0, 0, 20, color=$000000). Subtitle ("only gain and rpow"+ " " +string(contrast_label), y = height(last)))\
.Letterbox(20, 0, x1=0, x2=0, color=$00FF00).Subtitle( "Perhaps other good combinations ?",align = 8))}
""")

Bernardd
7th January 2017, 22:26
End - Function lines

/*
#----------------------------------------------based on RGBADapt plugin ---------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.php?t=170642 #
#------------------------------------------------------------------------------------------------------------------------------------------------#

#---------------------------------------------- need RT_Stats plugin -------------------------------------------------------------------------#
# script author : StainlessS http://forum.doom9.org/showthread.php?t=165479 #
#------------------------------------------------------------------------------------------------------------------------------------------------#

#---------------------------------------------- need GRunT plugin ----------------------------------------------------------------------------#
# plugin author : Gavino http://forum.doom9.org/showthread.php?t=139337 #
#-----------------------------------------------------------------------------------------------------------------------------------------------#

#---------------------------------------------- need GScript plugin ----------------------------------------------------------------------------#
# plugin author : Gavino http://forum.doom9.org/showthread.php?t=147846 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #
*/

# ---------------------------- function script -------------------------------------

function RGBAdapt_awb_process(clip clip, string "matrix",bool "show_scrutinized", bool "show_info", float "x", float "y", float "w", float "h", \
float "threshold", int "threshold_auto", float "gain_strength", float "rpow_strength", float "bias_strength")
{
myName="RGBAdapt_awb_process: "
Assert(RT_FunctionExist("RGBAdapt"),myName+"RGBAdapt plugin must be loaded, http://forum.doom9.org/showthread.php?t=170642")
Assert(RT_FunctionExist("GScriptClip"),myName+"GRunT plugin must be loaded, http://forum.doom9.org/showthread.php?t=139337")
Assert(RT_FunctionExist("GScript"),myName+"GScript plugin must be loaded, http://forum.doom9.org/showthread.php?t=147846")
Assert(IsYV12(clip) || IsRGB(clip),RT_String("%sInput video colorspace must be YV12 or RGB, not YUV",myName))
matrix = Default(matrix, "Rec601") # Color standard, Rec 601 or Rec 709
Assert(matrix == "Rec601" || matrix == "Rec709",RT_String("%smatrix 'Rec601' or 'Rec709'('%s')",myName,matrix))
show_scrutinized = Default(show_scrutinized, false) # show scrutinized area or not, default false
show_info = Default(show_info, false) # show info or not, default false
x = float(Default(x,0.0)) #width percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= x <= 0.99,RT_String("%s0.0 <= x <= 0.99(%f)",myName,x))
y = float(Default(y,0.0)) #height percentage to specify the coords source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= y <= 0.99,RT_String("%s0.0 <= y <= 0.99(%f)",myName,y))
w = float(Default(w,0.0)) #coords specify the source rectangle under scrutiny, the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= w <= 0.99,RT_String("%s0.0 <= w <= 0.99(%f)",myName,w))
Assert(0.0 <= (x+w) <= 0.99 ,RT_String("%s0.0 <= (x+w) <= 0.99(%f)",myName,x+w))
h = float(Default(h,0.0)) #coords specify the source rectangle under scrutiny , the default : x = y = h = w = 0.00 is full frame
Assert(0.0 <= h <= 0.99,RT_String("%s0.0 <= h <= 0.99(%f)",myName,h))
Assert(0.0 <= (y+h) <= 0.99 ,RT_String("%s0.0 <= (y+h) <= 0.99(%f)",myName,y+h))
threshold = Float(Default(threshold, 0.10)) # threshold arg of RT_Stats plugin
Assert(0.0 <= threshold <= 1.0,RT_String("%s0.0 <= threshold <= 1.0(%f)",myName,threshold))
threshold_auto = Int(Default(threshold_auto, 128)) # threshold for enable cont process
Assert(0 <= threshold_auto <= 255,RT_String("%s0 <= threshold_auto <= 255(%d)",myName,threshold_auto))
gain_strength = Float(Default(gain_strength, 1.0)) # gain strength
Assert(0.0 <= gain_strength <= 1.0,RT_String("%s0.0 <= gain_strength <= 1.0(%f)",myName,gain_strength))
rpow_strength = Float(Default(rpow_strength, 1.0)) #rpow strength
Assert(0.0 <= rpow_strength <= 1.0,RT_String("%s0.0 <= rpow_strength <= 1.0(%f)",myName,rpow_strength))
bias_strength = Float(Default(bias_strength, 1.0)) #bias strength
Assert(0.0 <= bias_strength <= 1.0,RT_String("%s0.0 <= bias_strength <= 1.0(%f)",myName,bias_strength))

#---------- Specify the source rectangle under scrutiny

x = int(Width(clip) * x)
y = int(Height(clip) * y)
w = int(-Width(clip) * w)
h = int(-Height(clip) * h)

#--------- RGB color space process

RGB_clip = (!isRGB(clip)) ? ConvertToRGB24(clip, matrix=matrix) : clip

#----------------- technical string definition to avoid quote use errors with ScriptClip and Gscript mix

r_args1_string = " R_bias =%7.3f : R_gain =%7.3f : R_cont =%7.3f"
r_args2_string = " R_rpow =%7.3f"

g_args1_string = " G_bias=%7.3f : G_gain=%7.3f : G_cont =%7.3f"
g_args2_string = " G_rpow=%7.3f"

b_args1_string = " B_bias=%7.3f : B_gain=%7.3f : B_cont =%7.3f"
b_args2_string = " B_rpow=%7.3f"
start_string = "Departure : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d"
end_string = "Finish : Average=%-7.3f : Min/max=%-3d : Min=%-3d : Max=%-3d"
display_string = "\nchannels averages average : %f \nmin max average diff : %f contrast : %s\n\n" +
\ "Red values :\n" +
\ "%s\n%s\n%s\n%s\n\n" +
\ "Green values :\n" +
\ "%s\n%s\n%s\n%s\n\n" +
\ "Blue values :\n" +
\ "%s\n%s\n%s\n%s\n\n" +
\ "channels averages average : %f"
rt_string_format_string = "%s"
police_string = "Courier New"

#--------- AWB process

ScriptClip( RGB_clip,"""
Gscript("
#---------- First pass : gain process for each channel

RT_RgbChanStats( RGB_clip, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+16)

# ------ detection BlankClip and condition to avoid division by 0

blankclip = RCS_MinMaxDiff_0 + RCS_MinMaxDiff_1 + RCS_MinMaxDiff_2

RCS_MinMaxDiff_0 = Max (RCS_MinMaxDiff_0, 0.01) RCS_MinMaxDiff_1 = Max (RCS_MinMaxDiff_1, 0.01) RCS_MinMaxDiff_2 = Max (RCS_MinMaxDiff_2, 0.01)

#------ contrast automatic enable

if (Max(RCS_Ave_0,RCS_Ave_1,RCS_Ave_2)- Min(RCS_Ave_0,RCS_Ave_1,RCS_Ave_2) > threshold_auto) {contrast = true} else {contrast = false}

#---- gain args calculation

r_gain = 1 + (255.0/RCS_MinMaxDiff_0 - 1) * gain_strength g_gain = 1 + (255.0/RCS_MinMaxDiff_1 - 1) * gain_strength b_gain = 1 + (255.0/RCS_MinMaxDiff_2 - 1) * gain_strength
r_gain_bias = - RCS_Min_0 * r_gain * gain_strength g_gain_bias = - RCS_Min_1 * g_gain * gain_strength b_gain_bias = - RCS_Min_2 * b_gain * gain_strength

#---- cont args calculation

# Cont is dangerous, because it can overshoot light and dark, but it is necessary to help to find good correction for very big
# color cast. Thus it is enable only for big color cast with a automatic weighted autocont strength based on my tests results.
# I observe that picture do'nt need contraste is picture, which have a large histogram, which have min value near 0 and
# max value near 255, which have bigger min max diff value.

if (contrast == true){r_cont = 1 + (r_gain - 1) * (255.0 - RCS_MinMaxDiff_0)/255.0
r_cont_max = RCS_Max_0 * r_gain + r_gain_bias + (r_cont - 1) *(RCS_Max_0 - 128)
r_cont_bias = (255 - r_cont_max) * gain_strength

g_cont = 1 + (g_gain - 1) * (255.0 - RCS_MinMaxDiff_1)/255.0
g_cont_max = RCS_Max_1 * g_gain + g_gain_bias + (g_cont - 1) *(RCS_Max_1 - 128)
g_cont_bias = (255 - g_cont_max) * gain_strength

b_cont =1 + (b_gain - 1) * (255.0 - RCS_MinMaxDiff_2)/255.0
b_cont_max = RCS_Max_2 * b_gain + b_gain_bias + (b_cont - 1) *(RCS_Max_2 - 128)
b_cont_bias = (255 - b_cont_max) * gain_strength }

else { r_cont = 1.0 g_cont = 1.0 b_cont = 1.0
r_cont_bias = 0.0 g_cont_bias = 0.0 b_cont_bias = 0.0}

r_bias = r_gain_bias + r_cont_bias g_bias = g_gain_bias + g_cont_bias b_bias = b_gain_bias + b_cont_bias

#----gamma args calculation in accordance with gray world theory

# In gray world theory, in YUV range, we increase or decrease average value to ref = 128.0, but in RGB range
# ref = average of channel average values is better.
# With contrast use, average of channel average value after gain process without cont process give a better picture light.

# In gamma process, to incresae or decrease average value, we use gamma args. To find this gamma args, we
# solve this equation ref = pow(average value/255.0,1/gamma args)

ref = (RCS_Ave_0 * r_gain + r_gain_bias + RCS_Ave_1 * g_gain + g_gain_bias + RCS_Ave_2 * b_gain + b_gain_bias)/3.0

r_rpow = 1 + (log((RCS_Ave_0 * r_gain + r_gain_bias)/255.0)/log(ref/255.0) - 1) * rpow_strength
r_rpow = Min (4.0, Max (r_rpow, 0.1))
g_rpow = 1 + (log((RCS_Ave_1 * g_gain + g_gain_bias)/255.0)/log(ref/255.0) - 1) * rpow_strength
g_rpow = Min (4.0, Max (g_rpow, 0.1))
b_rpow = 1 + (log((RCS_Ave_2 * b_gain + b_gain_bias)/255.0)/log(ref/255.0) - 1) * rpow_strength
b_rpow = Min (4.0, Max (b_rpow, 0.1))

#--------- bias gain cont spow and spmid in RGBadapt args range

r_bias = Min (512.0, Max (r_bias, -512.0)) g_bias = Min (512.0, Max (g_bias, -512.0)) b_bias = Min (512.0, Max (b_bias, -512.0))
r_gain = Min (8.0, Max (r_gain, -8.0)) g_gain = Min (8.0, Max (g_gain, -8.0)) b_gain = Min (8.0, Max (b_gain, -8.0))
r_cont = Min (8.0, Max (r_cont, -8.0)) g_cont = Min (8.0, Max (g_cont, -8.0)) b_cont = Min (8.0, Max (b_cont, -8.0))

#---------- bias corrections in accordance with gray world theory

#----------- bias corrections extraction and calcul

RGBAdapt( RGB_clip, R_bias = r_bias, R_Gain = r_gain, R_Cont = r_cont, R_rpow = r_rpow,\
G_bias = g_bias, G_Gain = g_gain, G_Cont = g_cont, G_rpow = g_rpow,\
B_bias = b_bias, B_Gain = b_gain, B_Cont = b_cont, B_rpow = b_rpow)

RT_RgbChanStats( last, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 16)

# Ref for bias corrections is always calculated with gain output, because is more light than calculated with gain cont and gamma output

dr = (ref - RCS_Ave_0)* bias_strength dg = (ref - RCS_Ave_1)* bias_strength db = (ref - RCS_Ave_2)* bias_strength
r_bias = (r_gain_bias + r_cont_bias + dr) g_bias = (g_gain_bias + g_cont_bias + dg) b_bias = (b_gain_bias + b_cont_bias + db)
r_bias = Min (512.0, Max (r_bias, -512.0)) g_bias = Min (512.0, Max (g_bias, -512.0)) b_bias = Min (512.0, Max (b_bias, -512.0))

#------------ AWB output with gain cont rpow and bias process

RGBAdapt( RGB_clip, R_bias = r_bias, R_Gain = r_gain, R_Cont = r_cont, R_rpow = r_rpow,\
G_bias = g_bias, G_Gain = g_gain, G_Cont = g_cont, G_rpow = g_rpow,\
B_bias = b_bias, B_Gain = b_gain, B_Cont = b_cont, B_rpow = b_rpow)

(blankclip == 0) ? RGB_clip : last

#----------- variables strings are tuned in global mode for data display in following ScriptClip

if (show_info) { global contrast = contrast

global r_args1 = RT_String(r_args1_string,r_bias, r_gain, r_cont)
global r_args2 = RT_String(r_args2_string,r_rpow)

global g_args1 = RT_String(g_args1_string,g_bias, g_gain, g_cont)
global g_args2 = RT_String(g_args2_string,g_rpow)

global b_args1 = RT_String(b_args1_string,b_bias, b_gain, b_cont)
global b_args2 = RT_String(b_args2_string,b_rpow) }

return last ")""", args = " RGB_clip, show_info, x, y, w , h, threshold,threshold_auto, gain_strength, rpow_strength, bias_strength,"+\
"r_args1_string, r_args2_string, g_args1_string, g_args2_string, b_args1_string, b_args2_string")

#--------- datas display process

Gscript(""" if (show_info) { ScriptClip(last,"

#--------- start RGB values extraction for display

RT_RgbChanStats( RGB_clip, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+16)
start_ave = (RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2)/3.0 start_minmax = Max(RCS_Ave_0,RCS_Ave_1,RCS_Ave_2)- Min(RCS_Ave_0,RCS_Ave_1,RCS_Ave_2)
r_start1 = RT_String(start_string,RCS_Ave_0, RCS_MinMaxDiff_0, RCS_Min_0, RCS_Max_0)
g_start1 = RT_String(start_string,RCS_Ave_1, RCS_MinMaxDiff_1, RCS_Min_1, RCS_Max_1)
b_start1 = RT_String(start_string,RCS_Ave_2, RCS_MinMaxDiff_2, RCS_Min_2, RCS_Max_2)

#--------- final RGB values extraction for display

RT_RgbChanStats( last, x = x, y = y, w = w, h = h, threshold = threshold, chan = -1, flgs = 1+2+4+8+16)

r_end1 = RT_String(end_string, RCS_Ave_0, RCS_MinMaxDiff_0, RCS_Min_0, RCS_Max_0)
g_end1 = RT_String(end_string, RCS_Ave_1, RCS_MinMaxDiff_1, RCS_Min_1, RCS_Max_1)
b_end1 = RT_String(end_string, RCS_Ave_2, RCS_MinMaxDiff_2, RCS_Min_2, RCS_Max_2)

#-------- display
CWID=65 CHIT=25 # display Width and Height in Subtitle characters
MinWid=CWID*10 MinHit=CHIT*20 # RT_Subtitle required width height in pixels (fixed font size is 10x20)
TooSmall=(Width<MinWid || Height<MinHit)

S=RT_String(display_string,
\ start_ave, start_minmax, contrast,
\ r_start1, r_args1, r_args2, r_end1,
\ g_start1, g_args1, g_args2, g_end1,
\ b_start1, b_args1, b_args2, b_end1,
\ (RCS_Ave_0 + RCS_Ave_1 + RCS_Ave_2 )/3, Esc=(TooSmall)?0:1)

(TooSmall)
\ ? Subtitle(S,Font=police_string,lsp=0,text_color=$00FFFF00,halo_color=$00000000,size=height/float(CHIT),Font_width=width/FloaT(CWID))
\ : RT_Subtitle(rt_string_format_string,S)

return last ", args = "RGB_clip, x, y, w , h, threshold,start_string, end_string, display_string, rt_string_format_string, police_string") }
else { return last }

#-------- display scrutinized aera

if (show_scrutinized) {

scrutinized_green = BlankClip(RGB_clip, width = (Width(last)-x+w), height = (Height(last)-y+h), color=$00FF00)
scrutinized_white = Blankclip(RGB_clip, width = (Width(last)-x+w), height = (Height(last)-y+h), color=$FFFFFF)
scrutinized_int = Blankclip(RGB_clip, width = (Width(scrutinized_white)-4), height = (Height(scrutinized_white)-4),\
color=000000)

scrutinized_mask = Overlay(scrutinized_white, scrutinized_int, x=2, y=2, opacity=1.0, mode="multiply", greymask=true,\
ignore_conditional=false, pc_range=false)

scrutinized = Overlay(last, scrutinized_green, mask = scrutinized_mask, x=x, y=y, opacity=1.0, mode="blend", greymask=true,\
ignore_conditional=false, pc_range=false)

return scrutinized } """)

#--------- End of RGB color space process

!isRGB(clip) ? ConvertToYV12(last, matrix=matrix) : last

}

Mounir
8th January 2017, 02:54
Can you upload the .avs directly , thank you

StainlessS
8th January 2017, 03:19
Copy and paste aint that difficult, but here you go:- http://www.mediafire.com/file/93pv92jq5jy9fff/RGBAdapt_awb_process.zip

Mounir
8th January 2017, 12:17
Invalid arguments for RGBAdapt_awb_process()

Error on line 82 also (in the avs you have uploaded).....

StainlessS
8th January 2017, 14:26
At a guess I'de say that you are using Avs+, and GScript is built-in in Avs+, if you are gonna use non-standard Avs, then you really do need to know
the pitfalls to expect and fix them yourself.

Remove the calls to GScript(""" and terminating """)
or the single quote versions where used. I'm not gonna do it for you, you need to be able to do it yourself.

EDIT: You will probably want to remove the LoadPlugin() for GScript too.