KcFnMi
KcFnMi

Reputation: 6171

gdal translate scale and save to jpg using python

I know how to use gdal translate to scale and save to jpg via cmd line:

gdal_translate image.bsq image.jpg -of JPEG -outsize 10% 10% -scale

This produces (what I call a nice image):

enter image description here

I would like to produce similar image via python, something like:

from osgeo import gdal
img_bsq  = 'image.bsq'
img_jpg  = 'image.jpg'  
gdal.Translate(img_jpg, img_bsq, format='JPEG', width=1024, height=0, scaleParams=[[500,1000,10,20]])

The issue I think is how to properly select scaleParams. It seems the -scale on the cmd line compute values automatically, as per man gdal_translate:

-scale [src_min src_max [dst_min dst_max]]:
           Rescale the input pixels values from the range src_min to src_max to the range dst_min to dst_max. If omitted the output range is 0
           to 255. If omitted the input range is automatically computed from the source data.

Any tip on how to select scaleParams (or other relevant options)?

Upvotes: 3

Views: 8383

Answers (1)

Rutger Kassies
Rutger Kassies

Reputation: 64443

You should be able to leave it blank here as well, like:

gdal.Translate(img_jpg, img_bsq, format='JPEG', width=1024, height=0, scaleParams=[[]])

This causes GDAL to make a guess itself, as described in the docs:

-scale [src_min src_max [dst_min dst_max]]: Rescale the input pixels values from the range src_min to src_max to the range dst_min to dst_max. If omitted the output range is 0 to 255. If omitted the input range is automatically computed from the source data.

http://www.gdal.org/gdal_translate.html

Alternatively, you could also retrieve the statistics (per band) and make something up yourself.

Getting the statistics:

ds = gdal.Open('img_bsq')
stats = [ds.GetRasterBand(i+1).GetStatistics(True, True) for i in range(ds.RasterCount)]
ds = None

vmin, vmax, vmean, vstd = zip(*stats)

With those statistics you should be able to come up with some desired stretching. If you want to scale between the min and max for each band you could do:

scaleParams = list(zip(*[vmin, vmax]))

Or if you want to use the absolute highest and lowest (over all bands)

scaleParams = [[min(vmin), max(vmax)]]

etc.

Upvotes: 9

Related Questions