I am attempting to display a 4-band Sentinel image where the RGB bands are the first 3 bands, each represented as uint16.
Reason: Currently viewers like COGEO tinyurl.com/3jy9jjcy do stretch each COG tile and therefore,
Expected result: we need on stretching over the entire zoomlevel like in QGIS
To achieve this, I am using Leaflet with GeoRaster, based on an existing example. My goal is to:
A) Enhance each RGB band using the formula band[i] = Math.cbrt(0.6 * band[i] – 0.035).
B) Convert the result to RGB 8-bit for display.
I am encountering difficulties in parsing the channels, enhancing them, and converting them for display. In my JavaScript code my.js, I am struggling to access each band individually with new GeoRasterLayer: The resulting image is all black
var layer = new GeoRasterLayer({
attribution: "Unknown",
georaster: georaster,
resolution: 128,
pixelValuesToColorFn: function(values) {
// Stretch values using cube root function for the first three bands
var stretchedValues = [
Math.cbrt(0.6 * values[0] - 0.035), // Stretch first band
Math.cbrt(0.6 * values[1] - 0.035), // Stretch second band
Math.cbrt(0.6 * values[2] - 0.035) // Stretch third band
];
// Scale stretched values to 8-bit RGB
var scaledValues = stretchedValues.map(value => Math.round(value * 255));
return scaledValues;
}
});
There is no error thrown (exxept the one forovr which can be ignored)
How can I properly access each band in the GeoTIFF file, apply the enhancement formula on zoomlevel, and show the result to RGB 8-bit for display using Leaflet and GeoRaster?
Best Answer
I have absolutely no knowledge about COG and GeoTIFF, so this answer is only how to make the code from question show at least something.
First problem: If you look at the content of
georaster
object,mins
andmaxs
properties tell about min and max values for each channel. Since max values for all three channels are a little below 15000, calculated color values inscaledValues
are way above 255.Second problem:
pixelValuesToColorFn
option function should return CSS color definition as string, like for example:rgba(100, 50, 250, 1)
.Third problem: Sentinel image is in
EPSG:2056
projection, so to display it correctly in Leaflet map, this projection has to be used.Fourth problem: Channel value 9999 stands for no value, so pixel should be transparent.
In the below code channel values are normalized to 255 value and some Swiss map with
EPSG:2056
projection is used as a background:This is how the result looks like:
Now to get desired/correct image just correct formulas have to be used for converting channel values to RGB.
P.S.: Since image has 1.6 GB, it took ages to show this in Firefox on Windows 10. Chrome and Edge both failed.