I have 4 separate raster bands of the same image and 4 different coefficients (one for each band) stored as variables. I would like to iterate over the raster folder, and multiply each band with its corresponded coefficient. I can recognize each band by its file name. Let's say I have in folder c:\bands
these bands:
sn2_b1.tif
sn2_b2.tif
sn2_b3.tif
sn2_b3.tif
And let's say these are my coefficients:
coeff_b1 = 10
coeff_b2 = 20
Coeff_b3 = 30
Coeff_b4 = 40
My goal is iterate over the bands, multiply each one with its corresponded coefficient and save the result as a new raster. My solution so far is quite cumbersome:
import gdal
import os
src = r"c:\bands"
dst = r"c:\cal_bands"
for i in os.listdir(src):
if i.endswith(".tif"):
orig_tif = os.path.join(src,i)
band_ds = gdal.Open(os.path.join(src,i))
band_DN = band_ds.GetRasterBand(1).ReadAsArray()
geotransform = band_ds.GetGeoTransform()
geoproj = band_ds.GetProjection()
xsize = band_ds.RasterXSize
ysize = band_ds.RasterYSize
band_DN = band_DN.astype('f')
format1 = "GTiff"
driver = gdal.GetDriverByName(format1)
dst_datatype = gdal.GDT_Float32
if i.split("_")[1] == 'b1.tif':
cal_band = band_DN * coeff_b1
elif i.split("_")[1] == 'b2.tif':
cal_band = band_DN * coeff_b2
elif i.split("_")[1] == 'b3.tif':
cal_band = band_DN * coeff_b3
elif i.split("_")[1] == 'b4.tif':
cal_band = band_DN * coeff_b4
new_name = "cal_" + i
output_path = os.path.join(dst,new_name)
dst_ds = driver.Create(output_path ,xsize,ysize,1,dst_datatype)
dst_ds.GetRasterBand(1).WriteArray(cal_band)
dst_ds.SetGeoTransform(geotransform)
dst_ds.SetProjection(geoproj)
dst_ds = None
This script works great but is there a way to make it less cumbersome? In this example I have only 4 bands, which is easy to write all the ifs, but I might have 20 bands or more.
Best Answer
It looks as though you are doing different operations inside a single loop, which you can break off into functions.
If I understand correctly, you:
tif
s in a source folderAnd you can match them together by extracting the band name from the string. The natural way to write LUTs in Python is with built-in dictionaries.
Code
Conclusion
You can now handle an arbitrary number of bands just by updating the
COEFF_LUT
dictionary.You could further break the
multiply_raster_by_coeff
function. Of course, performance-wise the two scripts are equivalent, but future you (and collaborators) will appreciate this if it needs changes.