В качестве примера можно привести Гибралтарский залив, заморскую территорию Великобритании, расположенную географически к югу от Испании. Я получил мультиспектральное оптическое изображение Sentinel-2 с Sentinel Hub и сделал подмножество интересующей области с помощью SNAP.

Ближний инфракрасный диапазон (NIR) на исследуемом изображении Sentinel-2 вполне достаточен для обнаружения воды. Полоса 8 - это полоса ближнего ИК-диапазона в продуктах Sentinel-2 и имеет разрешение 10 м. Эта полоса хорошо впитывает воду. Поэтому мы предлагаем отличать воду от суши путем кластеризации этой полосы на два класса с использованием кластеризации K-средних. По этой ссылке вы можете скачать подмножество диапазона NIR, доступное в формате GeoTiff, которое было обработано в примере ниже.

Кластеризация K-средних - один из самых основных алгоритмов неконтролируемой классификации. Под неконтролируемым это означает, что этому классификатору не требуется набор обучающих данных, который был помечен заранее.

Вкратце, K-means в своей первоначальной реализации работает, как описано в этом сообщении в блоге:

  1. Алгоритмы K-средних начинают с инициализации случайным образом такого количества центроидов, которое соответствует количеству кластеров, которые мы хотим в конечном итоге получить.
  2. Каждая точка в наборе данных назначается кластеру, центроид которого является ближайшим (например, евклидово расстояние).
  3. В конце каждой итерации центроид в каждом кластере обновляется до среднего значения точек, классифицированных в этом кластере.
  4. Условие остановки - когда кластеры не меняются.

В этом руководстве не нужно беспокоиться о реализации K-средних, поскольку мы собираемся использовать Scikit-learn, который включает в себя множество алгоритмов машинного обучения, в том числе кластеризацию K-средних.

Прежде чем вдаваться в суть дела, нам нужно импортировать GDAL и модуль кластеризации из Scikit-learn:

Во-первых, спутниковое изображение считывается с помощью оболочки GDAL python, и из нее мы извлекаем полосу, которую хотим классифицировать:

Python-gdal значительно упрощает нашу жизнь, считывая данные в массив NumPy, который облегчает выполнение над ним различных операций с массивом. Это окажется полезным позже, когда в игру вступит Scikit-learn для классификации массива Numpy:

Классификация выполняется на уровне пикселей (т.е. каждый пиксель представляет собой статистическую личность, подлежащую классификации). Итак, перед кластеризацией нам сначала нужно предварительно обработать набор данных, изменив входное изображение с его исходных 2D-размеров (ширина x высота) на вектор отдельных лиц ([[x1] [x2]…. [Xn] ] где xi - интенсивность каждого пикселя):

После этого мы инициализируем классификатор, предоставляя количество кластеров в качестве входных данных, и подгоняем его к предварительно обработанному набору данных для его кластеризации (обучение не требуется, как описано выше):

Классифицированное изображение можно получить из меток, назначенных каждому пикселю. Однако этот массив меток имеет форму вектора и должен быть преобразован в изображение (ширина x высота):

Мы возвращаемся в GDAL, чтобы сохранить изображение как GeoTiff. Как и при открытии исходного NIR-изображения, мы начинаем с создания набора данных с теми же размерами, что и входное изображение. Затем мы сохраняем в нем кластерный массив изображений как отдельный бэнд:

Не забывайте аплодировать, если эта история была вам полезна.