pnmnorm1
Normalize the contrast in a netpbm image
Usage
pnmnorm
[-bpercent=percent | -bvalue=N | -bsingle]
[-wpercent=percent | -wvalue=N | -wsingle]
[-midvalue=N]
[-middle=N]
[-maxexpand=percent]
[-keephues]
[-luminosity | -colorvalue | -saturation]
[ppmfile]
All options can be abbreviated to their shortest unique prefix. You may use two hyphens instead of one to designate an option. You may use either white space or an equals sign between an option name and its value.
Overview
This program is part of Netpbm(1) .
pnmnorm reads a PNM image (PBM, PGM, or PPM). It normalizes the contrast by forcing the brightest pixels to white, the darkest pixels to black, and spreading out the ones in between. It produces the same kind of file as output. This is pretty useless for a PBM image.
The program offers two ways of spreading out the pixels in between the darkest and brightest: linear and quadratic. In the quadratic case, you specify some in between brightness and specify what brightness that should become in the output. With those three constraints: the brightness that becomes black, the brightness that becomes white, and the brightness that becomes that middle value, pnmnorm computes a quadratic equation that maps all the other brightnesses from input values to output values.
The program first determines a mapping of old brightness to new brightness. For each possible brightness of a pixel, the program determines a corresponding brightness for the output image.
Then for each pixel in the image, the program computes a color which has the desired output brightness and puts that in the output. With a color image, it is not always possible to compute such a color and retain any semblance of the original hue, so the brightest and dimmest pixels may only approximate the desired brightness.
For a PPM image, you have a choice of three ways to define brightness:
- •
-
luminosity
- •
-
color value
- •
-
saturation
In the case of saturation, "brightness" is pretty much a misnomer, but you can use the brightness analogy to see what it does. In the analogy, bright means saturated and dark means unsaturated.
Note that all of these are different from separately normalizing the individual color components.
An alternative way to spread out the brightnesses in an image is pnmhisteq. pnmhisteq stretches the brightest pixels to white and the darkest pixels to black, but rather than linearly adjusting the ones in between, it adjusts them so that there are an equal number of pixels of each brightness throughout the range. This gives you more contrast than pnmnorm does, but can considerably change the picture in exchange.
Options
In addition to the options common to all programs based on libnetpbm (most notably -quiet, see
Common Options ⟨index.html#commonoptions⟩ ), pnmnorm recognizes the following command line options:
By default, the darkest 2 percent of all pixels are mapped to black, and the brightest 1 percent are mapped to white. You can override this behavior and specify either a different percentage, or specific brightness values to map to black and to white, or just have the single greatest brightness map to white and the least brightness map to black.
-
-bpercent
-
-wpercent
-
-bvalue
-
-wvalue -
To specify a percentage, use the
-bpercentand-wpercentoptions, or you can specify the exact pixel values to be mapped by using the-bvalueand-wvalueoptions. You can get appropriate numbers for the options fromppmhist. If you just want to enhance the contrast, then choose values at elbows in the histogram; e.g. if value 29 represents 3% of the image but value 30 represents 20%, choose 30 for bvalue. If you want to brighten the image, then set bvalue to 0 and just fiddle with wvalue; similarly, to darken the image, set wvalue to maxval and play with bvalue.If you specify both
-bvalueand-bpercent,pnmnormuses the one that produces the least change. The same goes for-wvalueand-wpercent. (In Netpbm 10.26 (January 2005), the-bvalue/-wvaluetakes precedence, and before that, it's a syntax error to specify both).If you want to maximize the change instead of minimizing it, just cascade two runs of
pnmnorm, specifying values for the first and percentages for the second.-bpercentand-wpercentvalues are floating point decimal. Zero is valid and is the same as-bvalue=0or-wvalue=maxval, respectively.Because there are whole numbers of pixels at each brightness,
pnmnormobviously can't guarantee the exact percentage, so it arranges that at least the percentage of pixels you specify get remapped as promised.It is possible for your
-bpercentor-wpercentto overlap your-wvalueor-bvalue, respectively. For example, you say-bpercent=20and-wvalue=100for an image in which only 10 percent of the pixels are darker than 100. In that case,pnmnormadjusts the percentile value as required. In the example, it uses 99 as the black value (like-bvalue=99).It is also possible for your
-bpercentand-wpercentoptions to select the same brightness value for the stretch-to-white and stretch-to-black value because of the fact thatpnmnormcan't subdivide a histogram cell. E.g. if an image is all brightness 100, then no matter what-bpercentand-wpercentvalues you choose, it's the same as saying -bvalue=100 -wvalue=100. In that case,pnmnormchanges one of the values by 1 to make it legal. In the example,pnmnormwould either make the black value 99 or the white value 101.Before Netpbm 10.43 (June 2008),
pnmnormfails if the-wpercentand/or-bpercentvalues specify an overlap.The stretch points are further constrained by the
-maxexpandoption. Sometimes, too much contrast is a bad thing. If your intensities are all concentrated in the middle,-bpercent=2and-wpercent=1might mean that an intensity of 60 gets stretched up to 100 and intensity of 20 gets stretched down to zero, for a range expansion of 150% (from a range of 40 to a range of 100). That much stretching means two adjacent pixels that used to differ in intensity by 4 units now differ by 10, and that might be unsightly.
-
-bsingle -
To specify that the single least brightness in the image should stretch to black in the output, specify
-bsingle. To specify that the single greatest brightness in the image should stretch to white in the output, specify-wsingle.-bsingleand-wsinglewere new in Netpbm 10.69 (December 2014).
-
-maxexpand -
So that you can put a limit on the amount of expansion without having to examine the image first, there is the
-maxexpandoption. It specifies the maximum expansion you will tolerate, as an additional percentage. In the example above, you could say-maxexpand=50to say you want the range to expand by at most 50%, regardless of your other options.pnmnormfigures out what intensity to stretch to full intensity and what intensity to stretch to zero intensity as described above, and then raises the former and lowers the latter as needed to limit the expansion to the amount you specified.When
pnmnormlimits the expansion because of-maxexpand, it tells you about it with a message like this:<span style="font-family: monospace"> limiting expansion of 150% to 50% </span>In any case,
pnmnormtells you exactly what expansion it's doing, like this:<span style="font-family: monospace"> remapping 25..75 to 0..100 </span>Before Netpbm 10.26 (December 2004), it was not valid to specify both
-bvalueand-bpercentor-wvalueand-wpercent.-maxexpandwas new in Netpbm 10.32 (February 2006).
-
-keephues -
This option says to keep each pixel the same hue as it is in the input; just adjust its brightness. You normally want this; the only reason it is not the default behavior is backward compatibility with a design mistake.
By default,
pnmnormnormalizes contrast in each component independently (except that the meaning of the-wpercentand-bpercentoptions are based on the overall brightnesses of the colors, not each component taken separately). So if you have a color which is intensely red but dimly green,pnmnormwould make the red more intense and the green less intense, so you end up with a different hue than you started with.
-
-midvalue=N
-
-middle=N -
When you specify
-midvalue=N,pnmnormuses a quadratic function to map old brightnesses to new ones, making sure that an old brightness of N becomes 50% bright in the output. You can override that 50% default with-middle. The value of-middleis a floating point number in the range 0 through 1 with 0 being full darkness and 1 full brightness. If your-midvalueand-middleindicate an ambiguous or impossible quadratic function (e.g.-midvalueis the same as-bvalue, so an infinite number of quadratic functions fit),pnmnormjust ignores your-midvalueand maps linearly.-midvalueand-middlewere new in Netpbm 10.57 (December 2011).If you specify
-keephues,pnmnormwould likely leave this pixel alone, since its overall brightness is medium.-keephuescan cause clipping, because a certain color may be below a target intensity while one of its components is saturated. Where that's the case,pnmnormuses the maximum representable intensity for the saturated component and the pixel ends up with less overall intensity, and a different hue, than it is supposed to have.This option is meaningless on grayscale images.
When you don't specify
-keephues, the-luminosity,-colorvalue, and-saturationoptions affect the transfer function (which is the same for all three RGB components), but are meaningless when it comes to applying the transfer function (since it is applied to each individual RGB component).Before Netpbm 9.25 (March 2002), there was no
-keephuesoption.
-
-luminosity
-
-colorvalue
-
-saturation -
-luminosity,-colorvalue, and-saturationdetermine what property of the pixelspnmnormnormalizes. I.e., what kind of brightness. You cannot specify more than one of these.The
-luminosityoption says to use the luminosity (i.e. the "Y" in the YUV or YCbCr color space) as the pixel's brightness. The luminosity is a measure of how bright a human eye would find the color, taking into account the fact that the human eye is more sensitive to some RGB components than others.This option is default.
This option is meaningless on grayscale images.
Before Netpbm 10.28 (August 2005), there was no
-luminosityoption, but its meaning was still the default.Before Netpbm 10.28 (August 2005), there was no
-colorvalueoption.The
-colorvalueoption says to use the color value (i.e. the "V" in the HSV color space) as the pixel's brightness. The color value is the gamma-adjusted intensity of the most intense RGB component.This option is meaningless on grayscale images.
Before Netpbm 10.28 (August 2005), there was no
-colorvalueoption.The
-saturationoption says to use the saturation (i.e. the "S" in the HSV color space) as the pixel's brightness. The saturation is the ratio of the intensity of the most intense RGB component to the difference between the intensities of the most and least intense RGB component (all intensities gamma-adjusted).In this case, "brightness" is more of a metaphor than anything. "bright" means saturated and "dark" means unsaturated.
This option is meaningless on grayscale images.
Before Netpbm 10.28 (August 2005), there was no
-colorvalueoption.
Document source
This manual page was generated by the Netpbm tool 'makeman' from HTML source. The master documentation is at
-
http://netpbm.sourceforge.net/doc/pnmnorm.html
Releases
12 releases since Debian 3.1 (Sarge); the text changed 2 times.
-bpercent since Debian 12 (Bookworm);
-bsingle since Debian 12 (Bookworm);
-bvalue since Debian 12 (Bookworm);
-colorvalue since Debian 12 (Bookworm);
-keephues since Debian 12 (Bookworm);
-luminosity since Debian 12 (Bookworm);
-maxexpand since Debian 12 (Bookworm);
-middle since Debian 12 (Bookworm);
-midvalue since Debian 12 (Bookworm);
-saturation since Debian 12 (Bookworm);
-wpercent since Debian 12 (Bookworm);
-wvalue since Debian 12 (Bookworm).