SkyTruth / MTR

Mountain Top Removal
Other
8 stars 2 forks source link

Decide on Erode/Dilate Distance #69

Closed cjthomas730 closed 8 years ago

cjthomas730 commented 8 years ago

See #44

Based on our discussion on 07/12, for the time being we are going to use the 4 step Erosion-Dilation, although we will be looking in to whether we can compress it to 3 steps without altering the output. We also decided to use buffer distances which are multiples of 60, so that the Erosion-Dilation will align with the resolution of Landsat 1-3. For the time being we will use a 60 meter buffer.

@apericak we should update the master script to reflect this. The current (as of 07/13) Erosion-Dilation code:

  // Erode/dilate MTR sites to remove outliers (pixel clean-up)
  var MTR_eroded_dialated_dialated_eroded = MTR
    .reduceNeighborhood(ee.Reducer.max(), ee.Kernel.euclidean(30, 'meters'))
    .reduceNeighborhood(ee.Reducer.min(), ee.Kernel.euclidean(30, 'meters'))
    .reduceNeighborhood(ee.Reducer.min(), ee.Kernel.euclidean(30, 'meters'))
    .reduceNeighborhood(ee.Reducer.max(), ee.Kernel.euclidean(30, 'meters'));

  var MTR_masked = MTR_eroded_dialated_dialated_eroded.updateMask(MTR_eroded_dialated_dialated_eroded);

Dilates --> erodes --> erodes --> dilates using a 30 meter buffer distance.

We should update this to reflect the use of the 60 meter buffer distance, as well as to change the order: erode --> dilate --> dilate --> erode:

  // Erode/dilate MTR sites to remove outliers (pixel clean-up)
  var MTR_eroded_dialated_dialated_eroded = MTR
    .reduceNeighborhood(ee.Reducer.min(), ee.Kernel.euclidean(60, 'meters'))
    .reduceNeighborhood(ee.Reducer.max(), ee.Kernel.euclidean(60, 'meters'))
    .reduceNeighborhood(ee.Reducer.max(), ee.Kernel.euclidean(60, 'meters'))
    .reduceNeighborhood(ee.Reducer.min(), ee.Kernel.euclidean(60, 'meters'));

  var MTR_masked = MTR_eroded_dialated_dialated_eroded.updateMask(MTR_eroded_dialated_dialated_eroded);
apericak commented 8 years ago

Here are a bunch of screenshots of different ways of doing the erosion and dilation. The top of the screenshot contains the code changes per image. There's not much of an order here.

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12

Note that these aren't perfect because of how GEE shows results; i.e., if you were to zoom in, these might look different. However, to me image 11 (nearly identical to 3, which answers whether we need three or four steps) looks the closest to what I'm expecting. However, image 1 also looks good. In general, the images relying solely on 60 m distances seem worse, so I'd advocate moving back to a focus on 30 m.

And in thinking about it some more, I don't really think it matters to have 60 m to match the early Landsats. If I'm interpreting it correctly, the Euclidean kernel we're using isn't selecting pixels, per se, it's just moving the given distance away from the pixel. So a 30 m kernel will select the four direct neighboring pixels exactly, but only those four. A 60 m kernel might select all eight neighbors, but it will only select the four neighbors on early Landsat. So, we might be okay (at least for the later Landsats) to use a 30 m kernel at times.

cjthomas730 commented 8 years ago

@apericak this sounds good, and based the analysis script the 30 meter buffer has already been reimplemented.

  var mtrCleaned = mtr
    .reduceNeighborhood(ee.Reducer.min(), ee.Kernel.euclidean(30, 'meters'))  // erode
    .reduceNeighborhood(ee.Reducer.max(), ee.Kernel.euclidean(60, 'meters'))  // dilate
    .reduceNeighborhood(ee.Reducer.min(), ee.Kernel.euclidean(30, 'meters')); // erode

Unless there are any other issues, I think we can close this issue?