Komponowanie, maskowanie i mozaikowanie

Po załadowaniu kolekcji odbicia TOA Landsat 8 do zmiennej o nazwie l8 zobaczysz, że ten kod tworzy kompozycję z najnowszymi wartościami:

Edytor kodu (JavaScript)

var l8 = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA');
var landsat2016 = l8.filterDate('2016-01-01', '2016-12-31');
Map.addLayer(landsat2016, visParams, 'l8 collection');

Jednym z problemów z tym kompozytem jest to, że jest pełen chmur. Zamiast po prostu pobierać ostatni piksel w kolekcji (gdy dodajesz kolekcję do mapy, Earth Engine niejawnie wywołuje na niej funkcję mosaic()), możesz zredukować funkcję ImageCollection (więcej informacji o redukowaniu kolekcji obrazów).

Łączenie za pomocą funkcji Reducer

Reduktory zostały po raz pierwszy wprowadzone w kontekście uzyskiwania statystyk w regionie obrazu. To była redukcja przestrzenna. Zmniejszenie kolekcji obrazów do jednego obrazu jest redukcją czasową, gdy kolekcja reprezentuje obrazy w czasie. Rodzaj Reducer określa sposób, w jaki Earth Engine obsługuje nakładające się piksele. Landsat 8 odwiedza to samo miejsce na Ziemi co 16 dni. Oznacza to, że w ciągu 6 miesięcy będzie około 12 zdjęć (a w miejscach, gdzie sceny się pokrywają, będzie ich więcej). Każdy piksel na mapie pochodzi ze stosu pikseli – po jednym z każdego obrazu w wyświetlanej kolekcji.

Samo dodanie kolekcji do mapy powoduje wybranie najnowszego piksela, czyli tego z najnowszego obrazu w stosie. To działanie można zmienić za pomocą funkcji redukujących Earth Engine. Na przykład zamiast pobierać najnowszy piksel ze stosu, można polecić Earth Engine, aby wybierał wartość środkową w stosie. Dzięki temu można usunąć chmury (które mają wysoką wartość) i cienie (które mają niską wartość). Gdy kolekcja obrazów jest zmniejszana za pomocą funkcji median reducer, wartość złożona to mediana w każdym paśmie w czasie. Na przykład w przypadku scen Landsat w 2016 r.:

Edytor kodu (JavaScript)

// Get the median over time, in each band, in each pixel.
var median = l8.filterDate('2016-01-01', '2016-12-31').median();

// Make a handy variable of visualization parameters.
var visParams = {bands: ['B4', 'B3', 'B2'], max: 0.3};

// Display the median composite.
Map.addLayer(median, visParams, 'median');

Nowością w tym kodzie jest metoda median() zastosowana do kolekcji obrazów. Podobnie jak metody filtrowania jest to skrót do bardziej ogólnej metody reduce() w przypadku kolekcji obrazów, która przyjmuje argument ee.Reducer(). Na karcie Docs w edytorze kodu znajdź pakiet ee.Reducer, aby wyświetlić listę wszystkich funkcji redukujących Earth Engine. Jeśli rozważasz użycie funkcji redukującej w przypadku kolekcji obrazów, pamiętaj, że wynikiem jest obraz, więc funkcje redukujące z wynikami nienumerycznymi, np. histogram lub toList, nie będą działać w przypadku kolekcji obrazów.

Tutorial_api_06_median_composite
Rysunek 6. Kompozyt mediany Landsat 8.

Po oddaleniu widoku mediany kompozytowej powinien pojawić się obraz podobny do tego na rysunku 6. Powinno to wyglądać znacznie lepiej niż ostatnia kompozycja wartości, którą utworzono wcześniej. W tym momencie warto się cofnąć i zastanowić, co zostało zrobione, aby uzyskać tę medianę złożoną. Earth Engine wczytał całą kolekcję Landsat 8 dla kontynentalnej części Stanów Zjednoczonych i obliczył medianę dla każdego piksela. To bardzo dużo danych. Oczywiście możesz obliczyć mediany roczne, najpierw filtrując kolekcję, tak jak wcześniej. Chodzi o to, że gdyby trzeba było pobrać wszystkie te zdjęcia i utworzyć z nich kompozycję, byłoby to duże przedsięwzięcie. Dzięki Earth Engine wynik otrzymasz w kilka sekund.

Więcej informacji o komponowaniu i mozaikowaniu znajdziesz tutaj.

Zamaskowanie

Chociaż mediana kompozycji jest lepsza od kompozycji z ostatnią wartością, możesz chcieć zamaskować części obrazu. Maskowanie pikseli na obrazie powoduje, że stają się one przezroczyste i są wykluczane z analizy. Każdy piksel w każdym paśmie obrazu ma maskę. Elementy o wartości maski 0 lub niższej będą przezroczyste. Wyświetlane będą te, które mają maskę o wartości powyżej 0. Maskę obrazu ustawia się za pomocą wywołania takiego jakimage1.mask(image2). To wywołanie przyjmuje wartości image2 i tworzy z nich maskę image1. Wszystkie piksele w image2, które mają wartość 0, staną się przezroczyste w image1.

Załóżmy na przykład, że chcesz zamaskować wszystkie piksele wody w kompozycji mediany. Maskę wody można utworzyć na podstawie zbioru danych opisanego przez Hansena i in. (2013), który znajduje się w katalogu danych Earth Engine. (Więcej informacji o zbiorze danych Hansen et al. znajdziesz w tym samouczku). W tym zbiorze danych woda ma wartość 2, ląd – 1, a „brak danych” – 0. Użyj logiki, aby utworzyć obraz maski, który zawiera zera w miejscach, gdzie nie ma lądu:

Edytor kodu (JavaScript)

// Load or import the Hansen et al. forest change dataset.
var hansenImage = ee.Image('UMD/hansen/global_forest_change_2015');

// Select the land/water mask.
var datamask = hansenImage.select('datamask');

// Create a binary mask.
var mask = datamask.eq(1);

// Update the composite mask with the water mask.
var maskedComposite = median.updateMask(mask);
Map.addLayer(maskedComposite, visParams, 'masked');

W tym kodzie jest kilka nowych elementów, które warto omówić szczegółowo. Po pierwsze, funkcja select() przydaje się do wyodrębniania z obrazu interesujących nas pasm. Wybieramy tylko pasmo, które nas interesuje: datamask. Kolejną nowością jest operator logiczny eq(), który oznacza „równa się”. Używamy eq(1) do utworzenia obrazu binarnego, w którym wszystkie piksele, które nie mają wartości 1 w paśmie datamask (czyli te, które przedstawiają wodę lub brak danych), otrzymują wartość 0 w wynikowym obrazie.

W wyniku maskowania wszystkie piksele w kompozycji mediany, które znajdują się nad lądem (zgodnie ze zbiorem danych Hansena i in.), są widoczne, ale te, które znajdują się nad wodą (lub nie zawierają danych), są przezroczyste i zostaną wykluczone z każdej analizy obrazu maskedComposite.

Mozaikowanie

Łącząc koncepcje kolekcji obrazów, operatorów logicznych, maskowania i komponowania, możesz uzyskać ciekawe wyniki kartograficzne. Załóżmy na przykład, że chcesz uzyskać obraz, na którym piksele lądu są wyświetlane w prawdziwych kolorach, a wszystkie pozostałe piksele są wyświetlane na niebiesko. Możesz to zrobić w ten sposób:

Edytor kodu (JavaScript)

// Make a water image out of the mask.
var water = mask.not();

// Mask water with itself to mask all the zeros (non-water).
water = water.mask(water);

// Make an image collection of visualization images.
var mosaic = ee.ImageCollection([
  median.visualize(visParams),
  water.visualize({palette: '000044'}),
]).mosaic();

// Display the mosaic.
Map.addLayer(mosaic, {}, 'custom mosaic');

W tym kodzie wiele się dzieje, więc przeanalizujmy go. Najpierw używamy operatora logicznego not(), aby odwrócić maskę utworzoną wcześniej. W szczególności funkcja not() zamienia wszystkie zera na jedynki, a wszystkie inne liczby na zera. Nazwanie tej zmiennej water nie jest do końca poprawne, ponieważ zawiera ona również piksele bez danych, ale w obecnym kontekście kartograficznym jest to dopuszczalne. Następnie zamaskuj „wodę” samą sobą. W efekcie powstaje obraz, na którym wszystkie piksele wody mają wartość 1, a wszystkie pozostałe są zamaskowane. Ostatnim krokiem jest połączenie obrazów z mosaic(). Ponieważ funkcja mosaic() działa na kolekcji obrazów, przekazujemy listę obrazów, które chcemy połączyć, do konstruktora kolekcji obrazów, a następnie wywołujemy funkcję mosaic() jako ostatni krok. Kolejność obrazów na tej liście jest ważna. Obraz wyjściowy będzie zawierać ostatni niezasłonięty piksel ze stosu obrazów w kolekcji wejściowej. W tym przypadku działa to, ponieważ warstwa wody jest ostatnim (górnym) obrazem w kolekcji i zawiera tylko niezasłonięte piksele, w których występuje woda.

Pamiętaj, że obrazy w kolekcji to obrazy wizualizacyjne. Gdy wywołasz funkcję visualize() na obrazie, zostanie on przekształcony w 8-bitowy obraz 3-pasmowy zgodnie z przekazanymi parametrami wizualizacji. Domyślne parametry wizualizacji działają prawidłowo w przypadku 3-pasmowych obrazów 8-bitowych, więc nie musisz ich używać podczas dodawania obrazu do mapy. Wynik powinien wyglądać jak na rysunku 7.

Tutorial_api_07_mosaic.png
Rysunek 7. Niestandardowa mozaika, która sprawia, że obszary wodne mają jednolity kolor.

Wiesz już, jak wizualizować kolekcje obrazów jako kompozycje z ostatnich wartości, jak tworzyć kompozycje z kolekcji obrazów za pomocą funkcji redukujących oraz jak tworzyć niestandardowe kompozycje przez maskowanie i mozaikowanie kolekcji obrazów. Na następnej stronie dowiesz się, jak dodać indeks wegetacji do każdego obrazu w kolekcji i użyć go do utworzenia kompozycji „najbardziej zielony piksel”.