Skip to main content
Question

How to calculate an NDVI with FME?


fmelizard
Safer
Forum|alt.badge.img+18
Hi List,

 

I have a four band raster (geotiff) that I need to use to create an NDVI.

 

 

Basically I need to do the following maths on every cell of the raster:

 

 

(Band4 - Band1) / (Band4 + Band1)

 

 

How do I do this with FME? I can't seem to figure out the whole "cell calculator" thing it has going on.

 

 

There's a FME case study (http://blog.safe.com/2013/09/a-perfect-pairing-fme-and-rapideye-imagery-in-la-rioja-spain/) which mentions using FME to create an NDVI but doesn't show how that part was done. :-/

 

 

Thoughts welcome.

 

Thanks!

 

Jonathan

9 replies

gio
Contributor
Forum|alt.badge.img+15
  • Contributor
  • May 28, 2014
rastercellexpressionevaluator is used to do cell calculations

david_r
Celebrity
  • May 28, 2014
Hi,

 

 

you can use the RasterExpressionEvaluator with an expression like "(A[3] - A[0]) / (A[3] + A[0])". Note: Band numbering is 0-based.

 

 

See the RasterExpressionEvaluator (http://docs.safe.com/fme/html/FME_Transformers/Default.htm#Transformers/rasterexpressionevaluator.htm) help for more info, in particular under the "Band expression(s)".

 

 

David

 

 


fmelizard
Safer
Forum|alt.badge.img+18
  • Author
  • Safer
  • May 28, 2014
Hi David,

 

Yep, I found that and got that equation after Gio's response (thanks Gio!).

 

 

Unfortunately it's still not working. The output is a couple hundred kB - the input is over 100MB!

 

 

So I've done some further testing.

 

The process is just fine doing the two separate steps:

 

 

(A[3] - A[0])

 

(A[3] + A[0])

 

However, when I try and join them together with the divide I get the invalid result.

 

 

I now have three RasterExpressionEvaluators (REE). One each for the first two parts, and a third which takes in the two rasters and divides. However, even with this:

 

floor((A[0] / B[0]) * 255)

 

 

It still refuses to create a valid result. As you can see, it should be creating an int of value 0-255 (I'm putting it into a UInt32 to be safe!). Even trying to output to Real32 I was getting the same output.

 

 

Anyone have any insights as to why this is happening? Can the REE not perform divides?

 

 

Thanks,

 

Jonathan

 

 


takashi
Influencer
  • May 28, 2014
Hi Jonathan,

 

 

Possibly it's an issue on dividing integer values. int / int = int.

 

How about multiplying either numerator or denominator by 1.0?

 

e.g.

 

floor(1.0*A[0] / B[0] *255)

 

 

Takashi

fmelizard
Safer
Forum|alt.badge.img+18
  • Author
  • Safer
  • May 28, 2014
Hi Takashi,

 

That did it thanks. This seems like odd behaviour so I'll raise it with safe.

 

 

Cheers,

 

Jonathan

takashi
Influencer
  • May 28, 2014
See the help documentation on the ExpressionEvaluator. There is description about converting between integer and floating point in an expression.

 

http://docs.safe.com/fme/html/FME_Transformers/Default.htm#Transformers/expressionevaluator.htm

 


gio
Contributor
Forum|alt.badge.img+15
  • Contributor
  • June 2, 2014
It's not an issue.

 

You just need to always take it into account.

 

Would be bad if 1.0 would be 1. For a lot of reasons.

 

 

There are some knoledgebase pages i think on this. ALso in most scriptingcommunities.

 

 

I like to do things like testing for x/4=x/4.0, or whatever number. The most easy way to make periodics!

 

 


fmelizard
Safer
Forum|alt.badge.img+18
  • Author
  • Safer
  • June 2, 2014
Hi Gio,

 

Good insite, but my problem is mostly that the failure is transparent. FME is failing and giving no errors/warnings as to why.

david_r
Celebrity
  • June 2, 2014
Hi,

 

 

this is not a failure as such, it is how many scripting langues (such as TCL and Python, on which parts of FME is built) was designed: A division will always return the same type as the operands. So unless you force the operands to floats (as you do when you multiply with a float), a division of two integers will always return an integer: 1 / 2 = 0.

 

 

It can, however, be quite confusing when you encounter it for the first time :-) Even Guido van Rossum, the inventor of Python, admits it is too confusing and regrets having done it that way (see http://python-history.blogspot.ch/2009/03/problem-with-integer-division.html). Incidentally, this is one of the fundamental behaviors to change in Python 3, in which you would get 1 / 2 = 0.5 without any further ado.

 

 

David

Reply


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings