It seems the data conversion operation has an issue. It’s not handling NaN values correctly.
There is also the question how it should do it when converting the data from float32 to uint8.
uint8 has no NaN value and so NaN becomes 255, for some reason.
It would be good if the data conversion asks for the value which shall replace Nan values.
How can you over com this?
Either don’t wright NaN values with your Band Math or you use the Band Maths again and replace the NaN values manually.
The expression might look like:
nan(water_mask) ? 128 : water_mask
This will replace every NaN value with 128 and preserve the other values (0,255)
Marpet, Thanks a lot for your good info. I have tried nan(water_mask) ? 128 : water_mask on the water mask produced, but the value of NaN still exists! Nothing carries the value of 128. I have even checked the properties, the same as the original band!
Is there any way I can share the data with you? Maybe I am missing sth which I haven’t notice yet! I really need to get it fixed. I have done all this processing to get to the end which is water mask maps in geotif.
As Marpet suggested, the target no data value should come from a user input parameter.
I’ll add this to the operator.
The problem is that it does not accept any new value for NaN. I tried to change NaN for bandmask produced in SNAP to 128, the new band math still shows NaN, nothing changed in the properties! Any temporary solution appreciated!
I think you’ve been hit by wrong or at least confusing behaviour in the Band Maths. Also I am.
The nan() function really checks the value for nan. If it is only marked as invalid it’s not returning true. Even in the Pixel Info view we show NaN. Maybe better to show Inv there. I’ve created recently a ticket (SNAP-697) to be able to check for invalid pixels in the Band Maths.
However, you can overcome this issue.
Use this equation for your mask:
feq(Sigma0_HH_Dissimilarity, 0) ? 0 : Sigma0_HH_Dissimilarity/10<1
On the new band open the properties and remove the valid pixel expression. Now only the water pixels are one, all others are zero.
Now you can convert it and store it to GeoTIFF.
I am posting here what I wrote in this other thread since it seems related to what is being discussed here.
The problem I have is that SNAP seems to be converting pixels with a zero value in the I or Q component of S1 SLC images into NaN. These NaNs are then propagated through a graph run on gpt. In that particular graph, the problem results in a coherence image with NaN values. SNAP converts those NaN values back to 0, but you would expect coherence values close to 1 for those pixels.
Complex numbers with zero-valued I or Q compenents should be treated as such, not as NaN. Is there a way to force gpt to do this?
Is it maybe caused by a division by zero? This could be a reason.
I don’t know the algorithm, maybe @lveci can shed some light.
Marpet, Thank you so much for the proposed solution!
Right now the only problem is that both image background (originally NaN) and non-water (land) have the same value of 0. This will cause issues for temporal change detection since each scene has a different size, so that we need to calculate the non-water areas for each image. I am wondering whether there is any way after data conversion, the background still carries NaN, non-water 0, and water 255 (8bit)?
I do appreciate your time and assistance.
I believe a fix for this made it into the 5.0.3 snap-engine update. Please go to tools -> plugins and check for updates.
I use SNAP 5 with updated plugins. Do you know by any chance why the batch processing does not accept the new band math algorithm, while the band math itself does not give any error!
You can change the expression to
feq(Sigma0_HH_Dissimilarity, 0) ? 128 : Sigma0_HH_Dissimilarity/10<1
Then you can distinguish the values.
I think the fix does not help. Because the pixels are not checked for NaN or invalid only the target no-data value is set.
The invalid pixels are still converted to 255 even if I set the target no-data value to zero.
By changing it to 128, again the same issue will arise, the water boundary is gone…
But now it is only visually gone.
You can remove the valid pixel expression on the new band and update the colour interpretation. You can inspect the values with the Pixel Info view.
After removing the expression I get this result
After Updating the colour interpretation I see this
Thanks Marpet! I guess I am missing one step here. How can I save the color changes made in order to become effective on the image (in geotiff)?
the color adjustment doesn’t change the raster values at all. It just defines which pixel value is displayed in which colour. So there is actually nothing to save that affects your exported data.
So, does that mean that I can not get a separate code for the image background of my geotiff output? I just don’t want the background carries the same value as water or land does.
if the pixels have different values within SNAP (different colours couldn’t be assigned if this wasn’t the case) these should also remain after the export to GeoTiff. So first you need to get a three colour image like demonstrated in marpet’s post and then export shouldn’t be no problem.
All the discussion we’ve had here so far was about the problem of data conversion. To quickly go through it:
the band math produced in SNAP is our ideal where water carries 1, land 0, and background NaN. So far so good!
The problem starts after data conversion: the image background also gets a value of water (1). marpet fixed the issue (feq(Sigma0_HH_Dissimilarity, 0) ? 0 : Sigma0_HH_Dissimilarity/10<1) , where now I can get the water in 1, land in 0, but the background also carries value of 0 as land does!
So the second band math recommended (feq(Sigma0_HH_Dissimilarity, 0) ? 128 : Sigma0_HH_Dissimilarity/10<1) resulted in the same background issue we had at the beginning. So, that’s why the color manipulation was suggested then. However, it can not be saved and the final geotiff product would remain the same.
The objective is to produce water mask maps that water , land, and image background carries a different code.
I think you do it way too complicated. Don’t apply the terrain correction too early as it tilts your image and you introduce the background area.
What works for me (I just did it in the GUI but it shouldn’t be a problem with a graph file as well):
Calibration to Sigma0, speckle filtering and subsetting (could be any other product as well):
Applying a threshold for water:
This gives me this result
Range Doppler Terrain Correction with output GeoTiff: >
This is how it looks in SNAP
And how it looks in a GIS:
Or with different colors:
ABraun, Thanks for sharing this. But, my image processing order is a little bit different, CALIBARAION> TC> TEXTURE> BAND MATH
I am getting water mask out of texture bands which have worked well. In so doing, I need to get the ortho first, produce the texture then. Only issue is for the geotiff products obtained from data conversion.