In order to process an image with PrecisionImage.NET it must first be imported into a universal object type that can be understood by the various functional components of the library. This type is defined within the root namespace of the library as the SourceData class. Once a SourceData object has been instantiated and initialized it can be passed through a processing pipeline of any length and complexity with all intermediate results being maintained at 32-bit floating point precision.
A SourceData object can be thought of as a data container for the numerical values underlying the pixels of a given image. SourceData objects consist of one or more channels of source data, where each channel consists of a given number of rows and columns and contains the numerical values for a particular channel of an initializing image (a channel of an initializing image being the red, green or blue channel for color image sources. Grayscale image sources consist of only a single grayscale channel).
SourceData objects are instantiated using one of the parameterized constructors. In cases where the source data is in the form of a BitmapSource object, this object is passed to the constructor along with (optionally) two additional parameters: an enumeration specifying the image's gamma encoding state and a boolean indicating whether or not the image pixel values should be normalized to the range of (0.0 - 1.0) prior to storage in the SourceData object. In the case where the data is either unknown at the time of instantiation or is not in the form of a BitmapSource object, a SourceData object can be instantiated as an empty container where the dimensions and number of data channels are specified as constructor parameters. We will consider the parameterized constructor form of instantiation first.
A SourceData object can instantiated specifying all the constructor arguments as follows (only the first argument is required, the rest are optional):
The above constructor takes one mandatory and two optional parameters:
The first argument is a Windows Imaging Component BitmapSource image object encapsulating the image used to initialize the SourceData object with data. SourceData objects can be instantiated from BitmapSource images consisting of the following pixel formats: Gray8, Gray16, Gray32Float, Bgr24, Rgb24, Bgr32, Bgra32, Rgb48, Rgba64, Rgb128Float, and Rgba128Float
The second constructor argument is a PrecisionImage.GammaEncoding enumeration specifying the gamma encoding type of the source image. This argument is optional and has a default value of . This argument is ignored for BitmapSource images of type Gray32Float, Rgb128Float and Rgba128Float since these formats are not usually gamma encoded.
In general RGB image types other than the 32-bit floating point formats have had a non-linear function applied to the original values collected by the camera sensor. This is the image gamma encoding. The GammaEncoding specifier is used to remove the gamma encoding and linearize the data within the BitmapSource image prior to storage in the SourceData object. This is especially important in workflows that require color space conversions (where removal of the gamma encoding is critical) but may also be desirable for other processing pipelines where linearity of source data has been assumed.
The third constructor argument is a boolean indicating whether or not to normalize the pixel values to the range 0.0 - 1.0 when storing. This argument is optional and defaults to true i.e. all pixel values are normalized by default unless false is passed into the constructor. This is particularly important for color-space conversions where the original values are assumed to be linearly normalized to the range 0.0 - 1.0.
For example, consider the following case where a BitmapSource image ("bitmapSource") of type Bgra32 is used to instantiate a SourceData object as follows:
The above operation returns a new SourceData object called "imageData". This object will contain 4 data channels; one for each color of the original BitmapSource image passed to the constructor (blue, green, red and alpha in that order. The order of the data channels in the SourceData object is the same as the order of the color channels in the BitmapSource from which it was derived). Although the specified source image is an 8-bit sRGB image with values ranging from 0 - 255, no third constructor argument is specified and the default normalization behavior (true) will be observed. The values within each channel of imageData will therefore consist of normalized 32-bit floating point values within the range of 0.0 - 1.0, where 0.0 is equivalent to 0 in the original image and 1.0 is equivalent to 255 in the original image. Furthermore, the normalized values will not correspond to a simple linear normalization of the 8-bit values since sRGB was specified in the constructor indicating that bitmapSource is gamma encoded according to the sRGB standard. This forces the application of a non-linear gamma-encoding removal operation to the normalized values. To bypass the gamma encoding removal, specify None. The resulting values stored in imageData will therefore be normalized versions of the original 8-bit values with the gamma encoding removed. Lastly, since the GammaEncoding specifier is optional, the same result would have been achieved had the constructor been invoked as follows:
As a second example, consider the case where "bitmapSource" is a PixelFormats.Gray16 type and imageData is instantiated as follows:
In this case, imageData will consist of a single channel of normalized values corresponding to the single channel of data in bitmapSource. Since bitmapSource is a 16-bit grayscale image, the value 0.0 in imageData corresponds to 0 in bitmapSource and the value 1.0 in imageData corresponds to the value 65535 in bitmapSource.
Alternatively, an empty SourceData object can be instantiated with a specified number of data channels - each channel consisting of the specified number of rows and columns - as follows:
This operation returns a new SourceData object consisting of 2 data channels, each channel having 1024 rows and 2048 columns. All values are initialized to 0.0 by default.
Regardless of the method of instantiation, the values contained within a SourceData object can be queried and assigned very easily by using the GetValue and SetValue methods. These methods return the 32-bit floating point value contained at the zero-indexed row, column and channel of the SourceData object.
For example, given a single channel SourceData object with 1024 rows and 2048 columns, the value contained at the last row and column can be retrieved as follows:
Similarly, the value at the same location can be assigned as follows: