使用衛星嵌入資料集進行相似性搜尋

在 GitHub 上編輯
回報問題
頁面記錄
本教學課程是 Satellite Embedding 資料集系列教學課程之一,請參閱簡介非監督式分類監督式分類迴歸

嵌入內容提供獨特的機會,可使用地球觀測資料尋找相似的位置和特徵。比較參考位置的嵌入向量與嵌入圖片所有其他像素的嵌入向量,即可找出與參考位置具有相似屬性的位置。在實務上,這可讓我們輕鬆找出感興趣區域中的物體或特定類型的地點。

在本教學課程中,我們將嘗試找出某個區域中的所有穀物筒倉。穀倉或穀物倉是高聳的建築物,通常用於大量儲存穀物。這些裝置通常位於農場或加工廠。使用傳統遙測方法難以對應這些結構,因此需要訓練自訂物件偵測模型。筒倉的形狀和結構獨一無二,且通常由類似材質製成,因此在衛星嵌入圖片中會以獨特的嵌入向量表示,方便我們透過簡單的相似度搜尋找到筒倉。


穀物筒倉 (圖片:維基百科)

選取搜尋區域

在本教學課程中,我們將繪製堪薩斯州富蘭克林郡的穀物筒倉地圖。我們套用篩選器,並選取這個郡的多邊形。

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');


圖:所選區域

選取參考位置

首先,我們會標示一或多個穀物筒倉的位置。在程式碼編輯器中,您可以使用衛星底圖,輕鬆找出物件。

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

找到感興趣的物件位置後,使用「繪圖工具」中的「新增標記」工具放置點,將該位置標示為參考位置。


圖:新增參考位置

通常只要一個位置就夠了,但多幾個範例有助於減少誤判 (在本例中,是指識別為穀物筒倉但實際上不是穀物筒倉的位置)。我們會將幾何圖形類型變更為 FeatureCollection,以便新增多個參考點。按一下幾何圖形旁的「編輯圖層屬性」按鈕。將圖層名稱變更為 samples,並將匯入類型設為 FeatureCollection。按一下 [確定]。


圖:設定樣本層

返回主要的程式碼編輯器視窗,在幾個更具代表性的位置新增點。


圖:新增更多參考位置

在本教學課程中,我們選取了 3 個參考位置。這些資料會用於從衛星嵌入圖片擷取嵌入向量。

選取時間範圍

選擇要搜尋的年份。

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

篩選並拼接衛星嵌入資料集

我們載入衛星嵌入資料集,篩選所選年份的圖片,並建立影像拼接。

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

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

從樣本中擷取嵌入向量

我們會對參考位置的鑲嵌圖像進行取樣,取得與這些點相關聯的嵌入向量。我們也需要選取要擷取和比較嵌入向量的比例。Satellite Embedding 的內嵌表示法有一項非常實用的屬性,就是經過設計可線性組合,也就是說,內嵌表示法可彙整或分層,同時保留距離關係和解讀的意義。如果我們對 2x2 像素取空間平均值,結果會代表較大低解析度像素的嵌入。衛星嵌入的原始解析度為 10 公尺,適合用來識別穀物筒倉等小型物體。但如要尋找較大的物體或地點,可以使用較大的值 (即 20 公尺、1000 公尺),以符合較粗略比例的物件。

// 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
});

計算相似度

計算兩個嵌入向量之間的點積,即可計算出兩者的相似度。點積會將兩個向量的大小和角度縮減為單一數字,而就我們的案例來說,嵌入向量是單位長度,因此結果只是向量之間的角度。

我們只要將兩個 64D 的單位長度嵌入向量相乘,然後加總乘積,即可取得向量夾角的餘弦值 (又稱「點積」)。我們會針對每個參考位置計算 1 張圖片,並取結果的平均值,取得點積的像素值圖片。

// 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();

點積接近 1 的像素具有相對相似的嵌入向量 (兩者之間的角度接近 0),而點積接近 -1 則表示向量之間有較大的差異 (正交於相反方向)。我們可以將平均距離圖片新增至地圖,以視覺化呈現結果。

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);


圖:參考點周圍的像素相似度 - 越亮的區域越相似

擷取相符地點

下一步,我們需要定義門檻,並擷取包含目標物件的位置。所有含有穀物筒倉的像素,其嵌入向量都會與參考嵌入向量非常相似,兩者間的角度會接近 1。我們會定義門檻,找出區域內的所有這類像素。找出合適的門檻取決於您要尋找的物體和比例。您可以嘗試不同的值,看看哪一個最適合您的應用程式。

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

結果是二進位圖片,其中像素的相似度值小於門檻。現在,我們會將產生的圖片轉換為多邊形。

// 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
});

每個多邊形代表一個與參考位置相符的網站。我們可以使用質心代表相符的地點。

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

將比對結果匯出至資產 (選用)

在 Earth Engine 中,向量化是需要大量記憶體和運算資源的作業。為避免在視覺化呈現結果時發生「計算逾時」或「圖塊錯誤」,建議將結果匯出為資產。匯出資產後,即可匯入指令碼並以視覺化方式呈現。這個方法也能確保您可以在大範圍區域進行搜尋,不會發生問題。

// 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
});

啟動匯出工作,並等待完成後再繼續操作。匯出作業完成後,我們會將比對結果匯回程式碼。

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

以視覺化方式呈現相符結果

無論您是以互動方式擷取相符項目,還是匯出至特徵集合,現在都會有 predictedMatches 變數,其中包含搜尋區域內參考位置的預測相符項目。我們來看看這些項目。

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

驗證結果

如要評估結果,可以放大每個預測的相符項目,查看該位置是否有穀物筒倉。你會發現許多相符項目都正確識別出穀物筒倉。


圖:正確識別出有穀物筒倉的場地

結果中也可能出現誤判情形。如您所見,相符項目與參考位置有許多相似特徵,因此嵌入向量也相似。


圖:誤判相符項目

如要改善結果,可以調整參考位置和選取的門檻。

在 Earth Engine 程式碼編輯器中試用本教學課程的完整指令碼