CImage Class Math Operators

The CImage class provides a syntax for making your scripts easier to understand when using operations involving images and numbers (also see CImage Class Methods). This is similar to operator overloading in the C++ language. CImage class math operators make it possible for a script to use expressions like the following:

     ImResult = 0.08 / -(Im ^ 0.5)
     Im = (Im - ImBias - ImDark) / ImFlat

All operators have class method counterparts. For example, the alternative to using the operator + would be the method Add. A primary difference between the operators and corresponding methods is that many of the operators create the result as a new CImage object, whereas the method operates on the object it is called from. The operators do not modify the original image, although the class methods may modify the CImage that calls the class method. These differences are described in the table below.

CImage operators that perform a math operation automatically create an image with floating point (double precision) data type. If you do not want to create a new image or a floating point image, use the class methods to exercise greater control over the process.

Operator Expressions

Operator Definition Operator Example Script Equivalent
Im1 + Im2 Adds the values of two images and creates a new CImage for the result. This is equivalent to the CImage:Add method. Im3 = Im1 + Im2  Im3 = CImage:new( Im1 )
Im3:Add( Im2 )
Im1 + num Adds a number to the image values and creates a new CImage for the result. This is equivalent to the CImage:Add method.
Im2 = Im1 + 0.5 Im2 = CImage:new(Im1)
Im2:Add( 0.5 )
Im1 - Im2 Subtracts the values of Im2 from Im1 and creates a new CImage for the result. This is equivalent to the CImage:Sub method. Im3 = Im1 - Im2  Im3 = CImage:new( Im1 )
Im3:Sub( Im2 )
Im1 - num Subtracts a number from the image values and creates a new CImage for the result. This is equivalent to the CImage:Sub method. Im2 = Im1 - 0.5 Im2 = CImage:new( Im1 )
Im2:Sub( 0.5 )
Im1 * Im2 Multiplies the values of two images and creates a new CImage for the result. This is equivalent to the CImage:Mul method. Im3 = Im1 * Im2 Im3 = CImage:new( Im1 )
Im3:Mul( Im2 )
Im1 * num Multiplies the values of an image by a number and creates a new CImage for the result. This is equivalent to the CImage:Mul method. Im2 = Im1 * 0.5 Im2 = CImage:new( Im1 )
Im2:Mul( 0.5 )
Im1 / Im2 Divides the values of Im1 by those of Im2 and creates a new CImage for the result. This is equivalent to the CImage:Div method. Im3 = Im1 / Im2 Im3 = CImage:new( Im1 )
Im3:Div( Im2 )
Im1 / num Divides the image values by a number and creates a new CImage for the result. This is equivalent to the CImage:Div method. Im2 = Im1 / 0.5 Im2 = CImage:new( Im1 )
Im2:Div( 0.5 )
Im1 ^ Im2 Raises the values of Im1 to the power of Im2, pixel by pixel, and creates a new CImage for the result. This is equivalent to the CImage:Pow method. Im3 = Im1 ^ Im2 Im3 = CImage:new( Im1 )
Im3:Pow( Im2 )
Im1 ^ num Raises the image values to a numeric power and creates a new CImage for the result. This is equivalent to the CImage:Pow method. Im2 = Im1 ^ 0.5 Im2 = CImage:new( Im1 )
Im2:Pow( 0.5 )
Im1 % Im2 Computes the modulus (or remainder) of Im1 divided by Im2 and creates a new CImage for the result. This is equivalent to the CImage:Mod method. Im3 = Im1 % Im2 Im3 = CImage:new( Im1 )
Im3:Mod( Im2 )
Im1 % num Computes the modulus (or remainder) of image values divided by a number and creates a new CImage for the result. This is equivalent to the CImage:Mod method. Im2 = Im1 % 0.5 Im2 = CImage:new( Im1 )
Im2:Mod( 0.5 )
-Im Computes the unary minus of the image by negating its pixel values, creating a new CImage for the result. This is equivalent to the CImage:Chs method. Im2 = -Im1 Im2 = CImage:new( Im1 )
Im2:Chs()
== Compares two images on a pixel by pixel basis. Returns true if every pixel value in Im1 is equal to the corresponding pixel in Im2. This is equivalent to the CImage:CompareEQ method. if Im2 == Im1 then
  Func()
end
if Im2:CompareEQ( Im1 ) == true then
  Func()
end
<= Compares two images on a pixel by pixel basis. Returns true if every pixel value in Im1 is less than or equal to the corresponding pixel in Im2. This is equivalent to the CImage:CompareLE method. if Im2 <= Im1 then
  Func()
end
if Im2:CompareLE( Im1 ) == true then
  Func()
end
< Compares two images on a pixel by pixel basis. Returns true if every pixel value in Im1 is less than the corresponding pixel in Im2. This is equivalent to the CImage:CompareLT method. if Im2 < Im1 then
  Func()
end
if Im2:CompareLT( Im1 ) == true then
  Func()
end

Comparison between Operators and Methods

The examples above show how operators simplify complex expressions. Now compare an operator-based expression with its equivalent using class methods. Assume that a raw image and several calibration images are open in memory. The scripts below perform a typical intensity calibration and photometric adjustment.

Here is the expression using operators:

     ImResult = 1.0024 * ((ImRaw - ImBiasPattern - ImDark) / ImFlatPixel / ImFlatIntensity)

Realizing the same result using class methods would use the following script:

     ImRaw:SetDatatype( "double" )
     Im:Sub( ImBiasPattern )
     Im:Sub( ImDark )
     Im:Div( ImFlatPixel )
     Im:Div( ImFlatIntensity )
     Im:Mul( 1.0024 )

One drawback to the operator based expression is that it may create intermediate images that are not deleted from memory until after going "out of scope", which may occur at the end of the function where they are used or ultimately, at the end of the script. For example, in evaluating the operator-based expression, Im - ImBias creates a CImage as an intermediate result. Then subtracting ImDark creates another result. Subtracting from that result to make yet another result, and so on. In fact, the expression creates 5 new instances of a CImage that are "hidden" and you can not manually delete. There is no way to avoid this. By comparison, the alternative script works by repeatedly changing the CImage Im and and does not even need to create a new image to hold the result. However, Im is altered by the method based script whereas the operators leave Im intact. If you want the method-based script to leave Im intact, simply construct a new copy of Im at the beginning, as in Im2 = CImage:new( Im ), and then call the methods from Im2. There is no work-around to these differences in behavior; so goes object-oriented programming. If you do not care that intermediate images are created, then using the expression can make your scripts far easier to understand.

 

Learn More

Name  *

E-mail  *

Item of Interest

Organization

Telephone

Application

Comments

Verification *