Pixel Math



::Index  <Prev  >Next

The PixelMath Process

Target Image and Operands

Operators

NOP — No operation

ADD — Addition

SUB — Subtraction

MUL — Multiplication

DIV — Division

DIV* — Division with constrained infinity

POW — Power (exponentiation)

DIF — Absolute difference

MIN — Minimum value

MAX — Maximum value

MOV — Move (copy) pixels

OR — Bitwise Logical OR

AND — Bitwise Logical AND

XOR — Bitwise Logical XOR

Result Options

Channel Coefficients

Additive Constant

Rescale

Inversion

Features and Limitations

The amount of images that can be operated with a single instance of PixelMath

Parenthesized expressions

Sizes of operand images

Operating between color and grayscale images

The accuracy of intermediate calculations

The accuracy of rescale operations

How bitwise logical operations are calculated

When the target image is also used as an operand

Using PixelMath with preview objects

The Pixel Math Window

Source Operands list box

Current Operand Parameters controls

Operator combo box

Operand combo box

Channel Coefficient edit controls

Invert check box

Reset Channel Coefficients / Inversion button

Move Operand buttons

New button

Delete button

Clear button

Result Parameters controls

Channel Coefficient edit controls

Add Constant edit control

Invert check box

Rescale check box / edit

Destination Parameters controls

Replace Target radio button

Create New Image radio button



The PixelMath Process

PixInsight's PixelMath performs a series of pixel-level arithmetic and logical operations between images. For example, suppose four images of the same object, identified as A, B, C, D. Once properly aligned, a common operation is averaging them to increase the signal-to-noise ratio of the resulting stacked image:

(A + B + C + D) / 4

The above averaging formula is applied to each pixel of the four-pixel stack. PixelMath can perform the above expression very easily in a single operation —in fact, PixelMath is able to do many complex and interesting things.

The applications of PixelMath are numerous and important in all fields of technical image processing: image integration and composition, mask generation, correction of uneven illumination (application of flat fielding, vignetting or gradient correction masks), just to mention some well-known examples.

Basically, an instance of PixelMath contains a set of references to operand images, the operations that must be performed between them, and some parameters to control how the result image is generated.


Target Image and Operands

The image an instance of PixelMath is applied to is called the target image of the process. From PixelMath's point of view, the target image is just a placeholder variable: it is unknown until the process instance is executed, so it isn't included as an actual parameter.

The rest of elements that participate in the expression being calculated are operands. Operands can be either images or constant values. For example, if you want to subtract the image identified as 'Image01' from any target image, the required PixelMath instance could be represented as:

<*target*> SUB Image01

where:

<*target*> identifies the target image, which is unknown until execution.

SUB stands for the subtraction operator.

Image01 is the identifier of an operand image.

When no image is used for an operand, a different constant value is used for each channel of the target image. For example, if the target is a RGB color image, a PixelMath instance like:

<*target*> MUL (0.95, 1.00, 0.98)

might be used to apply a linear color correction to the target image. MUL stands for the multiplication operator. For grayscale images, a single constant is used.

In addition, target and operand images can be inverted. Inversion always takes place before the operations associated to operands. If p is a target or operand pixel, and inversion has been selected for the target or the corresponding operand image, then

p' ¬ 1 — p

where p' is the inverted pixel used to operate.


Operators

Let's identify a target image as T, and an operand, either an image or a set of numerical constants, as P. Then the following operators are supported in PixInsight LE 1.0:


NOP — No operation

This operator does just nothing. It is included mainly for formal reasons. When an operand has been assigned this operator, it is simply ignored. This can be useful to temporarily disable an operand without having to remove it from the PixelMath instance.


ADD — Addition

Operand pixels or values are added to target pixels:

T ¬ T + P


SUB — Subtraction

Operand pixels or values are subtracted from target pixels:

T ¬ T – P


MUL — Multiplication

Target pixels are multiplied by operand pixels or values:

T ¬ T × P


DIV — Division

Target pixels are divided by operand pixels or values:

T ¬ T / P

When an operand pixel or value is less than 1.0×10–35 in absolute value, an effective division by zero is assumed. The resulting target pixel is given the largest possible numerical value in the range of IEEE 32-bit floating point, that is, 3.4×10+38, with the same sign as the target pixel value (the sign of the operand is ignored in this case).

Note that if some division by zero occurs and the rescale result option is selected, the resulting image will probably be unusable, since the available dynamic range will first be extended to +/-3.4×10+38 in order to keep all of the existing data, then pixel values will be rescaled to the specified range, and finally to the normalized [0,1] range, if necessary. In these cases, actual image data is constrained to a tiny effective range of numerical values, which leads to a severe loss of accuracy.


DIV* — Division with constrained infinity

This operator is equivalent to the normal division DIV operator. However, if the rescale result option is selected and there are divisions by zero, the problem mentioned for the DIV operator does not occur with DIV*.

To avoid severe loss of numerical accuracy due to infinities generated in divisions by zero operands, all of the resulting infinity pixel values are discarded by plain truncation to the specified rescaling range. Then, pixel values are rescaled to the specified range, and finally to the normalized [0,1] range, if necessary. The neat result is that infinities result in pure white (or black, if negative pixel values were generated by PixelMath operations), and the rest of the image is the result of a normal division, with an optimal usage of the full available dynamic range.


POW — Power (exponentiation)

Target pixels are raised to operand pixels or values:

T ¬ TP


DIF — Absolute difference

Target pixels are replaced with the absolute values of their differences with operand pixels or values:

T ¬ |T – P|


MIN — Minimum value

Target pixels are replaced with operand pixels or values, only if the operand is less than the target:

T ¬ Min( T, P )


MAX — Maximum value

Target pixels are replaced with operand pixels or values, only if the operand is greater than the target:

T ¬ Max( T, P )


MOV — Move (copy) pixels

Target pixels are replaced with operand pixels or values:

T ¬ P


OR — Bitwise Logical OR

Target pixels are bitwise-ORed with operand pixels or values:

T ¬ T or P

The bitwise logical OR operation works between two integer numbers at the bit level. For each single bits t, p of the result pixel and the operand, respectively,

t or p ®
0 if t = 0 and p = 0
1 if t = 1 or p = 1

See a specific section on this document to learn how bitwise logical operators are calculated by PixelMath.


AND — Bitwise Logical AND

Target pixels are bitwise-ANDed with operand pixels:

T ¬ T and P

The bitwise logical AND operation works between two integer numbers at the bit level. For each single bits t, p of the result pixel and the operand, respectively,

t and p ®
1 if t = 1 and p = 1
0 if t = 0 or p = 0

See a specific section on this document to learn how bitwise logical operators are calculated by PixelMath.


XOR — Bitwise Logical XOR

Target pixels are bitwise-XORed with operand pixels:

T ¬ T xor P

The bitwise logical XOR operation works between two integer numbers at the bit level. For each single bits t, p of the result pixel and the operand, respectively,

t xor p ®
1 if t ¹ p
0 if t = p

See a specific section on this document to learn how bitwise logical operators are calculated by PixelMath.


Result Options

The resulting image can be modified by the following optional parameters:


Channel Coefficients

Each channel of the result image can be multiplied by a constant value. This is mainly used to apply linear color corrections to RGB color images.


Additive Constant

A unique constant value can be added to all channels of the resulting image.


Rescale

When no rescaling is selected, resulting pixels are just truncated to the normalized range. For each pixel r of the result:

r' ¬ Min(Max(0, r), 1)

where r' represents the truncated resulting pixel value.

If the Rescale option is selected, then the resulting pixels are first rescaled to the normalized [0,1] range. This is done by:

r' ¬ (r — m) / (M — m)

where r' is the normalized pixel value. m and M are, respectively, the minimum and maximum pixel values in the resulting image prior rescaling, such that m < M.

If the result is filled with a constant value, i.e. if m = M, then all result pixels are replaced by the truncating expression:

r' ¬ Min(Max(0, m), 1)

and no more rescaling is done.

When m < M, a numerical range, distinct from the normalized range, can be specified to rescale the resulting image. If [a, b] denotes the user-specified rescaling range, such that a < b, a ³ 0, and b £ 1, then an additional rescaling operation is applied:

r'' ¬ (r' — a) / (b — a)

Where r'' is the resulting pixel rescaled to the user-specified range.


Inversion

Optionally, the resulting image can be inverted, that is, for each pixel r of the result:

r' ¬ 1 — r

is the inverted result in the normalized [0,1] range. Inversion is always done after rescaling, when applicable.


Features and Limitations


The amount of images that can be operated with a single instance of PixelMath

PixelMath can take an unlimited number of operands. When operand images are used, the only limitation is the size of available RAM, since all of the operand images must be open in PixInsight for PixelMath to access them. Additional data structures and temporary images may be necessary during PixelMath execution, which are also allocated in RAM.


Parenthesized expressions

In PixInsight LE 1.0, there is no provision to build parenthesized expressions with PixelMath. If you need to operate with some images and your expression includes two or more parentheses, you may have to break it into appropriate subexpressions and use one instance of PixelMath to calculate each of them, then a final PixelMath to calculate the result. Parenthesized expressions are fully supported in PixInsight Standard.


Sizes of operand images

PixelMath can operate with images of any sizes. If an operand image and the target image have different dimensions, a temporary duplicate of the operand is generated, resampled to match the target, and the corresponding operation is performed. Then the temporary duplicate is destroyed and PixelMath continues with the next operand. Size-matching resampling operations are performed automatically on the fly. The bicubic interpolation algorithm is used.


Operating between color and grayscale images

With some restrictions, PixelMath can operate between grayscale and color images. If the target image is grayscale, then all of the operand images must also be grayscale. If the target is a color image and an operand is grayscale, the grayscale operand applies to each color channel of the target image.


The accuracy of intermediate calculations

The entire sequence of operations is accumulated as a temporary floating point matrix. During the whole calculation, the full IEEE 32-bit floating point range is used for each pixel. This gives a final accuracy better than, roughly, six or seven decimal digits, depending on the complexity of the whole process. Rescale or truncation to the normalized [0,1] range (as selected by the user) is performed at the very last calculation step to ensure minimal round-off error.


The accuracy of rescale operations

All rescale operations, including intermediate operations performed automatically, as well as the final rescaling to the normalized [0,1] range, when selected, are calculated with temporary variables in 64-bit IEEE floating point format.


How bitwise logical operations are calculated

PixInsight stores and manipulates pixel values as IEEE 32-bit floating point numbers. To apply bitwise logical operations (OR, AND, XOR), both target and operand pixel values are first transformed to unsigned 32-bit integers by multiplication with 4294967295 and rounding to the nearest integer. The multiplicative constant is equal to 232 – 1, the largest possible unsigned integer value. Note that this multiplication assumes pixel values in the normalized [0,1] range. Then the bitwise logical operation is performed and the result is back-converted to the normalized floating point range, transforming it to floating point format and dividing by 4294967295.


When the target image is also used as an operand

For example, this happens if the following PixelMath instance:

<*target*> ADD Image01 ADD Image02

is applied to Image02. When this occurs, and PixelMath is being executed on the actual target image —not on a preview object—, a temporary duplicate of the target image is used to accumulate the result. The duplicate is generated at the beginning of the process, just before calculation starts. When the target image is not used as an operand, it works internally as a matrix where intermediate results are being accumulated. This is done to save memory.


Using PixelMath with preview objects

Instances of PixelMath can be applied to preview objects without any restrictions. When executed on a preview, PixelMath uses just those pixels falling into the preview rectangle, for all of the operand images, for the sake of execution speed. However, when an automatic resampling is needed to adapt mismatching operand dimensions, a temporary copy of the entire operand image is resampled, instead of the preview subimage, to ensure coherence between previewed and applied processes.


The Pixel Math Window

This is the standard interface to the PixelMath process described in the preceding section:


Source Operands list box

On this list box you can inspect all of the currently defined operands. The first list row corresponds to the target image.The rest of list rows correspond to PixelMath operands.

The following columns are defined for this list:

#
Shows the operand number (zero for the target image).

Op
Shows the operator selected for each operand.

Image Id
The image identifier for each operand, if any has been selected.

R/K, G, B
These three columns are coefficients for the red/gray, green, and blue channels, respectively.

Inv
This column is checked on rows where inversion has been selected for the corresponding image.

To select an operand or the target image, just click on the corresponding list row. Data corresponding to the item selected are loaded on, and can be edited with, the controls in the Current Operand Parameters section.


Current Operand Parameters

Controls in this area correspond to parameters of the currently selected operand (or target image) in the Source Operands list box.


Operator combo box

This control includes the whole set of available operators. This combo box is disabled if the target image is selected in the Source Operands list box.


Operand combo box

By clicking on this control you can select an image for the current operand, if any is currently open. You select an image by its image identifier, or the item labelled as "No view selected" if you don't want to have an image associated to the current operand. This combo box is disabled if the target image is selected in the Source Operands list box.

When you select no image for an operand, all of the target pixels are operated with the channel coefficients of the operand. This works as if an image filled with a constant color, as defined by the channel coefficients, was associated with the operand.


Channel Coefficient edit controls

If an image has been selected for the current operand, these coefficients multiply the red (or gray), green, and blue channels, respectively, of the selected operand image. For the target image, the coefficients also multiply their respective channels. Finally, if no image has been selected for an operand, coefficients are directly operated, according to the selected operator, with the corresponding channels of the target image.

Channel coefficients can range from -100 to +100. Default values are 1.0 for the three channels. For grayscale images, only the first coefficient is taken into account.


Invert check box

When the Invert check box is checked, the operand or target image is inverted prior calculation. This check box is disabled if there is no image selected for the current operand. This option is unselected by default.


Reset Channel Coefficients / Inversion button

Click this button to reset the three channel coefficients and the Invert check box to their default states. Default values are coefficients equal to 1.0 and no inversion.


Move Operand buttons

You can change the order of operands by clicking these buttons. Click the up-arrow button to move the current operand upwards. Click the down-arrow button to move the current operand downwards. As you click these buttons, you can see how the operands are reorganized on the Source Operands list box. Of course, the target image item (the first list row) cannot be moved.


New button

Click this button to add a new operand to the PixelMath instance. A new operand is created with default values that you can modify to match your needs.


Delete button

Click this button to remove the current operand from the PixelMath instance. Operand deletion cannot be undone.


Clear button

By clicking this button the entire operand set is deleted. This operation cannot be undone. Use this button to start definition of a new PixelMath instance from scratch.


Result Parameters

Controls in this section modify parameters that apply after the entire set of operands has been applied to the target image.


Channel Coefficient edit controls

These coefficients multiply their respective channels of the resulting target image. For grayscale images, only the first coefficient is considered. The default value is 1.0 for the three coefficients.


Add Constant edit control

This constant value is added to all pixels of the resulting image, just after multiplication by the corresponding channel coefficients. The default value is zero.


Invert check box

When this check box is checked, the resulting image is inverted after multiplication by the channel coefficients and addition of the constant value. This option is unselected by default.


Rescale check box / edit

When the Rescale check box is checked, resulting pixels are rescaled to the specified range of values. The rescaling range is defined as two boundaries such as the normalized [1,0] range cannot be exceeded. See the corresponding explanation on this document to learn how rescaling is applied.

When the Rescale check box is unchecked, resulting pixels are truncated to the normalized [0,1] range and the two edit controls for range boundaries are disabled.

The rescale option is enabled by default, and the rescaling range is the normalized [0,1] range.


Destination Parameters

This section determines how the resulting image is presented after PixelMath execution. Note that the following options are irrelevant when PixelMath is executed on a preview object.


Replace Target radio button

If this option is selected, the resulting image replaces the target image. Prior target contents can only be recovered by the Edit > Undo operation, provided that Undo is currently enabled for the target image window.


Create New Image radio button

The resulting image goes to a newly created window. The new window receives an automatically generated identifier consisting of the target image identifier plus a specific postfix. The postfix can be specified by global preferences (Edit > Preferences, Identifiers tab sheet). The default PixelMath postfix is "_pixelMath". For example, if PixelMath is applied to Image01, the resulting image window would be identified as "Image01_pixelMath". Successive PixelMath executions on the same target would generate unique image identifiers automatically: "Image01_pixelMath1", "Image01_pixelMath2", and so on.



::Index  <Prev  >Next