Математические вычисления с изображениями можно выполнять с помощью таких операторов, как add()
и subtract()
, но для сложных вычислений с более чем парой членов хорошая альтернатива — функция expression()
. Дополнительные сведения об операторах и выражениях см. в следующих разделах.
Операторы
Математические операторы выполняют основные арифметические операции над полосами изображений. Они принимают два входных параметра: либо два изображения, либо одно изображение и постоянный член, который интерпретируется как однополосное постоянное изображение без маскированных пикселей. Операции выполняются попиксельно для каждой полосы.
В качестве базового примера рассмотрим задачу расчета индекса нормализованной разницы растительности (NDVI) с использованием изображений VIIRS, где используются операторы add()
, subtract()
и divide()
:
Редактор кода (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
Колаб (Питон)
# 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') ) ) )
Только пересечение немаскированных пикселей между двумя входными данными рассматривается и возвращается как немаскированное, все остальное маскируется. В общем, если какой-либо вход имеет только одну полосу, то он используется для всех полос на другом входе. Если входы имеют одинаковое количество полос, но не одинаковые имена, они используются попарно в естественном порядке. Выходные полосы названы в честь более длинного из двух входов или, если они равны по длине, в порядке первого входа. Тип выходных пикселей представляет собой объединение входных типов.
Следующий пример вычитания многоканального изображения демонстрирует, как каналы автоматически сопоставляются, в результате чего получается «вектор изменения» для каждого пикселя для каждой совпадающей полосы.
Редактор кода (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
Колаб (Питон)
# 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):
Редактор кода (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
Колаб (Питон)
# 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
. Только пересечение немаскированных пикселей рассматривается и возвращается как немаскированное, когда оцениваются полосы из более чем одного исходного изображения. Поддерживаемые операторы выражений перечислены в следующей таблице.
Тип | Символ | Имя |
---|---|---|
Арифметика | + - * / % ** | Сложение, вычитание, умножение, деление, модуль, показатель степени |
Реляционный | == != < > <= >= | Равно, Не равно, Меньше, Больше и т. д. |
Логический | && || ! ^ | И, Или, Нет, Ксор |
тройной | ? : | Если тогда еще |
Математические вычисления с изображениями можно выполнять с помощью таких операторов, как add()
и subtract()
, но для сложных вычислений с более чем парой членов хорошая альтернатива — функция expression()
. Дополнительные сведения об операторах и выражениях см. в следующих разделах.
Операторы
Математические операторы выполняют основные арифметические операции над полосами изображений. Они принимают два входных параметра: либо два изображения, либо одно изображение и постоянный член, который интерпретируется как однополосное постоянное изображение без маскированных пикселей. Операции выполняются попиксельно для каждой полосы.
В качестве базового примера рассмотрим задачу расчета индекса нормализованной разницы растительности (NDVI) с использованием изображений VIIRS, где используются операторы add()
, subtract()
и divide()
:
Редактор кода (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
Колаб (Питон)
# 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') ) ) )
Только пересечение немаскированных пикселей между двумя входными данными рассматривается и возвращается как немаскированное, все остальное маскируется. В общем, если какой-либо вход имеет только одну полосу, то он используется для всех полос на другом входе. Если входы имеют одинаковое количество полос, но не одинаковые имена, они используются попарно в естественном порядке. Выходные полосы названы в честь более длинного из двух входов или, если они равны по длине, в порядке первого входа. Тип выходных пикселей представляет собой объединение входных типов.
Следующий пример вычитания многоканального изображения демонстрирует, как каналы автоматически сопоставляются, в результате чего получается «вектор изменения» для каждого пикселя для каждой совпадающей полосы.
Редактор кода (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
Колаб (Питон)
# 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):
Редактор кода (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
Колаб (Питон)
# 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
. Только пересечение немаскированных пикселей рассматривается и возвращается как немаскированное, когда оцениваются полосы из более чем одного исходного изображения. Поддерживаемые операторы выражений перечислены в следующей таблице.
Тип | Символ | Имя |
---|---|---|
Арифметика | + - * / % ** | Сложение, вычитание, умножение, деление, модуль, показатель степени |
Реляционный | == != < > <= >= | Равно, Не равно, Меньше, Больше и т. д. |
Логический | && || ! ^ | И, Или, Нет, Ксор |
тройной | ? : | Если тогда еще |