Question

Mix raster using Multiply and controling min-max of the band

  • 19 September 2018
  • 15 replies
  • 8 views

Badge +14
  • Contributor
  • 120 replies

I would like to create a terrain shadow by mixing Hill shade and Slope. The starting point is a DEM-file. I have used the RasterHillShader and the RasterSlopeCalculator to generate the basics. But in the next step I would like to mix these two by adjusting the min and max values and multiplying one layer on top of the other. Are there any transformers that could do this?

I am guessing that the RasterExpressionEvaluator might be able to do the min-max limit? If so I could need some help with the correct syntax.

If there is some way to adjust contrast and add some gausian blur that would be a welcome bonus.


15 replies

Badge +2

Hi @aron,

Depending on how exactly you want to adjust the min-max values the RasterBandInterpretationCoercer may also be of interest to you. Alternatively if you can provide a sample file and specify how you want the values to be altered then it will make it easier for someone from the community to help you put together the correct syntax. This article may also help you with that: https://knowledge.safe.com/articles/1272/simple-examples-using-the-rasterexpressionevaluato.html

For the multiplication part of your process the RasterCellValueCalculator sounds most appropriate. You can also add a Gaussian Blur using the RasterConvolver.

Badge +22

Assuming you want to adjust the min/max values by performing a stretch other than RasterBandInterpretationCoercer Scale by Data Values, you can perform an arbitrary linear stretch with the following equation:

 

 

x' = u + (v-u)/(b-a)*(x-a)

 

where

 

a: minimum value of the original range

 

b: maximim value of the original range

 

u: minimum value of the new range

 

v: maximim value of the new range

 

x: original pixel value

 

x': new pixel value

In the rasterExpressionEvaluator, assuming your ranges were stored as attributes it would look something like

 

@Value(A:_newMin)+(@Value(A:_newMax-@Value(A:_newMin))/(@Value(A:oldMax)-@Value(A:oldMin))*(A[0]-@Value(A:oldMin))

Badge +14

Assuming you want to adjust the min/max values by performing a stretch other than RasterBandInterpretationCoercer Scale by Data Values, you can perform an arbitrary linear stretch with the following equation:

 

 

x' = u + (v-u)/(b-a)*(x-a)

 

where

 

a: minimum value of the original range

 

b: maximim value of the original range

 

u: minimum value of the new range

 

v: maximim value of the new range

 

x: original pixel value

 

x': new pixel value

In the rasterExpressionEvaluator, assuming your ranges were stored as attributes it would look something like

 

@Value(A:_newMin)+(@Value(A:_newMax-@Value(A:_newMin))/(@Value(A:oldMax)-@Value(A:oldMin))*(A[0]-@Value(A:oldMin))

Thank you @jdh!

 

 

I got this to work. But reading my qustion again I realize I was unclear in my description of what I wanted to achieve, sorry. What I really want to do is to filter out ranges from the band. Zero heights, like sea level, come out as grey from the hillshader and I would like to filter out the light greys (and also some of the darker in the slopes). The formula you provided compresses the range, so I still get a faint grey.

 

 

How would I go about setting a min and max that exludes everything outside that range?

 

Userlevel 2
Badge +17

Assuming you want to adjust the min/max values by performing a stretch other than RasterBandInterpretationCoercer Scale by Data Values, you can perform an arbitrary linear stretch with the following equation:

 

 

x' = u + (v-u)/(b-a)*(x-a)

 

where

 

a: minimum value of the original range

 

b: maximim value of the original range

 

u: minimum value of the new range

 

v: maximim value of the new range

 

x: original pixel value

 

x': new pixel value

In the rasterExpressionEvaluator, assuming your ranges were stored as attributes it would look something like

 

@Value(A:_newMin)+(@Value(A:_newMax-@Value(A:_newMin))/(@Value(A:oldMax)-@Value(A:oldMin))*(A[0]-@Value(A:oldMin))

Hi @aron, if a cell value was less (greater) than the minimum (maximum), do you need to just set the minimum (maximum) to the cell?
Badge +14
Hi @aron, if a cell value was less (greater) than the minimum (maximum), do you need to just set the minimum (maximum) to the cell?
Hi @takashi,

 

Ideally I would like to do a similar thing to what in QGIS is called Contrast enhancement, "Stretch to minmax". I have no idea what this does under the hood but it produces nicer borders between high and low contrast areas.

 

Badge +22
Thank you @jdh!

 

 

I got this to work. But reading my qustion again I realize I was unclear in my description of what I wanted to achieve, sorry. What I really want to do is to filter out ranges from the band. Zero heights, like sea level, come out as grey from the hillshader and I would like to filter out the light greys (and also some of the darker in the slopes). The formula you provided compresses the range, so I still get a faint grey.

 

 

How would I go about setting a min and max that exludes everything outside that range?

 

a,b is the original range you want to stretch, not necessarily the range of the original data.

 

Say you had elevation between -10 and 5000, and you want to stretch that into 0-255 UINT, but you only wanted elevations between 100 and 2000. If you set a to 100 and b to 2000, then everything between -10 and 100 would become zero, and everything over 2000 would be 255 and the rest would be stretched between.

 

 

 

Badge +22
Hi @aron, if a cell value was less (greater) than the minimum (maximum), do you need to just set the minimum (maximum) to the cell?
@aron if all you want is a stretch to minmax, then use the RasterBandInterpretaionCoercer in mode stretch by data values.

 

Badge +14
@aron if all you want is a stretch to minmax, then use the RasterBandInterpretaionCoercer in mode stretch by data values.

 

@jdh

 

I had a look at the RasterBandInterpretaionCoercer at a very early stage but discarded it beacuse I could not find a way to set new min-max values. And I can not find the stretch by data value option anywhere in it. *scratching head*

 

 

Badge +22
@jdh

 

I had a look at the RasterBandInterpretaionCoercer at a very early stage but discarded it beacuse I could not find a way to set new min-max values. And I can not find the stretch by data value option anywhere in it. *scratching head*

 

 

The new min-max is the range of the Destination Interpretation Type. Ex. UInt8 would be 0-255, Int8 -128-127, etc.

 

 

In the Convert from Color|Numeric to Numeric parameters there are four options in the drop down menus, one of them is Scale by data values.
Userlevel 2
Badge +17

Assuming you want to adjust the min/max values by performing a stretch other than RasterBandInterpretationCoercer Scale by Data Values,  you can perform an arbitrary linear stretch with the following equation: 

 

 

x' = u + (v-u)/(b-a)*(x-a)

 

where 

 

a: minimum value of the original range

 

b: maximim value of the original range

 

u: minimum value of the new range

 

v: maximim value of the new range

 

x: original pixel value

 

x': new pixel value

In the rasterExpressionEvaluator, assuming your ranges were stored as attributes it would look something like

 

@Value(A:_newMin)+(@Value(A:_newMax-@Value(A:_newMin))/(@Value(A:oldMax)-@Value(A:oldMin))*(A[0]-@Value(A:oldMin))

I think this expression suggested by @jdh performs the "Stretch to MinMax" operation. I'm unclear what's wrong.

 

x' = u + (v-u)/(b-a)*(x-a)
Badge +14

Hi @hollyatsafe, @takashi & @jdh,

Thank you all for your advice. I have got most of this working as I wanted now. The only thing I have not figured out is the multiplying of slope and hillshade. I do not get the results I wish in FME. If I save slope and hill as two TIF-files and multiply them in Photoshop they look the way I want, neatly overlayed with details. But when I use the RasterCellValueCalculator it turns goes full whiteout, and all that remains are a few smal patches where the very darkest shades where. What am I doing wrong here?

Included a screen grab of the result I am after.

multiply-terrainshadow.fmw

Userlevel 2
Badge +17

Hi @hollyatsafe, @takashi & @jdh,

Thank you all for your advice. I have got most of this working as I wanted now. The only thing I have not figured out is the multiplying of slope and hillshade. I do not get the results I wish in FME. If I save slope and hill as two TIF-files and multiply them in Photoshop they look the way I want, neatly overlayed with details. But when I use the RasterCellValueCalculator it turns goes full whiteout, and all that remains are a few smal patches where the very darkest shades where. What am I doing wrong here?

Included a screen grab of the result I am after.

multiply-terrainshadow.fmw

If you set "Two Rasters" to the Mode parameter in the RasterExpressionEvaluator, the "B" input port would be added to the transformer's interface. You can then enter a pair of rasters to the transformer via "A" and "B" ports, and perform multiplying, as in:

 

Userlevel 2
Badge +17

Hi @hollyatsafe, @takashi & @jdh,

Thank you all for your advice. I have got most of this working as I wanted now. The only thing I have not figured out is the multiplying of slope and hillshade. I do not get the results I wish in FME. If I save slope and hill as two TIF-files and multiply them in Photoshop they look the way I want, neatly overlayed with details. But when I use the RasterCellValueCalculator it turns goes full whiteout, and all that remains are a few smal patches where the very darkest shades where. What am I doing wrong here?

Included a screen grab of the result I am after.

multiply-terrainshadow.fmw

Ah, you did the operation using the RasterCellValueCalculator already. Both results would be identical and the result should be correct theoretically if the requiement was just to multiply A with B.

 

I don't know what operation Photoshop performs. Is that really just the operation of A x B?

 

 

Badge +2
Ah, you did the operation using the RasterCellValueCalculator already. Both results would be identical and the result should be correct theoretically if the requiement was just to multiply A with B.

 

I don't know what operation Photoshop performs. Is that really just the operation of A x B?

 

 

Hi @aron

 

If this is the operation you are referring to in Photoshop (https://www.photoshopessentials.com/photo-editing/layer-blend-modes/multiply/) then it looks like it is doing more than just multiplying the corresponding cell values together - as is in FME.

 

"Photoshop takes the colors from the layer that's set to the Multiply blend mode and multiplies them by the colors on the layer(s) below it, then divides them by 255 to give us the result."

 

So in FME you will need to do (A[0]*B[0])/255 to produce the same result.
Badge +14
Hi @aron

 

If this is the operation you are referring to in Photoshop (https://www.photoshopessentials.com/photo-editing/layer-blend-modes/multiply/) then it looks like it is doing more than just multiplying the corresponding cell values together - as is in FME.

 

"Photoshop takes the colors from the layer that's set to the Multiply blend mode and multiplies them by the colors on the layer(s) below it, then divides them by 255 to give us the result."

 

So in FME you will need to do (A[0]*B[0])/255 to produce the same result.
Awesome @hollyatsafe!

 

 

That was exactly the result I was after! I lernt a lot from this.

 

Reply