Comparing 2 NDVI images

Hi, I have downloaded two Sentinel-2 images (MSI) with a time difference between the 2 downloads. I created the NDVI from them (Bands 8 and 4)-OK. I want to compare the 2 images to find the differences between the them. How to perform ? Thx.

before calculating the difference in NDVI you should calibrate the scenes first.
You can do this with the sen2cor plugin.

Then calculate the NDVI for both scenes

Stack the two NDVI rasters (Raster > Geometric Operations > Collocation)

Then you can open the band maths of the collocated product and subtract the NDVI from the second scene from the NDVI of the first scene. This shows you the total increase/decrease at each pixel.
If you want the relative change (in %) perform a division instead.

1 Like

Thx. ABraun. I will explore the sen2cor plugin/

Hi,

I would like to comparise two NDVI images of the same area, acquired from Sentinel 2 Level 2 products.
After collocation, when I try to open any band in collocated product, the error shows up:

_Failed to open image view. _
expression: Undefined symbol ā€˜ndvi_flags_M.NDVI_ARITHMETIC_Mā€™.

There are 5 bands in collocated product: ndvi_M, ndvi_flags_M, ndvi_S, ndvi_flags_S, collocation_flags. The same error for each of them.

Besides that error, what expression would you recommend to use in ā€˜band mathsā€™ later, to show the differences between two ndviā€™s? Something like (ndvi_M-ndvi_S)/(ndvi_M) ?

Thanks in advance, Wojciech

This happens because of a bug in the collocation. You can work around by right-clicking on the band and select Properties. Remove the valid pixel expression. Afterwards, it should work.

Thank you for your reply. The valid pixel expression was present only in ndvi_S, ndvi_flags_S bands. After making it empty the error still shows up :confused:

I can paste error logs here If it can help to solve the problem:

org.esa.snap.core.jexp.ParseException: Undefined symbol ā€˜ndvi_flags_M.NDVI_ARITHMETIC_Mā€™.
at org.esa.snap.core.jexp.impl.ParserImpl.reportError(ParserImpl.java:1036)
at org.esa.snap.core.jexp.impl.ParserImpl.parseCallOrRef(ParserImpl.java:722)
at org.esa.snap.core.jexp.impl.ParserImpl.parsePrimary(ParserImpl.java:678)
at org.esa.snap.core.jexp.impl.ParserImpl.parsePostfix(ParserImpl.java:637)
at org.esa.snap.core.jexp.impl.ParserImpl.parseUnary(ParserImpl.java:624)
at org.esa.snap.core.jexp.impl.ParserImpl.parseMul(ParserImpl.java:530)
at org.esa.snap.core.jexp.impl.ParserImpl.parseAdd(ParserImpl.java:487)
at org.esa.snap.core.jexp.impl.ParserImpl.parseBitwiseAnd(ParserImpl.java:461)
at org.esa.snap.core.jexp.impl.ParserImpl.parseBitwiseXOr(ParserImpl.java:434)
at org.esa.snap.core.jexp.impl.ParserImpl.parseBitwiseOr(ParserImpl.java:408)
at org.esa.snap.core.jexp.impl.ParserImpl.parseComparison(ParserImpl.java:319)
at org.esa.snap.core.jexp.impl.ParserImpl.parseLogicalAnd(ParserImpl.java:286)
at org.esa.snap.core.jexp.impl.ParserImpl.parseLogicalOr(ParserImpl.java:259)
at org.esa.snap.core.jexp.impl.ParserImpl.parseConditional(ParserImpl.java:230)
at org.esa.snap.core.jexp.impl.ParserImpl.parseAssign(ParserImpl.java:179)
at org.esa.snap.core.jexp.impl.ParserImpl.parseTerm(ParserImpl.java:168)
at org.esa.snap.core.jexp.impl.ParserImpl.parseImpl(ParserImpl.java:150)
at org.esa.snap.core.jexp.impl.ParserImpl.parse(ParserImpl.java:136)
at org.esa.snap.core.jexp.impl.ParserImpl.parse(ParserImpl.java:115)
at org.esa.snap.core.dataop.barithm.BandArithmetic.parseExpression(BandArithmetic.java:115)
at org.esa.snap.core.image.VirtualBandOpImage.parseExpression(VirtualBandOpImage.java:106)
Caused: java.lang.IllegalArgumentException: expression: Undefined symbol ā€˜ndvi_flags_M.NDVI_ARITHMETIC_Mā€™.
at org.esa.snap.core.image.VirtualBandOpImage.parseExpression(VirtualBandOpImage.java:108)
at org.esa.snap.core.image.VirtualBandOpImage.parseExpression(VirtualBandOpImage.java:94)
at org.esa.snap.core.datamodel.VirtualBand.createSourceImage(VirtualBand.java:259)
at org.esa.snap.core.datamodel.Mask$BandMathsType.createImage(Mask.java:251)
at org.esa.snap.core.datamodel.Mask.createSourceImage(Mask.java:128)
at org.esa.snap.core.datamodel.RasterDataNode.getSourceImage(RasterDataNode.java:2137)
at org.esa.snap.core.layer.MaskLayerType.createMultiLevelSource(MaskLayerType.java:81)
at org.esa.snap.core.layer.MaskLayerType.createMultiLevelSource(MaskLayerType.java:77)
at org.esa.snap.core.layer.MaskLayerType.createLayer(MaskLayerType.java:63)
at org.esa.snap.core.layer.MaskLayerType.createLayer(MaskLayerType.java:52)
at org.esa.snap.ui.product.ProductSceneImage.createMaskCollectionLayer(ProductSceneImage.java:338)
at org.esa.snap.ui.product.ProductSceneImage.getMaskCollectionLayer(ProductSceneImage.java:184)
at org.esa.snap.ui.product.ProductSceneView.getMaskCollectionLayer(ProductSceneView.java:1211)
at org.esa.snap.ui.product.ProductSceneView.setMaskOverlayEnabled(ProductSceneView.java:619)
at org.esa.snap.ui.product.ProductSceneView.(ProductSceneView.java:272)
[catch] at org.esa.snap.rcp.actions.window.OpenImageViewAction$1.done(OpenImageViewAction.java:223)
at javax.swing.SwingWorker$5.run(Unknown Source)
at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.run(Unknown Source)
at sun.swing.AccumulativeRunnable.run(Unknown Source)
at javax.swing.SwingWorker$DoSubmitAccumulativeRunnable.actionPerformed(Unknown Source)
at javax.swing.Timer.fireActionPerformed(Unknown Source)
at javax.swing.Timer$DoPostEvent.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$500(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:159)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Thank you.

I addition you need to remove the masks in the Mask Manager.
Iā€™m sorry. Itā€™s not very convenient to use at the moment, at least in certain cases. I hope we can fix this soon

1 Like

Works excellent, feel like a boss, thanks a lot for your help!

Have a nice weekend,
Wojciech

1 Like

@ABraun What do you mean by ā€œcalibrate the sceneā€ with sen2cor? I thought Sen2cor was used to obtain L2A image from L1C image.

yes. And by doing so your values of different scenes become comparable because it reduces the different illumination conditions or atmospheric layers, for example.

For L2A images this is should be already done then?

yes, in the meanwhile, some can be downloaded already at level 2A.

1 Like

Hello,

I have had the same problem displaying NDVI images. I have cleared out the valid expression box and removed all the masks. I still get a null value reply from the image viewer. Iā€™m using an iMac computer, if that makes a difference.

Thanks, Norm

I also had this problem very recently. Please fix the collocation bug.