#! /usr/bin/python3 # Last edited on 2025-08-21 19:52:51 by stolfi # Reads the raw PGM multispectral images, converts them to numpy arrays # and saves them to disk. # # The parameters are the {page} and the name {clip} of one or more clips. # # The multispectral images are assumed to be in the external directory # {pgdir_in}, namely "MS/davis/{page}". # # Assumes that there is a file "{pgdir_in}/bands.txt" that specifies the # names of the bands avaliable for that page (e.g. "MB870IR_030_F"), the # type of illumination {illum}, and the corresponding {maxval} # for sample scaling. # # The input images are read from "{pgdir_in}/clips/{clip}.pgm", for each # frontal illumination and narrow reflection band ("MB") {band} listed # in the "bands.txt" file above. These files are assumed to be 16-bit # PNG, with the pixel values extracted from the TIFF files # without any gamma mapping (other than whatever was used to encode # those file by the scanning team). # # The converted images is saved to disk as as a file # "pages/{page}/clips/{clip}/{band}.npy". Each file contains a matrix # with shape {(ny,nx)} where {ny} and {ny} are the height and width of # the clip in pixels. from math import sin, cos, log, exp, floor, pi, inf import sys, re, os import numpy from PIL import Image from error_funcs import prog_error, arg_error, debug from process_funcs import bash, run_command from bands_table_funcs import read_page_bands_tables from image_funcs import \ read_mask_image, read_clip_image, \ quantize_image, write_image_as_gray_png import argparser def main(): page, clips = parse_options() # Read the spectral bands tables: bfile = f"MS/davis/{page}/bands.txt" # Read dicts mapping band name to illumination type and {maxval} to use: bands_tb = read_page_bands_tables(bfile) # debug(f"bands_tb[{band}]", bands_tb[band]) for clip in clips: for band in bands_tb.keys(): illum = bands_tb[band]['illum'] maxval = bands_tb[band]['maxval'] sys.stderr.write(f"band {band} illum = {illum} maxval = {maxval:5d}\n") if illum == 0 or illum == 1 or illum == 2: assert band[0:2] == "MB", "bug: band name should be 'MB')" elif illum == 3: assert band[0:2] == "TX", "bug: band name should be 'TX'" cfile = f"MS/davis/{page}/{band}/clips/{clip}.png" sys.stderr.write(f"reading {cfile} ...\n") # Read the clip image: C = read_clip_image(cfile, maxval) assert len(numpy.shape(C)) == 2, "clip image should be monochrome" ny, nx = numpy.shape(C) fval_min = numpy.min(C, axis=(0,1)) fval_max = numpy.max(C, axis=(0,1)) sys.stderr.write(f"{cfile}: rows = {ny:4d} cols = {nx:4d}") sys.stderr.write(f" range = [{fval_min:8.6f} _ {fval_max:8.6f}]\n") sdir = f"pages/{page}/clips/{clip}" bash(f"mkdir -p {sdir}/npy") nfile = f"{sdir}/npy/{band}.npy" numpy.save(nfile, C) bash(f"mkdir -p {sdir}/png") pfile = f"{sdir}/png/{band}.png" write_image_as_gray_png(pfile, C) sys.stderr.write("%s\n" % ("." * 70)) return 0 # ---------------------------------------------------------------------- def parse_options(): page = sys.argv[1] clips = []; iarg = 2 while iarg < len(sys.argv): clip = sys.argv[iarg] # name of clip to take pixels from. clips.append(clip) iarg += 1 return page, clips # ---------------------------------------------------------------------- def band_error(band, msg): sys.stderr.write(f"** {band}: {msg}\n") assert False # ---------------------------------------------------------------------- main()