Search code examples
pythonjavaarrayspython-3.xgoogle-earth-engine

Exported image black with 0 value


I tried to use the following code but when exporting my map and I check my output data in arcmap. It is totally black and the value is 0. I don't know what is wrong with my code.

https://code.earthengine.google.com/476db72426a67e03a604b6712ce97ef4?hl=ar

// The purpose of this script is to estimate sub-pixel fractions
// of identifiable spectral "endmembers".  This involves finding
// "pure" areas to estimate the endmembers, some matrix algebra
// followed by the mapping of the fractional cover.

// Use the reflective bands. 
var bands = ['B2', 'B3', 'B4', 'B5', 'B6', 'B7'];

// First, let's find a cloud free scene in our area of interest.
// Make a point using the geometry tools and name the import 'point'.
// Import Landsat 8 TOA data and name the collection 'l8'.
var image = ee.Image(l8
    .filterBounds(point)
    .filterMetadata('CLOUD_COVER','less_than', 2)
    .filter(ee.Filter.calendarRange(2020,2020,'year'))
    .filter(ee.Filter.calendarRange(10,12,'month'))
    .first())
    .select(bands);
    
  print(image)
Map.addLayer(image, {bands: ['B4', 'B3', 'B2'], max: 0.3}, 'image');

// Now, delineate polygons of 'pure' regions.  Click +New Layer for 
// each polygon.  Name the imports 'bare', 'vegetation' and 'water'.
// Get the mean spectrum in each of the endmember polygons.
var bareMean = image.reduceRegion(ee.Reducer.mean(), bare, 30).values();
var waterMean = image.reduceRegion(ee.Reducer.mean(), water, 30).values();
var vegMean = image.reduceRegion(ee.Reducer.mean(), vegetation, 30).values();
var snowMean = image.reduceRegion(ee.Reducer.mean(), snow, 30).values();

// Optional: plot the endmembers
print(ui.Chart.image.regions(image, ee.FeatureCollection([
    ee.Feature(bare, {label: 'bare'}), 
    ee.Feature(water, {label: 'water'}),
    ee.Feature(vegetation, {label: 'vegetation'}),
    ee.Feature(snow, {label: 'snow'})]), 
  ee.Reducer.mean(), 30, 'label', [0.48, 0.56, 0.65, 0.86, 1.61, 3.2]));

// Turn the endmember lists into an array that can be used in unmixing.
// Concatenate the lists along the 1-axis to make an array.
var endmembers = ee.Array.cat([bareMean, vegMean, waterMean, snowMean], 1);
//print(endmembers)

// Turn the image into an array image, in which each pixel has a 2-D matrix.
var arrayImage = image.toArray().toArray(1);

// Perform the unmixing in array space using the matrixSolve image method.  
// Note the need to cast the endmembers into an array image.
var unmixed = ee.Image(endmembers).matrixSolve(arrayImage);

// Convert the result from an array image back to a multi-band image.
var unmixedImage = unmixed.arrayProject([0])
    .arrayFlatten([['bare', 'veg', 'water', 'snow']]);

// Display the result.
Map.addLayer(unmixedImage, {}, 'fractions');

// Constrained:constraining the result to be non-negative and sum to one.
var constrained = image.unmix([bareMean, vegMean, waterMean, snowMean], true, true);
Map.addLayer(constrained, {}, 'constrained fractions');

//Export output to Google Drive
Export.image.toDrive({
  image: constrained,
  description: 'unmix',
  scale: 30,
  region: point,
  maxPixels: 1e9,
  fileFormat: 'GeoTIFF'
});

Please guide me how to solve this problem.


Solution

  • You're only exporting a single pixel - the region is set to point. All bands are actually not 0, but whatever tool you're using to visualise the image will have problems picking a good stretch, giving you a black pixel.

    You could for instance use image.geometry() instead of pixel in this case:

    Export.image.toDrive({
      image: constrained,
      description: 'unmix',
      scale: 3000,
      region: image.geometry(),
      maxPixels: 1e9,
      fileFormat: 'GeoTIFF'
    });