Using the ``Macro/image math'' menu, mathematical formulas can be entered to transform each pixel value in one pass. These formulas could be any legal C-style mathematical equation consisting of constants, variables, and operators from the following list:
Constants - any real number (floating point or integer)
Any of several pre-defined constants (see below)
Variables - one of 6 pre-defined variables:
i = intensity (total pixel value)
v = pixel density (pixel value, corrected for image depth and scaled to 0 to 1, but not corrected for calibration)
d = calibrated pixel density (see Image Calibration)
r = red component of the pixel
g = green component of the pixel
b = blue component of the pixel
x = x coordinate of the pixel (0,0=upper left of image)
y = y coordinate of the pixel
re = FFT real coefficient
im = FFT imaginary coefficient
w = Wavelet coefficient
variable is read only (any changes to this variable are ignored).
Operators -
, , =, +=, -=, *=, /=, ==, !=,
,
=,
,
=,
+, - , * , / , ++, -, [ , ] , {, }, (, ), if, else, for, while
Integer operators -
NOTE: The operands are truncated to integers before integer operators are applied.
|=, &=, =, ||, &&, | , , & , , !
Single parameter functions
sin cos tan
sinh cosh tanh
asin acos atan
sqrt abs
log (natural logarithm)
ln (natural logarithm)
log10 (base 10 logarithm)
exp
pi
rand (random number based on specified seed, scaled 0-1.0)
The following 4 functions are only available on Linux:
asinh
acosh
atanh
cbrt (cube root)
Two-parameter functions
max
min
pow (pow(x,y) = x raised to the power y)
Image names, if used in quotes, will evaluate to the image number and can be used anywhere an image number is needed. See Sec. 13.2.
Miscellaneous functions Any macro function (Sec. 14) can be included along with image math.
User-defined variables
Variable names must start with a letter. It is not necessary to declare variables before using them. If they are referenced without being initialized, the value is 0.
For example, if you entered the following equations:
increase=1.2345;
r=r+3;
g=(r/4)+increase;
b=g-pow(b,2);
imal would create a variable named increase and set it to 1.2345. Each pixel would have its red component increased by 3, its green component would be set equal to red/4 + 1.2345, and blue would be set equal to green minus (blue squared). Since pixels can only have integral values of red, green, and blue, the numbers are converted back to integers before being stored in the pixel.
The formula
i = abs(w);
Copies the absolute value of the wavelet coefficients into the image. Warning: Wavelet-transformed images may have a different size from the original image.
These image algebra formulas are automatically iterated over every pixel in the current image or selected region. You can select a region with the `select' command, or iterate over some other variable by explicitly creating a `for' or `while' loop. See `Macro Programming Guide' for details.
All variables are double-precision floating point numbers and are remembered from one call to the next. Thus, it is possible to declare and initialize variables on one pass and change them on the next. For example, to initialize the variable ``increment'', select a small region and execute the equation
increment = 0; .
Then one can select the image and execute a set of equations such as:
if(r>80 && g>80 && b>80){ r=increment; g=66; } else { g=77; b=88; }
increment+=0.01;
This would create a gradient effect in the image because increment would be increased by 0.01 after every pixel was processed.
After editing the equations, there are several options:
Example: To perform ``gamma correction'' to an image, enter the following equations:
r = pow(r,1.8);
g = pow(g,1.8);
b = pow(b,1.8); ,
where 1.8 is the gamma correction factor. For monochrome, a higher value (e.g., 2.35) is often used.
Example: Conditional expressions:
if(r==32) g=r+x+y;
Sets green equal to red plus the x and y coordinates (measured in pixels from the upper left corner of the image), if red is equal to 32.
Example: Multiple nested if..then..else statements:
if(r>=23){ g=34; b=45; }else{ g=99; if(r>56) b=56; else b=76;}
if(r>=23)
{ g=34;
b=45;
}else
{ g=99;
if(r>56)
b=56;
else
b=76;
}
These two equations are equivalent. White space and line breaks are ignored. Syntax is similar to ``C'' programming. If two or more statements are on the same line, C-style semicolons are required between statements. Portions of the statement could also be executed as a single line, by pressing Shift-Enter instead of clicking OK. If a single line is executed, all lines before and after it are ignored, and the line must have valid syntax when taken by itself out of context. Note: The line will be iterated over all pixels in the image or selected area, even if the statements before and after it define a loop over some other variable.
Example: To eliminate all pixels below 100 and above 200:
i = min(200,max(i,100));
Using data from other images
Mathematical operations can also be performed using data from other images, other frames, or other regions in the same image using the [][][][] operator. These variables can only appear on the right-hand side of an equation. Putting them on the left, e.g., saying something like "image[1][0][x][y]+=4", will cause a syntax error. Use i, r, g, and b for variables on the left side of equations.
Unix version:
image[image_number][frame][x][y]
red[image_number][frame][x][y]
green[image_number][frame][x][y]
blue[image_number][frame][x][y]
real[image_number][x][y]
imag[image_number][x][y]
wave[image_number][x][y]
density[image_number][frame][x][y]
DOS version:
image[image_number][x][y]
red[image_number][x][y]
green[image_number][x][y]
blue[image_number][x][y]
where:
image_number is the number assigned to the source image by imal (This number may change unexpectedly when images are unloaded). You can also use variables or functions for each of these indices, for example:
re = imag["myimage.gif"][sqrt(a)][cbrt(b+c)];
See Sec. 13.2. for more details.
As in C, brackets denote array notation. Thus, the x, y, and frame coordinates in a bracket are in pixel units relative to the upper left corner of the image, which will be different from the screen coordinates if the image is not located at the upper left corner of the main window.
frame is the frame number of the source image (3D images only). For non-3D images, the frame number must be 0. It may be convenient to create an image with 2 or more frames to hold intermediate calculations. By default, no intermediate values are stored; therefore, an equation such as
if(x
0&&y
0) i = image[0][0][x-1][y-1];
will overwrite its own source data. (This would have given an `out of bounds' error without the `if' statement.)
Note that, if all operations are on the same pixel and same image, then i,r,g,b,im,re, and w are the same as their longer versions (image, red, green, blue, imag, real, and wave). For example,
i = i+10;
would be the same as
i = image[1][0][x][y];
However, the long versions are technically functions and so they may not appear on the left side of an equation. Thus, the following is illegal:
image[1][0][x][y] += 6; // Illegal
if(r>g) green[1][0][x][y]++; // Illegal
Instead, use the following:
i+=6;
if(r>g) g=green[1][0][x][y]+1;
y and x are the coordinates of the source pixel. The coordinates are relative to the upper left corner of the source image. If you specify an x or y coordinate below zero or above the x or y size of the image, or if you specify an image number or frame number that does not exist, it will say "array out of bounds".
Note that wavelet coefficients and the real and imaginary components of FFTs have only 3 indices, since there is only a single frame for FFT'd images. Referring to a real or imaginary component of an image that has not been transformed, or referring to coordinates or frames not present in a given image, will produce an error.
`density[][][][]' is similar to `image[][][][]' except that the value is corrected for bits/pixel and calibration (if the image has been calibrated), and the value is returned as a number between 0 (black) and 1.0 (white). See also `rdensity' and `cdensity'.
'd' gives the same result as `density[][][][]', but gives the calibrated density for the current image and current x and y value.
NOTE: The value returned by `density' will be different depending on the Pixel Density Calibration setting in the Densitometry dialog. This can also be changed in a macro by changing the COMPENSATE constant13.2. If `z units' was selected, the image must be calibrated first. See the sections on Image Calibration and Densitometry for details.
Before using the functions real and imag to copy frequency components from one FFT'd image to another, it may be desirable to increase the size of the destination window to match the size of the source image. This can be done by the command
resizewindow( ino, xsize, ysize); .
For example:
resizewindow(1, 128, 128);
will increase the window for image no. 1 to 128x128, leaving the original image in the upper left corner.
All numbering of frames, images, and x and y coordinates starts with 0. An invalid coordinate, frame, or image causes an error and returns a value of 0.0. The formula is iterated over every (x,y) in the selected destination image or region.
If this form is used, all 4 bracketed parameters must be specified even if only one frame exists.
Since 3D images are not supported in the DOS version, only the image number and x and y coordinates need to be specified.
Example: Subtracting 2 images with a small offset and increase the brightness of the result by a factor of 2.5.
1. Click on destination image. (Assume source image is #1).
2. Select ``image math''.
3. i=2.5*(i-image[1][0][x-2][y-2]);
Example: Making all the pixel values in 8-bit image #0 an even number:
i=image[0][0][x][y]&254;
Example: Increasing the green in pixels whose red and blue are both greater than 128:
if(r
128 && b
128) g*=2;
Example: Multiplying the real frequencies of Fourier-transformed image no. 7 by 2:
re=2*real[7][x][y];
Exercises:
Practice running the sample macros supplied with imal.
Notes:
if(r==g)
b+=20;
g=0;
will increase b only if r is equal to g, but will set all g's to 0.