When ImageAdjust is called with an image, i.e. with one parameter, it returns an automatically adjusted Image. I would like to retrieve the {contrast, brightness, gamma} values ImageAdjust has calculated and use them as starting points for a following interactive manipulation of these value using ImageAdjust[img, {contrast, brightness, gamma}], i.e. with four parameters.

An obvious solution is to perform an image histogram equalization and calculate {contrast, brightness, gamma}. However, since Mathematica provides the solution somewhere in its code and I intend to continue using ImageAdjust I would rather conform with the already implemented algorithm.

Hence, my questions is: How do I retrieve the parameters calculated and used by ImageAdjust when it runs automatically?


2 Answers 2


Major update at the bottom. First part may be obsolete.

A brute force approach:

Define a function that provides a measure of the difference between the automatically adjusted image and an image with given contrast, brightness and gamma adjustments (for now, this only works for images that are made of a raster of color triplets):

f[c_?NumericQ, b_?NumericQ, γ_?NumericQ, im_Image] := 
    Total[Map[#.# &, ImageData@ImageAdjust[im] - ImageData@ImageAdjust[im, {c, b, γ}], {2}], 2]

Get an image:


Mathematica graphics

Now minimize the image differences:

adj = FindMinimum[f[c, b, γ, img], {{c, 0.1, 0, -1, 1}, {b, 0.1, 0, -1, 1}, {γ, 1.1, 1, 0.1, 3}}]

{14.19915417, {c -> -0.06143890985, b -> 0.09520280553, γ -> 1.094933574}}

Comparison of original image and automatically adjusted image:

Row[{img, ImageReflect[ImageAdjust[img], Left -> Right], img}]

Mathematica graphics

Comparison of the semi-automatically adjusted image and fully automatically adjusted image:

Row[{ImageAdjust[img, {c, b, γ} /. adj[[2]]],
     ImageReflect[ImageAdjust[img], Left -> Right], 
     ImageAdjust[img, {c, b, γ} /. adj[[2]]]}

Mathematica graphics

The differences are small:

ImageSubtract[ImageAdjust[img, {c, b, γ} /. adj[[2]]], ImageAdjust[img]]

Mathematica graphics

And 'small' is this:

ImageSubtract[ImageAdjust[img, {c, b, γ} /. adj[[2]]], ImageAdjust[img]] // ImageData // Max


Using ImageAdjust itself to enhance those differences:

ImageSubtract[ImageAdjust[img, {c, b, γ} /. adj[[2]]], ImageAdjust[img]] // ImageAdjust

Mathematica graphics

Not quite an exact match but close.


Originally, I believed that ImageAdjust does a simple histogram stretch, scaling the maximum pixel value to 1 and the minimum to 0, basically this:

imgd = img // ImageData;
min = Min[imgd];
max = Max[imgd];
Rescale[imgd, {min, max}, {0, 1}]

But that simply didn't work out. If I use the measure introduced in the beginning to determine the difference between the {c,b,γ}-adjusted pictures and the automatically ImageAdjusted pictures on the one hand and the rescaled pictures and the automatically ImageAdjusted pictures on the other hand, the {c,b,γ} seems to be better 4 out of the 5 test images I used it on.

   img = #;
   imgd = img // ImageData;
   min = Min[imgd];
   max = Max[imgd];
   adj = FindMinimum[f[c, b, γ, img], 
                     {{c, 0.1, 0, -1, 1}, {b, 0.1, 0, -1, 1}, {γ, 1.1, 1, 0.1, 3}}];
   {Total[Map[#.# &,
          ImageData@ImageAdjust[img]-ImageData@ImageAdjust[img, {c, b, γ} /. adj[[2]]], {2}],
    Total[Map[#.# &, ImageData@ImageAdjust[img]-Rescale[imgd, {min, max}, {0, 1}], {2}], 2]
   ) & /@ { ...images...}

For the five pictures on the ImageAdjust doc page I get:

{{50.5394233, 81.76899059}, {14.19915417, 14.46839005}, {30.34660515, 46.0902785}, {6.459238754, 2.528418174}, {537.6580546, 1011.243348}}

It seems that ImageAdjust does more than a simple stretching of the values. It probably uses histogram equalization, which linearizes the cumulative distribution function of the pixel intensity values. This is a rather non-linear transformation. It probably requires a transformation to another color space first, to separate color values from luminance values (CIELab for instance). The transformation will then be done on the luminance component only after which an inverse color space transformation occurs.

Yet another edit

Trying to test the hypothesis Mathematica is using histogram equalization.

Load an image and turn it into grayscale (we won't do this colorspace hence and forth stuff here):

img = Import["https://i.sstatic.net/xGMge.png"]
imgG = ImageData[ColorConvert[img, "Grayscale"]];

Mathematica graphics

Do histogram equalization:

SetAttributes[cdf, Listable]
Scan[(cdf[#[[1]]] = #[[2]]) &,
     Transpose[MapAt[Accumulate, Transpose[Sort@Tally[Flatten[imgG]]], 2]]]
imgH = (cdf[imgG] - cdf[Min[imgG]])/(Times @@ ImageDimensions[img] - cdf[Min[imgG]]);

Accumulated counts before equalization:

ListPlot@Transpose[MapAt[Accumulate, Transpose[Sort@Tally[Flatten[imgG]]], 2]]

Mathematica graphics

Accumulated counts after equalization:

ListPlot@Transpose[MapAt[Accumulate, Transpose[Sort@Tally[Flatten[imgH]]], 2]]

Mathematica graphics

Image comparisons:

Original grayscale image:

imgG // Image

Mathematica graphics

Automatically adjusted image:

imgG // Image // ImageAdjust

Mathematica graphics

Histogram equalized image:

imgH // Image

Mathematica graphics

Clearly, ImageAdjust does not do a histogram equalization.

Final edit

For grayscale images at least, Mathematica seems to do a simple rescaling after all. The rescaling I used above used the minimum and maximum values measured over all color channels. In a grayscale image, rescaling with

Rescale[imgG, {Min[imgG], Max[imgG]}, {0, 1}] 

yields an image that is virtually identical to the adjusted image:

(imgG // Image // ImageAdjust // ImageData) - 
 Rescale[imgG, {Min[imgG], Max[imgG]}, {0, 1}] // Abs // Max


So, conclusion: there are no {c, b, γ} parameters to be estimated because ImageAdjust, called without additional parameters, doesn't use them.

  • $\begingroup$ +1 Cool question & solution ;) Nice to see clean convergence in 3-parameters space. $\endgroup$ Nov 20, 2012 at 23:16
  • $\begingroup$ Here, one could use FindArgMin[] instead of FindMinimum[], since we're only interested in the parameters (as opposed to the minimum value.) $\endgroup$ Nov 21, 2012 at 0:07
  • $\begingroup$ Thank you very much. That is neat, is very well presented and works well. But a) it is not really what I asked for and b) it is fairly slow. The actual issue is, the values have already been calculated by ImageAdjust and I wonder if there isn't a simple way to get them with the adjusted image. $\endgroup$ Nov 21, 2012 at 8:45
  • 1
    $\begingroup$ @ErnstStelzer Please see my final edit: there seem to be no parameters to be estimated after all. $\endgroup$ Nov 21, 2012 at 10:44
  • 1
    $\begingroup$ @SjoerdC.deVries For RGB images, each R, G, B channel is processed independently. $\endgroup$ Nov 26, 2012 at 17:34

With only one argument, ImageAdjust[img] performs histogram stretching, ie. pixel values, which run from min to max in img, are rescaled so they run from 0 to 1 in the ouput image.

The setting {contrast, brightness, gamma} = {0, 0, 1} does not change anything: ImageAdjust[img, {0, 0, 1}] === img gives True.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.