RasterExpressionEvaluator

From fmepedia

RasterExpressionEvaluator is a Workbench Transformer


Table of contents



Description

RasterExpressionEvaluator is a transformer that evaluates expressions on each cell in a raster, such as algebraic operations or conditional statements.




Examples

Note that you need FME2009 or newer in order to run these examples.

The examples include simple calculations and conditions with one input raster as well as the operations with two inputs.


Simple Calculation Examples

Inverting Colors

attachment 'RGBColorInverter.fmw|This example' not found demonstrates how to invert images with the following band interpretation list and expression:

RED8;GREEN8;BLUE8
255-A[0];255-A[1];255-A[2]

image 'negative.png' not found

image 'inverted.png' not found

The images show Heritage Mountain Elementary School and the surrounding area in Google Earth

  • attachment 'RGBColorInverter.fmw|Workspace' not found
  • attachment 'negative.png|Source data' not found
  • attachment 'inverted.png|Result' not found
Brightness Correction

If attachment 'BrightnessSource.jpg|an image is too dark' not found, we can attachment 'BrightnessCorrection.fmw|boost brightness' not found with the following simple expression:

A[0]*1.5;A[1]*1.5;A[2]*1.5

image 'BrightnessSourceResized.jpg' not found

image 'BrightnessCorrectedResized.jpg' not found

Port Moody, Greater Vancouver

Note that this method should be used cautiously - if there are bright areas in the image, they will reach or exceed the maximum value (255 in my example), which will make them purely white (255, 255, 255 in case of RGB24), and the information in those areas will be lost.

  • attachment 'BrightnessCorrection.fmw|Workspace' not found
  • attachment 'BrightnessSource.jpg|Source data' not found
  • attachment 'BrightnessCorrected.jpg|Result' not found
Color Correction

If one of the colors on attachment 'ColorCorrection.jpg|an image seems to dominate' not found over the others, we can attachment 'ColorCorrection.fmw|change only one band' not found (or apply different coefficients to different bands):

A[0];A[1]/1.2;A[2]

image 'ColorCorrectionResized.jpg' not found

image 'ColorCorrectedResized.jpg' not found

  • attachment 'ColorCorrection.fmw|Workspace' not found
  • attachment 'ColorCorrection.jpg|Source data' not found
  • attachment 'ColorCorrected.jpg|Result' not found
Color to Grayscale Conversion

Most internet sources suggest the following formula for attachment 'infraredRGB.jpg|color' not found to grayscale attachment 'RGB2Grayscale.fmw|conversion' not found (and many sources also mention that depending on the image it may vary):

0.2989*A[0] + 0.5870*A[1] + 0.1140*A[2]

image 'InfraredRGBResized.jpg' not found

image 'GrayscaleResized.jpg' not found

The workspace also makes an image based on calculating average values,

0.3333*A[0] + 0.3333*A[1] + 0.3333*A[2]

but the first formula gives better contrast.

  • attachment 'RGB2Grayscale.fmw|Workspace' not found
  • attachment 'infraredRGB.jpg|Source data' not found
  • attachment 'Grayscale.jpg|Result' not found
Unit Conversion

attachment 'UnitConversion.fmw|Conversion between all kinds of units' not found is a very natural operation for RasterExpressionEvaluator. In this example we take attachment '092g02_0101_deme.dem|a numeric raster representing DEM in meters' not found and convert units into attachment 'USGSDEM.dem|feet DEM' not found (band interpretation is INT32):

INT32
A[0]/0.3048

If we inspect results in Visualizer, we will see the results of conversion:

MetersFeet
image 'unitsMeters.png' not foundimage 'unitsFeet.png' not found
  • attachment 'UnitConversion.fmw|Workspace' not found
  • attachment '092g02_0101_deme.dem|Source data' not found
  • attachment 'USGSDEM.dem|Result' not found



Condition Examples

Color classification

With a simple condition attachment 'GreenFilter.fmw|we can compare' not found cell values in different bands to classify colors. For example, we can find all green cells representing parks. Note that in this workspace we use only one band in the band interpretation list, but we still can use values from all bands:

RED8
if (A[1]-A[0]>5 && A[1]-A[2]>5, 200, 255)

This expression sets cell values to 200 where green is bigger than red and blue more than by 5. The rest of the cells gets the value of 255.

image 'GreenFilterResized.png' not found

image 'GreenFilteredResized.png' not found

Note that if we simply compare green with red and blue as follows:

if (A[1]>A[0] && A[1]>A[2], 200, 255)

then we will select not only green cells but also cells that are rather close to gray colors.

  • attachment 'GreenFilter.fmw|Workspace' not found
  • attachment 'GreenFilter.png|Source data' not found
  • attachment 'GreenFiltered.png|Result' not found
Update to road centerline extractor example

The example above shows how much simpler my another example - road centerline extractor could be with this new transformer. The expression finds colors where all bands have similar values (white/gray/black) used for roads, their edges, and road labels) or colors that are rather yellowish - red and green band values are close, and they are quite bigger than blue band.

if ((abs(A[0]-A[1])<=3 && abs(A[0]-A[2])<=3) || (abs(A[0]-A[1])<=4 && abs(A[0]-A[2])>10) , 200, 255)

The expression gives the following result:

image 'RoadFilterResized.png' not found

image 'RoadFilteredResized.png' not found

  • attachment 'RoadsOnly.fmw|Workspace' not found
  • attachment 'RoadFilter.png|Source data' not found
  • attachment 'RoadFiltered.png|Result' not found



Two-Input Examples

Change Detection

The idea of change detection is quite simple - we check whether the cell values of the new image are different from the the cell values of the original image. In this example I had to make one extra step to set cells containing data (not equal to 255) in both images to the same value (200 in this case):

if (A[0]<255, 200, 255)

After that the comparison goes as follows:

For deleted:
if(A[0]!=B[0] && A[0]<255, 0, A[0]) 
For added:
if(A[0]!=B[0] && B[0]<255, 0, A[0]) 

If we want to combine results together, but still make visible what was added, deleted, or stayed unchanged, we can combine the two bands together. However, they both have the same interpretation of RED8. We can change it to GREEN8 and BLUE8, and add the missing RED8. As result, the bands will be ordered as GREEN8;BLUE8;RED8. We can use RasterBandOrderer or reorder bands with RasterExpressionEvaluator, which fits better for this page:

A[2];A[0];A[1]

The source and the revised data as well as the results of comparison are shown below:

OriginalRevised

image 'SAIF.png' not found

image 'SAFE.png' not found

DeletedAdded

image 'deleted.png' not found

image 'added.png' not found

Added/Deleted
image 'added_deleted.png' not found
  • attachment 'ChangeDetection.fmw|Workspace' not found
  • attachment 'SAIF.png|Source data 1' not found
  • attachment 'SAFE.png|Source data 2' not found
  • attachment 'added.png|Result 1' not found
  • attachment 'deleted.png|Result 2' not found
  • attachment 'added_deleted.png|Result 3' not found
Adding Data

Two rasters can be combined in a way when one raster supplies a certain layer of information - for example, only a road network (surface and labels), and another raster works as a background.

Classifying only road related cells from the raster map requires quite a complex condition - it should consider major routes (yellow), regular roads (white), and labels on both kinds of roads (labels have different colors). If if the cell satisfies the condition, we can take it from the road raster, otherwise we use the background raster:

if((B[0]==B[1] && B[0]==B[2]) || (abs(B[0]-B[1])<=5 && (B[0]-B[2]>6 && B[0]<100) || (B[0]-B[2]>20 && B[0]>100)), B[0], A[0]);
if((B[0]==B[1] && B[0]==B[2]) || (abs(B[0]-B[1])<=5 && (B[0]-B[2]>6 && B[0]<100) || (B[0]-B[2]>20 && B[0]>100)), B[1], A[1]);
if((B[0]==B[1] && B[0]==B[2]) || (abs(B[0]-B[1])<=5 && (B[0]-B[2]>6 && B[0]<100) || (B[0]-B[2]>20 && B[0]>100)), B[2], A[2])

This is how the result looks:

RoadsBackground

image 'AddLayerRoads.png' not found

image 'AddLayerBackground.jpg' not found

Combined
image 'AddLayerCombined.jpg' not found

You may note that the condition stays the same for all three bands, and only index of the band is changing in the last portion of the statement. We can redesign our workspace in a way that we will need only one condition, but it requires much more transformers.

  • attachment 'AddingLayer.fmw|Workspace' not found
  • attachment 'AddingLayer.fmw|Workspace with one condition' not found
  • attachment 'background.tif|Source data 1' not found
  • attachment 'roads.png|Source data 2' not found
  • attachment 'Combined.tif|Result' not found
Semitransparency

When we combine two rasters it's quite easy to achieve semitransparency of one of the rasters - we simply add to the existing value of the background only a small portion of the raster we want to see semitransparent:

if(B[0]==0,A[0],A[0]+B[0]/5);if(B[1]==0,A[1],A[1]+B[1]/2);if(B[2]==0,A[2],A[2]+B[2]/5)

As result of this calculation, the original pixels of the aerial image that are covered by the park areas get an addition equal to one fifth of the park pixel value, and this gives us semitransparent look:

ParksBackground

image 'TranspParks.png' not found

image 'TranspBackground.jpg' not found

Combined
image 'TranspCombined.jpg' not found
  • attachment 'Semitransparency.fmw|Workspace' not found
  • attachment 'AUSTIN_EAST-NEA3_resampled.tif|Source data 1' not found
  • attachment 'MI_parks.zip|Source data 2' not found
  • attachment 'SemitransparentParks.tif|Result' not found



Using Attribute Value Examples

The expressions in RasterExpressionEvaluator may contain attribute values; in order to use them we have to use the following syntax:

A:attribute_name

Below is an expression with an attribute value:

(A[0]*A:i/10.0 + B[0]*((11-B:i)/10.0));
(A[1]*A:i/10.0 + B[1]*((11-B:i)/10.0));
(A[2]*A:i/10.0 + B[2]*((11-B:i)/10.0));
if(A[3]==0 || B[3]==0,0,255)

attachment 'DonDaleMorph.fmw|The workspace that uses this expression' not found has a loop, which, after ten iterations gives us the following images:

image 'morph_1.png' not found image 'morph_2.png' not found image 'morph_3.png' not found image 'morph_4.png' not found image 'morph_5.png' not found
image 'morph_6.png' not found image 'morph_7.png' not found image 'morph_8.png' not found image 'morph_9.png' not found image 'morph_10.png' not found

Or, assembled into an animated sequence:

image 'morph.gif' not found

  • attachment 'DonDaleMorph.fmw|workspace' not found
  • attachment 'dale.png|Source data (Dale)' not found
  • attachment 'don.png|Source data (Don)' not found

Elevation Zoning Scenario

This example combines rasters of two types - attachment '092g07_0100_demw.dem|a numeric DEM raster' not found and attachment 'map_ref.png|a color RGB raster' not found (don't forget attachment 'map_ref.wld|the worldfile' not found). Besides, it shows how to bring the rasters to the same size in pixels - otherwise RasterExpressionEvaluator won't work.

attachment 'elevationZoning.fmw|The workspace' not found demonstrates an elevation zoning scenario. Depending on values in DEM and zoning interval (zone height), it creates two to four different zones - low, average, high and very high elevations, and shows them on a road map taken from Google Maps.

attachment 'ElevationZoning.png|The resulting map' not found can help you choosing the right vehicle - if you live in red zone, in winter you need four wheel drive or at least perfect tires, in green zone you should be fine even with old tires (perhaps, you can feel some sad memories in my voice).

DEMRoad Map

image 'smallDEM.png' not found

image 'smallRoadMap.png' not found

Elevation Zoning
image 'smallZoning.png' not found

After two rasters are brought to the same size (see the workspace comments), RasterExpressionEvaluators start their job.

In the first expression transformer the road map is changed to have grayscale look, although we still need it in RGB interpretation for two reasons - first, we want to see zones in color, and second - the map looks nicer, when ocean is left blue:

if(A[0]==153 && A[1]==179 && A[2]==204, A[0], 0.2989*A[0] + 0.5870*A[1] + 0.1140*A[2]);
if(A[0]==153 && A[1]==179 && A[2]==204, A[1], 0.2989*A[0] + 0.5870*A[1] + 0.1140*A[2]);
if(A[0]==153 && A[1]==179 && A[2]==204, A[2], 0.2989*A[0] + 0.5870*A[1] + 0.1140*A[2])

The second RasterExpressionEvaluator classifies the DEM. It also uses an attribute _height, which can be changed from its default value (50 meters) to any integer value in the range between 20 to 100 meters. Press Ctrl+R in order to change this parameter.

if(A[0]==0,0,A[0]/A:_height+1)

The last ExpressionEvaluator changes red and green bands of the A raster (road map) according to zone number stored in raster B (classified DEM). The higher the elevation, the more red we add. Green is boosted for lower elevation zones:

if(B[0]<=2,A[0], if(B[0]==3 || B[0]==4, A[0]*1.1, if(B[0]==5 || B[0]==6, A[0]*1.3, A[0]*1.5)));
if(B[0]==0 || B[0]==5 || B[0]==6, A[1], if(B[0]==1 || B[0]==2,A[1]*1.3, if(B[0]>=7, A[1]/1.1, A[1]*1.1)));
A[2]
  • attachment 'elevationZoning.fmw|workspace' not found
  • attachment '092g07_0100_demw.dem|source data 1 (DEM)' not found
  • attachment 'map_ref.png|source data 2 (road map)' not found
  • attachment 'map_ref.wld|worldfile for road map' not found
User Comments Add a new comment