Home / Alt manpages / pbmminkowski(1)

  • pbmminkowski(1)
  • User command
  • linux

Measure PBM Shape Geometry with pbmminkowski

pbmminkowski is one of Netpbm's stranger corners: a tool built for image analysis rather than image editing. You will finish with three Minkowski measurements for a black-and-white PBM image: area, perimeter and Euler characteristic, plus the tile, edge and vertex counts that make the calculation easier to inspect.

The examples use the Netpbm 11.5.2 build installed here as Debian package netpbm 2:11.05.02-1.1build1. Allow about ten minutes. You need a shell, a readable PBM file and the pbmminkowski program.

No elevated privileges are needed. This guide only reads the image; it does not alter the input or any persistent system setting.

1. Check the installed command

Confirm the executable and package version before you trust any output in a script:

$ command -v pbmminkowski
/usr/bin/pbmminkowski
$ dpkg-query -W -f='${Package} ${Version}\n' netpbm
netpbm 2:11.05.02-1.1build1
$ pbmminkowski --version
pbmminkowski: Using libnetpbm from Netpbm Version: Netpbm 11.5.2
pbmminkowski: Built from source dated 2024-03-31 09:09:47

The version query earns its keep here, since the program has no separate option reference beyond its manpage. This build prints its library and build information to standard error, then exits. The actual synopsis is just pbmminkowski pbmfile.

Checkpoint

You have a PBM input path, and you have recorded the Netpbm version if the measurement will be compared over time.

2. Make a small, known PBM test image

A temporary plain PBM gives you a reproducible smoke test. In PBM, 1 is black and 0 is white, and pbmminkowski measures the white foreground, so this example contains a two-pixel white shape on a black background:

$ test_file=$(mktemp --suffix=.pbm)
$ trap 'rm -f "$test_file"' EXIT
$ printf 'P1\n3 2\n0 1 0\n1 0 0\n' > "$test_file"

mktemp picks a fresh file, the redirection writes only that temporary file, and the trap removes it when the shell exits. If you use a real input image instead, do not redirect into its path: that would truncate it before the program even reads it.

Check the header and dimensions without touching the image:

$ head -n 2 "$test_file"
P1
3 2

P1 identifies plain PBM; Netpbm also uses raw PBM, identified by P4. Either way, the input must actually be PBM, not a PGM or PPM file wearing a different suffix.

3. Run pbmminkowski and read the result

Pass exactly one input file. The program writes a labelled report to standard output:

$ pbmminkowski "$test_file"
   tiles:  4
 x-edges:  7
 y-edges:  7
vertices:  11
    area:  4
perimeter:  12
 eulerchi:  1

That spacing is only for alignment, not syntax. The tile count is the number of white image cells in the lattice; the horizontal and vertical edge counts, and the vertex count, are intermediate topological figures. The three fields that matter are area, total boundary length, and Euler characteristic for the white foreground.

  • Euler characteristic of 1 is normal for a single connected region with no hole.
  • Multiple disconnected regions increase it; holes reduce it. Treat this as a shape property, not a pixel count.
  • Perimeter is the total boundary of all white regions, so separate regions contribute their boundaries independently.

Do not assume a visually black object is the foreground here. PBM stores black as 1 and white as 0, and this tool's foreground is white. Black marks on a white page need inverting before measurement, if the marks themselves are what you want to analyse, and the inverted image should go to a new path so the original stays intact.

4. Verify a result with a second shape

A blank image is a good boundary check: no white tiles means every reported measurement comes back zero:

$ blank_file=$(mktemp --suffix=.pbm)
$ printf 'P1\n3 3\n1 1 1\n1 1 1\n1 1 1\n' > "$blank_file"
$ pbmminkowski "$blank_file"
   tiles:  0
 x-edges:  0
 y-edges:  0
vertices:  0
    area:  0
perimeter:  0
 eulerchi:  0
$ rm -f "$blank_file"

That final removal is safe for a newly created temporary file, but it is irreversible all the same. Had blank_file been a valuable path instead, the printf redirection would already have wiped its contents before you got anywhere near rm. Use mktemp for experiments and keep source images somewhere else entirely.

For a machine-checkable smoke test, capture standard output and test the exit status:

$ report=$(pbmminkowski "$test_file")
$ status=$?
$ test "$status" -eq 0 && printf '%s\n' "$report"
   tiles:  4
 x-edges:  7
 y-edges:  7
vertices:  11
    area:  4
perimeter:  12
 eulerchi:  1

A zero status means the program accepted the file and finished the calculation. It does not prove the pixels you intended were white, that this is the right image, or that the measurement suits your scientific model: check the PBM header and inspect the image separately when those distinctions matter.

5. Diagnose the common failures

A missing file gets reported on standard error with a non-zero status:

$ pbmminkowski /path/to/missing.pbm
pbmminkowski: Unable to open file '/path/to/missing.pbm' for reading. fopen() returns errno 2 (No such file or directory)
$ printf 'status: %s\n' "$?"
status: 1

Check the path and read permission rather than reaching for sudo immediately:

$ ls -l /path/to/input.pbm
$ test -r /path/to/input.pbm && echo readable

If the first bytes are not a PBM magic number, the program reports an error reading the Netpbm magic number. Use head -n 2 for a plain PBM or od -An -tx1 -N2 for a raw one; a file extension alone does not decide its format.

The installed manpage lists no pbmminkowski-specific options. It does recognise common libnetpbm options, but do not borrow one from a different Netpbm program and assume it applies here; keep automated calls to the one documented input operand unless you have verified a common option against your installed version.

Done means

  • You confirmed the installed Netpbm version and passed one readable PBM file.
  • You know 0 is white and that pbmminkowski measures the white foreground.
  • You recorded area, perimeter and Euler characteristic, with the intermediate counts available for checking.
  • You tested the command against a known image and checked its exit status.
  • Source images stayed intact, with temporary paths used for every experiment.