0
votes

I have a black and white image which has to be rendered on screen as grayscale image of precise colours. Black should be displayed as rgb(40,40,40) and white as rgb(128,128,128).

The problem is the software to render this image does not allow colours to be specified directly; the only parameters I can vary are brightness, contrast and gamma (converting image to the desired colours is not an option).

Is there any formulae to calculate specific values for those parameters to adjust colours as desribed?

2

2 Answers

1
votes

In general, there are several ways to alter an image's contrast, gamma and brightness and it is difficult to know which method your chosen tool uses, and therefore provide the correct answer.

What you are trying to do is move the blue line (no contrast or brightness changes) in the image below to where the red line (decreased contrast) is:

enter image description here

In general, decreasing the contrast will rotate the blue line clockwise whereas increasing it will rotate it anti-clockwise. In general, increasing the brightness will shift the blue line to the right whereas decreasing the brightness will shift it left. Changing the gamma will likely make the line into a curve.

Can you use ImageMagick at the commandline instead?

convert input.png +level 15.69%,50.2% -depth 8 result.png

If you have v7+, use magick in place of convert.


I made a little gradient for you with:

convert -size 60x255 gradient: -rotate 90 gradient.png

enter image description here

And if you apply the suggested command:

convert gradient.png +level 15.69%,50.2% -depth 8 result.png

You will get this:

enter image description here

And you can check the statistics (min and max) with:

identify -verbose result.png | more

Image: result.png
  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: PseudoClass
  Geometry: 255x60+0+0
  Units: Undefined
  Type: Grayscale
  Base type: Palette
  Endianess: Undefined
  Colorspace: Gray
  Depth: 8-bit
  Channel depth:
    Gray: 8-bit
  Channel statistics:
    Pixels: 15300
    Gray:
      min: 40 (0.156863)                        <--- MIN looks good
      max: 128 (0.501961)                       <--- MAX looks good
      mean: 84.0078 (0.329443)
      standard deviation: 25.5119 (0.100047)
      kurtosis: -1.19879
      skewness: 0.000197702
1
votes

Without knowing how they compute brightness and contrast, it is hard to tell you how to do your computation.

Perhaps I still misunderstand. But you can find the min and max values in your image using Imagemagick

convert image -format %[fx:255*minima] info: 

convert image -format %[fx:255*maxima] info:

Those will be in the range of 0 to 255.

As Mark showed above the transformation is linear. So it obeys the equation

Y = a*X + b

where a is a measure of contrast and b is a measure of brightness; X is your input value and Y is your desired output value.

Thus

Ymax = a*Xmax + b

and

Ymin = a*Xmin + b

Subtracting and solving for a, we get

a = (Ymax-Ymin)/(Xmax-Xmin)

and substituting that into the equation for Ymax and saving for b, we get

b = Ymax - a*Xmax = Ymax - ( (Ymax-Ymin)/(Xmax-Xmin) )*Xmax

Then you can use the Imagemagick function -function polynomial to process your image.

In unix, I would do it as follows

Xmin=$(convert image -format %[fx:255*minima] info:)

Xmax=$(convert image -format %[fx:255*maxima] info:)

If your image is pure black and pure white, then you can skip the above and just use

Xmin=0

Xmax=255

And your desired values are

Ymin=40

Ymax=128

These are now variables and I can use -fx to do the calculations for a and b

a = $(convert xc: -format "%[fx:($Ymax-$Ymin)/($Xmax-$Xmin)]" info:)

b = $(convert xc: -format "%[fx:$Ymax - $a*$Xmax]" info:)

And to convert your image,

convert image -function polynomial "$a,$b" result image