אפשר לבצע פעולות מתמטיות בתמונות באמצעות אופרטורים כמו add()
ו-subtract()
, אבל לחישוב מורכב עם יותר מכמה מונחים, הפונקציה expression()
היא חלופה טובה. מידע נוסף על אופרטורים ועל ביטויים זמין בקטעים הבאים.
אופרטורים
אופרטורים מתמטיים מבצעים פעולות אריתמטיות בסיסיות על פסלי תמונה. הם מקבלים שני מקורות קלט: שתי תמונות או תמונה אחת ומשתנה קבוע, שמתורגם כתמונה קבועה עם פס אחד ללא פיקסלים מוסתרים. הפעולות מתבצעות לכל פיקסל בכל פס.
כדוגמה בסיסית, נניח שרוצים לחשב את אינדקס ההפרש המנורמלי של הצמחייה (NDVI) באמצעות תמונות VIIRS, תוך שימוש באופרטורים add()
, subtract()
ו-divide()
:
Code Editor (JavaScript)
// Load a VIIRS 8-day surface reflectance composite for May 2024. var viirs202405 = ee.ImageCollection('NASA/VIIRS/002/VNP09H1').filter( ee.Filter.date('2024-05-01', '2024-05-16')).first(); // Compute NDVI. var ndvi202405 = viirs202405.select('SurfReflect_I2') .subtract(viirs202405.select('SurfReflect_I1')) .divide(viirs202405.select('SurfReflect_I2') .add(viirs202405.select('SurfReflect_I1')));
import ee import geemap.core as geemap
Colab (Python)
# Load a VIIRS 8-day surface reflectance composite for May 2024. viirs202405 = ( ee.ImageCollection('NASA/VIIRS/002/VNP09H1') .filter(ee.Filter.date('2024-05-01', '2024-05-16')) .first() ) # Compute NDVI. ndvi202405 = ( viirs202405.select('SurfReflect_I2') .subtract(viirs202405.select('SurfReflect_I1')) .divide( viirs202405.select('SurfReflect_I2').add( viirs202405.select('SurfReflect_I1') ) ) )
רק הצטלבות הפיקסלים ללא מסכה בין שני מקורות הקלט נלקחת בחשבון ומוחזרת ללא מסכה, כל השאר ממוסתרים. באופן כללי, אם לכל אחד מהקלטים יש רק תדר אחד, הוא משמש כנגד כל התדרים בקלט השני. אם למשתני הקלט יש אותו מספר פסגות אבל לא אותם שמות, הם משמשים בזוגות בסדר הטבעי. השמות של פס ההמרה ייקבעו לפי אורך הקלט הארוך מבין שני הקלטים, או לפי הסדר של הקלט הראשון אם שני הקלטים באורך זהה. הסוג של הפיקסלים בפלט הוא האיחוד של סוגי הקלט.
הדוגמה הבאה של חיסור תמונות בכמה תדרים ממחישה איך התדרים מותאמים באופן אוטומטי, וכתוצאה מכך נוצר "וקטור שינוי" לכל פיקסל בכל תדר שמופיע בו-זמנית.
Code Editor (JavaScript)
// Load a VIIRS 8-day surface reflectance composite for September 2024. var viirs202409 = ee.ImageCollection('NASA/VIIRS/002/VNP09H1').filter( ee.Filter.date('2024-09-01', '2024-09-16')).first(); // Compute multi-band difference between the September composite and the // previously loaded May composite. var diff = viirs202409.subtract(ndvi202405); Map.addLayer(diff, { bands: ['SurfReflect_I1', 'SurfReflect_I2', 'SurfReflect_I3'], min: -1, max: 1 }, 'difference'); // Compute the squared difference in each band. var squaredDifference = diff.pow(2); Map.addLayer(squaredDifference, { bands: ['SurfReflect_I1', 'SurfReflect_I2', 'SurfReflect_I3'], min: 0, max: 0.7 }, 'squared diff.');
import ee import geemap.core as geemap
Colab (Python)
# Load a VIIRS 8-day surface reflectance composite for September 2024. viirs202409 = ( ee.ImageCollection('NASA/VIIRS/002/VNP09H1') .filter(ee.Filter.date('2024-09-01', '2024-09-16')) .first() ) # Compute multi-band difference between the September composite and the # previously loaded May composite. diff = viirs202409.subtract(ndvi202405) m = geemap.Map() m.add_layer( diff, { 'bands': ['SurfReflect_I1', 'SurfReflect_I2', 'SurfReflect_I3'], 'min': -1, 'max': 1, }, 'difference', ) # Compute the squared difference in each band. squared_difference = diff.pow(2) m.add_layer( squared_difference, { 'bands': ['SurfReflect_I1', 'SurfReflect_I2', 'SurfReflect_I3'], 'min': 0, 'max': 0.7, }, 'squared diff.', ) display(m)
בחלק השני של הדוגמה הזו, הפרש הריבועים מחושב באמצעות image.pow(2)
. הרשימה המלאה של אופרטורים מתמטיים שמטפלים בחשבון בסיסי, בטריגונומטריה, בהעלאה בחזקה, בעיגול, בהמרה, בפעולות בייטיות ועוד מופיעה במסמכי התיעוד של ה-API.
ביטויים
כדי להטמיע ביטויים מתמטיים מורכבים יותר, מומלץ להשתמש בפונקציה image.expression()
, שמנתחת ייצוג טקסט של פעולה מתמטית.
בדוגמה הבאה נעשה שימוש ב-expression()
כדי לחשב את מדד הצמחייה המשופרת (EVI):
Code Editor (JavaScript)
// Load a Landsat 8 image. var image = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318'); // Compute the EVI using an expression. var evi = image.expression( '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', { 'NIR': image.select('B5'), 'RED': image.select('B4'), 'BLUE': image.select('B2') }); Map.centerObject(image, 9); Map.addLayer(evi, {min: -1, max: 1, palette: ['a6611a', 'f5f5f5', '4dac26']});
import ee import geemap.core as geemap
Colab (Python)
# Load a Landsat 8 image. image = ee.Image('LANDSAT/LC08/C02/T1_TOA/LC08_044034_20140318') # Compute the EVI using an expression. evi = image.expression( '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', { 'NIR': image.select('B5'), 'RED': image.select('B4'), 'BLUE': image.select('B2'), }, ) # Define a map centered on San Francisco Bay. map_evi = geemap.Map(center=[37.4675, -122.1363], zoom=9) # Add the image layer to the map and display it. map_evi.add_layer( evi, {'min': -1, 'max': 1, 'palette': ['a6611a', 'f5f5f5', '4dac26']}, 'evi' ) display(map_evi)
שימו לב שהארגומנט הראשון של expression()
הוא הייצוג הטקסטואלי של הפעולה המתמטית, והארגומנט השני הוא מילון שבו המפתחות הם שמות המשתנים שנעשה בהם שימוש בביטוי, והערכים הם פסלי התמונה שאליה צריך למפות את המשתנים. אפשר להתייחס לפסים בתמונה בתור b("band name")
או b(index)
, למשל b(0)
, במקום לספק את המילון. אפשר להגדיר פסות מתמונות שאינן הקלט באמצעות מילון מפת הפסות. שימו לב שב-expression()
נעשה שימוש ב'חלוקה ללא שארית', שמבטלת את השארית ומחזירה מספר שלם כשמחלקים בין שני מספרים שלמים. לדוגמה
10 / 20 = 0
. כדי לשנות את ההתנהגות הזו, מכפילים את אחד מהאופרטנדים ב-1.0
: 10 * 1.0 / 20 = 0.5
. רק הצטלבות הפיקסלים ללא מסכה נלקחת בחשבון ומוחזרת ללא מסכה כשבודקים פסות מיותר מתמונה מקור אחת. אופרטורי הביטויים הנתמכים מפורטים בטבלה הבאה.
סוג | סמל | שם |
---|---|---|
Arithmetic | + - * / % ** | הוספה, חיסור, כפל, חילוק, מודול, מעריך |
יחסי | == != < > <= >= | שווה, לא שווה, קטן מ-, גדול מ- וכו'. |
לוגי | && || ! ^ | And, Or, Not, Xor |
טרינרי | ? : | If then else |