‫NDVI, מיפוי פונקציה על אוסף, פסיפס באיכות גבוהה

במאמרים הקודמים למדתם איך להשיג סצנות Landsat ספציפיות באמצעות פקודה כמו זו, כאשר l8 ו-point הם ייבוא שמייצג את אוסף Landsat 8 TOA ואת הגיאומטריה של אזור העניין:

עורך הקוד (JavaScript)

// Define a point of interest. Use the UI Drawing Tools to import a point
// geometry and name it "point" or set the point coordinates with the
// ee.Geometry.Point() function as demonstrated here.
var point = ee.Geometry.Point([-122.292, 37.9018]);

// Import the Landsat 8 TOA image collection.
var l8 = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA');

// Get the least cloudy image in 2015.
var image = ee.Image(
  l8.filterBounds(point)
    .filterDate('2015-01-01', '2015-12-31')
    .sort('CLOUD_COVER')
    .first()
);

נניח שרוצים לחשב תמונה של אינדקס הפרש מנורמל של צמחייה (NDVI) מתוך תמונת Landsat. הצמחייה מחזירה אור בחלק האינפרה-אדום הקרוב (NIR) של הספקטרום האלקטרומגנטי וסופגת אור בחלק האדום (מידע נוסף על החזרת אור NIR מצמחייה). המדד NDVI משתמש בנתונים האלה כדי ליצור ערך יחיד שמשקף בערך את הפעילות הפוטוסינתטית שמתרחשת בפיקסל. החישוב הוא (NIR - red) / (NIR + red). התוצאה היא מספר בין 1 ל-1-, כאשר פיקסלים עם פעילות פוטוסינתטית גבוהה מקבלים ערך NDVI גבוה. זו אחת הדרכים לחשב NDVI ב-Earth Engine:

עורך הקוד (JavaScript)

// Compute the Normalized Difference Vegetation Index (NDVI).
var nir = image.select('B5');
var red = image.select('B4');
var ndvi = nir.subtract(red).divide(nir.add(red)).rename('NDVI');

// Display the result.
Map.centerObject(image, 9);
var ndviParams = {min: -1, max: 1, palette: ['blue', 'white', 'green']};
Map.addLayer(ndvi, ndviParams, 'NDVI image');

התוצאה אמורה להיראות כמו באיור 8. שימו לב שאנחנו משתמשים בפונקציה select() שמוסברת בקטע הקודם בנושא מיסוך כדי לקבל את הנתונים של הפסים NIR והאדומים, ואז מחשבים את NDVI באמצעות אופרטורים מתמטיים של תמונות שמוסברים בקטע בנושא מתמטיקה של Image. לבסוף, מציגים את התמונה עם פלטה. כאן השתמשנו בשמות צבעים במקום במחרוזות הקסדצימליות בלוח הצבעים. (פרטים נוספים זמינים במאמר הזה בנושא צבעים בשירות CSS).

Tutorial_api_08_ndvi.png
איור 8. ‫NDVI של סצנת Landsat אחת. הצבע הכחול מייצג ערך נמוך של NDVI והצבע הירוק מייצג ערך גבוה של NDVI.

הפעולה של הפרש נורמלי היא כל כך נפוצה בחישה מרחוק, שיש פונקציית קיצור ב-ee.Image שיכולה לפשט את הקוד בדוגמה הקודמת:

עורך הקוד (JavaScript)

var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');

מיפוי פונקציה על אוסף

נניח שרוצים להוסיף NDVI לכל תמונה באוסף תמונות. כדי לעשות את זה ב-Earth Engine, צריך map() פונקציה על האוסף. אל תתבלבלו בין map() לבין האובייקט Map. האפשרות הראשונה היא שיטה באוסף, והיא משתמשת ב-map במובן של מחשוב מקבילי של החלת פונקציה על כל רכיב באוסף. הפונקציה מגדירה את הפעולות שיחולו על כל רכיב באוסף. ראיתם פונקציה פשוטה במדריך ל-JavaScript, אבל עכשיו ניצור פונקציה שכוללת פונקציונליות של Earth Engine. לדוגמה, מעתיקים את קוד ה-NDVI הקודם לפונקציה שמחזירה את תמונת הקלט עם פס NDVI:‏

עורך הקוד (JavaScript)

var addNDVI = function(image) {
  var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');
  return image.addBands(ndvi);
};

// Test the addNDVI function on a single image.
var ndvi = addNDVI(image).select('NDVI');

יכול להיות שהקוד הזה לא יהיה יעיל לחישוב NDVI לתמונה אחת, אבל אפשר להשתמש בפונקציה הזו כארגומנט ל-map() כדי להוסיף פס NDVI לכל תמונה באוסף. לעתים קרובות כדאי קודם לבדוק פונקציה על תמונה אחת, כדי לוודא שהיא פועלת כמו שציפיתם. אחרי שבודקים את הפונקציה על תמונה ספציפית וקובעים שהיא עושה את מה שרוצים, אפשר למפות אותה על הקולקציה:

עורך הקוד (JavaScript)

var withNDVI = l8.map(addNDVI);

כדי לוודא שאכן נוסף פס NDVI לכל תמונה באוסף הזה, אפשר להוסיף את withNDVI האוסף למפה ולשאול על מיקום אקראי באמצעות הכרטיסייה Inspector. אפשר לראות שלכל תמונה באוסף יש עכשיו פס שנקרא NDVI.

יצירת תמונה מורכבת של הפיקסלים הירוקים ביותר

אחרי שיצרתם אוסף תמונות שבו לכל תמונה יש פס NDVI, אפשר לבחון דרך חדשה ליצירת תמונות מורכבות: qualityMosaic(). יכול להיות ששמתם לב לבעיות המשכיות בין נתיבי Landsat, גם בתמונת הפסיפס של חציון הפיקסלים. הסיבה לכך יכולה להיות קשורה בחלקה להבדלים בפנולוגיה כתוצאה מכך שתמונות בנתיבים סמוכים נאספות בזמנים שונים (במרווח של 8 ימים). אחת הדרכים לצמצם את ההשפעה הזו היא לנסות להגדיר ערכי פיקסלים בקומפוזיציה מאותו שלב פנולוגי בערך, למשל הזמן שבו הצמחים ירוקים במיוחד (כשהעלים נמצאים על הצמח ופעילים פוטוסינתטית). אם נגדיר את הערך המקסימלי של הירוק לפי הערך המקסימלי של NDVI, נוכל להשתמש ב-qualityMosaic() כדי ליצור קומפוזיציה שבה כל פיקסל מכיל את הפיקסל עם הערך המקסימלי של NDVI מהאוסף. עכשיו אפשר להשתמש בפס ה-NDVI שנוסף באוסף withNDVI:

עורך הקוד (JavaScript)

// Make a "greenest" pixel composite.
var greenest = withNDVI.qualityMosaic('NDVI');

// Display the result.
var visParams = {bands: ['B4', 'B3', 'B2'], max: 0.3};
Map.addLayer(greenest, visParams, 'Greenest pixel composite');

התוצאה של הקוד הזה צריכה להיראות כמו באיור 9. בהשוואה בין איור 9 לבין הממוצע המשוקלל שמוצג באיור 6, אפשר לראות שהממוצע המשוקלל של הפיקסלים הירוקים הוא אכן ירוק הרבה יותר. עם זאת, בדיקה מדוקדקת של מקווי מים תגלה בעיה אחרת. באופן ספציפי, גופי מים נראים עכשיו מעוננים. הסיבה לכך היא האופן שבו פועלת השיטה qualityMosaic(): בכל מיקום, נבדקת סדרת הזמן כולה והפיקסל עם הערך המקסימלי בפס ה-NDVI מוגדר כערך המורכב. ערך ה-NDVI מעל עננים גבוה יותר מאשר מעל מים, ולכן אזורים עם מים מקבלים פיקסלים מעוננים, ואילו אזורים עם צמחייה מופיעים בירוק כי ערך ה-NDVI הוא הכי גבוה כשהצמחייה בפיקסל פעילה פוטוסינתטית.

Tutorial_api_09_greenest.png
איור 9. קומפוזיציה של הפיקסלים הכי ירוקים ב-Landsat 8.

עכשיו ראיתם כמה דרכים ליצור קומפוזיציה ופסיפס של תמונות ב-Earth Engine. אתם יכולים ליצור קומפוזיציות של ערכים עדכניים, חציון או הפיקסל הירוק ביותר מתמונות שסוננו לפי זמן ומקום, או מכל התמונות באוסף. למדתם איך לבצע חישובים על התמונות ולחלץ מידע. בדף הבא מוסבר איך להוציא מידע מ-Earth Engine, למשל כתרשים או כמערך נתונים שמיוצא לתיקייה ב-Google Drive.