The image_tool program serves as a utility for the user to interact with the ENVI images that are output by many DIRSIG simulations.

Overview

The DIRSIG generated ENVI image files do not normally have native support in most operating systems' default image viewers, so a tool to interact with them can be useful. These images can also be viewed via QGIS or interacted with programmatically in Python via the spectral package or via GDAL. However, DIRSIG ships image_tool with the standard distribution for simplicity and to support some common operations.

image_tool is a tool-based application and operates on subcommands, similar to many other well-known CLI applications, such as git or aws. The list of available tools can be obtained via:

$ image_tool --help

The help tool is used to obtain the command-line usage for a specific tool in image_tool. Its command-line usage is straightforward:

$ image_tool help <tool_name>

For example, to get help on the test tool:

Example output of help tool
$ image_tool help test
Usage: image_tool test [options] operator inputs


run options:
  --stdin   Takes test input JSON from stdin

Arguments:
  operator  The test operator to perform:

            * run
              Run the specified tests (filename(s) or JSON from --stdin)
            * make
              Output test input for the given image
  inputs    Inputs for the operator

The Convert Tool

The convert tool is used to convert ENVI images into other common image formats that can be viewed in common image viewers. This program uses QImageWriter to write output images and thus the supported output formats are determined by the abilities of that library. The reason ENVI images are output by DIRSIG is their support for arbitrary spectral bands and lossless floating point output. Since these are not features of many common image formats, this conversion will be lossy and thus has a number of options to control the conversion. For the current full list of options, use the help command, however an overview will be given here.

The --autoscale option specifies how the input range of image values will be scaled into the 8-bit range of the output (0-255). Normally, this is done by computing statistics of the image.

  • The none option allows the user to specify a manual linear mapping via the additional --gains and --biases options. The gain is first multiplied by the input value, then the bias is added. The default gain and bias values are 1 and 0, respectively.

  • The minmax option scales the minimum value to 0 and the maximum value to 255. For this option, the minimum and maximum are from all the bands (see the --bands option) being scaled.

  • The bandminmax option scales the minimum value to 0 and the maximum value to 255. For this option, the minimum and maximum are unique to each band (see the --bands option) being scaled.

  • The twosigma option scales the mean minus 2 standard deviations to 0 and the mean plus 2 standard deviations to 255.

  • The percent option scales between the minimum and maximum values across all bands (see the --bands option) being scaled, but the maximum is computed by ignoring the top N percent of the values. By default, N is 2% but can be changed via the additional --percent option.

  • The gamma option applies a non-linear gamma function to the data and linearly stretches it to the new minimum and maximum. The non-linear function that is applied to each value is DC1/G. The default value for G is 2, but can be changed via the additional --gamma option.

The --bands option is used to specify which band indices (0-based) are to be mapped to the red, green and blue bands in the output image. If the input image only had 3 bands, these will be used, however, it is good practice to explicitly specify this option.

Tip If the default bands variable is set in an ENVI image header file, these bands will be used as default if the --bands option is not provided.

The --format or -f option can be used to specify the output format. This should the extension desired for the output images. For example, png or jpg are valid values for this option. By default, this will be appended onto the filenames of the input files to construct the output filenames. The exception to this is if --stdout is specified, which will write the output file to stdout, which allows the use of shell pipes to redirect the output to another program.

The --tonemap option is similar to --autoscale but applies a tone-mapping operation after the image has been scaled to the 8-bit range (0-255). The initial scaling is done in floating point space and this tone mapping is applied in a 0-1 floating point space and then scaled back to 0-255, so no quantization concerns should be present. See the help output for the various supported tone mappings. This option is intended primarily for making linear response images, such as radiance images, more natural-looking for visual consumption.

The --output_filename option allows the user to specify the name of the output image file. By default, the output filename is the input filename with the file format extension (e.g., .png, .jpeg, etc.) appended to it.

Example Usage

To convert bands 16, 11 and 6 in DIRSIG (ENVI) .img file to an RGB PNG using a 2.5 gamma scaling, use the following example syntax:

$ image_tool convert --autoscale=gamma --gamma=2.5 --format=png --bandlist=16,11,6 test.img

This will produce test.img.png.

To make a grayscale JPEG file using the 1% scaling, specify the same band for all three bands:

$ image_tool convert --autoscale=percent --percent=1 --format=jpeg --bandlist=3,3,3 --output_filename=gray.jpeg test.img

This will produce gray.jpeg.

To bulk convert a series of images, you can use standard shell wildcards on LINUX and macOS:

$ image_tool convert --autoscale=twosigma --format=png --bandlist=2,1,0 demo-t0000-c*.img

This works because LINUX and macOS shells expand demo-t0000-c*.img into a list of all matching files, which is supplied to image_tool and it then iterates through that list. However on Windows, neither CMD or PowerShell expands wildcards. Instead, they simply pass them to programs and expects the program to expand them (which image_tool does not support). Hence, we need to generate the list of matches outside of image_tool and pass that list to the program. Here is an example of how to do that in PowerShell using the build-in Get-Item cmdlet:

PS C:\Users\dirsig\demos\PlatformJitter1> $list = Get-Item demo-t0000-c*.img
PS C:\Users\dirsig\demos\PlatformJitter1> image_tool convert --autoscale=gamma --format=png $list

The Analyze Tool

The analyze tool is intended to help with basic statistical analysis on images. Its full options can be seen with the help output. There are three classes of control options to this tool. The first group is the band subsetting options. These options are optional and can be used to constrain the bands on which analysis is performed. The second group is the region of interest (ROI) controls. These options are used to constrain the spatial part of the image over which analysis is performed. Finally, and most importantly, are the operator options. These specify which statistical function(s) should be applied to the region specified by the other options. These include minimum/maximum, mean, standard deviation and covariance (see the help output for the complete list).

Example Usage

To compute the min/max for a specific set of bands, use the following syntax:

$ image_tool analyze band_min_max --bandlist=0,2,11 test.img

To compute the mean and stddev for a single band (band index = 2) within a rectangular ROI (with lower-left and upper-right image coordinates of 10,8 and 32,21, respectively), use the following syntax:

$ image_tool analyze band_mean_stddev --band=2 --rect=10,8,32,21 test.img

The Test Tool

The test tool is used to make and perform tests on images. This can be useful for making assertions about DIRSIG output. Tests can be specified in a JSON format either via a file or through stdin with the --stdin option. An example test input is:

Example test JSON document
[
  {
    "filename": "rgb.img",
    "tests": [
      {
        "description": "Verifies the spatially-averaged band values of the image.",
        "expected": [0.01513, 0.01513, 0.01513],
        "history": "Test automatically generated with 'image_tool' 2021.30 (04678d1)",
        "id": "band_mean",
        "metric": "band_mean",
        "name": "Spatially-averaged band values for the image",
        "tolerance": [1.513e-05, 1.513e-05, 1.513e-05]
      }
    ]
  }
]

This JSON was generated by the make subcommand:

$ image_tool test make <image_filename>

The supported values for metric are:

  • "band_mean" - The mean of the ROI for each band

  • "band_min" - The minimum of each band in the ROI

  • "band_max" - The maximum of each band in the ROI

  • "band_min2" - The mean of the bottom 2% of values in the ROI for each band

  • "band_max2" - The mean of the bottom 2% of values in the ROI for each band

"tolerance" can alternatively be specified as "percentage" where each element is a percentage (0-100) error (from "expected") that can be tolerated.

In addition to the fields shown above, the following options are also supported:

  • bandSubset - This can be used to confine the bands over which the statistics are calculated. This field is an object of the form:

{
  "type": "band",
  "value": [0]
}

The supported values for type are "band", "list", and "range". For "band"`, a single band index is given, for "list", an arbitrary number of band indices are given, and for "range", two band indices are given that are the start and end (inclusive) band indices. Any of these band indices can also be substituted with a string of the form "$<BAND_NAME:name>", where name is the name of the band in the image.

  • roi - This can be used to confine the spatial region of interest over which the statistics are calculated. This field is an object of the form:

{
  "type": "rect",
  "value": [0, 5, 10, 15]
}

The supported values for type are "rect", "xline", "yline" and "pixel". For "rect", the value should be a length-4 array of min_x,min_y,max_x,max_y, for "xline" and "yline", it should be a length-1 array of the x or y index at which to take a line profile and for pixel, it should be a 2-length array with the [x,y] of the pixel.

Python Tests

As an alternative to the statistical tests given above, image_tool also supports running user-defined tests using Python. This can be done with slight modifications to the test JSON:

Example Python test JSON document
[
  {
    "filename": "rgb.img",
    "tests": [
      {
        ""
        "description": "Runs a user-defined Python Test",
        "history": "Developed by <name>",
        "id": "user_defined_test_0"
        "name": "MyTest",
        "pyModule": "image_test",
        "arguments": ["15"]
      }
    ]
  }
]

This example would look for the "image_test" module in your PYTHONPATH, which would include the current working directory. Normally, this would correspond to a file called image_test.py. Additional paths may be added via the --pythonpath argument on image_tool test run. In this file, there should be a global function called test, for example:

import numpy as np

# args is present only if "arguments" is in the JSON
def test(image, args):
    exp = float(args[0])
    sum = np.sum(image)
    return abs(sum - exp) < 0.01, f"Expected sum to be {exp}, was {sum}"

The first value of the return tuple should be a boolean indicating the success of the test and the second should be an error string that will be shown upon failure. Note that "arguments" is an optional field in the JSON and should be omitted from test()'s argument list if it is not provided.

The ENVI Tool

The envi tool is intended to provide some functionality specifically targeted to local (on disk) ENVI images. Currently, only one operation is implemented, which is a scanning of the ENVI header file to extract metadata about the image. The usage is:

$ image_tool envi header_scan --field="field name" <header filename>

This will print the requested field in the requested header file to standard output. Fields that have multiple values (curly-brace lists) will be printed with one value per line. This tool is intended for script usage to avoid potentially complicated parsing of an ENVI file with tools like grep.

Example Usage

To fetch a given ENVI header variable, you supply the field (tag) name to the --field option. For example, to get the number of lines in the image file, use the following syntax:

$ image_tool envi header_scan --field='lines' test.img.hdr

To get the radiometric units of the image file, use the following syntax:

$ image_tool envi header_scan --field='data units' test.img.hdr
Note The '' around the field (tag) name is important when the field has a multi word name (e.g., data type, header offset, data units, etc.).