Log in

View Full Version : A scheme for white balancing


HighInBC
19th June 2005, 01:47
I am currently using a perl script to create an RGBAdjust command for white balancing. You give it the color of a pixel that should be white, and it gives you the command to put into avisynth.

This is the perl routine:


sub wb
{
my $r = shift;
my $g = shift;
my $b = shift;
my $modify = shift || 1;
my $largest = $r;
($largest = $g) if ($g > $largest);
($largest = $b) if ($b > $largest);
$largest = ($largest * $modify);
$r = $largest/$r;
$g = $largest/$g;
$b = $largest/$b;
my $avs_line = "RGBAdjust($r,$g,$b,1)";
return $avs_line;
}


I was wondering if anyone could whip up a filter where I could give it a clip, frame number, and x/y pixel coords of a pixel that should be white, and optionaly a brightness value. The filter would simply invoke RGBAdjust with the calculated values.

eg:
clip.WhiteBalance(frame=46,x=245,y=146)
or
clip.WhiteBalance(frame=46,x=245,y=146,bright=.95)

Perhaps this could even be part of the core filters, as it lets you very easily white balance clips.

I have included before and after images, in this case I gave the sub the color fo a pixel on the table and it gave me:
RGBAdjust(1,1.17058823529412,2.09473684210526,1)

Before:
http://adserton.crackerjack.net/~rambler/before.jpg
After:
http://adserton.crackerjack.net/~rambler/after.jpg

For more information on this routine see my thread in the avisynth usage: http://forum.doom9.org/showthread.php?t=96042

Oh by the way this code is declared public domain by owner(me!).

HighInBC
19th June 2005, 16:16
here is a pure avisynth version of this function:


function WhiteBalance(clip clip, int r, int g, int b, float bright)
{
largest = ((r > g) ? (r) : (g))
largest = ((largest > b) ? (largest) : (b))
largest = largest * bright
new_r = largest / Float(r)
new_g = largest / Float(g)
new_b = largest / Float(b)
return clip.RGBAdjust(new_r,new_g,new_b,1)
}


Is there a way for avisynth to return the color of a specific pixel into an int?

Wilbert
20th June 2005, 19:00
Is there a way for avisynth to return the color of a specific pixel into an int?
You will have to program something yourself :)

communist
30th June 2005, 10:15
Cool thats a nice script - I just tried it on some DV files and works as it should :)
I was wondering if anyone could whip up a filter where I could give it a clip, frame number, and x/y pixel coords of a pixel that should be white, and optionaly a brightness value. The filter would simply invoke RGBAdjust with the calculated values.

eg:
clip.WhiteBalance(frame=46,x=245,y=146)
or
clip.WhiteBalance(frame=46,x=245,y=146,bright=.95)

Perhaps this could even be part of the core filters, as it lets you very easily white balance clips.

Something like what you suggested but that allowed you to give it a list of frames and X/Y coordinates or alternatively RGB values for pixels that should be white (-> 'animated WB') - because right now it works only good with scenes with static "off WB" - footage with changing WB isnt catched by it.
Thanks again for the function :)

HighInBC
30th June 2005, 15:47
Good idea! Perhaps this could be accomplioshed with the animate command, however I would like a filter that takes a text file listing like so:

<FRAME>:<X>,<Y>
<FRAME>:<X>,<Y>
......

it would determine a white balance for each frame, then have a smooth transition from one to the other using gradients.

This would allow for white balance in more dynamic footage.

Glad to hear that the function works so well... Oh, I had an idea of basing the divisor on the average of the 3 channels instead of the largest... this should stop the function from increasing the brightness of the video.

like this:


function WhiteBalance(clip clip, int r, int g, int b, float bright)
{
divisor = (Float(r)+Float(b)+Float(g))/3
divisor = divisor * bright
new_r = divisor / Float(r)
new_g = divisor / Float(g)
new_b = divisor / Float(b)
return clip.RGBAdjust(new_r,new_g,new_b,1)
}


I just typed this up, I have not tested it. I will later

scharfis_brain
30th June 2005, 16:09
the average luma of a channel can be measured with averageluma()

i.e. prepare it like this:


global x=avisource("blah.avi")
global xr=x.converttogrb32().rgbadjust(1,0,0,0).converttoyv12()
global xg=x.converttogrb32().rgbadjust(0,1,0,0).converttoyv12()
global xb=x.converttogrb32().rgbadjust(0,0,1,0).converttoyv12()
x0=scriptclip(x,"whitebalance(x,r,g,b)")
x1=x0.frameevalutate("r=rx.averageluma()")
x2=x1.frameevalutate("g=gx.averageluma()")
x2.frameevalutate("b=bx.averageluma(r)")


this code is directly moved from brain to hands, so expect typos and conceptional mistakes

Cyberia
30th June 2005, 19:37
Your adjusted picture seems like it is overcompensated. There is a slight blue tint to the image like the Cb was overshifted.

You might not have picked a starting pixel that was meant to be true white. Try using one of the shiny buttons on the doctors coat, or the bright reflection on the wine glass as your starting pixel.

trevlac
30th June 2005, 21:06
Your adjusted picture seems like it is overcompensated. There is a slight blue tint to the image like the Cb was overshifted.


Now that you mention it ... I noticed that the girl's face is a little blue.

I ran a vectorscope on the before and after. It looks like white not only shifts, but the saturation of Blue jumped a bit. You can see the skin tones shifted from the "I" line, towards blue.

http://www.trevlac.us/pics/HighinBC_VS.JPG


Don't get me wrong ... I think this is a beautifully easy user interface. It screams to be a virtualDub filter. :D Pull the image up in preview and click on what should be white ... black ... whatever ... add a color picker and a color pallet ... and ... :)

[edit]

To make it easier to see the effect on the girls face, I masked out everything else.

http://www.trevlac.us/pics/HighinBC_VS2.JPG

HighInBC
1st July 2005, 00:16
Indeed it is a little blue, but that is because the table I used to show the function what is white has a slight orange tint to it in reality.

trevlac
1st July 2005, 18:46
@HighInBC

I made a quick and dirty virtualDub filter from your idea. You click on 'white' in the preview and it makes that white and adjusts everything else. I did not implement the brightness. Not sure of the best way to do that. It has a sort of before and after color picker.

It's a rather slow and sloppy alpha ... but I included the source. I was not sure if you had a c compiler or could do c. If you're interested in doing the development or want things added, I'd be happy to help.

http://www.trevlac.us/HighInBC.zip

Sorry for posting vdub stuff in the avs area ... I just thought the idea was such a nice way to do a quick adjustment.

joshbm
1st July 2005, 20:14
Yes,

I agree, it screams "VDub Plugin" ;).

Regards,
joshbm

HighInBC
6th July 2005, 15:16
thanks trevlac, most usefull

Backwoods
31st March 2006, 06:23
What would the exact method of using this script? If someone could post an example I would greatly appreciate it.

jmac698
2nd April 2006, 15:05
Someone is working on this at http://forum.doom9.org/showthread.php?t=108602. Help them/bug them to finish it :)