PNMHISTEQ(1)
๐ PNMHISTEQ ๐
okay bestie, gather round, because we're about to talk about pnmhisteq, a Netpbm girlie from the General Commands Manual, section 1. she does one thing and she does it gorgeously: histogram equalization of a PNM image. no cap.
โจ NAME โจ
pnmhisteq โ histogram equalize a PNM image ๐ฆ
โจ SYNOPSIS โจ
pnmhisteq
[-gray]
[-noblack] [-nowhite]
[-rmap pgmfile]
[-wmap pgmfile]
[-verbose]
[pnmfile]
like. that's it. that's the whole vibe. ๐
โจ DESCRIPTION โจ
so this program is part of Netpbm(1), and what she does is: pnmhisteq increases the contrast of a PGM or PPM image through the technique of "histogram equalization."[1] iconic technique. legendary technique. periodt.
here's what's actually happening under the hood: pnmhisteq computes a histogram of the luminosity of the pixels in the image. then it calculates a mapping between each luminosity and a new luminosity such that it spreads out intensity levels around histogram peaks and compresses them at troughs. I.e. it moves pixels around in the histogram so as to make it flat. then it applies that mapping to the input image to produce the output image. ๐
and the effect of all that? the image has equal numbers of pixels at each possible intensity level, which means it uses the available levels of intensity more efficiently and thereby has more visible detail. she's efficient. she's detail-oriented. she's the main character fr fr.
the math part (yes we're doing math, stay with me) ๐งฎ
mathematically, the luminosity mapping is this: assume the pixels are sorted by luminosity into B buckets numbered from 0 (lowest luminosity) to B-1. N[i] is the number of pixels in bucket i. T is the total number of pixels (sum of N[i] over all i). W is the luminosity of white.
pnmhisteq replaces an input pixel whose luminosity falls into bucket j with one whose luminosity is:
j
---
\
> (N[i] / T) * W
/
---
i=0
considering a grayscale image for simplicity, this means that pixels in the most luminous bucket become white. pixels in the 10th per centile of luminosity become 10% of white. โญ
pnmhisteq maps a single luminosity in the input to a single luminosity in the output. that means if pixels A and B both have luminosity .2 in the input, and pixel A has luminosity .4 in the output, pixel B also has luminosity .4 in the output. and since the luminosities in the input are not continuous, the luminosities in the output aren't either and pnmhisteq doesn't meet the ideal of having exactly the same number of pixels of each luminosity in the output. she's doing her best, okay, quantization is hard. ๐ญ
the frame-to-frame thing ๐ฌ
if you're processing a related set of images, for example frames of an animation, it's generally best to apply the same luminosity mapping to every frame, since otherwise you'll get distracting frame-to-frame changes in the brightness of objects. (not the good kind of distracting. the bad kind.)
pnmhisteq's -wmap option allows you to save, as a PGM image, the luminosity map it computes from an image. the -rmap option causes pnmisteq to use such an image as its luminosity map. ๐ซถ
so you can run pnmhisteq with -wmap on a composite you created with pamcat of the images you intend to process. then, you can run pnmisteq with -rmap on each of the individual images, using the luminosity map you generated from the composite. chef's kiss. ๐
use pnmhistmap to see the result. run a color image through ppmtopgm first so that you see a histogram of the luminosity instead of histograms of the three color components. it should generally show a flat histogram. but because of the quantization effects described above, you might see high bars interleaved with low bars, with the local average being flat. to see local averages, use the -width option of pnmhistmap. ๐
โจ OPTIONS โจ
in addition to the options common to all programs based on libnetpbm (most notably -quiet, see Common Options), pnmhisteq recognizes the following command line options:
you can abbreviate any option to its shortest unique prefix. (slay, she's flexible ๐ )
-grayโ when processing a color image, only gray pixels (those with identical red, green, and blue values) are included in the histogram and modified in the output image. this is a special purpose option intended for images where the actual data are gray scale, with color annotations you don't want modified. weather satellite images that show continent outlines in color are best processed using this option. the option has no effect when the input is a graymap. ๐ฐ๏ธ-noblackโ do not include black pixels in the equalization. the black pixels in the output are exactly the black pixels in the input and the number of black pixels does not affect the color of any other pixels.
sometimes, black isn't as much a color as a background or annotation for the real colors, so you want to treat it specially this way. think of a picture of stars, which is nearly all black, but with lots of stars of different brightness. you want to change the brightnesses of the stars to maximize contrast between them, but if you considered the blackness to be significant, all the stars would end up close to full white. ๐โจ
this option was new in Netpbm 10.70 (March 2015).
-nowhiteโ same as-noblack, but for the white pixels.
you can use both -noblack and -nowhite if you like. (living your truth, bestie ๐ซถ)
this option was new in Netpbm 10.70 (March 2015).
-rmapmapfile โ process the image using the luminosity map specified by the PGM file mapfile.
the PGM image, usually created by an earlier run of pnmhisteq with the -wmap option, contains a single row with number of columns equal to the maxval (greatest intensity value) of the image plus one. each pixel in the image is transformed by looking up its luminosity in the corresponding column in the map file (column number = luminosity) and changing it to the value given by that column. ๐
-wmapmapfile โ creates a PGM file mapfile, containing the luminosity map computed from the histogram of the input image. this map file can be read on subsequent runs ofpnmhisteqwith the-rmapoption, allowing a group of images to be processed with an identical map. ๐พ-verboseโ prints the histogram and luminosity map on Standard Error. (she's yapping, but like, productively.) ๐ฌ
โจ LIMITATIONS โจ
histogram equalization is effective for increasing the visible detail in scientific imagery and in some continuous-tone pictures. it is often too drastic, however, for scanned halftone images, where it does an excellent job of making halftone artifacts apparent. ๐ฌ you might want to experiment with pnmnorm and pnmgamma for more subtle contrast enhancement. (sometimes you don't need the full drama, sometimes you need a soft launch.)
the luminosity map file supplied by the -rmap option must have the same maxval as the input image. this is always the case when the map file was created by the -wmap option of pnmhisteq. if this restriction causes a problem, simply adjust the maxval of the map with pamdepth to agree with the input image. ๐ ๏ธ
if the input is a PBM file (on which histogram equalization is an identity operation), the only effect of passing the file through pnmhisteq will be the passage of time. ๐ literally nothing happens. she just vibes and time passes. iconic honestly.
โจ SEE ALSO โจ
pnmnorm(1), pamcat(1), pamdepth(1), pnmgamma(1), pnm(1),
[1] Russ, John C. The Image Processing Handbook. Boca Raton: CRC Press, 1992. Pages 105-110. ๐
โจ 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/pnmhisteq.html
and that's the whole page, bestie. ๐ written up as netpbm documentation, dated 22 March 2015, from the Pnmhisteq User Manual(1). go forth and equalize your histograms. slay. ๐ธ๐ฆ๐
๐ฆ where this page comes from
- ubuntu stonking: netpbm 2:11.13.03+ds-2 ยท MIT
- ๐ girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms