gdal_calc is one of the lesser used tools among the GDAL utilities. There aren’t many examples of using it in the wild and some advanced features are not well documented. I am finding myself using it a lot lately and have discovered some really powerful use cases.
Working with multi-band rasters
gdal_calc has a peculiar syntax for specifying inputs. If you wanted to use 2 images – input1.tif and input2.tif, you specify them as follows
gdal_calc -A input1.tif -B input2.tif ...
But what if you wanted to do some band math or use each bands of the input separately? If your input.tif has 4 bands, here’s how you can specify them
gdal_calc -A input.tif --A_band=1 -B input.tif --B_band=2 -C input.tif --C_band=3 -D input.tif --D_band=4 ...
gdal_calc uses numpy syntax for specifying calculations. There are many different ways to write the expression. Here’s some example of my preferred method
Say you have a 1-band image input.tif and you want to find all pixels with value > 100. The following expression will be evaluated at each pixel. The result will be 1 where the pixel value passes the expression text and 0 elsewhere.
gdal_calc -A input.tif --calc="A>100" --outfile output.tif
So this gives us the building block for doing re-classification. Say your goal is to reclassify the input.tif as follows
- 0-100 → 1
- 101-200 → 2
- >200 → 3
We can add 3 conditions in the expression and multiply the result with appropriate re-classified value to get the result.
gdal_calc -A input.tif --calc="(A<=100)*1 + (A>100)*(A<=200)*2 + (A>200)*3" --outfile output.tif
You can also use logical_or and logical_and functions to achieve the same result.
gdal_calc -A input.tif --calc="(A<=100)*1 + logical_and(A>100,A<=200)*2 + (A>200)*3" --outfile output.tif
But logical_and and logical_or takes only 2 arguments. So if you had multiple conditions (as we will see in the example below), the expression gets trickier to write. So I prefer to use the multiplication syntax that we used before. But gdal_calc can use the full suite of functions provided by the numpy library. See the routines documentation for all available functions.
Reclassifying Multi-band Rasters
Now we can attempt to apply these concepts at re-classifying multi-band rasters. The expression gets a bit complex, but if you followed the above examples, it should make sense.
Let’s say we want to re-classify a 4-band input.tif as follows
- (R, G, B, A) values of (<=100, <=100, <=100, 255) → 1
- (R, G, B, A) values of (100-200, 100-200, 100-200, 255) → 2
- (R, G, B, A) values of (>=200, >=200, >=200, 255) → 3
- All other combinations to 0
The expression can be compiled as follows
gdal_calc -A input.tif --A_band=1 -B input.tif --B_band=2 -C input.tif --C_band=3 -D input.tif --D_band=4 --outfile output.tif --calc="(A<=100)*(B<=100)*(C<=100)*(D==255) + (A>100)*(A<=200)*(B>100)*(B<=200)*(C>100)*(C<=200)*(D==255)*2 + (A>=200)*(B>=200)*(C>=200)*(D==255)*3"
You can see other examples of how gdal_calc is used, do check out my Mastering GDAL Tools course material.