Computing L1C TCI from RGB Bands

Hello,

I am trying to reproduce the TCI RGB 8bits image from the B04, B03 and B02 bands of an image and failing to reproduce the exact results,

Currently I tried the following (from the 16bits band data)

  • Clip to and normalize each band by 4095 then stretch to [0,255]*
  • Normalize each band by the maximum per band, then stretch to [0,255]**
  • Clip to and Normalize each band in the [1th percentile / 99th percentile] of each band,then stretch to [0,255]***
  • Normalize by 10000, clip to 0.2 then stretch to 0-255 as per https://sentinel.esa.int/web/sentinel/user-guides/sentinel-2-msi/definitions

In numpy, providing x is the RGB in int16 obtained from [B04, B03, B02] converted to float32:

*: x = np.clip(x / 4095., 0., 1.) * 255. (then to np.uint8)
** x = x / np.maximum(x, axis=(0,1))
*** x = (x - np.percentile(x, 1) ) / (np.percentile(x, 99) - np.percentile(x,1)) . clip(0.,1.) )

Is there an official public algorithm to convert [B04, B03, B02] to the TCI jp2 ?

For reference, there’s also a “custom script” on sentinel hub to get TCI (https://github.com/sentinel-hub/custom-scripts/blob/master/sentinel-2/true_color/script.js) but I don’t know the starting space…

Best regards,