next up previous contents index
Next: Predefined Variables Up: imal-manual Previous: Configure...   Contents   Index

Mathematical pixel operations (Image Algebra)

Although it is possible to add or multiply pixel values by any factor by using the ``brightness'' or ``contrast'' menu items, imal also has a more powerful tool - mathematical pixel operations.

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:

  1. Conditional expressions must consist of a single line unless the predicate statements are enclosed between braces. For example, the lines:
             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.
  2. Multiple expressions can appear on the same line if separated by semicolons (;).
  3. Equations which do not make sense to apply to the image are ignored. For example, it is not possible to alter the RGB components of a grayscale image separately. While is is possible to directly alter the intensity components of indexed-color images, this is not recommended.
  4. 8-bit indexed-color images are temporarily converted to 24 bits before applying the formulas. The RGB values for 8 bit images therefore range from 0 to 255 instead of their normal range of 0 to 63. When the image is converted back to 8 bits/pixel, its colormap is regenerated to make the actual colors correct. This in turn causes the actual pixel values for each color to change in an unpredictable manner. Moreover, although the colors are correct, the ultimate RGB values will be lower by a factor of 4 than the RGB values specified in the equation.
  5. It is strongly recommended that 8-bit indexed-color images be converted to 24 bits before proceeding. This provides greater accuracy and prevents problems from equations like i=image[1][0][x][y]; . Since the image being operated on is temporarily at 24 bits/pixel, copying parts of another 8-bit image will result in very dark colors, unless the source image is also 24 bits/pixel. This is not done automatically for performance reasons.
  6. Syntax and operator precedence is similar to C.
  7. The calculations may be interrupted at any time by pressing the Escape key (Keyboard focus must be on the editor or image window for this to work).
  8. i should be used with grayscale images, and r, g, and b should be used with color images.
  9. ``i'' has precedence over r,g, and b. That is, if the equation i=r=g=b=2444444; is entered, the selected region will be set to 2444444 (a light blue), not white (r,g,b = 255,255,255, where 255 is the highest permitted red, green, or blue value).
  10. The predefined variables i,r,g,b,x,y,temp, and user-defined variables may appear on either side of an equation, but functions such as sin(), max(), and image[][][][] may only appear on the right side.
  11. The predefined variables i,r,g,b,w,x,y, temp, etc., may be redefined or accessed within a formula, e.g., x=23; ; however, their values will be automatically reset for the next pixel. Other variables retain their previous values as long as imal is running.
  12. All calculations are carried out with double-precision floating point numbers. When the result is placed back into a pixel, it is converted to the closest integer. Thus, intermediate calculations such as multiplying by $ \pi$ give the correct result, but you should not expect to see floating point numbers in the image.
  13. The `math' command is no longer applicable, and has been removed since macro statements and algebra statements can now be freely intermixed.



Subsections
next up previous contents index
Next: Predefined Variables Up: imal-manual Previous: Configure...   Contents   Index
root 2008-10-10