Pixel Math |
|
DIV* Division with constrained infinity The amount of images that can be operated with a single instance of PixelMath 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 Current Operand Parameters controls Channel Coefficient edit controls Reset Channel Coefficients / Inversion button Channel Coefficient edit controls |
|
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. 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:
where:
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:
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
where p' is the inverted pixel used to operate. 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: 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. Operand pixels or values are added to target pixels:
Operand pixels or values are subtracted from target pixels:
Target pixels are multiplied by operand pixels or values:
Target pixels are divided by operand pixels or values:
When an operand pixel or value is less than 1.0×1035 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.
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. Target pixels are raised to operand pixels or values:
Target pixels are replaced with the absolute values of their differences with operand pixels or values:
Target pixels are replaced with operand pixels or values, only if the operand is less than the target:
Target pixels are replaced with operand pixels or values, only if the operand is greater than the target:
Target pixels are replaced with operand pixels or values:
Target pixels are bitwise-ORed with operand pixels or values:
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,
See a specific section on this document to learn how bitwise logical operators are calculated by PixelMath. Target pixels are bitwise-ANDed with operand pixels:
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,
See a specific section on this document to learn how bitwise logical operators are calculated by PixelMath. Target pixels are bitwise-XORed with operand pixels:
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,
See a specific section on this document to learn how bitwise logical operators are calculated by PixelMath. The resulting image can be modified by the following optional parameters: 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. A unique constant value can be added to all channels of the resulting image. When no rescaling is selected, resulting pixels are just truncated to the normalized range. For each pixel r of the result:
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:
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:
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:
Where r'' is the resulting pixel rescaled to the user-specified range. Optionally, the resulting image can be inverted, that is, for each pixel r of the result:
is the inverted result in the normalized [0,1] range. Inversion is always done after rescaling, when applicable.
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. 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. 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.
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 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.
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.
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.
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.
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. This is the standard interface to the PixelMath process described in the preceding section: 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:
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. Controls in this area correspond to parameters of the currently selected operand (or target image) in the Source Operands list 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. 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.
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. 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.
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. 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. 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. Click this button to remove the current operand from the PixelMath instance. Operand deletion cannot be undone. 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. Controls in this section modify parameters that apply after the entire set of operands has been applied to the target image.
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. 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. 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. 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. 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. If this option is selected, the resulting image replaces the target image. Prior target contents can only be recovered by the operation, provided that Undo is currently enabled for the target image window.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 ( , 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. |