完成本週實作後,同學應能:
關於本講義的引用 本講義實作內容整理自開放教科書 Cardille 等(2024)Cloud-Based Remote Sensing with Google Earth Engine 的兩章:F1.1「Exploring Images」(Howarth, 2024, pp. 19–39,§2.1.3–2.1.5)與 F2.0「Image Manipulation: Bands, Arithmetic, Thresholds, and Masks」(Dyson, Nicolau, Saah, & Clinton, 2024, pp. 97–114)。文中引用標示到「節」(如 §5.2.1),對應教科書網站與 Springer 線上版的節號;程式碼依原書範例改寫,示範區域由上海、舊金山、西雅圖改為高雄。本講義內容以生成式 AI(Anthropic Claude)協助整理與編排,並經授課教師審閱修訂。理論背景請對照「第 3 週講義(理論篇)」。
開始前 三個步驟
RGB 合成:用紅、綠、藍三原色同時顯示每個像元在三個波段的值;bands 清單中的第 1、2、3 個波段依序送進紅、綠、藍色頻道 (Howarth, 2024, §2.1.3)。
// ===== 壹、RGB 合成 =====
var pointKH = ee.Geometry.Point([120.30, 22.63]); // 高雄市政府附近
// Sentinel-2 地表反射率集合
var s2 = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')
.filterDate('2024-11-01', '2025-02-28')
.filterBounds(pointKH)
// 雲量 < 10%
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 10))
// 取最早的一幅
.first();
Map.centerObject(s2, 11); // 置中於高雄
// 紅綠藍 → 肉眼所見
Map.addLayer(s2, { bands: ['B4', 'B3', 'B2'], min: 0, max: 3000 }, '真色彩');
// 近紅外進紅頻道 → 植生呈紅
Map.addLayer(s2, { bands: ['B8', 'B4', 'B3'], min: 0, max: 3000 }, '彩色紅外');
Map.addLayer(s2, { bands: ['B11', 'B8', 'B3'], min: 0, max: 3000 }, '短波紅外假色'); // SWIR 進紅頻道 → 建成區、裸土偏紫紅| 合成 | Sentinel-2 波段(R, G, B) | 判讀重點 |
|---|---|---|
| 真色彩 natural/true color | B4, B3, B2 | 波段與顯示顏色自然配對,看起來像從飛機窗外所見(Howarth, 2024, §2.1.3) |
| 彩色紅外 color-infrared | B8, B4, B3 | 人眼看不見卻能學會判讀:近紅外高的像元呈亮紅(健康植生);水體因三波段皆低而呈黑(§2.1.4) |
| 短波紅外假色 | B11, B8, B3 | 比真色彩對比更高;SWIR 對含水量敏感,燒跡地、裸土、建成區明顯(§2.1.4) |
加色系統:讀懂任何合成 電腦螢幕上的一切都用紅、綠、藍三個顯示頻道;某波段的 DN 相對於另外兩個較高時,像元就帶有該頻道的色調,強度反映差異的大小。紅 + 綠 = 黃、綠 + 藍 = 青、紅 + 藍 = 洋紅;三者皆高為白、皆低為黑 (Howarth, 2024, §2.1.5, Fig. 2.9)。
| 像元顏色 | DN 相對大小(順序 R, G, B) | 在彩色紅外合成中的高雄例子 |
|---|---|---|
| 紅 | 第 1 ≫ 第 2、3 | 美濃平原農田、壽山、澄清湖周邊林地 |
| 黃(紅+綠) | 第 1、2 > 第 3 | 收割後的乾田、裸土 |
| 青(綠+藍) | 第 2、3 > 第 1 | 高雄港、愛河口的混濁水體 |
| 藍/灰白 | 第 3 高或三者皆中等 | 市區建成區、道路 |
| 黑 | 三者皆低 | 蓮池潭、澄清湖等清澈水體、陰影 |
課堂操作 1 用 Inspector 點三個位置(美濃農田、高雄港、三多商圈),先只看 B3、B4、B8、B11 四個數值,用上表推論它們在三種合成中各是什麼顏色,再開圖層驗證。推論正確,就已經會「讀」任何 RGB 合成了。
Map.addLayer 的 min/max 就是理論篇的最小–最大線性拉伸。Code Editor 的圖層設定面板另提供百分比與標準差拉伸,可直接對照理論篇第肆節(補充):
| Stretch 選項 | 對應理論篇(Garg, 2024, pp. 186–189) |
|---|---|
| 100% | 最小–最大線性拉伸:影像的最小值→黑、最大值→白 |
| 98%、90% | 百分比線性拉伸:捨去兩端 1% 或 5% 的極端像元再拉伸,對比通常更好 |
| 2σ、3σ | 以平均值 ± 2 或 3 個標準差為拉伸端點,也是百分比拉伸的一種 |
| Gamma 滑桿 | 冪次轉換:< 1 增強暗部(類似對數),> 1 增強亮部(類似指數) |
課堂操作 2 對「真色彩」圖層分別用 100% 與 98% 拉伸,用 Inspector 點同一個港區像元,記下兩次的顯示範圍與視覺差異;再把 Gamma 調到 0.6,觀察港區泥沙羽流是否更清楚。三組觀察寫在腳本註解中。提醒:拉伸只改變顯示,不改變像元值——之後計算指標仍用原始反射率。
波段運算(band arithmetic)是把影像中兩個以上波段相加、相減、相乘或相除。雲端波段運算是 Earth Engine 最強大的面向之一:平台的電腦專為這類重運算最佳化,即使行星尺度也能很快完成 (Dyson 等, 2024, §5.2.1)。
植生在近紅外(約 750–900 nm)反射率高、在紅光(約 630–690 nm)因葉綠素吸收而低。Landsat 1 發射後不久,分析者就設計出一個穩健的單一數值,以 −1 到 1 的尺度表達植生健康——NDVI = (NIR − Red)/(NIR + Red)。這種形式稱為「正規化差異」:分子是差、分母把值正規化。大量綠色植生約 0.8–0.9,沒有綠葉時接近 0,水體接近 −1 (Dyson 等, 2024, §5.2.1)。
// ===== 參、波段運算 =====
var nir = s2.select('B8'); // select:取近紅外波段
var red = s2.select('B4'); // select:取紅光波段
var numerator = nir.subtract(red); // subtract:NIR − Red
var denominator = nir.add(red); // add:NIR + Red
var ndvi = numerator.divide(denominator); // divide:得到 NDVI,值域 −1 到 1
var vegPalette = ['red', 'white', 'green']; // 低值紅、中值白、高值綠
// 顯示手算的 NDVI
Map.addLayer(ndvi, { min: -1, max: 1, palette: vegPalette }, 'NDVI 手算');用 Inspector 檢視植生區與非植生區的數值。正規化差異在遙測中太常見,Earth Engine 提供 normalizedDifference 方法把減、加、除一次完成;兩個波段的順序很重要——第一個是近紅外 B8,第二個是紅光 B4。若兩種算法畫出來不一樣,先檢查順序 (Dyson 等, 2024, §5.2.1):
// normalizedDifference:(B8 − B4)/(B8 + B4),一行完成
var ndvi2 = s2.normalizedDifference(['B8', 'B4']);
// 應與手算結果相同
Map.addLayer(ndvi2, { min: -1, max: 1, palette: vegPalette }, 'NDVI 內建');NDWI 同樣的方法可用於其他指標。Gao(1996)提出的 NDWI 是植生含水量的指標,對植冠液態水含量的變化敏感,可偵測乾旱逆境的植生或區分灌溉程度,也稱 NDMI:NDWI = (NIR − SWIR)/(NIR + SWIR),NIR 中心約 860 nm、SWIR 約 1240 nm。Sentinel-2 的 B8 為 NIR、B11 為 SWIR (Dyson 等, 2024, §5.2.1):
// NDWI(Gao 1996):植生含水量
var ndwi = s2.normalizedDifference(['B8', 'B11']);
var waterPalette = ['red', 'yellow', 'green', 'blue'];
// 愈藍含水量愈高
Map.addLayer(ndwi, { min: -0.5, max: 1, palette: waterPalette }, 'NDWI');觀察 NDVI 判定為植生的區域中,哪些在 NDWI 偏藍——那是含水量較高的植生 (Dyson 等, 2024, §5.2.1, Fig. 5.5;對應 Code Checkpoint F20a)。
對照理論篇 這就是第玖節的「波段比值」:NIR/Red 型的指標能抵銷地形陰影,所以高雄東側山區向陽與背陽面的 NDVI 相近,單看 B8 卻差很多——用 Inspector 在旗山、美濃丘陵兩側各點一處試試。另外,B11 是 20 m、B8 是 10 m,GEE 在計算時自動以最鄰近法重取樣(理論篇第捌節)。第 4 週會再介紹 NDBI 與 LST。
前一節用波段運算產生新的連續值;本節用邏輯運算子把波段或指標值分類。閾值用一個數字(閾值)與邏輯運算子,把影像的變異切成類別——例如把每個像元的 NDVI 概括為「無植生」或「植生」。這是相當大的簡化,但有助於理解地表的豐富變異,例如要看一座城市有多少比例是植生時 (Dyson 等, 2024, §5.2.2)。用 Inspector 查詢:公園與林地的 NDVI 約大於 0.5,因此可把 NDVI > 0.5 定義為林地、以下為非林地:
// ===== 肆、閾值與遮罩 =====
var threshold = 0.5;
// gt:逐像元檢查 NDVI > 0.5,真 → 1、假 → 0
var vegBinary = ndvi2.gt(threshold);
// 0 白、1 綠
Map.addLayer(vegBinary, { min: 0, max: 1, palette: ['white', 'green'] }, '植生二分');gt 屬於布林運算子家族:在每個像元做一次測試,成立回傳 1、否則 0。同家族還有 lt(小於)、lte(小於等於)、eq(等於)、neq(不等於)、gte(大於等於)(Dyson 等, 2024, §5.2.2)。用 Inspector 點綠色處,NDVI 應大於 0.5;點白色處應小於等於 0.5。
二分圖很有用,但常需要切成兩類以上。Earth Engine 的 where 方法依測試結果逐像元條件求值,類似其他語言的 if;但寫 Earth Engine 程式時要避免用 JavaScript 的 if——if 不在 Google 的伺服器上計算,會把所有資料送到自己的瀏覽器執行而造成嚴重問題。改以 −0.1 與 0.5 為閾值,把影像切成水體、非植生、植生三類:先用 ee.Image 建立全為 1 的影像,用 clip 裁到與 NDVI 相同範圍 (Dyson 等, 2024, §5.2.2):
// ee.Image(1):建立所有像元值為 1 的常數影像
var ndviClass = ee.Image(1)
// clip:裁到與 NDVI 影像相同的範圍
.clip(ndvi2.geometry());
// where:NDVI < −0.1 → 0(水體)
ndviClass = ndviClass.where(ndvi2.lt(-0.1), 0);
// where:NDVI > 0.5 → 2(植生);其餘維持 1(非植生)
ndviClass = ndviClass.where(ndvi2.gt(0.5), 2);
Map.addLayer(ndviClass, { min: 0, max: 2, palette: ['blue', 'white', 'green'] }, '水體/非植生/植生');ndvi2.gte(-0.1).and(ndvi2.lt(0.5)) 取出中間值域 (Dyson 等, 2024, §5.2.2)。遮罩把影像的特定區域(被遮罩覆蓋的)從顯示或分析中移除。Earth Engine 可檢視目前的遮罩,也可更新它。做遮罩時,把想看、想分析的值設為大於 0 的數,不要的值設為 0;用 updateMask 把這些值加入既有遮罩後,值為 0 的像元就被遮掉(螢幕上完全不顯示)(Dyson 等, 2024, §5.2.2):
// mask:檢視現有遮罩(影像範圍外為 0)
Map.addLayer(vegBinary.mask(), {}, '目前的遮罩');
// eq:植生像元 → 1,其餘 → 0,作為遮罩
var vegMask = vegBinary.eq(1);
// updateMask:把非植生像元遮掉
var vegOnly = s2.updateMask(vegMask);
// 真色彩,只剩植生
Map.addLayer(vegOnly, { bands: ['B4', 'B3', 'B2'], min: 0, max: 3000 }, '只顯示植生');
Map.addLayer(vegOnly.mask(), {}, '更新後的遮罩'); // 非植生區現在也是黑的關閉其他圖層,可看到 vegOnly 只剩植生區,非植生區透明。再畫出更新後的遮罩就能理解原因 (Dyson 等, 2024, §5.2.2, Figs. 5.9–5.11)。
remap 把影像中的特定值指派為不同的值,對類別資料特別有用。把 ndviClass 的 0、1、2 改為 0、1、10;因為中間值變成最大,palette 順序也要跟著調整 (Dyson 等, 2024, §5.2.2):
// remap:植生由 2 改為 10
var ndviRemap = ndviClass.remap([0, 1, 2], [0, 1, 10]);
Map.addLayer(ndviRemap, { min: 0, max: 10, palette: ['blue', 'white', 'green'] }, 'remap 後');用 Inspector 比較:點植生區,原圖為 2、remap 後為 10 (Dyson 等, 2024, §5.2.2, Fig. 5.12;對應 Code Checkpoint F20b)。
對照理論篇 gt 就是「灰階閾值」、where 就是「灰階切片」(理論篇第貳節);教材用平均值 + 0.5 σ 決定河流閾值,而不是目測——第 5 週會用 reduceRegion 算出高雄影像的統計量,把 0.5 這個閾值換成有依據的數字。
目標 新開腳本 w03_hw,以上週的高雄 Sentinel-2 影像計算 NDVI,切成水體/非植生/植生三類,並只顯示植生區的真色彩。
要求
| 評分項目 | 內容 | 配分 |
|---|---|---|
| NDVI 計算與顯示 | normalizedDifference 正確、波段順序正確、palette 合理 | 25 |
| 閾值決定 | 三處 NDVI 記錄完整、閾值有依據 | 25 |
| 三類圖與遮罩 | where 三類正確、updateMask 只留植生 | 25 |
| NDWI 與註解、繳交 | NDWI 正確、兩處數值比較說明合理、函式皆有註解、連結可開啟、準時 | 25 |
進階(選做) 教材 §5.3 的三個練習:黏土礦物比值 CMR = SWIR1/SWIR2、氧化鐵比值 IOR = Red/Blue、建成區指標 NDBI = (SWIR − NIR)/(SWIR + NIR)。試著算高雄的 NDBI,並用 JavaScript 的 reverse() 把 NDWI 的 palette 反轉——會發現 NDBI 正好是 NDWI 的負值 (Dyson 等, 2024, §5.3)。這是第 4 週與「都市擴張」專題的起點。
(參考答案要點:1. 第 2 個波段 B8 最高 → 健康植生。2. 百分比線性拉伸;不會,只改顯示。3. 正負號相反。4. if 在瀏覽器端執行,無法對伺服器端逐像元運算。5. 不存在(被遮罩),計算統計量時不納入,因此平均值只反映未遮罩區域。)
第 4 週實作:以高雄 Sentinel-2 與 Landsat 8/9 計算 NDVI、NDWI、NDBI 與地表溫度(LST),比較兩種感測器的結果,並用 reduceRegion 取得區域統計量。請先完成本週作業,並確認會用 normalizedDifference 與 where。
Cardille, J. A., Crowley, M. A., Saah, D., & Clinton, N. E. (Eds.). (2024). Cloud-based remote sensing with Google Earth Engine: Fundamentals and applications. Springer. https://doi.org/10.1007/978-3-031-26588-4(開放取用;全書亦可於 https://www.eefabook.org 免費閱讀;程式碼儲存庫 projects/gee-edu/book)
Dyson, K., Nicolau, A. P., Saah, D., & Clinton, N. (2024). Image manipulation: Bands, arithmetic, thresholds, and masks. In J. A. Cardille, M. A. Crowley, D. Saah, & N. E. Clinton (Eds.), Cloud-based remote sensing with Google Earth Engine: Fundamentals and applications (pp. 97–114). Springer. https://doi.org/10.1007/978-3-031-26588-4_5
Gao, B.-C. (1996). NDWI—A normalized difference water index for remote sensing of vegetation liquid water from space. Remote Sensing of Environment, 58(3), 257–266. https://doi.org/10.1016/S0034-4257(96)00067-3
Howarth, J. (2024). Exploring images. In J. A. Cardille, M. A. Crowley, D. Saah, & N. E. Clinton (Eds.), Cloud-based remote sensing with Google Earth Engine: Fundamentals and applications (pp. 19–39). Springer. https://doi.org/10.1007/978-3-031-26588-4_2
Garg, P. K. (2024). Remote sensing. Mercury Learning and Information. https://doi.org/10.1515/9781501522840(本週理論教材,見理論篇)