Fred's ImageMagick Scripts



 

 

AUTOWHITE


Automatically adjusts the white balance of an image.

Download Script

last modified: June 03, 2009



USAGE: autowhite [-m method] [-p percent] infile outfile
USAGE: autowhite [-help]

-m .... method .......... method to adjust white balance;
......................... method=1 is multiplicative adjust;
......................... method=2 is additivie adjust; default=1
-p .... percent ......... percent pixels closest to white to get average;
......................... float; 0<=percent<=100; default=1

PURPOSE: To automatically adjust the white balance of an image.

DESCRIPTION: AUTOWHITE automatically adjusts the white balance of an image. Two methods are available. Method 1 uses a multiplicative adjustment using -recolor. Method 2 uses an additive adjustment using -evaluate add. Both methods compute RGB channel averages of a user specified percentage of pixels closest to white. The channel averages are used in a ratio compared with white in method 1 and as a difference from white in method 2.

ARGUMENTS:

-m method ... METHOD defines how the white balance adjustment will be handled. Method 1 uses a multiplicative adjustment using -recolor, where the recolor matrix values are the ratios of 100% to the channel averages in percent graylevel. Method 2 uses an additive adjustment using -evaluate add, where the additive amount is the percent difference of the channel averages from 100%. Method 1 is generally superior. Method 2 often shifts the overall color oddly. The default is method=1.

-p percent ... PERCENT is the percentage of pixels closest in color to white that is used to compute the average graylevel of each RGB channel in the image. Values are floats between 0 and 100. Default=1

CAVEAT: No guarantee that this script will work on all platforms, nor that trapping of inconsistent parameters is complete and foolproof. Use At Your Own Risk.


EXAMPLES


Variation In Percent Pixels Used To Compute Average

Original Image

Arguments:
-m 1 -p 0

Arguments:
-m 1 -p 1

Arguments:
-m 1 -p 5

Original Image

Arguments:
-m 2 -p 0

Arguments:
-m 2 -p 1

Arguments:
-m 2 -p 5



Comparison Method 1 And 2 --- Percent=1

Original Image

Arguments:
-m 1 -p 1

Arguments:
-m 2 -p 1



Comparison Method 1 And 2 --- Percent=1

Original Image

Arguments:
-m 1 -p 1

Arguments:
-m 2 -p 1



Comparison Method 1 And 2 --- Percent=1

Original Image

Arguments:
-m 1 -p 1

Arguments:
-m 2 -p 1



Comparison Method 1 And 2 --- Percent=1

Original Image

Arguments:
-m 1 -p 1

Arguments:
-m 2 -p 1



What the script does is as follows:

  • Converts the image to RGB and separates channels
  • Iterates computing a binary mask image using a fuzz value
    to threshold the selection of near white pixels
    and continues until the percentage of white pixels is
    greater than the specified percent parameter
  • Multiplies the mask image by each channel image
  • Computes the average of the masked channel image
    ignoring pixels with value=0 (black)
  • Computes the ratio of 255/average for each channel
  • Applies -recolor to the original image using the ratios
    for the main diagonal elements of the matrix and zero elsewhere

This is equivalent to the following IM commands for method=1.

  • convert $infile -colorspace RGB -channel R -separate $tmpR1
  • convert $infile -colorspace RGB -channel G -separate $tmpG1
  • convert $infile -colorspace RGB -channel B -separate $tmpB1
  • thresh=1; mean=0; stop=0;
  • while [ $stop -eq 0 ]; do
  • convert $infile -fuzz $thresh% -fill black \
    +opaque white -fill white -opaque white $tmpM1
  • mean=`convert $img -format "%[mean]" info:`
  • mean=`convert xc: -format "%[fx:100*$mean/quantumrange]" info:`
  • thresh=`expr $thresh + 1`
  • stop=`echo "$mean > $percent" | bc`
  • done
  • convert $tmpR1 $tmpM1 -compose multiply -composite $tmpT1
  • Generate histogram of $tmpT1 and compute average of non-black pixels
  • redratio=`convert xc: -format "%[fx:255/$ave]" info:`
  • convert $tmpG1 $tmpM1 -compose multiply -composite $tmpT1
  • Generate histogram of $tmpT1 and compute average of non-black pixels
  • greenratio=`convert xc: -format "%[fx:255/$ave]" info:`
  • convert $tmpB1 $tmpM1 -compose multiply -composite $tmpT1
  • Generate histogram of $tmpT1 and compute average of non-black pixels
  • blueratio=`convert xc: -format "%[fx:255/$ave]" info:`
  • convert $tmpA1 -recolor "$redratio 0 0 0 $greenratio 0 0 0 $blueratio" $outfile