Wyszukiwanie podobieństw za pomocą zbioru danych wektorów dystrybucyjnych satelitów

Edytuj w GitHubie
Zgłoś problem
Historia strony
Ten samouczek jest częścią serii samouczków dotyczących zbioru danych Satellite Embedding. Zobacz też Wprowadzenie, klasyfikację bez nadzoru, klasyfikację z nadzorem i regresję.

Osadzanie danych to wyjątkowa możliwość znajdowania podobnych lokalizacji i obiektów za pomocą danych obserwacji Ziemi. Porównując wektor dystrybucyjny lokalizacji referencyjnej z wektorami dystrybucyjnymi wszystkich innych pikseli obrazu wektorowego, możemy znaleźć lokalizacje o podobnych właściwościach. W praktyce pozwala to łatwo znajdować obiekty lub określone typy witryn w interesującym nas regionie.

W tym samouczku spróbujemy znaleźć wszystkie silosy na zboże w danym regionie. Silosy i zbiorniki na zboże to wysokie konstrukcje, które są powszechnie używane do przechowywania zboża luzem. Można je znaleźć w gospodarstwach rolnych lub zakładach przetwórczych. Mapowanie tych struktur byłoby trudne przy użyciu tradycyjnych metod teledetekcji i wymagałoby wytrenowania niestandardowego modelu wykrywania obiektów. Silosy mają unikalny kształt i strukturę, a zwykle są wykonane z podobnych materiałów, dlatego w obrazach osadzonych z danych satelitarnych będą reprezentowane przez unikalne wektory osadzania. Dzięki temu będziemy mogli je lokalizować za pomocą prostego wyszukiwania podobieństw.


Silosy na zboże (zdjęcie: Wikipedia)

Wybierz region wyszukiwania

W tym samouczku zmapujemy silosy na zboże w hrabstwie Franklin w stanie Kansas. Zastosujemy filtr i wybierzemy wielokąt dla tego hrabstwa.

var counties = ee.FeatureCollection('TIGER/2018/Counties');

// Select Franklin County, Kansas
var selected = counties
  .filter(ee.Filter.eq('GEOID', '20059'));
var geometry = selected.geometry();

Map.centerObject(geometry);
Map.addLayer(geometry, {color: 'red'}, 'Search Area');


Ilustracja: wybrany region

Wybierz lokalizacje referencyjne

Zaczynamy od oznaczenia lokalizacji co najmniej jednego silosu na zboże. W Edytorze kodu możesz używać mapy bazowej Satellite, która ułatwia lokalizowanie obiektów.

// Use the satellite basemap
Map.setOptions('SATELLITE');

Gdy znajdziesz lokalizację interesującego Cię obiektu, użyj narzędzia Dodaj znacznik z sekcji Narzędzia do rysowania, aby umieścić punkt i oznaczyć go jako lokalizację odniesienia.


Ilustracja: dodawanie lokalizacji odniesienia

Często wystarczy nawet jedna lokalizacja, ale kilka dodatkowych przykładów pomaga ograniczyć liczbę fałszywych alarmów (w tym przypadku lokalizacji, które zostały zidentyfikowane jako silosy na zboże, ale w rzeczywistości nimi nie są). Zmienimy typ geometrii na FeatureCollection, aby można było dodać wiele punktów odniesienia. Obok geometrii kliknij przycisk Edytuj właściwości warstwy. Zmień nazwę warstwy na samples i ustaw typ importu na FeatureCollection. Kliknij przycisk OK.


Ilustracja: konfigurowanie warstwy próbek

Wróć do głównego okna edytora kodu i dodaj punkty w kilku innych reprezentatywnych lokalizacjach.


Ilustracja: dodawanie kolejnych lokalizacji odniesienia

Na potrzeby tego samouczka wybraliśmy 3 lokalizacje odniesienia. Będą one używane do wyodrębniania wektorów dystrybucyjnych z obrazów wektorów dystrybucyjnych satelitarnych.

Wybierz okres

Wybierz rok, w którym chcesz przeprowadzić wyszukiwanie.

var year = 2024;
var startDate = ee.Date.fromYMD(year, 1, 1);
var endDate = startDate.advance(1, 'year');

Filtrowanie i mozaikowanie zbioru danych osadzania satelitarnego

Wczytujemy zbiór danych Satellite Embedding, filtrujemy obrazy z wybranego roku i tworzymy mozaikę.

var embeddings = ee.ImageCollection('GOOGLE/SATELLITE_EMBEDDING/V1/ANNUAL');

var mosaic = embeddings
  .filter(ee.Filter.date(startDate, endDate))
  .mosaic();

Wyodrębnij wektor dystrybucyjny z próbek

Próbkujemy mozaikę w lokalizacjach referencyjnych, aby uzyskać wektor osadzania powiązany z tymi punktami. Musimy też wybrać skalę, w której chcemy wyodrębnić i porównać wektor osadzania. Bardzo praktyczną cechą osadzeń w Satellite Embedding jest to, że zostały one zaprojektowane tak, aby można je było łączyć liniowo, co oznacza, że można je agregować lub piramidować, zachowując przy tym relacje odległości i interpretowane znaczenie. Jeśli weźmiemy średnią przestrzenną z 2 x 2 pikseli, wynik będzie reprezentować osadzenie większego piksela o niższej rozdzielczości. Rozdzielczość natywna w przypadku osadzania zdjęć satelitarnych wynosi 10 m. Jest to dobra skala do identyfikowania małych obiektów, takich jak silosy na zboże. Jeśli jednak chcesz znaleźć większe obiekty lub witryny, możesz użyć większej wartości (np. 20 m, 1000 m), aby dopasować obiekty w większej skali.

// Choose the scale
// You may choose a larger value for larger objects
var scale = 10;

// Extract the embedding vector from the samples
var sampleEmbeddings = mosaic.sampleRegions({
  collection: samples,
  scale: scale
});

Obliczanie podobieństwa

Obliczenie iloczynu skalarnego między dwoma wektorami dystrybucyjnymi pozwala obliczyć ich podobieństwo. Iloczyn skalarny sprowadza wielkość dwóch wektorów i kąt między nimi do jednej liczby. W naszym przypadku wektory osadzeń mają długość jednostkową, więc wynikiem jest tylko kąt między wektorami.

Wystarczy pomnożyć 2 64-wymiarowe wektory reprezentacji właściwościowych o długości jednostkowej i zsumować iloczyny, aby uzyskać cosinus kąta między wektorami (czyli „iloczyn skalarny”). Obliczamy 1 obraz dla każdej lokalizacji odniesienia i wyliczamy średnią z wyników, aby uzyskać obraz z wartościami pikseli iloczynu skalarnego.

// We compute the dot product between two embedding vectors
var bandNames = mosaic.bandNames();

var sampleDistances = ee.ImageCollection(sampleEmbeddings.map(function (f) {
  var arrayImage = ee.Image(f.toArray(bandNames)).arrayFlatten([bandNames]);
  var dotProduct = arrayImage.multiply(mosaic)
    .reduce('sum')
    .rename('similarity');
  return dotProduct;
}));

// Calculate mean distance from all reference locations
var meanDistance = sampleDistances.mean();

Piksele, których iloczyn skalarny jest bliski 1, mają stosunkowo podobne wektory osadzania (kąt między nimi jest bliski 0), a iloczyny skalarne bliższe -1 wskazują większą rozbieżność między wektorami (ortogonalnymi w przeciwnym kierunku). Wyniki możemy zwizualizować, dodając do mapy obraz średniej odległości.

var palette = [
  '000004', '2C105C', '711F81', 'B63679',
  'EE605E', 'FDAE78', 'FCFDBF', 'FFFFFF'
];
var similarityVis = {palette: palette, min: 0, max: 1};

Map.addLayer(meanDistance.clip(geometry), similarityVis,
  'Similarity (bright = close)', false);


Ilustracja: podobieństwo pikseli wokół punktu odniesienia – jaśniejsze obszary są bardziej podobne

Wyodrębnianie dopasowanych lokalizacji

W następnym kroku musimy zdefiniować próg i wyodrębnić lokalizacje zawierające nasz obiekt docelowy. Wszystkie piksele z silosami na zboże będą miały wektory dystrybucyjne bardzo podobne do wektora dystrybucyjnego odniesienia, a kąt między nimi będzie bliski 1. Określamy próg, aby znaleźć wszystkie takie piksele w regionie. Odpowiedni próg zależy od obiektu, który chcesz znaleźć, i skali. Możesz eksperymentować z różnymi wartościami i sprawdzać, która z nich najlepiej sprawdza się w Twojej aplikacji.

// Apply a threshold
var threshold = 0.90;
var similarPixels = meanDistance.gt(threshold);

W rezultacie otrzymasz obraz binarny z pikselami o wartościach podobieństwa mniejszych niż wartość progowa. Obecnie przekształcamy wynikowy obraz w wielokąty.

// Mask 0 values using selfMask()
// to get polygons only for the matched pixels
var polygons = similarPixels.selfMask().reduceToVectors({
  scale: scale,
  eightConnected: false,
  maxPixels: 1e10,
  geometry: geometry
});

Każdy wielokąt reprezentuje witrynę, która pasuje do lokalizacji referencyjnych. Do reprezentowania dopasowanej lokalizacji możemy używać środka ciężkości.

// Extract the centroids of vectorized polygons
var predictedMatches = polygons.map(function(f) {
  return f.centroid({maxError:1});
});

Eksportowanie dopasowań do komponentu (opcjonalnie)

Wektoryzacja to w Earth Engine operacja wymagająca dużej ilości pamięci i mocy obliczeniowej. Aby uniknąć błędów Computation Timed Out lub Tile Error podczas wizualizacji wyników, warto wyeksportować wyniki jako zasób. Po wyeksportowaniu komponentu można go zaimportować do skryptu i wyświetlić. Ta metoda zapewnia też możliwość skalowania wyszukiwania na dużych obszarach bez żadnych problemów.

// Replace this with your asset folder
// The folder must exist before exporting
var exportFolder = 'projects/spatialthoughts/assets/satellite_embedding/';
var matchesExportFc = 'predicted_grain_silo_matches';
var matchesExportFcPath = exportFolder + matchesExportFc;

Export.table.toAsset({
  collection: predictedMatches,
  description: 'Predicted_Matches_Export',
  assetId: matchesExportFcPath
});

Rozpocznij zadania eksportowania i poczekaj na ich zakończenie, zanim przejdziesz dalej. Po zakończeniu zadania eksportowania importujemy dopasowania z powrotem do naszego kodu.

// Use the exported asset
var predictedMatches = ee.FeatureCollection(matchesExportFcPath);

Wizualizacja dopasowań

Niezależnie od tego, czy dopasowania zostały wyodrębnione interaktywnie, czy wyeksportowane do kolekcji obiektów, będziesz mieć teraz zmienną predictedMatches z przewidywanymi dopasowaniami do lokalizacji odniesienia w obszarze wyszukiwania. Przyjrzyjmy się im.

Map.addLayer(predictedMatches, {color: 'cyan'} , 'Predicted Matches');

Weryfikowanie wyników

Aby ocenić wyniki, możesz powiększyć każdy przewidywany wynik, aby sprawdzić, czy w danej lokalizacji znajduje się silos na zboże. Zobaczysz, że wiele wyników prawidłowo identyfikuje silosy na zboże.


Ilustracja: prawidłowo zidentyfikowane miejsca z silosami na zboże

Wyniki zawierają też pewną liczbę fałszywych dopasowań. Jak widać, pasujące lokalizacje mają wiele podobnych cech do naszej lokalizacji referencyjnej, a co za tym idzie, podobne wektory osadzania.


Ilustracja: wyniki fałszywie pozytywne

Aby poprawić wyniki, możesz dostosować lokalizacje odniesienia i wybrany próg.

Wypróbuj pełny skrypt tego samouczka w edytorze kodu Earth Engine