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

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

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Usage
Register FAQ Calendar Today's Posts Search

Reply
 
Thread Tools Search this Thread Display Modes
Old 2nd June 2015, 19:40   #41  |  Link
Bernardd
Registered User
 
Join Date: Jan 2012
Location: Toulon France
Posts: 249
Thanks Gavino,

I have tried the yuv [16,235] <-> rgb [0,255] formulas, copied on Avisynth web page, but i did not know that 255 is not 255.0, like this short script show it. Thus i have not took this formula the last time.
Quote:
ScriptClip( """

Kr = 0.299
Kg = 0.587
Kb = 0.114

y = AverageLuma()
u = AverageChromaU()
v = AverageChromaV()

r_255 = (255/219)*y + (255/112)*v*(1-Kr) - (255*16/219 + 255*128/112*(1-Kr))
g_255 = (255/219)*y - (255/112)*u*(1-Kb)*Kb/Kg - (255/112)*v*(1-Kr)*Kr/Kg - (255*16/219 - 255/112*128*(1-Kb)*Kb/Kg - 255/112*128*(1-Kr)*Kr/Kg)
b_255 = (255/219)*y + (255/112)*u*(1-Kb) - (255*16/219 + 255*128/112*(1-Kb))

r_255_0 = (255.0/219)*y + (255.0/112)*v*(1-Kr) - (255.0*16/219 + 255.0*128/112*(1-Kr))
g_255_0 = (255.0/219)*y - (255.0/112)*u*(1-Kb)*Kb/Kg - (255.0/112)*v*(1-Kr)*Kr/Kg - (255.0*16/219 - 255.0/112*128*(1-Kb)*Kb/Kg - 255.0/112*128*(1-Kr)*Kr/Kg)
b_255_0 = (255.0/219)*y + (255.0/112)*u*(1-Kb) - (255.0*16/219 + 255.0*128/112*(1-Kb))

Subtitle( "Red value 255 : "+String(r_255) + " Red value 255.0 : "+String(r_255_0) +\
"\nGreen value 255 : "+String(g_255) + " Green value 255.0 : "+String(g_255_0) +\
"\nBlue value 255 : "+String(b_255) + " Blue value 255.0 : "+String(b_255_0) \
,y=40,lsp=20) """)
Now i understand, why StainlessS has added missing Float() in my script.
Bernardd is offline   Reply With Quote
Old 2nd June 2015, 23:42   #42  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
Originally Posted by Bernardd View Post
Now i understand, why StainlessS has added missing Float() in my script.
That was from Gavino too, I just copy him
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???
StainlessS is offline   Reply With Quote
Old 11th June 2015, 19:02   #43  |  Link
Bernardd
Registered User
 
Join Date: Jan 2012
Location: Toulon France
Posts: 249
Hello,

I have written this script to show my problem. I do not understand why RGBAdjust (working only with bias args) give a picture with look of coloryuv white balance,
but whith differents luma an chroma values. I need advice.

Thanks

Quote:
ScriptClip( """

#------------ Color matrix input

Kr = 0.299
Kg = 0.587
Kb = 0.114

#------------ YUV values extraction

y = AverageLuma()
u = AverageChromaU()
v = AverageChromaV()

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

r = (y-16)*255.0/219 + 2*(v-128)*255.0/224*(1-Kr)
g = (y-16)*255.0/219 - 2*(u-128)*255.0/224*(1-Kb)*Kb/Kg - 2*(v-128)*255.0/224*(1-Kr)*Kr/Kg
b = (y-16)*255.0/219 + 2*(u-128)*255.0/224*(1-Kb)

#----------- AWB corrections calcul

du = 128-u # in YUV range, correction is 128 subtract YUV channel value
dv = 128-v

#--------- Chroma values after automatic white balance

u_awb = u + du
v_awb = v + dv

#-------- RGB values for AWB chroma values

r_awb = (y-16)*255.0/219 + 2*(v_awb-128)*255.0/224*(1-Kr)
g_awb = (y-16)*255.0/219 - 2*(u_awb-128)*255.0/224*(1-Kb)*Kb/Kg - 2*(v_awb-128)*255.0/224*(1-Kr)*Kr/Kg
b_awb = (y-16)*255.0/219 + 2*(u_awb-128)*255.0/224*(1-Kb)

#------- For display target AWB Chroma values

y_awb = (Kr*219/255.0)*r_awb + (Kg*219/255.0)*g_awb + (Kb*219/255.0)*b_awb + 16
v_awb = 112.0/255.0*r_awb - Kg*112.0/255.0*g_awb/(1-Kr) - Kb*112.0/255.0*b_awb/(1-Kr) + 128.0
u_awb = - Kr*112.0/255.0*r_awb/(1-Kb) - Kg*112.0/255.0*g_awb/(1-Kb) + 112.0/255.0*b_awb + 128.0

#------ AWB RGB correction calculation

dr = r_awb - r
dg = g_awb - g
db = b_awb - b

#------ RGBAdjust bias use

ConvertToRGB(matrix = "REC601")

RGBAdjust(rb = dr, gb = dg, bb = db)

ConvertToYV12(last, matrix = "Rec601")

#------- For display output AWB Chroma values

y_out = AverageLuma(last)
u_out = AverageChromaU(last)
v_out = AverageChromaV(last)
Subtitle("target luma awb : " + string(y_awb)+ " target chroma u awb : " + string(u_awb)+ " target chroma v awb : " + string(v_awb)+\
"\nluma-output : " + string(y_out)+ " chroma u output : " + string(u_out)+ " chroma v output : " + string(v_out),lsp=20)
return last
""")
Bernardd is offline   Reply With Quote
Old 11th June 2015, 21:06   #44  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
I imagine that it's mainly because of the colorspace conversions (16->235 -> 0->255 -> 16->235), ie
ConvertToRGB(matrix = "REC601") and ConvertToYV12(last, matrix = "Rec601")
EDIT: Precision loss, pixel values are integer (also, Even though RGBAdjust takes float Bias args, cannot adjust pixels by fractional amount).

I've added a line and commented out a couple (and changed order a little bit)

Code:
ScriptClip( """

#------------ Color matrix input

Kr = 0.299
Kg = 0.587
Kb = 0.114

#------------ YUV values extraction

y = AverageLuma()
u = AverageChromaU()
v = AverageChromaV()

#----------- AWB corrections calcul

du = 128-u # in YUV range, correction is 128 subtract YUV channel value
dv = 128-v

#--------- Chroma values after automatic white balance

y_awb = y  	# ssS, Same as original
u_awb = u + du
v_awb = v + dv

#-------- RGB values for AWB chroma values

r_awb = (y-16)*255.0/219 + 2*(v_awb-128)*255.0/224*(1-Kr)
g_awb = (y-16)*255.0/219 - 2*(u_awb-128)*255.0/224*(1-Kb)*Kb/Kg - 2*(v_awb-128)*255.0/224*(1-Kr)*Kr/Kg
b_awb = (y-16)*255.0/219 + 2*(u_awb-128)*255.0/224*(1-Kb)

#------- For display target AWB Chroma values

# ssS, unnecessary colorspace conversion back to what it was before (above awb->rgb->awb)
#y_awb = (Kr*219/255.0)*r_awb + (Kg*219/255.0)*g_awb + (Kb*219/255.0)*b_awb + 16
#v_awb = 112.0/255.0*r_awb - Kg*112.0/255.0*g_awb/(1-Kr) - Kb*112.0/255.0*b_awb/(1-Kr) + 128.0
#u_awb = - Kr*112.0/255.0*r_awb/(1-Kb) - Kg*112.0/255.0*g_awb/(1-Kb) + 112.0/255.0*b_awb + 128.0

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

r = (y-16)*255.0/219 + 2*(v-128)*255.0/224*(1-Kr)
g = (y-16)*255.0/219 - 2*(u-128)*255.0/224*(1-Kb)*Kb/Kg - 2*(v-128)*255.0/224*(1-Kr)*Kr/Kg
b = (y-16)*255.0/219 + 2*(u-128)*255.0/224*(1-Kb)


#------ AWB RGB correction calculation

dr = r_awb - r
dg = g_awb - g
db = b_awb - b

#------ RGBAdjust bias use

ConvertToRGB(matrix = "REC601")

RGBAdjust(rb = dr, gb = dg, bb = db)

ConvertToYV12(last, matrix = "Rec601")

#------- For display output AWB Chroma values

y_out = AverageLuma(last)
u_out = AverageChromaU(last)
v_out = AverageChromaV(last)
Subtitle("target luma awb : " + string(y_awb)+ " target chroma u awb : " + string(u_awb)+ " target chroma v awb : " + string(v_awb)+\
"\nluma-output : " + string(y_out)+ " chroma u output : " + string(u_out)+ " chroma v output : " + string(v_out),lsp=20)
return last
""") 

return last
EDIT: Also, there are some legal range YUV TV Levels (eg $10F0F0 fully chroma saturated BLACK) that cannot be converted into RGB,
and of course out of range YUV TV levels colors too, eg $000000.

EDIT: Two page thread that is quite interesting: http://forum.doom9.org/showthread.php?t=92944
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 11th June 2015 at 23:10.
StainlessS is offline   Reply With Quote
Old 12th June 2015, 18:24   #45  |  Link
Bernardd
Registered User
 
Join Date: Jan 2012
Location: Toulon France
Posts: 249
Hi StainlessS,

Color space conversion can not explain the whole problem. I have modified my script to display output RGB channel values without ConvertToYV12.
RGBAdjust use a channel standard deviation and thus apply a bias is not a simple value copy. RGB color space action is not easy. But RGBADjust and RGBAdapt work well.

Quote:
ScriptClip( """

#------------ Color matrix input

Kr = 0.299
Kg = 0.587
Kb = 0.114

#------------ YUV values extraction

y = AverageLuma()
u = AverageChromaU()
v = AverageChromaV()

#----------- AWB corrections calcul

du = 128-u # in YUV range, correction is 128 subtract YUV channel value
dv = 128-v

#--------- Chroma values after automatic white balance

y_awb = y # ssS, Same as original
u_awb = u + du
v_awb = v + dv

#-------- RGB values for AWB chroma values

r_awb = (y-16)*255.0/219 + 2*(v_awb-128)*255.0/224*(1-Kr)
g_awb = (y-16)*255.0/219 - 2*(u_awb-128)*255.0/224*(1-Kb)*Kb/Kg - 2*(v_awb-128)*255.0/224*(1-Kr)*Kr/Kg
b_awb = (y-16)*255.0/219 + 2*(u_awb-128)*255.0/224*(1-Kb)

#------- For display target AWB Chroma values

# ssS, unnecessary colorspace conversion back to what it was before (above awb->rgb->awb)
#y_awb = (Kr*219/255.0)*r_awb + (Kg*219/255.0)*g_awb + (Kb*219/255.0)*b_awb + 16
#v_awb = 112.0/255.0*r_awb - Kg*112.0/255.0*g_awb/(1-Kr) - Kb*112.0/255.0*b_awb/(1-Kr) + 128.0
#u_awb = - Kr*112.0/255.0*r_awb/(1-Kb) - Kg*112.0/255.0*g_awb/(1-Kb) + 112.0/255.0*b_awb + 128.0

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

r = (y-16)*255.0/219 + 2*(v-128)*255.0/224*(1-Kr)
g = (y-16)*255.0/219 - 2*(u-128)*255.0/224*(1-Kb)*Kb/Kg - 2*(v-128)*255.0/224*(1-Kr)*Kr/Kg
b = (y-16)*255.0/219 + 2*(u-128)*255.0/224*(1-Kb)


#------ AWB RGB correction calculation

dr = r_awb - r
dg = g_awb - g
db = b_awb - b

#------ RGBAdjust bias use

ConvertToRGB(matrix = "REC601")

RGBAdjust(rb = dr, gb = dg, bb = db, analyze = false)

output_video = last

#------ For display AWB RGB correction after RGBAdjust

black = BlankClip(output_video, pixel_type="RGB32", color=$000000)
red = ShowRed(output_video,pixel_type="RGB32")
green = ShowGreen(output_video,pixel_type="RGB32")
blue = ShowBlue(output_video,pixel_type="RGB32")
red_out = RGBDifference(red, black)
green_out = RGBDifference(green, black)
blue_out = RGBDifference(blue, black)
dr_out = red_out - r
dg_out = green_out - g
db_out = blue_out - b

ConvertToYV12(last, matrix = "Rec601")

#------- For display output AWB Chroma values

y_out = AverageLuma(last)
u_out = AverageChromaU(last)
v_out = AverageChromaV(last)
Subtitle("Input Red awb value : "+String(r)+" Input Green awb value : "+String(g)+" Input Blue awb value : "+String(b)+\
"\nTarget Red awb value : "+String(r_awb)+" Target Green awb value : "+String(g_awb)+" Target Blue awb value : "+String(b_awb)+\
"\nOutput Red awb value : "+String(red_out)+" Output Green awb value : "+String(green_out)+" Output Blue awb value : "+String(blue_out)\
,lsp=20)
return last
""")
Bernardd is offline   Reply With Quote
Old 13th June 2015, 06:42   #46  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Each pixel could be up to 0.5 in error for both of the colorspace conversions and also up to 0.5 in error for the RgbAdjust step.
What is the biggest discrepancy you are seeing ?

I'm currently knocking up an RgbAdapt graffer thing, will post when done.

EDIT: For RgbAdjust step, each and every pixel will suffer the same error (Bias float rounded to int before addition, for the each channel).

Quote:
RGBAdjust use a channel standard deviation and thus apply a bias is not a simple value copy.
Is a simple addition
Code:
New_R = Min(Max(Old_R + Round(Bias_R),0),255)
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 13th June 2015 at 06:57.
StainlessS is offline   Reply With Quote
Old 13th June 2015, 09:23   #47  |  Link
Bernardd
Registered User
 
Join Date: Jan 2012
Location: Toulon France
Posts: 249
Hi StainlesS,

I have seen some differences for bias application, that i cannot explain with round error.
I believe find the reason : channel standard deviation. But your answer i understand it is a mistake.
I have written this short script to illustrate what i have seen.
With a BlanckClip as video, channel standard deviation = 0, 100% of bias is in output.
With any of my life videos, channel standard deviation > 0, only X % of bias is in input.
I have only seen that with big bias. Thus in this example a bias value is 100.

I do not know the rule, but it is good. With AWB bias computed in YUV color space and converted in RGB color space
the RGB output picture look is very near the UV output picture look.

Quote:
BlankClip( pixel_type="RGB32", color=$808080)
# AViSource("C:\your video.avi")
# ConvertToRGB(matrix="Rec601", interlaced=false) #If neccesary
a = RGBAdjust(analyze=true)
b = RGBAdjust(rb=100, analyze=false)
StackHorizontal(a,b.RGBAdjust( analyze=true))

Last edited by Bernardd; 13th June 2015 at 09:28.
Bernardd is offline   Reply With Quote
Old 13th June 2015, 21:56   #48  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
@Bernardd

Can I clarify earlier post, When setting Bias only and other args at default, then be equivalent to
Code:
New_R = Min(Max(Old_R + Round(Bias_R),0),255)
Here is the Lut creator (for RgbAdapt_Graffer) in VB6
Code:
Private Sub Make_Lut(Lutix As Long)
' Lutix, 0 = Blue, 1 = Green, 2 = Red
Dim x As Long, i As Long, Bias As Double, Gain As Double, Cont As Double, RPow As Double, Spow As Double, v As Double, Lin As Long
Dim rGam As Double, sGam As Double, SPMid As Double
Dim pord As Boolean, Val As Long
    Bias = Lut_Bias(Lutix)
    Gain = Lut_Gain(Lutix)
    Cont = Lut_Cont(Lutix)
    RPow = Lut_RPow(Lutix)
    Spow = Lut_SPow(Lutix)
    pord = Lut_Pord(Lutix)
    SPMid = Lut_SPMid(Lutix)
    If RPow < 0.1 Then RPow = 0.1
    rGam = 1# / RPow
    If rGam < 0.004 Then rGam = 0.004
    
    sGam = 1# / Spow
        
    Bias = Bias / 256#
    For i = 0 To 255
        v = i / 255#
        v = (v * Gain) + ((v - 0.5) * Cont + 0.5) - v + Bias
        If (rGam <> 1# Or sGam <> 1#) Then
            If (pord = False) Then
                If (rGam <> 1#) Then            ' Here, rpow 1st
                    If (v > 0#) Then            ' avoid error
                        v = v ^ rGam
                    End If
                End If
                If (sGam <> 1#) Then
                    v = v - SPMid
                    If (v < 0#) Then            ' bottom half
                        v = -v                  ' abs(), spin right way up
                        v = v / SPMid           ' Make in range 0 -> 1.0
                        v = v ^ sGam            ' spow
                        v = v * SPMid           ' Back to original range
                        v = -v                  ' spin upside down again
                    Else
                        v = v / (1# - SPMid)    ' Make in range 0 -> 1.0
                        v = v ^ sGam            ' spow
                        v = v * (1# - SPMid)    ' Back to range 0 -> 0.5
                    End If
                    v = v + SPMid
                End If
            Else
                If (sGam <> 1#) Then            ' Here Spow 1st
                    v = v - SPMid
                    If (v < 0#) Then            ' bottom half
                        v = -v                  ' abs(), spin right way up
                        v = v / SPMid           ' Make in range 0 -> 1.0
                        v = v ^ sGam            ' spow
                        v = v * SPMid           ' Back to range 0 -> 0.5
                        v = -v                  ' spin upside down again
                    Else
                        v = v / (1# - SPMid)    ' Make in range 0 -> 1.0
                        v = v ^ sGam            ' spow
                        v = v * (1# - SPMid)    ' Back to range 0 -> 0.5
                    End If
                    v = v + SPMid
                End If
                If (rGam <> 1#) Then
                    If (v > 0#) Then            ' avoid error
                        v = v ^ rGam            ' rpow
                    End If
                End If
            End If
            ' Avoid possible overflow due to multiple powers
            If (v > 1#) Then
                v = 1#
            ElseIf v < 0# Then
                v = 0#
            End If
        End If
        v = (v * 255#) + 0.5
        Val = Int(v) ' Round towards -ve infinity
        If (Val > 255) Then
            Val = 255
        ElseIf Val < 0 Then
            Val = 0
        End If
        Lut(Lutix, i) = Val
    Next i
End Sub
And here for RgbAdjust Graffer in VB 6 (direct conversion from the dll CPP EDIT: Avisynth source not dll).
Where 'off' is equivalent to Bias.
Code:
Private Sub Make_Lut(Lutix As Long)
Dim i As Long
Dim off As Double, gain As Double, gamma As Double
Dim v As Double
    off = Lut_off(Lutix)
    gain = Lut_gain(Lutix)
    gamma = 1# / Lut_gamma(Lutix)
    If gamma < 0.004 Then gamma = 0.004
    For i = 0 To 255
        v = (off + i * gain) / 255#
        v = IIf(v < 0#, 0#, IIf(v > 1#, 1#, v))
        Lut(Lutix, i) = Int((v ^ gamma) * 255# + 0.5)
    Next i
End Sub
@All

RgbAdapt() zip updated 13 june 2015, Added RgbAdapt_Graffer executable to demo plugin.
Dll not updated from v0.1. See 1st post.

Fish:


Frog: Showing Line=2, ie bubbles rather than straight line graph [EDIT: Shows big jump for both red and green in LUT].


EDIT: I should have moused over the graphic for both jpg's to show Before and After RGB colors under the mouse.
Zip includes Graffer source in VB6.

Fish2b showing Full Grid and Before & After Colors.


EDIT: The 'Copy To Clipboard' button copies the RgbAdapt() function call together with arguments.
The Left half of frame is corrected (After and Right Half Before).
You can see my Windows 95 RedTile's,

EDIT: And with full frame modified [Half Screen unticked]:
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 15th July 2017 at 18:55.
StainlessS is offline   Reply With Quote
Old 15th June 2015, 21:44   #49  |  Link
Bernardd
Registered User
 
Join Date: Jan 2012
Location: Toulon France
Posts: 249
Hi StainlessS

I have read RGBAdapt source in the past, but it is difficult for me to understand formulas in vb6. Thus now with "lut" i can not say if it is a variable or a instruction. If you have internet page to learn,thank you.

Your graffer is a nice tool. Perhaps, it will be a few better with display of RGB values before and after. But I have used it to analyse my manual process. I make iteration.

Thus i propose this new version, which add linear correction to gamma correction. Linear correction is based on the output of gamma correction.

Quote:
function RGBAdapt_auto_awb_process(clip clip, bool "show_info", bool "matrix", float "linear_gamma_mix", float "spmid", bool "pord", float "gamma")
{

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

#---------------------------------------------- need GRunT plugin ----------------------------------------------------------------------------#
# script author : Gavino http://forum.doom9.org/showthread.ph...83#post1157083 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #

standard = (matrix == false) ? "Rec601" : "Rec709"

show_info = Default(show_info, false) # show info or not, default false
matrix = Default(matrix, false) # Color standard, false = Rec 601, true = Rec 709

linear_gamma_mix = Default(linear_gamma_mix, 0.5) # linear curve use strength, between 0.0 and 1.0, default 0.5
Assert(linear_gamma_mix>=0.0 && linear_gamma_mix <= 1.0,"RGBAdapt_auto_awb: linear_gamma_mix 0.0 -> 1.0")
spmid = Default(spmid, 0.5) # it is original RGBADapt Channel_spmid args, range 0.1 to 0.99 center 0.5
Assert(spmid>=0.01 && spmid <= 0.99,"RGBAdapt_auto_awb: spmid 0.01 -> 0.99")
pord = Default(pord, false) # it is original RGBADapt Channel_pord args

gamma = Default(gamma, 2.2) # gamma value defintion for calcul between 1.0 and 15.0, default 2.2, neutral value 1.0
Assert(gamma>=0.1 && gamma <= 15.0,"RGBAdapt_auto_awb: gamma 1.0 -> 15.0")

ScriptClip(clip, """

clip = last

#------------ Color matrix input

standard = (!matrix) ? "REC601" : "REC709"
Kr = (matrix == false) ? 0.299 : 0.2126
Kg = (matrix == false) ? 0.587 : 0.7152
Kb = (matrix == false) ? 0.114 : 0.0722

#------------ YUV values extraction

(!isYV12(clip)) ? ConvertToYV12(clip, matrix=standard) : clip

y = AverageLuma()
u = AverageChromaU()
v = AverageChromaV()

#---------- Automatic white balance corrections calcul

du = 128-u # in YUV range, correction is 128 subtract YUV channel value
dv = 128-v

u_awb = u + du
v_awb = v + dv

#------------ YUV values to RGB values

#-------- original values
r = (y-16)*255.0/219 + 2*(v-128)*255.0/224*(1-Kr)
g = (y-16)*255.0/219 - 2*(u-128)*255.0/224*(1-Kb)*Kb/Kg - 2*(v-128)*255.0/224*(1-Kr)*Kr/Kg
b = (y-16)*255.0/219 + 2*(u-128)*255.0/224*(1-Kb)

#-------- AWB target RGB values

r_awb = (y-16)*255.0/219 + 2*(v_awb-128)*255.0/224*(1-Kr)
g_awb = (y-16)*255.0/219 - 2*(u_awb-128)*255.0/224*(1-Kb)*Kb/Kg - 2*(v_awb-128)*255.0/224*(1-Kr)*Kr/Kg
b_awb = (y-16)*255.0/219 + 2*(u_awb-128)*255.0/224*(1-Kb)

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

dr = r_awb - r
dg = g_awb - g
db = b_awb - b

#----------- Linear curve correction range (Bias)

dr_linear = dr * linear_gamma_mix
dg_linear = dg * linear_gamma_mix
db_linear = db * linear_gamma_mix

#---------- Remaining RGB correction after classic linear curve process

dr_gamma = dr - dr_linear
dg_gamma = dg - dg_linear
db_gamma = db - db_linear

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

yr = pow(gamma,dr_gamma/128)
yr = Min (4.0, Max (yr, 0.1))
yg = pow(gamma,dg_gamma/128)
yg = Min (4.0, Max (yg, 0.1))
yb = pow(gamma,db_gamma/128)
yb = Min (4.0, Max (yb, 0.1))

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

sr = pow(gamma,dr_gamma/128)
sr = Min (4.0, Max (sr, 0.1))
sg = pow(gamma,dg_gamma/128)
sg = Min (4.0, Max (sg, 0.1))
sb = pow(gamma,db_gamma/128)
sb = Min (4.0, Max (sb, 0.1))

#---------- RGBAdapt use

(!isRGB(clip)) ? ConvertToRGB24(last, matrix=standard) : clip

#---------- first pass : process only with gamma curves

output_video = RGBAdapt( \
R_Bias = 0, R_Gain = 1.0, R_Cont = 1.0, R_RPow = yr, R_Spow = sr, R_SPMid = spmid, R_Pord = pord,\
G_Bias = 0, G_Gain = 1.0, G_Cont = 1.0, G_RPow = yg, G_Spow = sg, G_SPMid = spmid, G_Pord = pord,\
B_Bias = 0, B_Gain = 1.0, B_Cont = 1.0, B_RPow = yb, B_Spow = sb, B_SPMid = spmid, B_Pord = pord)

#--------- first pass output RGB values extraction

black = BlankClip(output_video, pixel_type="RGB32", color=$000000)
red = ShowRed(output_video,pixel_type="RGB32")
green = ShowGreen(output_video,pixel_type="RGB32")
blue = ShowBlue(output_video,pixel_type="RGB32")
red_out = RGBDifference(red, black)
green_out = RGBDifference(green, black)
blue_out = RGBDifference(blue, black)

#------- Difference between AWB target RGB values and first pass output RGB values

dr_out = (r_awb - red_out)*(1-kr) # experiment say necessary to insert luma channel factors
dg_out = (g_awb - green_out)*(1-kg)
db_out = (b_awb - blue_out)*(1-kb)

output_video = RGBAdapt( \
R_Bias = dr_linear + dr_out*(1 -linear_gamma_mix), R_Gain = 1.0, R_Cont = 1.0, R_RPow = yr, R_Spow = sr, R_SPMid = spmid, R_Pord = pord,\
G_Bias = dg_linear + dg_out*(1 -linear_gamma_mix), G_Gain = 1.0, G_Cont = 1.0, G_RPow = yg, G_Spow = sg, G_SPMid = spmid, G_Pord = pord,\
B_Bias = db_linear + db_out*(1 -linear_gamma_mix), B_Gain = 1.0, B_Cont = 1.0, B_RPow = yb, B_Spow = sb, B_SPMid = spmid, B_Pord = pord)

output_video = RGBAdjust(output_video,analyze=false)
output_video = (!isRGB(clip)) ? ConvertToYV12(output_video, matrix=standard) : output_video

#-------- displayed info or no

(!show_info)? output_video : output_video.Subtitle("Red value : "+String(r)+" Target Red awb value : "+String(r_awb)+\
"\nRed Values Diff : "+String(dr)+\
"\nClassic AWB linear correction : "+String(dr_linear)+\
"\nGamma curves correction base : "+String(dr_gamma)+\
"\nRpow : "+String(yr)+" Spow : "+String(sr)+" last linear adjust : "+String(dr_out)+\
"\nOutput Red value : "+String(red_out),y=40,lsp=20)\
.Subtitle("Green value : "+String(g)+" Target Green awb value : "+String(g_awb)+\
"\nGreen Values Diff : "+String(dg)+\
"\nClassic AWB linear correction : "+String(dg_linear)+\
"\nGamma curves correction base : "+String(dg_gamma)+\
"\nRpow : "+String(yg)+" Spow : "+String(sg)+" last linear adjust : "+String(dg_out)+\
"\nOutput Green value : "+String(green_out),y=190,lsp=20)\
.Subtitle("Blue value : "+String(b)+" Target Blue awb value : "+String(b_awb)+\
"\nBlue Values Diff : "+String(db)+\
"\nClassic AWB linear correction : "+String(db_linear)+\
"\nGamma curves correction base : "+String(db_gamma)+\
"\nRpow : "+String(yb)+" Spow : "+String(sb)+" last linear adjust : "+String(db_out)+\
"\nOutput Blue value : "+String(blue_out), y=340,lsp=20)\
.Subtitle("Luma value "+String(y)+" Gamma : "+String(gamma), y=500)
""", args = "show_info, matrix,linear_gamma_mix, spmid, pord, gamma, standard")

}
Bernardd is offline   Reply With Quote
Old 16th June 2015, 11:15   #50  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
A LUT (Look Up Table) is just an array that is pre-prepared, where you LATER get the modified color using the
original channel value as an index into the table. EDIT: Lutix is just the RGB channel number, 0=B, 1=G, R=2.
It is quicker to set up a 3*256 pre-calculated array than to do the calculations on each and every pixel for each
channel.

I screwed up the display of 'Before' and 'After' colors, I forgot that RGB is upside down when I added that.
Added two little boxes show the actual color as well as Hex values.
Have added 4 more arguments for each channel, IMin, OMin, IMax, and OMax (all 0->255, IMin <= IMax).
Any INPUT value less than IMin will be mapped to OMin, and values greater than IMax will be mapped to
OMax. Only input values that do not comply with above are processed as usual.
This allows for weird shaped LUT to eg create masks.
Made a few more changes to the Graffer, will update a bit later today (I think)
EDIT: Both Graffer and dll pending update.


EDIT:
Previously posted RgbAdjust Graffer in VB 6 converted from Avisynth CPP source, with comments
Where 'off' is equivalent to Bias (in RgbAdapt). [EDIT: Actually its called eg rb rather than off or R_Bias in RgbAdjust,
Off is just what I called it in the RgbAdjust graffer code].
Code:
Private Sub Make_Lut(Lutix As Long)
Dim i As Long
Dim off As Double, gain As Double, gamma As Double
Dim v As Double
    off = Lut_off(Lutix)                     # Below just getting Off(bias) Gain and Gamma args
    gain = Lut_gain(Lutix)
    gamma = 1# / Lut_gamma(Lutix)
    If gamma < 0.004 Then gamma = 0.004
    For i = 0 To 255                        # Process 0 to 255 in the LUT array
        v = (off + i * gain) / 255#      # apply Gain and Bias and range 0.0 -> 1.0
        v = IIf(v < 0#, 0#, IIf(v > 1#, 1#, v))    # This is just a Min(Max()) 0.0 -> 1.0 operation, 1# just means a Double Float ie same as 1.0
        Lut(Lutix, i) = Int((v ^ gamma) * 255# + 0.5)  # Apply Gamma, range 0 -> 255, store in LUT array for Lutix chan(2 dim array, 3x256)
    Next i
End Sub
Later will use something like
Code:
NEW_R = RED_LUT(OLD_R) # where OLD_R is original Red channel value
Where Gamma and Gain at default 1.0 (ie no effect), same result as
Code:
New_R = Min(Max(Round(Old_R + Bias_R),0),255)
And because OLD_R is an integer, so is same as
Code:
New_R = Min(Max(Old_R + Round(Bias_R),0),255)
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 17th June 2015 at 03:49.
StainlessS is offline   Reply With Quote
Old 16th June 2015, 18:43   #51  |  Link
Bernardd
Registered User
 
Join Date: Jan 2012
Location: Toulon France
Posts: 249
Hi StainlessS,

Thank for explanation.

This day, i have used the graffer, and i have found a error conception for my script.
I have linked Rpow and Spow corrections. For little correction is not a real problem, but for big is not good.
I believe that i have smelt this problem, because i have put in the old script a pseudo gamma variable, which can be increase if neccessary.
With your graffer, i can analyze the process with a external view.
For gamma curve the RGB difference must be converted by formula pow(4.0, RGB difference) to give the gamma correction value.
With this formula, i can have similar power action in automated white balance and graffer white balance with bias and rpow args tunes.
But with this formula Rpow and Spow link is no good for little corrections.
Thus i have written a new version where the spow args are only manual. It is like a automated RGBAdjust with manual inflexion curves if necessary.
For normal video automated correction have a good look. For bad video add manual correction can be nice.
This day, now, i have not idea to automate Spow action.

Quote:
function RGBAdapt_auto_awb_process(clip clip, bool "show_info", bool "matrix", float "linear_gamma_mix",\
bool "spow_action_enable",float "r_spow", float "g_spow", float "b_spow",\
float "r_spmid", float "g_spmid", float "b_spmid", bool "r_pord", bool "g_pord", bool "b_pord")
{

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

#---------------------------------------------- need GRunT plugin ----------------------------------------------------------------------------#
# script author : Gavino http://forum.doom9.org/showthread.ph...83#post1157083 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #

standard = (matrix == false) ? "Rec601" : "Rec709"

show_info = Default(show_info, false) # show info or not, default false
matrix = Default(matrix, false) # Color standard, false = Rec 601, true = Rec 709

linear_gamma_mix = Default(linear_gamma_mix, 0.5) # linear curve use strength, between 0.0 and 1.0, default 0.5
Assert(linear_gamma_mix>=0.0 && linear_gamma_mix <= 1.0,"RGBAdapt_auto_awb: linear_gamma_mix 0.0 -> 1.0")
spow_action_enable = Default(spow_action_enable, false)
r_spow = Default(r_spow, 1.0) # it is original RGBADapt Channel_spmid args, range 0.1 to 0.99 center 0.5
Assert(r_spow>=0.1 && r_spow <= 4.0,"RGBAdapt_auto_awb: spow 0.1 -> 4.0")
g_spow = Default(g_spow, 1.0) # it is original RGBADapt Channel_spmid args, range 0.1 to 0.99 center 0.5
Assert(r_spow>=0.1 && g_spow <= 4.0,"RGBAdapt_auto_awb: spow 0.1 -> 4.0")
b_spow = Default(b_spow, 1.0) # it is original RGBADapt Channel_spmid args, range 0.1 to 0.99 center 0.5
Assert(r_spow>=0.1 && b_spow <= 4.0,"RGBAdapt_auto_awb: spow 0.1 -> 4.0")
r_spmid = Default(r_spmid, 0.5) # it is original RGBADapt Channel_spmid args, range 0.1 to 0.99 center 0.5
Assert(r_spmid>=0.01 && r_spmid <= 0.99,"RGBAdapt_auto_awb: spmid 0.01 -> 0.99")
g_spmid = Default(g_spmid, 0.5)
Assert(g_spmid>=0.01 && g_spmid <= 0.99,"RGBAdapt_auto_awb: spmid 0.01 -> 0.99")
b_spmid = Default(b_spmid, 0.5)
Assert(b_spmid>=0.01 && b_spmid <= 0.99,"RGBAdapt_auto_awb: spmid 0.01 -> 0.99")
r_pord = Default(r_pord, false) # it is original RGBADapt Channel_pord args
g_pord = Default(g_pord, false)
b_pord = Default(b_pord, false)

ScriptClip(clip, """

clip = last

#------------ Color matrix input

standard = (!matrix) ? "REC601" : "REC709"
Kr = (matrix == false) ? 0.299 : 0.2126
Kg = (matrix == false) ? 0.587 : 0.7152
Kb = (matrix == false) ? 0.114 : 0.0722

#------------ YUV values extraction

(!isYV12(clip)) ? ConvertToYV12(clip, matrix=standard) : clip

y = AverageLuma()
u = AverageChromaU()
v = AverageChromaV()

#---------- Automatic white balance corrections calcul

du = 128-u # in YUV range, correction is 128 subtract YUV channel value
dv = 128-v

u_awb = u + du
v_awb = v + dv

#------------ YUV values to RGB values

#-------- original values
r = (y-16)*255.0/219 + 2*(v-128)*255.0/224*(1-Kr)
g = (y-16)*255.0/219 - 2*(u-128)*255.0/224*(1-Kb)*Kb/Kg - 2*(v-128)*255.0/224*(1-Kr)*Kr/Kg
b = (y-16)*255.0/219 + 2*(u-128)*255.0/224*(1-Kb)

#-------- AWB target RGB values

r_awb = (y-16)*255.0/219 + 2*(v_awb-128)*255.0/224*(1-Kr)
g_awb = (y-16)*255.0/219 - 2*(u_awb-128)*255.0/224*(1-Kb)*Kb/Kg - 2*(v_awb-128)*255.0/224*(1-Kr)*Kr/Kg
b_awb = (y-16)*255.0/219 + 2*(u_awb-128)*255.0/224*(1-Kb)

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

dr = r_awb - r
dg = g_awb - g
db = b_awb - b

#----------- Linear curve correction range (Bias)

dr_linear = dr * linear_gamma_mix
dg_linear = dg * linear_gamma_mix
db_linear = db * linear_gamma_mix

#---------- Remaining RGB correction after classic linear curve process

dr_gamma = dr - dr_linear
dg_gamma = dg - dg_linear
db_gamma = db - db_linear

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

yr = pow(4.0,dr_gamma/128)
yr = Min (4.0, Max (yr, 0.1))
yg = pow(4.0,dg_gamma/128)
yg = Min (4.0, Max (yg, 0.1))
yb = pow(4.0,db_gamma/128)
yb = Min (4.0, Max (yb, 0.1))

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

r_spow = (!spow_action_enable)? 1.0 : r_spow
g_spow = (!spow_action_enable)? 1.0 : g_spow
b_spow = (!spow_action_enable)? 1.0 : b_spow

#---------- RGBAdapt use

(!isRGB(clip)) ? ConvertToRGB24(last, matrix=standard) : clip

#---------- first pass : process only with gamma curves

output_video = RGBAdapt( \
R_Bias = 0, R_Gain = 1.0, R_Cont = 1.0, R_RPow = yr, R_Spow = r_spow, R_SPMid = r_spmid, R_Pord = r_pord,\
G_Bias = 0, G_Gain = 1.0, G_Cont = 1.0, G_RPow = yg, G_Spow = g_spow, G_SPMid = g_spmid, G_Pord = g_pord,\
B_Bias = 0, B_Gain = 1.0, B_Cont = 1.0, B_RPow = yb, B_Spow = b_spow, B_SPMid = b_spmid, B_Pord = b_pord)

#--------- first pass output RGB values extraction

black = BlankClip(output_video, pixel_type="RGB32", color=$000000)
red = ShowRed(output_video,pixel_type="RGB32")
green = ShowGreen(output_video,pixel_type="RGB32")
blue = ShowBlue(output_video,pixel_type="RGB32")
red_out = RGBDifference(red, black)
green_out = RGBDifference(green, black)
blue_out = RGBDifference(blue, black)

#------- Difference between AWB target RGB values and first pass output RGB values

dr_out = (r_awb - red_out)*(1-kr) # experiment say necessary to insert luma channel factors
dg_out = (g_awb - green_out)*(1-kg)
db_out = (b_awb - blue_out)*(1-kb)

output_video = RGBAdapt( \
R_Bias = dr_linear + dr_out*(1 -linear_gamma_mix), R_Gain = 1.0, R_Cont = 1.0, R_RPow = yr, R_Spow = r_spow, R_SPMid = r_spmid, R_Pord = r_pord,\
G_Bias = dg_linear + dg_out*(1 -linear_gamma_mix), G_Gain = 1.0, G_Cont = 1.0, G_RPow = yg, G_Spow = g_spow, G_SPMid = g_spmid, G_Pord = g_pord,\
B_Bias = db_linear + db_out*(1 -linear_gamma_mix), B_Gain = 1.0, B_Cont = 1.0, B_RPow = yb, B_Spow = b_spow, B_SPMid = b_spmid, B_Pord = b_pord)

output_video = RGBAdjust(output_video,analyze=false)
output_video = (!isRGB(clip)) ? ConvertToYV12(output_video, matrix=standard) : output_video

#-------- displayed info or no

(!show_info)? output_video : output_video.Subtitle("Red value : "+String(r)+" Target Red awb value : "+String(r_awb)+\
"\nRed Values Diff : "+String(dr)+\
"\nClassic AWB linear correction : "+String(dr_linear)+\
"\nGamma curves correction base : "+String(dr_gamma)+\
"\nRpow : "+String(yr)+" Iteration linear adjust : "+String(dr_out)+\
"\nOutput Red value : "+String(red_out),y=40,lsp=20)\
.Subtitle("Green value : "+String(g)+" Target Green awb value : "+String(g_awb)+\
"\nGreen Values Diff : "+String(dg)+\
"\nClassic AWB linear correction : "+String(dg_linear)+\
"\nGamma curves correction base : "+String(dg_gamma)+\
"\nRpow : "+String(yg)+" Iteration linear adjust : "+String(dg_out)+\
"\nOutput Green value : "+String(green_out),y=190,lsp=20)\
.Subtitle("Blue value : "+String(b)+" Target Blue awb value : "+String(b_awb)+\
"\nBlue Values Diff : "+String(db)+\
"\nClassic AWB linear correction : "+String(db_linear)+\
"\nGamma curves correction base : "+String(db_gamma)+\
"\nRpow : "+String(yb)+" Iteration linear adjust : "+String(db_out)+\
"\nOutput Blue value : "+String(blue_out), y=340,lsp=20)\
.Subtitle("Luma value "+String(y), y=500)
""", args = "show_info, matrix,linear_gamma_mix,"+ \
"spow_action_enable, r_spow, g_spow, b_spow,"+\
"r_spmid, g_spmid, b_spmid, r_pord, g_pord, b_pord, standard")

}
Bernardd is offline   Reply With Quote
Old 17th June 2015, 03:19   #52  |  Link
kuchikirukia
Registered User
 
Join Date: Oct 2014
Posts: 476
Is this what I need to fix something like this:
kuchikirukia is offline   Reply With Quote
Old 17th June 2015, 03:23   #53  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Cant do update just yet.
For some reason my VS6 compiler is producing code that results in access violations, only for release mode (not DEBUG)
and not when using VS ToolKit 2003. Narrowed it down to about 10 lines of code the only effect of which was to link in
an avisynth dll, and when called produce a ThrowError() error message, ie "env->ThrowError("TEST: This is a test error");".
Was managing to produce access violation before getting there. [EDIT: But only in some media players eg WMP, not Vdub].

Finally tried a compile on another machine and no error exception produced by resultant dll. (same VS6 compiler).
[EDIT: And tested on same machine that was producing original error.]

When I started using VB6 a few days back, it demanded that I give it the Platform SDK Disk to update, and I think it somehow
screwed my CPP compiler.
Anyways, looks like I might be doing a system recovery from stable image from a few months back, I post update as soon as I can.

If you would like to try out the (much improved I think) Graffer, here tis:- EDIT LINK REMOVED

EDIT: kuchikirukia, DL the graffer and load in the image provided, you will easily see if the dll can be of use
(should not be too long till I update, perhaps tomorrow as I could [and usually do] do final compile using VS ToolKit 2003
which is not affected by the problem I'm having. I have to get some sleep now as its 03:30AM).
EDIT: The image YOU provided.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 17th June 2015 at 19:49.
StainlessS is offline   Reply With Quote
Old 17th June 2015, 04:19   #54  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
k, here spent about two minutes playing with the sliders, you could do better.
Maybe start with about same settings Ive used and also play with SPMid settings.
I've used identical for R,G and B.
Before on the right, mod on the left. You do not have a lot to play with.

Here:-


Gonna get some sleep now.
EDIT: The currently available dll has all args execept the bottom 4 (which are unlikely to be of use in this case).
You will want to reduce the lighter levels a bit from what I've used.

EDIT: If you do get a setting that you are happy with, post result here, I'de be interested to see what you can get out of the sample.

EDIT: I'll try to implement a Lock, so you can simultaneously set all channels the same, its real tricky one at a time.

EDIT: is it a single frame or video ?
Is camera stationary ?
Maybe need answer to both (well 2nd i video), so others could assist.
Perhaps needs some kind of mask if stationary or single frame, lighten audience and you screw with the stage lowlites.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 15th July 2017 at 18:56.
StainlessS is offline   Reply With Quote
Old 17th June 2015, 19:52   #55  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
RgbAdapt v0.3, dll and Graffer updates., see 1st post.

Added IMin, OMin, IMax, OMax args for each channel.
Now copies rather than zero Alpha channel (v0.2 no public release).


Code:
RGBAdapt v0.3, By StainlessS

For Avisynth v2.58+

RGB24/RGB32.
Audio as original.

RGBAdapt(clip c, \
    \ Float "R_Bias"=0.0,Float "R_Gain"=1.0,Float "R_Cont"=1.0,Float "R_RPow"=1.0,Float "R_Spow"=1.0,Float "R_SPMid"=0.5,Bool "R_Pord"=false,
    \ Float "G_Bias"=0.0,Float "G_Gain"=1.0,Float "G_Cont"=1.0,Float "G_RPow"=1.0,Float "G_Spow"=1.0,Float "G_SPMid"=0.5,Bool "G_Pord"=false,
    \ Float "B_Bias"=0.0,Float "B_Gain"=1.0,Float "B_Cont"=1.0,Float "B_RPow"=1.0,Float "B_Spow"=1.0,Float "B_SPMid"=0.5,Bool "B_Pord"=false,
    \ Int "R_IMin"=0,Int "R_OMin"=0,Int "R_IMax"=255,Int "R_OMax"=255,
    \ Int "G_IMin"=0,Int "G_OMin"=0,Int "G_IMax"=255,Int "G_OMax"=255,
    \ Int "B_IMin"=0,Int "B_OMin"=0,Int "B_IMax"=255,Int "B_OMax"=255
    \ )

Bias    -512.0 -> 512.0.                Bias = Brightness. 
Gain    -8.0   -> 8.0                   Gain = Zero relative contrast.
Cont    -8.0   -> 8.0                   Cont = Centre relative Contrast.
RPow    0.1    -> 4.0                   RPow = Gamma, r shaped power curve.
SPow    0.1    -> 4.0                   SPow = S shaped power curve.
SPMid   0.01   -> 0.99                  SPMid = Controls Inflection point for S shaped power curve, 0.5 = mid point ie 0.5*255.0
Pord    True/False                      Pord=Rpow processed first (False) or SPow first (True). The power functions are non commutative.

    Assuming all settings apart from RPow, SPow and SPMid at defaults:-
     Pord Default (false) RPow1st, when modifying RPow or SPow, the SPow power curve inflection point will
    remain fixed at Y = SPMid * 255.0, Rpow will slide it left or right.
     Pord SPow1st, when modifying RPow or SPow, the SPow power curve inflection point will remain fixed
    at X = SPMid * 255.0, RPow will slide it up or down.

New args v0.3
IMin    0 -> 255 : IMin <= (IMax+1)
OMin    0 -> 255
IMax    0 -> 255 : (IMin-1) <= IMax
OMax    0 -> 255

 Any INPUT value less than IMin will be mapped to OMin (both default to 0), and values greater than IMax will be mapped to
OMax (both default to 255). With default settings the Min/Max options have no effect. 
These options allow for weird shaped LUT's to eg create masks. Example, Leaving all other settings at default and
for some channel set IMax to eg 127 and OMax to 64 would map all input above 127 to 64 while leaving everything else untouched.
If you additionally set eg IMin=128 and OMin=180, then 0-127 would map to 180 and 128->255 map to 64.
The IMin <= (IMax+1) requirement allows you to map the entire 0->255 range to any two output values.

  

RgbAdapt_Graffer.exe demos the plugin and all arguments. (Will require VB6 runtimes, most will already have these.)
EDIT: Added ALL Channel Locking to the Graffer for each RgbAdapt argument, change R & G and B simultaneously.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 17th June 2015 at 21:54.
StainlessS is offline   Reply With Quote
Old 17th June 2015, 22:36   #56  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Here a better daft example what the Min/Max args could be used for (mask making) [frog not really part of example].
(not intended to do anything useful, just to show what you can do)



Also NOTE, RgbAdapt Graffer can be used with RgbAdjust (Bias[integer only], Gain and RPow only).
EDIT:Actually, Bias implemented already as Float in both dll and Graffer.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 16th March 2019 at 11:42.
StainlessS is offline   Reply With Quote
Old 17th June 2015, 23:03   #57  |  Link
kuchikirukia
Registered User
 
Join Date: Oct 2014
Posts: 476
I'm thinking something like this, maybe.



Preview is too small to really tell and I have another encode going so I'm not ready to get on this in avisynth.

Source is actually a commercial Blu-ray. I think they killed the levels because they projected onto a glossy screen which gave a hilariously enlarged and distorted reflection of the audience. So Miku is performing in a sea of demonic red faces.
kuchikirukia is offline   Reply With Quote
Old 17th June 2015, 23:16   #58  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
Preview is too small
Sorry bout dat, I struggled to make it fit 1024x768, and wanted a 512x512 graf
(which makes it actually a bit less smooth looking than if 256x256 [somewhat like point resize, sort of]).
EDIT: With 512x512 get better view when line in Dots/Bubbles style, to see jumps/gaps in LUT.
With 512x512 the graf consists of lots of little line segments without some overall formula (with rounding) to achieve
required curve. With 256x256, for the most part the lines can be up/down one pixel, left or right 1 pixel or
1 pixel 45 degree diagonal, looks quite smooth curve because of this.
Quote:
jumps/gaps in LUT
See 2nd image @ post #49.


I was trying to bring out more of the audience, silly me


EDIT: It's not too difficult to copy the RgbAdapt function call to clipboard (via the Button) and CTRL/V paste into eg VDubMod
script editor and press VD refresh button to view in all its glory.
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 18th June 2015 at 01:16.
StainlessS is offline   Reply With Quote
Old 18th June 2015, 11:15   #59  |  Link
StainlessS
HeartlessS Usurer
 
StainlessS's Avatar
 
Join Date: Dec 2009
Location: Over the rainbow
Posts: 10,980
Quote:
Also NOTE, RgbAdapt Graffer can be used with RgbAdjust (Bias[integer only], Gain and RPow only).
Actually I implemented as float in both dll and Graffer so Bias also identical for use of RgbAdjust via Graffer.
(dont know why, thought I'de done it as int in both dll and graffer).

EDIT: @ Bernardd
I see that you've left out all of the Float(Default()) floats again

Quote:
Originally Posted by StainlessS View Post
Also, there are some legal range YUV TV Levels (eg $10F0F0 fully chroma saturated BLACK) that cannot be converted into RGB,
and of course out of range YUV TV levels colors too, eg $000000.


http://forum.doom9.org/showthread.php?t=154731
__________________
I sometimes post sober.
StainlessS@MediaFire ::: AND/OR ::: StainlessS@SendSpace

"Some infinities are bigger than other infinities", but how many of them are infinitely bigger ???

Last edited by StainlessS; 18th June 2015 at 12:56.
StainlessS is offline   Reply With Quote
Old 18th June 2015, 23:36   #60  |  Link
Bernardd
Registered User
 
Join Date: Jan 2012
Location: Toulon France
Posts: 249
Hi StainlessS

Below, the last version. Default, white balance is automatic with Rpow curve. If it is not enought, first you can enable Spow curve (spmid and pord are auto), secund you can enable auto gain and cont args.
You have perhaps to choice the processed color channels by gain and cont. You can always mix classic awb (linear) with gamma awb (the only float(default) ).
You can also display the computed values to use as start values for RGBadapt manual use.

Quote:
Also, there are some legal range YUV TV Levels (eg $10F0F0 fully chroma saturated BLACK) that cannot be converted into RGB,
and of course out of range YUV TV levels colors too, eg $000000.
Why you say that ? In script, i use once "BlankClip(output_video, pixel_type="RGB32", color=$000000)", only to extract RGB channels values.
This work is in RGB color space for compute in RGB color space, do you think it is an error ? I need time to digest these datas http://forum.doom9.org/showthread.php?t=154731

Quote:
function RGBAdapt_auto_awb_process(clip clip, bool "show_info", bool "matrix", float "linear_gamma_mix", bool "booster_1",\
bool "booster_2", bool "booster_2_red_apply", bool "booster_2_green_apply", bool "booster_2_blue_apply")
{

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

#---------------------------------------------- need GRunT plugin ----------------------------------------------------------------------------#
# script author : Gavino http://forum.doom9.org/showthread.ph...83#post1157083 #
#----------------------------------------------------------------------------------------------------------------------------------------------- #

standard = (matrix == false) ? "Rec601" : "Rec709"

show_info = Default(show_info, false) # show info or not, default false
matrix = Default(matrix, false) # Color standard, false = Rec 601, true = Rec 709

linear_gamma_mix = Float(Default(linear_gamma_mix, 0.5)) # linear curve use strength, between 0.0 and 1.0, default 0.5
Assert(linear_gamma_mix>=0.0 && linear_gamma_mix <= 1.0,"RGBAdapt_auto_awb: linear_gamma_mix 0.0 -> 1.0")
booster_1 = Default(booster_1, false) # enable spow curve use
booster_2 = Default(booster_2, false) # enable gain and cont use
booster_2_red_apply = Default(booster_2_red_apply, false) # enable gain and cont use to red channel
booster_2_green_apply = Default(booster_2_green_apply, false) # enable gain and cont use to green channel
booster_2_blue_apply = Default(booster_2_blue_apply, false) # enable gain and cont use to blue channel

ScriptClip(clip, """

clip = last

#------------ Color matrix input

standard = (!matrix) ? "REC601" : "REC709"
Kr = (matrix == false) ? 0.299 : 0.2126
Kg = (matrix == false) ? 0.587 : 0.7152
Kb = (matrix == false) ? 0.114 : 0.0722

#------------ YUV values extraction

(!isYV12(clip)) ? ConvertToYV12(clip, matrix=standard) : clip

y = AverageLuma()
u = AverageChromaU()
v = AverageChromaV()

#---------- Automatic white balance corrections calcul

du = 128-u # in YUV range, correction is 128 subtract YUV channel value
dv = 128-v

u_awb = u + du
v_awb = v + dv

#------------ YUV values to RGB values

#-------- original values
r = (y-16)*255.0/219 + 2*(v-128)*255.0/224*(1-Kr)
g = (y-16)*255.0/219 - 2*(u-128)*255.0/224*(1-Kb)*Kb/Kg - 2*(v-128)*255.0/224*(1-Kr)*Kr/Kg
b = (y-16)*255.0/219 + 2*(u-128)*255.0/224*(1-Kb)

#-------- AWB target RGB values

r_awb = (y-16)*255.0/219 + 2*(v_awb-128)*255.0/224*(1-Kr)
g_awb = (y-16)*255.0/219 - 2*(u_awb-128)*255.0/224*(1-Kb)*Kb/Kg - 2*(v_awb-128)*255.0/224*(1-Kr)*Kr/Kg
b_awb = (y-16)*255.0/219 + 2*(u_awb-128)*255.0/224*(1-Kb)

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

dr = r_awb - r
dg = g_awb - g
db = b_awb - b

#----------- Linear curve correction range (Bias)

dr_linear = dr * linear_gamma_mix
dg_linear = dg * linear_gamma_mix
db_linear = db * linear_gamma_mix

#---------- Remaining RGB correction after classic linear curve process

dr_gamma = dr - dr_linear
dg_gamma = dg - dg_linear
db_gamma = db - db_linear

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

yr = pow(4.0,dr_gamma/128)
yr = Min (4.0, Max (yr, 0.1))
yg = pow(4.0,dg_gamma/128)
yg = Min (4.0, Max (yg, 0.1))
yb = pow(4.0,db_gamma/128)
yb = Min (4.0, Max (yb, 0.1))

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

sr = (!booster_1)? 1.0 : pow(4.0,dr_gamma/(256.0))
sr = Min (4.0, Max (sr, 0.1))
sg = (!booster_1)? 1.0 : pow(4.0,dg_gamma/(256.0))
sg = Min (4.0, Max (sg, 0.1))
sb = (!booster_1)? 1.0 : pow(4.0,db_gamma/(256.0))
sb = Min (4.0, Max (sb, 0.1))


#--------- Spmid calcul

r_spmid = 0.5 * sr
r_spmid = Min (0.99, Max (r_spmid, 0.01))
g_spmid = 0.5 * sg
g_spmid = Min (0.99, Max (g_spmid, 0.01))
b_spmid = 0.5 * sb
b_spmid = Min (0.99, Max (b_spmid, 0.01))

#------- Pord calcul

r_pord = (sr < 1.0) ? true : false
g_pord = (sg < 1.0) ? true : false
b_pord = (sb < 1.0) ? true : false

#---------- RGBAdapt use

(!isRGB(clip)) ? ConvertToRGB24(last, matrix=standard) : clip

#---------- first pass : process only with gamma curves

output_video = RGBAdapt( \
R_Bias = 0, R_Gain = 1.0, R_Cont = 1.0, R_RPow = yr, R_Spow = sr, R_SPMid = r_spmid, R_Pord = r_pord,\
G_Bias = 0, G_Gain = 1.0, G_Cont = 1.0, G_RPow = yg, G_Spow = sg, G_SPMid = g_spmid, G_Pord = g_pord,\
B_Bias = 0, B_Gain = 1.0, B_Cont = 1.0, B_RPow = yb, B_Spow = sb, B_SPMid = b_spmid, B_Pord = b_pord)

#--------- first pass output RGB values extraction

black = BlankClip(output_video, pixel_type="RGB32", color=$000000)

red = ShowRed(output_video,pixel_type="RGB32")
green = ShowGreen(output_video,pixel_type="RGB32")
blue = ShowBlue(output_video,pixel_type="RGB32")
red_out = RGBDifference(red, black)
green_out = RGBDifference(green, black)
blue_out = RGBDifference(blue, black)
y_out = red_out*kr+green_out*kg+blue_out*kb

#------- Difference between AWB target RGB values and first pass output RGB values

dr_out = (r_awb - red_out)*(1-kr) # experiment say necessary to insert luma channel factors
dg_out = (g_awb - green_out)*(1-kg)
db_out = (b_awb - blue_out)*(1-kb)

r_gain_out = (!booster_2) ? 0 : ((!booster_2_red_apply) ? 0 : dr_out/(red_out+r))
g_gain_out = (!booster_2) ? 0 : ((!booster_2_green_apply) ? 0 : dg_out/(green_out+g))
b_gain_out = (!booster_2) ? 0 : ((!booster_2_blue_apply) ? 0 : db_out/(blue_out+b))

r_cont_out = (!booster_2) ? 0 : ((!booster_2_red_apply) ? 0 : dr_out/(red_out+r))
g_cont_out = (!booster_2) ? 0 : ((!booster_2_green_apply) ? 0 : dg_out/(green_out+g))
b_cont_out = (!booster_2) ? 0 : ((!booster_2_blue_apply) ? 0 : db_out/(blue_out+b))

output_video = RGBAdapt( \
R_Bias = dr_linear + dr_out*(1 -linear_gamma_mix), R_Gain = 1.0 + r_gain_out, R_Cont = 1.0 + r_cont_out, \
R_RPow = yr, R_Spow = sr, R_SPMid = r_spmid, R_Pord = r_pord,\
G_Bias = dg_linear + dg_out*(1 -linear_gamma_mix), G_Gain = 1.0 + g_gain_out, G_Cont = 1.0 + g_cont_out, \
G_RPow = yg, G_Spow = sg, G_SPMid = g_spmid, G_Pord = g_pord,\
B_Bias = db_linear + db_out*(1 -linear_gamma_mix), B_Gain = 1.0 + b_gain_out, B_Cont = 1.0 + b_cont_out, \
B_RPow = yb, B_Spow = sb, B_SPMid = b_spmid, B_Pord = b_pord)

#--------- secund pass output RGB values extraction to display
red = ShowRed(output_video,pixel_type="RGB32")
green = ShowGreen(output_video,pixel_type="RGB32")
blue = ShowBlue(output_video,pixel_type="RGB32")
red_out = RGBDifference(red, black)
green_out = RGBDifference(green, black)
blue_out = RGBDifference(blue, black)

output_video = RGBAdjust(output_video,analyze=false)
output_video = (!isRGB(clip)) ? ConvertToYV12(output_video, matrix=standard) : output_video

#-------- displayed info or no

(!show_info)? output_video : output_video\
.Subtitle("Red value : "+String(r)+" Target Red awb value : "+String(r_awb)+\
"\nRed Values Diff : "+String(dr)+\
"\nClassic AWB linear correction : "+String(dr_linear)+" Iteration linear adjust : "+String(dr_out)+\
"\nGamma curves correction base : "+String(dr_gamma)+\
"\nRpow : "+String(yr)+" Spow : "+String(sr)+" Spmid : "+String(r_spmid)+" Pord : "+String(r_pord)+\
"\nGain / Cont : "+String(r_gain_out)+ " Output Red value : "+String(red_out),y=40,lsp=20)\
.Subtitle("Green value : "+String(g)+" Target Green awb value : "+String(g_awb)+\
"\nGreen Values Diff : "+String(dg)+\
"\nClassic AWB linear correction : "+String(dg_linear)+" Iteration linear adjust : "+String(dg_out)+\
"\nGamma curves correction base : "+String(dg_gamma)+\
"\nRpow : "+String(yg)+" Spow : "+String(sg)+" Spmid : "+String(g_spmid)+" Pord : "+String(g_pord)+\
"\nGain / Cont : "+String(g_gain_out)+ " Output Green value : "+String(green_out),y=190,lsp=20)\
.Subtitle("Blue value : "+String(b)+" Target Blue awb value : "+String(b_awb)+\
"\nBlue Values Diff : "+String(db)+\
"\nClassic AWB linear correction : "+String(db_linear)+" Iteration linear adjust : "+String(db_out)+\
"\nGamma curves correction base : "+String(db_gamma)+\
"\nRpow : "+String(yb)+" Spow : "+String(sb)+" Spmid : "+String(b_spmid)+" Pord : "+String(b_pord)+\
"\nGain / Cont : "+String(b_gain_out)+ " Output Blue value : "+String(blue_out), y=340,lsp=20)\
.Subtitle("Luma value "+String(y)+" "+String(r_cont_out), y=500)
""", args = "show_info, matrix,linear_gamma_mix,booster_1,"+ \
"booster_2, booster_2_red_apply,booster_2_green_apply,booster_2_blue_apply")

}

Last edited by Bernardd; 18th June 2015 at 23:42.
Bernardd is offline   Reply With Quote
Reply

Tags
rgbadjust


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

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

Forum Jump


All times are GMT +1. The time now is 05:25.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.