20

I am looking to scale a 16bit unsigned tiff image to an 8bit image using GDAL (OSGeo4W). However I want to constrain the pixel values so that they stay within the range of the 8bit imagery. What I mean is, I want to ensure the visual proportion in the 16bit image is represented in the 8bit image (0-255). Using gdal_translate to convert from 16bit to 8bit cuts the pixel values and does not produce a RGB image. I am unsure of what function and setting to call from within gdal_translate, or if there is a better option.


GDALINFO

C:\>gdalinfo C:\Projects\Stormwater\ForPCI\images\1537TORO_6cm_04761_RGBI.tif
Driver: GTiff/GeoTIFF
Files: C:\Projects\Stormwater\ForPCI\images\1537TORO_6cm_04761_RGBI.tif
Size is 17310, 11310
Coordinate System is `'
Metadata:
  TIFFTAG_DATETIME=2015:05:03 12:27:13
  TIFFTAG_IMAGEDESCRIPTION=UltraCam-Lvl03
--------------
CAM_ID: UC-SXp-1-50215465 [3]
IMG_NO: 4761
RECORD_GUID: 8fc3d7a9-d2e5-40e5-babf-939f1f803dcf
IMG_GUID: C850D0A4-39CA-4BC8-ACD7-81A363D78C6E
FILE_GUID: 86C4F8E4-A2FD-43FB-B3B1-4C4ED8DF0E42
LICENSE_ID: 820342819
SOFTWARE: UltraCam Aerial Radiometry Core 12.6.1408.2501
PIXEL_SIZE_WIDTH: 6 [micron]
PIXEL_SIZE_HEIGHT: 6 [micron]
APERTURE: F_8
EXPOSURE_TIME: 0.002000000000 [s]
HIGH_ISO_MODE_CAPTURE: off
HIGH_ISO_MODE_PROCESSING: off

----- Inner Orientation -----
PRINCIPAL_DISTANCE: 100.500000000000 [mm]
PRINCIPAL_POINT_X: -0.000000000000 [mm]
PRINCIPAL_POINT_Y: 0.180000000000 [mm]
SENSOR_AREA_WIDTH: 103.860000000000 [mm]
SENSOR_AREA_HEIGHT: 67.860000000000 [mm]
-----------------------------

----- Exposure Annotation Data -----
MID_EXPOSURE_CORRECTION: 0.000762000000 [s]
FMS_SENSOR_CODE: UCXp
FMS_CAMERA_PORT: 1
FMS_EXPOSURE_NUMBER: 4761
FMS_PROJECT: 1537TORO
FMS_AREA: 1537TORO_6cm_6030
FMS_LINE_NUMBER: 47
FMS_SEGMENT_NUMBER: 1
FMS_WAY_POINT_NUMBER: 0
GPS_DATE: 150412
GPS_TIME: 162517
GPS_LATITUDE: N43.745319 [degree]
GPS_LONGITUDE: W079.358953 [degree]
GPS_ALTITUDE: 1159 [m]
GPS_POSITION_SOLUTION: GPS
GPS_TRACK_OVER_GROUND: 73 [degree]
GPS_ABOVE_GROUND_LEVEL: 1008.7 [m]
GPS_GROUND_SPEED: 80.4 [mps]
------------------------------------

----- Level-3 Parameters -----
IMG_TYPE: High resolution multi channel RGBI
ROTATION: 0 [degree]
------------------------------------
TIFFTAG_RESOLUTIONUNIT=1 (unitless)
TIFFTAG_SOFTWARE=UltraCam Aerial Radiometry Core 12.6.1408.2501
Image Structure Metadata:
INTERLEAVE=PIXEL
Corner Coordinates:
Upper Left  (    0.0,    0.0)
Lower Left  (    0.0,11310.0)
Upper Right (17310.0,    0.0)
Lower Right (17310.0,11310.0)
Center      ( 8655.0, 5655.0)
Band 1 Block=17310x1 Type=UInt16, ColorInterp=Red
Band 2 Block=17310x1 Type=UInt16, ColorInterp=Green
Band 3 Block=17310x1 Type=UInt16, ColorInterp=Blue
Band 4 Block=17310x1 Type=UInt16, ColorInterp=Undefined
PolyGeo
  • 65,136
  • 29
  • 109
  • 338
Ryan Garnett
  • 9,479
  • 8
  • 61
  • 106
  • 1
    Could you please provide some details on the type of imagery you are using? – Aaron Nov 14 '16 at 19:11
  • For example by attaching the gdalinfo report of the source file. Write also the exact gdal_translate command that you used. – user30184 Nov 14 '16 at 19:42
  • gdalinfo has been added to the question as an UPDATE. The imagery is level 3 stereo imagery. The gdal_translate command used was:

    gdal_translate -ot Byte input.tif output.tif

    – Ryan Garnett Nov 14 '16 at 20:42
  • 1
    Perhaps the real data of the 16 bit imagery are only using a narrow slice of the full range. Checking the histogram with for example QGIS may reveal that. You can also just have a try with -scale parameter http://www.gdal.org/gdal_translate.html. If you wand RGB output from 4 band original se.lect three of them with -b parameters, for example -b 1 -b 2 -b 3 – user30184 Nov 14 '16 at 21:41

1 Answers1

32

If you don' want the values above 255 to be cut, you need to scale them down. For that purpose gdal_translate provides the option -scale:

From the Manual:

-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.

So what you can use is the following:

gdal_translate -of GTiff -ot Byte -scale 0 65535 0 255 src_dataset dst_dataset

Why 255 and 65535 ?

You have 2^nbits values. As the min value is usually 0, the max value is 2^nbits-1.

  • 8 bit --> 2^8 = 256 values --> 0-255
  • 16 bit --> 2^16 = 65536 vaues --> 0-65535
pLumo
  • 6,489
  • 20
  • 41
  • https://gis.stackexchange.com/questions/114184/exporting-16-bit-single-band-to-8-bit-in-saga-qgis – addcolor Jul 02 '23 at 02:59
  • https://gis.stackexchange.com/questions/370997/converting-from-16-bit-tiff-image-to-8-bit-with-gdal-does-not-work-properly – addcolor Jul 02 '23 at 02:59