This document describes the DIRSIG image_analyze tool, which can be used to extract data and statistics from the ENVI images created by the DIRSIG model. This tool is utilized heavily in our nightly testing to confirm the data in images produced by the model.

Overview

This program is a stand-alone solution to performing basic analysis on ENVI image files — it does not require IDL/ENVI, Matlab, python, etc. The original scope of the tool was to extract information and compute metrics from images. It was later modified to support a "testing" mode, where image metrics would be computed and compared to an expected value.

Basic Operation

Operators

The primary function of the tool is defined by the operator requested. These operators process the data in the image and provide some sort of output or metric. The tool supports the following "operators":

  • The extract operator, which will dump data for the spatial and spectral ROI to standard output. This is useful for creating spectral plots, image profiles, etc.

  • The minmax operator computes the minimum and maximum values in each channel across the spatial ROI.

  • The stats operator computes the mean and standard deviation in each channel across the spatial ROI.

Spatial regions of interest

By default the requested operator will process all the pixels in the image. However, the tool will let the user specify a spatial region of interest (ROI) for the operator to process using one of the following options:

  • A single pixel via the --pixel command-line argument.

  • A horizontal row of pixels via the --xline command-line argument.

  • A vertical row of pixels via the --yline command-line argument.

  • A 2D axis-aligned rectangle of pixels defined by the --rect command-line argument.

Spectral range

By default the requested operator will process all the bands in the image. However, the tool will let the user specify a spectral range for the operator to process using one of the following options:

  1. A single band via the --band option.

  2. An arbitrary list of bands via the --bandlist option.

  3. A continuous range of bands via the --bandrange option.

Usage Examples

The following examples demonstrate how the tool can be used

Computing the minimum and maximum values by band for all the pixels in a 211 band image:

$ image_analyze --operator=minmax --image=demo.img
N/A, N/A, 0, 0.0017605, 0.0233549
N/A, N/A, 1, 0.00198001, 0.0283795
N/A, N/A, 2, 0.001891, 0.0291672
N/A, N/A, 3, 0.00160349, 0.0265376
N/A, N/A, 4, 0.0018483, 0.0326575
...
N/A, N/A, 206, 0, 8.57758e-05
N/A, N/A, 207, 0, 2.60616e-05
N/A, N/A, 208, 0, 5.43256e-06
N/A, N/A, 209, 0, 0
N/A, N/A, 210, 0, 0

For the minmax operator the output is a comma-separated list as follows:

  1. The X pixel value (N/A unless a single pixel or line ROI is specified).

  2. The Y pixel value (N/A unless a single pixel or line ROI is specified).

  3. The band index (first band is 0)

  4. The minimum value across all the pixels in that band

  5. The maximum value across all the pixels in that band

Using the min/max operator on an arbitrary set of bands:

$ image_analyze --bandlist=0,2,4,208 --operator=minmax --image=demo.img
N/A, N/A, 0, 0.0017605, 0.0233549
N/A, N/A, 2, 0.001891, 0.0291672
N/A, N/A, 4, 0.0018483, 0.0326575
N/A, N/A, 208, 0, 5.43256e-06

Using the min/max operator on a range of bands:

$ image_analyze --bandrange=2,4 --operator=minmax --image=demo.img
N/A, N/A, 2, 0.001891, 0.0291672
N/A, N/A, 3, 0.00160349, 0.0265376
N/A, N/A, 4, 0.0018483, 0.0326575

Using the stats operator on a range of bands:

image_analyze --bandrange=2,4 --operator=stats --image=demo.img
N/A, N/A, 2, 4.132051e-03, 1.916341e-03, 2.156219
N/A, N/A, 3, 3.681493e-03, 1.726583e-03, 2.132242
N/A, N/A, 4, 4.459882e-03, 2.109407e-03, 2.114282

For the stats operator the output is a comma-separated list as follows:

  1. The X pixel value (N/A unless a single pixel or line ROI is specified).

  2. The Y pixel value (N/A unless a single pixel or line ROI is specified).

  3. The band index (first band is 0)

  4. The mean across all the pixels in that band

  5. The standard deviation across all the pixels in that band

  6. The mean divided by the standard deviation in that band

Using the extract operator on a single pixel (extract the spectral profile for a pixel):

image_analyze --pixel=10,10 --operator=extract --image=demo.img
10, 10, 3.29365288e-03, 3.90459110e-03, 3.92923787e-03, ... 1.87492106e-06, 0.00000000e+00, 0.00000000e+00

The output in the case is a comma-separated list as follows:

  1. The X pixel value (N/A unless a single pixel or line ROI is specified).

  2. The Y pixel value (N/A unless a single pixel or line ROI is specified).

  3. The value for each band in the band range (210 bands in the above example).

Using the extract operator on a row of pixels for a single band (extract a spatial transect in a given band):

image_analyze --yline=10 --band=1 --operator=extract --image=demo.img
10, 0, 3.80870861e-03
10, 1, 3.33576780e-03
10, 2, 3.65340311e-03
...
10, 237, 3.59767548e-03
10, 238, 3.55406296e-03
10, 239, 3.37930187e-03

The output in the case is a comma-separated list as follows:

  1. The X pixel value (N/A unless a single pixel or line ROI is specified).

  2. The Y pixel value (N/A unless a single pixel or line ROI is specified).

  3. The value of the pixel in the band(s) (in this case only 1 band, but in other cases it will be a list of values by band).

Using the extract operator on a 3x3 rectangular region of pixels for a single band (extract the pixels values for a set of pixels):

image_analyze --rect=10,10,12,12 --bandlist=1 --operator=extract --image=demo.img
10, 10, 3.90459110e-03
11, 10, 3.35050196e-03
12, 10, 3.89584825e-03
10, 11, 3.39535603e-03
11, 11, 3.28104086e-03
12, 11, 3.56469853e-03
10, 12, 3.60478368e-03
11, 12, 3.51797447e-03
12, 12, 3.53707532e-03

Test mode

The second major feature of the image_analyze tool is "test mode", where an input file defines the input image file, the spatial ROI for that image, the band range for the image, the specific operator to run and the expected value(s) of that operator. This mode is useful for checking if an image contains values that match an external calculation or values extracted from a previous simulation.

An input test supports 3 test metrics at this time:

  1. The mean metric, which computes the spatial mean for each band,

  2. The spectral_min metric, which computes the minimum value in each band, and

  3. The spectral_max metric, which computes the maximum value in each band.

In addition to the key operator variables (filename, metric, expected value, etc.), the test file also includes a "name" that is printed as the test is run and "description" and "history" variables that are used for documentation purposes.

A simple band mean test

Below is an input test file that checks the mean value in each band.

name = Spatially-averaged band values for the image
description = Verifies the spatially-averaged band values of the image.
history = Test automatically generated with 'image_analyze' 4.7.5 (r18149)
filename = demo.img
metric = mean
expected = 2.334133e-03,1.933457e-03,1.392983e-03
percentage = 0.1,0.1,0.1

In this case, we see that the expected variable was assigned 3 values. That implies that the input image (in this case, demo.img) is expected to have 3 bands. The band, bandlist or bandrange variables can be used to specify a subset of bands to process. Similarly the pixel, xline, yline or rect variables can be used to specify a subset of pixels to process. The expected values are compared to the computed value and the user can provide a tolerance around that value using two different options:

  1. The tolerance variable defines the absolute tolerance (+/-) about the expected value in each band.

  2. The percentage variable defines the relative tolerance (+/-) about the expected value in each band.

The "test" mode is triggered using the --tests option followed by a list of input files defining the test to perform. Below is an example of how the test file (named image_spatial_mean.test in this case) is run with the image_analyze tool:

$ image_analyze --tests image_spatial_mean.test
Spatially-averaged band values for the image (passed)

The (passed) message indicates that the test succeeded. If a test fails, the (failed) message will be printed and the specific issue that was encountered will be written to standard error:

$ image_analyze --tests image_spatial_mean.test
Spatially-averaged band values for the image (failed)
Band    Image           Expected        Abs Diff        % Diff
0       2.334133e-03    2.434133e-03    1.000003e-04    4.108251

Testing truth image values

The image_analyze tool is useful for checking the radiometric product of a DIRSIG simulation, but it can also be used to check values in a DIRSIG truth image file. Examples of truth tests that we have employed:

  • Testing the material index to confirm that a dynamic scene object is occupying the pixel you think it should.

  • Testing the slope of a surface (via the normal truth or angle truth) to confirm that a bump map or normal map is correctly working.

  • Testing the temperature of a surface to confirm that a temperature solver is correctly working.

  • Testing the shadow truth to confirm if the sun is where you expect it to be.

Below is a test file used to confirm that a car assigned a dynamic instance setup is where we expect it to be:

name = Car position test #1 (rear window)
description = Verifies the car is where we expect
filename = demo_truth.img
pixel = 67,76
band = 0
metric = mean
expected = 3
percentage = 0

In this case, we are probing a specific pixel (67,76) and a specific band (0, the material index truth band) and using the mean metric with zero tolerance to confirm that material index 3 is present.

Below is a test file for a normal map test that expects to poke the left-side of a virtual pyramid object (the normal map is emulating the pyramid shape on a flat surface) and find that the Z component of the normal vector has a specific value:

name = Normal Z component test, pyramid, left-side
description = Verifies the slope of the left-side of the pyramid
history = Hand-generated by Scott Brown (brown@cis.rit.edu)
filename = demo_truth.img
rect = 197,171,209,203
band = 11
metric = mean
expected = 0.440944
percentage = 0.1

In this case, we expect band 11 to contain the Z component of the normal map and we are averaging the normal over a uniform region on the side of this virtual pyramid to avoid noise in the normal when a small number of samples/pixel are used.

Running multiple tests

In most cases, we construct multiple tests for a given scene and then run all of them. For example, for an in-scene motion test we will typically test the basic statistics of the radiometric image and then several truth image values. The --tests mode lets you specify a list of test files, or just use the wildcard features of the shell to expand the file list:

$ image_analyze --tests *.test
Spatially-averaged band values for the image (passed)
Maximum band values for the image (passed)
Minimum band values for the image (passed)
Car position test #1 (rear window) (passed)
Car position test #2 (roof) (passed)
Car position test #3 (windshield) (passed)
Car position test #4 (ground, front) (passed)
Car position test #5 (ground, rear) (passed)

Generating image statistics tests

Although hand-crafting specific tests is an option, one of the simplest tests we use to "fingerprint" DIRSIG output images is a set of three tests:

  1. The average value of all pixels in each band,

  2. The minimum value of all the pixels in each band and

  3. The maximum value of all the pixels in each band.

We have found that these tests can do a good job at detecting subtle changes in the DIRSIG output radiometric image files. And the image_analyze tool has a simple option to generate the corresponding test files for these metrics if you have an existing image that is "trusted" to serve as the source "fingerprint". Supplying the --make_tests option to image_analyze will open the supplied image and compute these metrics for each band. This will produce the following test files: image_spatial_mean.test, image_spectral_min.test and image_spectral_max.test. In addition, the --basename option can be specified to change the image portion of those filenames to something else. This option is especially helpful when creating tests for several image files.