I have an image collection that is a binary layer that indicates whether there is a burn or not in each pixel, for the specified time period by which I filtered the satellite images. This is calculated from the differences in the Normalized Burn ratio (dNBR), calculated for each image. A pixel has value 1 (which means it is burned) if the dNBR value is above the threshold value for a pixel, both when looking at the difference between NBR of day1 and day2, and looking at the difference between NBR of day1 and day3. Now I want to reduce the image collection to an image such that each pixel that burnt at any point of time (within the given time period) has a positive value and attach a timestamp as a band to the image, such that each burnt value pixel has a time of burn. The way I am implementing it is by adding a date band to the original filtered image collection, then finding the dNBR and then reducing the image collection by max() reducer. But the problem is the reducer is maximising even the time band and I am getting only one value as the time stamp. Is there a way to apply reduce to only one value and retain the value of the other band which the maximum value was part of? I have been breaking my head over it for quite some time. Please help
var vis = {"opacity":1,"bands":["B4","B3","B2"],"gamma":3.464},
sent = ee.ImageCollection("COPERNICUS/S2")
var land = sent2.filterBounds(geometry).filterDate("2019-01-01","2019-06-01")
.filterMetadata("MGRS_TILE","equals",'44RLT')
.filter(ee.Filter.lt("CLOUDY_PIXEL_PERCENTAGE",5));
var landsort = land.sort("system:time_start");
print(landsort);
var addDate = function(image){
var doy = image.date().getRelative('day', 'year');
var doyBand = ee.Image.constant(doy).uint16().rename('doy')
doyBand = doyBand.updateMask(image.select('B8').mask())
return image.addBands(doyBand);
};
var a = ee.ImageCollection(landsort.toList(landsort.size()));
var a = a.map(addDate)
var a = a.toList(a.size())
var b = function(image){
var nbr3 = ee.Image(image).normalizedDifference(["B8","B12"]);
var nbr2 = ee.Image(a.get(a.indexOf(image).subtract(1))).normalizedDifference(["B8","B12"]);
var nbr1 = ee.Image(a.get(a.indexOf(image).subtract(2))).normalizedDifference(["B8","B12"]);
var e = nbr1.subtract(nbr2).gt(0.3);
var f = nbr1.subtract(nbr3).gt(0.3);
var g = e.multiply(f);
var h = g.addBands(ee.Image(a.get(a.indexOf(image).subtract(2)))
.metadata('system:time_start'));
return h;
};
var dnrcollect = ee.ImageCollection(a.map(b)).max();
Map.addLayer(dnrcollect)
Best Answer
Use:
col.reduce(ee.Reducer.max(nBands))
instead ofcol.max()
.The
ee.Reducer.max()
reducer allows you to specify additional bands to be included in the resulting image whose pixel values correspond to whatever image had the max value (of first band) among constituents.From your example:
ee.ImageCollection(a.map(b)).reduce(ee.Reducer.max(NEED TO SPECIFY NUMBER OF EXTRA BANDS))
A toy example - use the inspector and expand all of the layer info to verify (see image below):
Code Editor script: https://code.earthengine.google.com/b62c98246369e784ecd93852a7a2476e