1

I have a number of RGB images with NoData areas around them, where each band then has the value 0. To merge them, I can of course use gdal_merge like this:

python gdal_merge.py -n 0 -o output.tif input1.tif input2.tif

But in my specific case, there are pixels where only one of the three bands is 0, and then, gdal_merge also ignores these pixels. Is there any way to make it check all bands first and only ignore pixels where the NoData value occurs in EVERY band? Other GDAL solutions are also welcome, I'm not strictly bound to 'gdal_merge` here.

3
  • 1
    Could you prepare some test data with gdal_create gdal.org/programs/gdal_create.html? It may be complicated to handle the case with GDAL and GeoTIFF. GDAL is using per band nodata and it can be defined for example for gdalwarp gdal.org/programs/gdalwarp.html#cmdoption-gdalwarp-srcnodata but it may be that the GeoTIFF driver is not prepared for such case. It may be necessary to separate the bands and use VRT virtual raster format for combining them back to RGB. I have used VRT sometimes for handling images with blue background (RGB 0,0,255).
    – user30184
    Jun 16, 2021 at 14:25
  • I could, indeed, but will be offline for a couple of days. Will update and upload test data, when I have some.
    – s6hebern
    Jun 16, 2021 at 14:47
  • It does not take days, something like this will do it gdal_create -outsize 100 100 -bands 3 -burn 255 -burn 0 -burn 255 -a_nodata 0 test.tif
    – user30184
    Jun 16, 2021 at 15:00

1 Answer 1

1

Handling nodata per band is always complicated whether nodata values or mask bands are used. This recent GDAL pull request seems to deal with somehow similar use case https://github.com/OSGeo/gdal/pull/3932. Be prepared to have continuous trouble with per band nodata.

Test data can be generated with these commands

gdal_create -outsize 100 100 -bands 3 -burn 255 -burn 0 -burn 255 -a_nodata 0 test1.tif -a_srs epsg:3857 -a_ullr 500 300 600 200

gdal_create -outsize 200 200 -bands 3 -burn 0 -burn 255 -burn 255 -a_nodata 0 test2.tif -a_srs epsg:3857 -a_ullr 300 300 500 100

gdal_create -outsize 100 100 -bands 3 -burn 0 -burn 0 -burn 0 -a_nodata 0 test3.tif -a_srs epsg:3857 -a_ullr 500 200 600 100

gdal_create -outsize 100 100 -bands 3 -burn 255 -burn 0 -burn 255 -a_nodata 0 test4.tif -a_srs epsg:3857 -a_ullr 400 200 500 100

All of the images have now a tag NoData=0 but only image number 3 has nodata on all bands.

The first three images do not have overlaps

enter image description here

while the fourth one overlaps image 2

enter image description here

EDIT

I thought first that tests with gdal_merge.py and gdalbuildvrt were giving faulty results but now I think that perhaps those results are correct. When image 4 (RGB 255 0 255) is added on top of image 2 (RGB 0 255 255) the red and blue bands update the image, but green band does not. Therefore the result is white (RGB 255 255 255) even none of the source images has any white pixels. However, pixel values are correct band by band.

gdal_merge -n 0 -a_nodata 0  -o merged.tif test1.tif test2.tif test3.tif test4.tif 

gdalbuildvrt -srcnodata "0 0 0" -vrtnodata 0 output.vrt test1.tif test2.tif test3.tif test4.tif

enter image description here

In the next test I created first an empty mosaic with gdal_merge.

gdal_merge -n 0 -a_nodata 0  -createonly -o warped.tif test1.tif test2.tif test3.tif test4.tif 

Then I filled the mosaic with the source images one by one with gdalwarp. I was thinking that the result was good but actually it may be wrong because the nodata value of image 4 was burned into the final image.

gdalwarp test1.tif warped2.tif -srcnodata "0 0 0" -dstnodata "0 0 0"  
gdalwarp test2.tif warped2.tif -srcnodata "0 0 0" -dstnodata "0 0 0"  
gdalwarp test3.tif warped2.tif -srcnodata "0 0 0" -dstnodata "0 0 0"  
gdalwarp test4.tif warped2.tif -srcnodata "0 0 0" -dstnodata "0 0 0"  

enter image description here

Notice: The result looks all transparent in QGIS when opened with the default settings. QGIS is using just one nodata value and in the resulting image every pixel has zero in at least one band. Disabling nodata value from the image properties makes image visible in QGIS.

2
  • Wow, that's dedication, thanks a lot for this detailed deep dive! As said, I'm offline for a while and therefore cannot test (only have my phone), but I certainly will when I'm back!
    – s6hebern
    Jun 17, 2021 at 18:09
  • Your suggestion of using gdal_merge with -createonly and then using gdalwarp with the NoData values given as "0 0 0" did the trick! Did not know about this possibility, great stuff!
    – s6hebern
    Jun 28, 2021 at 9:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.