Open-EO / openeo-earthengine-driver

openEO back-end driver for Google Earth Engine.
Apache License 2.0
21 stars 7 forks source link

Results are black #22

Closed m-mohr closed 5 years ago

m-mohr commented 5 years ago

I have a process graph, which I processed on May, 23 and gave me a nice NDVI of a coastal region in Spain. If I run it now, it gives only a black image.

Process graph:

{
  "1": {
    "process_id": "load_collection",
    "arguments": {
      "id": "COPERNICUS/S2",
      "spatial_extent": {
        "west": -2.763447,
        "south": 43.040791,
        "east": -1.120991,
        "north": 43.838489
      },
      "temporal_extent": [
        "2018-04-30",
        "2018-06-26"
      ],
      "bands": [
        "B4",
        "B8"
      ]
    }
  },
  "2": {
    "process_id": "filter_bands",
    "arguments": {
      "data": {
        "from_node": 1
      },
      "bands": [
        "B4"
      ]
    }
  },
  "3": {
    "process_id": "normalized_difference",
    "arguments": {
      "band1": {
        "from_node": 2
      },
      "band2": {
        "from_node": 6
      }
    }
  },
  "4": {
    "process_id": "reduce",
    "arguments": {
      "data": {
        "from_node": 3
      },
      "reducer": {
        "callback": {
          "min": {
            "arguments": {
              "data": {
                "from_argument": "data"
              }
            },
            "process_id": "min",
            "result": true
          }
        }
      },
      "dimension": "temporal"
    }
  },
  "5": {
    "process_id": "save_result",
    "arguments": {
      "data": {
        "from_node": 4
      },
      "format": "png"
    },
    "result": true
  },
  "6": {
    "process_id": "filter_bands",
    "arguments": {
      "data": {
        "from_node": 1
      },
      "bands": [
        "B8"
      ]
    }
  }
}
m-mohr commented 5 years ago

Seems to be introduced with PR #21

Result before the PR: image

After applying the PR, the result is black.

After checking all files it seems the problem is the change in src/processgraph/context.js, method retrieveResults(). I assume that the hard-coded min and max values are a problem...

m-mohr commented 5 years ago

Applying a linear_scale_range works, too. The following process graph works as expected with the new code in retrieveResults():

{
  "1": {
    "process_id": "load_collection",
    "arguments": {
      "id": "COPERNICUS/S2",
      "spatial_extent": {
        "west": -2.763447,
        "south": 43.040791,
        "east": -1.120991,
        "north": 43.838489
      },
      "temporal_extent": [
        "2018-04-30",
        "2018-06-26"
      ],
      "bands": [
        "B4",
        "B8"
      ]
    }
  },
  "2": {
    "process_id": "filter_bands",
    "arguments": {
      "data": {
        "from_node": 1
      },
      "bands": [
        "B4"
      ]
    }
  },
  "3": {
    "process_id": "normalized_difference",
    "arguments": {
      "band1": {
        "from_node": 2
      },
      "band2": {
        "from_node": 7
      }
    }
  },
  "4": {
    "process_id": "reduce",
    "arguments": {
      "data": {
        "from_node": 3
      },
      "reducer": {
        "callback": {
          "min": {
            "arguments": {
              "data": {
                "from_argument": "data"
              }
            },
            "process_id": "min",
            "result": true
          }
        }
      },
      "dimension": "temporal"
    }
  },
  "5": {
    "process_id": "apply",
    "arguments": {
      "data": {
        "from_node": 4
      },
      "process": {
        "callback": {
          "lsr": {
            "arguments": {
              "x": {
                "from_argument": "x"
              },
              "inputMin": -1,
              "inputMax": 1,
              "outputMin": 0,
              "outputMax": 255
            },
            "process_id": "linear_scale_range",
            "result": true
          }
        }
      }
    }
  },
  "6": {
    "process_id": "save_result",
    "arguments": {
      "data": {
        "from_node": 5
      },
      "format": "png"
    },
    "result": true
  },
  "7": {
    "process_id": "filter_bands",
    "arguments": {
      "data": {
        "from_node": 1
      },
      "bands": [
        "B8"
      ]
    }
  }
}

So I guess the old "magical" way of Google, which did the scaling implicitly is not available any longer due to the hard-coded visualize. How do we solve this? We can't assume data is always in range 0 to 255...

claxn commented 5 years ago

I think the GEE has a main drawback in automatic visualisation (see https://developers.google.com/earth-engine/image_visualization). Normally, you analyse the distribtion of the values and take certain percentiles (e.g. 2 and 98), which then correspond to 0 and 255. However, GEE does not do this, it takes the data type as input, which is not meaningful (I think they want to save computation time and let the user decide how to visualise it). Your NDVI example works, since it is between 0 and 1, but if you want to visualise a S-2 band without specifying any visualisation parameters, it is just white. In the current GEE backend solution you need to imitate the visualisation parameter setting by applying a linear_scale_range operation beforehand. We could also add such scaling options to options inside save_result, which I would prefer. Because then it is clear that everything concerning the visualisation is done in the end.

m-mohr commented 5 years ago

After thinking a bit more about it, I think the implementation is fine as it is. PNG/JPEG has a fixed range from 0 to 255 and visualize is only called for them. So this seems to work as expected. I just was confused as it was a bit easier beforehand (magic stretching ;-) ).