Home / Alt manpages / ppmhist(1)

  • ppmhist(1)
  • User command
  • linux

Read PPM Colour Frequencies with ppmhist

ppmhist counts how many pixels in a PPM image use each exact colour, and reports it as a sorted table. This guide runs a basic histogram, reformats it for scripts, switches colour representations, exports a one-row palette, and covers the forensic mode for images with invalid samples. The examples were checked with Netpbm 11.5.2, packaged here as netpbm 2:11.05.02-1.1build1.

Allow about ten minutes. You need a shell, ppmhist, and a readable PPM file. The normal report only reads the image and writes to standard output: no elevated privileges are needed, and nothing here alters the source image.

1. Check the installed command

Confirm which executable is being used and record its Netpbm version. This is a read-only checkpoint:

$ command -v ppmhist
/usr/bin/ppmhist
$ ppmhist -version
ppmhist: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
ppmhist: Built from source dated 2024-03-31 09:09:47

The version matters here: the summary line at the top of a human report was added in Netpbm 10.82, and since Netpbm 10.88 colours with equal frequency get a stable RGB tie-break order. If your output differs on an older installation, check the version before treating that as an image difference.

2. Generate a basic histogram

Pass the PPM path as the final argument:

$ ppmhist /path/to/image.ppm
 Summary: 3 colors: 1 black, 1 white, 0 gray, 1 color

   r     g     b      lum       count
 ----- ----- -----  -----     -------
     0     0     0      0           3
   255     0     0     76           2
   255   255   255    255           1

Your rows depend on the image. The report lists red, green and blue sample values, a luminosity value, and the pixel count for that exact colour. The default sort is frequency, most common first, and the displayed component range follows the PPM maxval, so do not assume every file uses 255. The rows are the data to feed into a review or script; the summary is just a quick scan.

3. Make output suitable for a script or comparison

Suppress the headings and summary with -noheader:

$ ppmhist -noheader /path/to/image.ppm > /tmp/image-colours.txt
$ sed -n '1,5p' /tmp/image-colours.txt
     0     0     0      0           3
   255     0     0     76           2
   255   255   255    255           1

This is still whitespace-formatted text, not a CSV or a machine-readable interchange format. Treat the columns as a report, not something to split blindly on a fixed number of spaces.

Use -sort=rgb for a deterministic colour order, low red to high red, then green and blue:

$ ppmhist -sort=rgb -noheader /path/to/image.ppm

Use the full option spelling in scripts. The default frequency order is usually better for finding dominant colours; RGB order is easier to compare against a palette or colour table.

4. Choose a different colour representation

For web or graphics work, hexadecimal components can be more convenient:

$ ppmhist -hexcolor -noheader /path/to/image.ppm
  0000  0000  0000      0           3
  00ff  0000  0000     76           2
  00ff  00ff  00ff    255           1

For calculations, -float scales the components and luminosity into the range 0 to 1:

$ ppmhist -float -sort=rgb -noheader /path/to/image.ppm
 0.000 0.000 0.000  0.000           3
 1.000 0.000 0.000  0.299           2

Warning

-hexcolor and -float are alternatives. Do not combine either with -map, and do not combine them with each other. The installed command rejects the conflict with an error such as You can specify only one of -hexcolor, -float, and -map.

5. Export a one-row palette

Use -map when another Netpbm program needs a PPM colour map rather than a human report:

$ ppmhist -map /path/to/image.ppm > image-palette.ppm
$ head -5 image-palette.ppm
P3
# color map
3 1
255
#Summary: 3 colors: 1 black, 1 white, 0 gray, 1 color

The result is a genuine plain PPM image, one column per distinct input colour and one row, with the histogram information kept in its comments. Check the magic number and dimensions before passing it on:

$ file image-palette.ppm
image-palette.ppm: Netpbm image data, size = 3 x 1, pixmap, ASCII text

Warning

Redirection with > truncates an existing file before ppmhist runs. If the palette name already exists, write to a new temporary name first, for example image-palette.ppm.new, and only replace the old file after checking it:

$ mv image-palette.ppm.new image-palette.ppm

If the command fails, remove the incomplete .new file and the original stays available. Do not use sudo to write a working-directory palette.

6. Investigate invalid sample values

Normally, ppmhist rejects a PPM sample greater than the file's declared maxval, treating it as a malformed image rather than a harmless variation. Preserve the original and copy it to a disposable working file before investigating.

The -forensic option tells ppmhist to count the actual sample values despite that invalid declaration, and to report the invalid pixels:

$ ppmhist -forensic /path/to/suspect.ppm
... histogram and invalid-pixel diagnostics ...

Warning

Do not treat a forensic histogram as proof the image is valid. It is a diagnostic view of data that violates the PPM declaration. Values above 65535 cannot be processed even with this option, and in the rarely used plain PPM format, a number above that limit can appear where a sample belongs.

This is the point where an image viewer can quietly distract you: it may display something normally while the file remains structurally invalid. Check the declared maxval and the producer that wrote the file before repairing or converting it. Do any actual repair on a copy, never inside this read-only workflow.

7. Diagnose common failures

If the command cannot open the file, check the path and read permission without changing anything:

$ ls -l /path/to/image.ppm
$ test -r /path/to/image.ppm && echo readable
  • Unexpected counts? Identical RGB triples are counted together, while two visually similar colours remain separate entries.
  • Check the format too. A conversion step before ppmhist can change both the samples and the number of distinct colours, and plain versus raw PPM matters here.
  • -colorname adds a dictionary name. An exact match is shown plainly; the nearest dictionary colour is marked with an asterisk. It fails if the dictionary is unavailable, so treat it as a display aid, not a canonical colour identity.

Done means

  • Version and path confirmed. You checked the installed Netpbm version and the PPM path.
  • Histogram understood. You produced one and know the frequency order, sample scale and count column.
  • Format matched the need. You used -noheader, -sort=rgb, -hexcolor or -float for a specific purpose.
  • Palette exported carefully. You used -map only when a one-row PPM palette was required, and verified its dimensions.
  • Forensic mode used correctly. Reserved for malformed samples, with the original image kept unchanged.
  • No privilege overreach. You avoided sudo and protected existing output files from shell-redirection truncation.