| imexpr | images.imutil | imexpr |
imexpr -- General image expression evaluator
imexpr expr output [a b c ...]
imexpr evaluates an image expression and writes the result to the output image. Images may be any dimension or size and any datatype except complex (complex images may be read but only the real part will be used).
If the input images are not all the same size the computation will be performed over the largest area which is common to all images. If the images are not all the same dimension the lesser dimension operands will be iteratively combined with the higher dimension ones. For example, when both a one and two dimensional image are used in the same expression, the vector (one dimensional image) will be applied to all lines of the two dimensional image.
Evaluation of the image expression is carried out one line at a time. This is efficient and permits operations on arbitrarily large images without using excessive memory, but does not allow 2D or higher operations to be performed within the expression (e.g., transpose). The entire expression is evaluated once for each line of the output image.
Operands
Input operands are represented symbolically in the input expression using the symbols "a" through "z", corresponding to imexpr task parameters. Use of symbolic operands allows the same expression to be used with different data sets, simplifies the expression syntax, and allows a single input image to be used several places in the same expression.
Three classes of input operands are recognized: images, image parameters, and numeric constants.
dev$pix[*,55] image operand a.itime image parameter 1.2345 numeric constant
Since the input operands are CL parameters they may be set on the command line, or entered in response to parameter prompts when the task executes and evaluates the input expression. For example,
cl> imexpr "a - a/b" pix operand a: dev$pix[*,55] operand b: a.itime
would evaluate the expression shown, storing the result in the output image "pix".
Operands may also be specified directly in the expression, with the exception of image operands. For example,
cl> imexpr "a - a / a.itime"
is equivalent to the earlier example.
If the input operand is not a simple identifier (a simple name like "itime" containing only alphanumeric characters, underscore, ".", or "$") then it is necessary to quote the operand name and precede it with an "@", e.g.,
cl> imexpr a - a / @"a.i-time"
Finally, there is a special builtin type of operand used to represent the image pixel coordinates in an image expression. These operands have the special reserved names "I", "J", "K", etc., up to the dimensions of the output image. The names must be upper case to avoid confusion to with the input operands "i", "j", "k" and so on.
I X coordinate of pixel (column) J Y coordinate of pixel (line) K Z coordinate of pixel (band)
An example of the use of the pixel coordinate operands is the generation of multidimensional analytic functions.
Operators
The expression syntax implemented by imexpr provides the following set of operators:
( expr ) grouping + - * / arithmetic ** exponentiation // concatenate expr ? expr1 : expr2 conditional expression @ "name" get operand && logical and || logical or ! logical not < less than <= less than or equal > greater than >= greater than or equal == equals != not equals ?= substring equals & bitwise and | bitwise or ^ bitwise exclusive or ~ bitwise not (complement)
The conditional expression has the value expr1 if expr is true, and expr2 otherwise. Since the expression is evaluated at every pixel this permits pixel-dependent operations such as checking for special pixel values, or selection of elements from either of two vectors. For example, the command
(a < 0) ? 555 : b / a
has the constant value 555 if "a" is less than zero, and "b / a" otherwise. Conditional expressions are general expressions and may be nested or used anywhere an expression is permitted.
The concatenation operator applies to all types of data, not just strings. Concatenating two vectors results in a vector the combined length of the two input vectors.
The substring equals operator "?=", used for string comparisons, is like "==" but checks for the presence of a substring, rather than exact equality of the two strings.
Functions
Where it makes sense all intrinsic functions support all datatypes, with some restrictions on bool and char . Arguments may be scalars or vectors and scalar and vector arguments may be mixed in the same function call. Arguments are automatically type converted upon input as necessary. Some functions support a variable number of arguments and the details of the the operation to be performed may depend upon how many arguments are given.
Functions which operate upon vectors are applied to the lines of an image. When applied to an image of dimension two or greater, these functions are evaluated separately for every line of the multidimensional image.
Standard Instrinsic Functions
abs (a) absolute value
max (a, b, ...) maximum value
min (a, b, ...) mininum value
mod (a, b) modulus
sqrt (a) square root
Mathematical or trigonometric functions
acos (a) arc cosine
asin (a) arc sine
atan (a [,b]) arc tangent
atan2 (a [,b]) arc tangent
cos (a) cosine
cosh (a) hyperbolic cosine
exp (a) exponential
log (a) natural logarithm
log10 (a) logarithm base 10
sin (a) sine
sinh (a) hyperbolic sine
tan (a) tangent
tanh (a) hyperbolic tangent
The trigonometric functions operate in units of radians. The deg and rad intrinsic functions (see below) can be used to convert to and from degrees if desired.
Type conversion functions
bool (a) coerce to boolean
short (a) coerce to short
int (a) truncate to integer
nint (a) nearest integer
long (a) coerce to long (same as int)
real (a) coerce to real
double (a) coerce to double
str (a) coerce to string
The numeric type conversion functions will convert a string to a number if called with a character argument. The str function will convert any number to a string.
Projection functions
len (a) length of a vector
hiv (a) high value of a vector
lov (a) low value of a vector
mean (a [, ksigma]) mean of a vector
median (a) median of a vector
stddev (a [, ksigma]) standard deviation
sum (a) sum of a vector
The projection functions take a vector as input and return a scalar value as output. The functions mean and stddev , used to compute the mean and standard deviation of a vector, allow an optional second argument which if given causes a K-sigma rejection to be performed.
Miscellaneous functions
deg (a) radians to degrees
rad (a) degrees to radians
median (a, b, c [, d [, e]]) vector median of 3-5 vectors
repl (a, n) replicate
sort (a) sort a vector
shift (a, npix) shift a vector
The median function shown here computes the vector median of several input vectors, unlike the projection median which computes the median value of a vector sample. sort sorts a vector, returning the sorted vector as output (this can be useful for studying the statistics of a sample). shift applies an integral pixel shift to a vector, wrapping around at the endpoints. A positive shift shifts data features to the right (higher indices).
The repl (replicate) function replicates a data element, returning a vector of length (n * len(a)) as output. For example, this can be used to create a dummy data array or image by replicating a constant value.
The Expression Database
The imexpr expression database provides a macro facility which can be used to create custom libraries of functions for specific applications. A simple example follows.
# Sample IMEXPR expression database file. # Constants. SQRTOF2= 1.4142135623730950488 BASE_E= 2.7182818284590452353 PI= 3.1415926535897932385 GAMMA= .57721566490153286061 # Euler's constant # Functions. div10(a) ((a) / 10) divz(a,b) ((abs(b) < .000001) ? 0 : a / b) div(a,b) (div10(b) / a) sinx (cos(I / 30.0)) sinxy(a,b) (cos (I / a) + cos (J / b))
The complete syntax of a macro entry is as follows:
<symbol>[( arg-list )][:|'='] replacement-text
The replacement text may appear on the same line as the macro name or may start on the next line, and may extend over multiple input lines if necessary. If so, continuation lines must be indented. The first line with no whitespace at the beginning of the line terminates the macro. Macro functions may be nested. Macro functions are indistinguishable from intrinsic functions in expressions.
IMEXPR and Pixel Masks
Although imexpr has no special support for pixel masks, it was designed to work with masks and it is important to realize how these can be used. IRAF image i/o includes support for a special type of image, the pixel mask or ".pl" type image. Pixel masks are used for things such as region identification in images - any arbitrary region of an image can be assigned a constant value in a mask to mark the region. Masks can then be used during image analysis to identify the subset of image pixels to be used. An image mask stored as a ".pl" file is stored in compressed form and is typically only a few kilobytes in size.
There are many ways to create masks, but in some cases imexpr itself can be used for this purpose. For example, to create a boolean mask with imexpr merely evaluate a boolean expression and specify a ".pl" file as the output image. For example,
cl> imexpr "a > 800" mask.pl
will create a boolean mask "mask.pl" which identifies all the pixels in an image with a value greater than 800.
An example of the use of masks is the problem of combining portions of two images to form a new image.
cl> imexpr "c ? a : b" c=mask.pl
This example will select pixels from either image A or B to form the output image, using the mask assigned to operand C to control the selection.
1. Copy an image, changing the datatype to real (there are better ways to do this of course).
cl> imexpr a pix2 a=pix outtype=real
2. Create a new, empty image with all the pixels set to 0.
cl> imexpr "repl(0,512)" pix dim=512,512
3. Create a 1D image containing the sinc function.
cl> imexpr "I == 10 ? 1.0 : sin(I-10.0)/(I-10)" sinc dim=20
4. Create a new image containing a simple test pattern consisting of a 5 element vector repeated 100 times across each image line.
cl> imexpr "repl((9 // 3 // 3 // 11 // 11), 100)" patt dim=500,500
5. Subtract the median value from each line of an image.
cl> imexpr "a - median(a)" medimage
6. Compute the HIV (low value) projection of an image. The result is a transposed 1D image.
cl> imexpr "hiv(a)" hvector
7. Swap the left and right halves of an image.
cl> imexpr "a // b" pix swapimage
operand a: dev$pix[256:512,*]
operand b: dev$pix[1:255,*]
8. Create a circular mask of a given radius about a user-defined center.
cl> type expr
(sqrt((I-b)**2 + (J-c)**2) <= d)
cl> imexpr @expr mask.pl b=256 c=256 d=100 dims=512,512
The input and output images cannot be the same. No support for type complex yet, or operations like the fourier transform.
imarith, imfunction, imcombine