Style: Channels and Outputs Tutorial

This topic presents a tutorial exploring how Style tells images what channels to assign to which outputs.  Review the Style: Images topic together with this topic.

Images Show Data from Tables

In Manifold, all data is stored in tables.   Raster data is stored as tiles in tables, with each record in the table containing one tile.   Tiles contain data for some rectangular region of pixels, typically a square region that is 128 pixels wide by 128 pixels high, for a total 16,384 pixels.  Tables store raster data in tiles because it is more efficient to store data for sixteen thousand pixels at a time in a record than saving it as one pixel per record.


The data type within each tile matches the number of channels and the numeric type that is used by the data set for each pixel.  For example, a simple RGB image typically uses three channels for each pixel, to provide Red, Green, and Blue (RGB) channels, with a value of 0 to 255 for each channel.  Such images usually use a numeric type of uint8, an unsigned 8 bit number, for each channel, and thus a data type of uint8x3, a triplet of uint8 numbers, for each pixel.   Images often have four channels, with the fourth channel being an alpha channel specifying transparency, or, as in the case of very popular NAIP imagery in the US, with the fourth channel providing near-infrared information for use in computing NDVI or false color infrared images.


A data set that used more precise measurements of color values for each channel might use uint16x3, that is, a triplet of uint16 numbers, for each pixel.   uint8 provides color levels from 0 to 255 for R, G and B channels, which is plenty for most applications, while uint16 provides color levels from 0 to 65,535 for each channel, a much greater level of precision sometimes required for scientific and other remote sensing applications.



An image is just a viewport that shows data from tiles within a table.  The image itself contains no data.  The image contains only a few properties that tell the image what table to use for tile data and how to display that data.    For example, the image's properties may say to take data from a table called Boston Tiles, as seen above, using a field called Tile, and to use the tile data to display an image.   In the table above, tiles are 128 x 128 in size, with 4 channels.   In most such cases the first channel is used for the R channel, the second channel for the G channel and the third channel for the B channel.  


In the illustration above, we have Ctrl-clicked one of the rows in the table to select it.  The selected row appears in red selected color in the table, and the tile for that row appears in red selected color in the image window.  The selected tile in the image takes its pixel data from the selected tile in the table.


The properties of an image tell the image what table to use for the image's data, and what field in that table provides the tile data for the image.   To see the properties of an image, we right-click on the image in the Project pane and choose Properties.



The Table property for the Boston image specifies the table from which the image takes tiles, in this case, the Boston Tiles table.   the FieldTile property specifies the name of the field within that table that contains tile data.


The StylePixel property of the image is a human-readable, JSON text string that tells the image how to display the data found in the table.  We can change how an image window displays data from a table by changing the "instructions" in the JSON string in the StylePixel property,.  We normally would use the Style pane to change those style instructions with a point and click interface instead of editing free hand the JSON string, but if we were in a programmatic frame of mind we could certainly hand edit the JSON string if we wanted.   Changing the instructions in the JSON string doesn't change the data in the table: it only changes what the Image window does with that data.


Different image formats utilize different arrangements of channels within the actual image data.  Some have the red channel first, while other arrangements have the blue channel first.  No matter what channel ordering is used within the data, Manifold's Style pane allows us to specify how those channels should be assigned to red, green and blue display outputs.


Using the Style pane to say how data channels should be used does not  change the order of data channels within the actual image.   It simply reassigns how the data should be interpreted for display purposes.   If we want to change the actual order of data in the image, we should use the technique illustrated in the Example: Rearrange Channels using an Expression  topic.   In the examples below, we will use the Style pane to change the interpretation of data within the image, without actually changing the data itself.


Consider an image of the town of Exeter, in the United Kingdom.



We see the image above, zoomed in to native resolution so only a small part of the image is visible.   To see the properties for the image, we right-click on the Exeter image in the Project pane and we choose Properties in the context menu.



The properties dialog shows the Exeter image takes data from the Exeter Tiles table, from a field in that table called Tile.    The StylePixel property tells us that the image uses a fixed Value of 0 for the A or Alpha output, and, from what we can see above, it uses Channel 0 for the B or Blue output.    The nine properties we see define the image.   Other than the handful of bytes required to specify those nine properties, the image requires no space at all.     All of the data is in the table.



If we open the Exeter Tiles table we see each record contains a tile that is 128 pixels by 128 pixels in size, with a uint8x3 triplet of unsigned, eight-bit integers for each pixel.  


In the illustration above we have right-clicked the column header for the Tile field and chosen Style, to change the format for the Tile field to a format that reports the size of the tile as well as the data type of each channel and the number of channels.   The other illustrations in this topic showing image tables have also changed the Tile field format to show the data type of channels.


With the focus on the opened Exeter image window, we can click into the Style pane.



The Style pane shows a typical arrangement for an RGB image that uses three channels of data.   The table uses a uint8x3 triplet of unsigned, eight-bit integers for each pixel, providing three channels where the numeric value of each channel is a number from 0 to 255 (an unsigned, eight-bit integer can only represent integer values from 0 to 255).    There is no fourth channel so Manifold automatically assigns a fixed Value of 0 to the Alpha channel, meaning no transparency.


To see how the above arrangement that is displayed in the Style pane is written in the StylePixel property for the image, we can open the Properties pane for the Exeter image and right-click onto the value for the StylePixel property, choosing Edit in the context menu.    That opens the entire value in an editing dialog, so we can see the entire text.



The text displayed in the image above is:


{ "BGRA": { "A": { "Value": 0 }, "B": { "Channel": 0, "Max": 255, "Min": 0 }, "G": { "Channel": 1, "Max": 255, "Min": 0 }, "R": { "Channel": 2, "Max": 255, "Min": 0 } } }


We can compare that to the entries in the Style pane to see how the JSON string records what is shown in the Style pane.   



For example,  We can compare the entries for the B and A outputs to the JSON string:


"A": { "Value": 0 }, "B": { "Channel": 0, "Max": 255, "Min": 0 },


The StylePixel property says the image should use a fixed Value of 0 for the A output.    It also says the image should use Channel 0 for the B output with a minimum value of 0 and a maximum value of 255.


If we change settings in the Style pane, that simply changes the instructions written into the JSON string in the StylePixel property for the image.



For example, we can double-click into the channel settings in the Style pane to change the assignments of channels to outputs.   Instead of assigning Channels 2, 1, and 0 to outputs R, G, and B as the original arrangement had it, we can change the assignments so that Channels 1, 0, and 2 are assigned to outputs R, G and B respectfully, as seen in the illustration above.  



The result is a "false color" image, where the numbers in Channel 2 that were supposed to be powering the Red output are now powering the Blue output, the Channel 0 numbers that were supposed to be powering the Blue output are now being fed to the Green output, and the Channel 1 numbers that were supposed to be powering the Green output are now being sent to the Red output.


The numbers in the uint8x3 triplets within the tiles stored in the table are the same as they always have been.  They have not changed at all.  They are simply being sent to different outputs when the image displays those tiles.  


We can open the properties for the Exeter image and take a look at how the StylePixel property value has changed.



From what we can see of the StylePixel property, it has indeed changed the JSON text so that Channel 2 is being used for the B output.    The alteration in the instructions in the JSON string are changing the "recipe" used by the image window to know how to use the various Channel "ingredients" to create the display.

Images Require Zero Storage Space

As we can see from the above, the image component takes no storage space at all, just a handful of bytes to store the properties that tell the image what to display and how to display it.    When we Copy an image and then Paste that image to make a copy of the image, the copy is simply a copy of the image properties attached to a new image container.  



Suppose in the Project pane we click on the Exeter image, we press Ctrl-C to Copy the image, and then we press Ctrl-V to Paste the image, to make a copy called Exeter 2.   We open the new Exeter 2 image, as seen above, and we see that it is, indeed, an exact copy of the Exeter image, complete with the weird, "false color" assignment of channels to RGB outputs.


In the Project pane we can right-click on the Exeter 2 image and choose Properties to see the properties dialog for the image.  



We see that the StylePixel property value is the same JSON string that was in the Exeter image's StylePixel property, where instead of the original use of Channel 0 for the B output it uses Channel 2 for the B output.     If we like, we can change the JSON string so that it tells the image to use the original assignment of channels to outputs.  


Doing that is easy.   We launch this user manual in a browser and then we highlight and Copy the string below, which is the original JSON string that was used for the StylePixel property, before we changed assignments to weird, "false color" assignments:


{ "BGRA": { "A": { "Value": 0 }, "B": { "Channel": 0, "Max": 255, "Min": 0 }, "G": { "Channel": 1, "Max": 255, "Min": 0 }, "R": { "Channel": 2, "Max": 255, "Min": 0 } } }


The JSON string is nothing but plain, ordinary text, so we can Copy it from a browser, from a text file opened in Notepad, from a cell in a table somewhere or from any other text source.  Just like any other text, once we Copy it to the Windows clipboard we can then Paste it wherever we want.  



For example, we can right-click onto the value cell for the StylePixel property of the Exeter 2  image and choose Paste, to paste that string into that cell.   We press OK and that applies the change to the image.



The Exeter 2 image now uses the original JSON instructions to know how to use the numbers it finds in Channels 2, 1, and 0:  It uses those numbers to drive the R, G and B outputs, respectively.  That is what the original creators of the image intended, so the colors in the image appear, as intended, in natural, realistic colors.


In the Project pane we Copy the Exeter 2 image and then Paste, to create an Exeter 3 image.



As expected, the Exeter 3 image is an exact copy of the Exeter 2 image.   It uses the same tiles from the same table, displaying those tiles using exactly the same Style instructions as the Exeter 2 image.



We can change the Style instructions used by the Exeter 3 image to send a fixed Value of to the R, B and A outputs and to power the G output using numbers from Channel 1.  



Using a fixed value of 0 to power the Red and Blue channels means to turn those channels completely off, showing the image as if it only had a single Green channel.


We Copy the Exeter 2 image and Paste it again, to create an Exeter 4 image.



For this image, we will use significantly different Style instructions.



Instead of powering each R, G, B, and A output by either numbers from a channel or a fixed value, we will power them using a palette where the numbers in Channel 1 are used as a look-up index into color values assigned by intervals.    We use 5 interval Breaks and a method of equal count, using interpolate to fill colors from interval grayscale colors that range from black to white.



The result is what appears to be a grayscale image.   The Red, Green, and Blue outputs are being powered by triplets of numbers specified by the palette, computed on the fly using an interpolation between the five colors specified in the intervals.   When the same number appears for Red, Green, and Blue the result is a shade of gray, from black to white.



Instead of using interpolate we can change the Fill method to closest lower value.      Press Update Style.



That "quantizes" colors assigned to pixels so only colors from the four lower value intervals are used, resulting in a posterized effect.



We change the colors so the second interval is a shade of orange and two of the intervals use transparent color.   We also go back to using interpolate.   Press Update Style.




In the above illustration we have used the Layers pane to turn off the white, background of the image, so that wherever there are transparent pixels we can see the checkerboard pattern background that indicates transparency.   Note how not only do colors interpolate into each other but also how colors interpolate with transparency to form regions of partial transparency.



We can create a map and drag and drop the Exeter 4 image and the Exeter 2 image into the map.   This shows the tremendous power of the idea that an image does not itself contain data but simply displays data using whatever Style instructions it is told to use.   The map shows two images, both of which display pixels from exactly the same tiles in the same table, but the two images display those pixels very differently.   The lower, Exeter 2 image shows the pixels in natural color.   The upper, Exeter 4 image shows the pixels either not at all in regions where they are fully transparent or in palette colors, or in a blend between fully transparent pixels and partially-transparent colored pixels.



With the focus on the Exeter 4 layer we can choose an orange-yellow color for the middle interval.  In the Options tab we can turn on shading and use a Z scale of 0.1.   Press Update Style.




The Exeter 4 image window shows the effect in that image, with the Map window showing the combined effect.   Using hill shading, either with single channel images or using a single channel of a multi-channel image, is a way to enhance visual effects.   The particular example above is purely artificial, but it shows how easy the effect is to apply.



Taking a look at the Project pane we see there is only one table with data in it.  All four images display the same data from the same table, as does the map, which has two of the images as layers.  We could create one hundred images and maps based on the same Exeter Tiles table, each of which showed a different display using different Style, and not increase the stored size of the project at all.


"RGB" or "BGR"? - The universal slang for RGB images is, of course, "RGB images."  That slang refers to the use of Red, Green and Blue display outputs and does not arise from the literal order of data in the triplets of numbers that specify red data, green data and blue data.  Most users working with RGB images in graphics arts editing do not know and do not care what order channels come in, but when we are extracting data or mixing channels for multichannel remote-sensed images we must care about such technical details.  


Almost always the order of data in a triplet of image data numbers for a pixel is that blue comes first, green second and red third.  From a data perspective, the channel ordering is almost always BGR but such images nonetheless are referred to as "RGB" images.  


See Also



Images and Channels


Palette Images




Style: Drawings


Style: Labels


Style: Images


Style: Autocontrast


Style: Invisible Pixels


Style: Contouring using Colors


Style: Hill Shading


Style: Palettes


Example: Create Two Images From One Table - More than one image can show data from the same table, including from the same tile field.


Example: Change the Contrast of an Image - In this example we use the Style pane to change the contrast of an image.


Example: Using the Assign Channels Button - The Assign Channels button in the Style pane for images allows us to assign channels to the standard three Red, Green, and Blue display outputs using frequently-desired arrangements.   The button provides a short cut way to assign all channels at once instead of doing each channel individually.


Example: Assign Channels - How to use the Style pane for images to assign channels to display outputs such as R, G, B or A.  This topic shows examples of channel combinations and the visual results.


Example: Display an NAIP Four Band Image as Color Infrared (CIR) - How to use the Style pane for images to re-assign channels in a four band NAIP image to produce a Color Infrared (CIR) image display.


Example: Set Image Transparency using Alpha - The A row in the Style pane allows us to specify what transparency we want to apply to the image, either by applying the same value for A for all pixels or by using one of the other channels to also control the A value.


Example: Autocontrast and Hill Shading Images using Style - This example shows how the Style pane can hill shade an image using the values of pixels as heights and generating shadows as if the Sun were located at the specified azimuth and altitude.   This capability is used most frequently with raster images to give an impression of three dimensionality in cases where the values of pixels represent terrain elevations.


Example: Style Applied to an Image Server Image - Because the Style pane simply changes the way an image is displayed and not the data, it can operate on read-only data served by various web servers such as WMS REST servers.    In this example we look at every detail of creating a data source using an image server and then manipulating the appearance of the display with Style.  We will connect to a WMS server that provides LiDAR data in various forms, including as terrain elevation.


SQL Example: Create NDVI Displays - How to create a query that creates an NDVI display from a four-band NAIP image, with tips and tricks on how to copy and paste existing information to get the result we want.


Example: Rearrange Channels using an Expression - We use a simple expression in the Transform pane to rearrange the order of channels within the data.


Example: Import CTG Grid Cell File and Style - A companion topic to the Example: Import GIRAS vector LULC File and Style topic.  We import a CTG LULC Grid Cell file containing raster data showing land use and land cover and then we use Style to provide a more understandable display.


Example: Import DDF SDTS DEM Raster File -  We import a raster data terrain elevation surface from USGS SDTS format using DDF files.


Example: Import GIRAS vector LULC File and Style - A companion topic to the Example: Import CTG Grid Cell File and Style topic.   We import a USGS land use file in GIRAS vector format and then we use Style to provide a more understandable display.