Идея/Вдохновение
Я создаю проект, который может определять деревья по спутниковым данным. Эта идея пришла ко мне от компании 20tree.ai. Которая использует спутниковые снимки и искусственный интеллект для отслеживания лесов и растительности по всему миру. Они много используют для этой технологии. Вы можете отслеживать вырубку лесов в районе. Отслеживая количество пропавших деревьев за определенный период времени. Компания Спасепт использует спутниковые снимки и искусственный интеллект. Чтобы предотвратить пожары и перебои в подаче электроэнергии, заметив деревья, растущие слишком близко к линиям электропередач.
Использование спутниковых снимков экономит время и деньги. Так как проверка лесного хозяйства с помощью вертолета или дрона может стоить больших денег. И будет стоить много времени, чтобы настроить вертолет и дрон для полета над лесничеством.
Набор данных
Когда я впервые пытался собрать набор данных для модели машинного обучения. Я остановился на использовании движка Google Earth. Я почерпнул эту идею из этого среднего поста в блоге. Которая использовала спутниковые снимки для обнаружения оползней. В своем блоге он осветил проблему получения спутниковых данных. Где, если вы хотите получить изображения с веб-сайта ESA Copernicus SciHub. Вам придется делать их вручную. И вы не можете добавить координаты области, которую хотите захватить. Таким образом, вы получаете изображения размером с континент. С чем я также могу согласиться, исходя из моего личного использования сервиса. Когда я пытался получить изображение, покрывающее небольшую площадь в моем городе. Вместо этого я получил большие изображения, покрывающие всю Францию и Великобританию.
С помощью Google Earth Engine вы можете фильтровать по дате, области и облачности. Именно поэтому был рекомендован движок Google Earth. Я использовал код из блога для создания набора данных. Я добавил настройки в код для моего набора данных. В сообщении блога описан процесс ниже:
Наш окончательный (полу) автоматизированный конвейер работал следующим образом:
1. Введите координаты в Cropping_coordinates.py, чтобы рассчитать координаты квадрата площадью 10 км.
2. Скопируйте выходные данные и замените переменные в верхней части кода JavaScript в консоли Google Earth Engine (использованный нами код JavaScript). Не забудьте изменить диапазон дат на тот, который вам нравится.
3. Загрузите изображения со средней плотностью облаков менее 100, щелкнув ссылку, напечатанную в выводе консоли.
Когда я получил изображения, они выглядели так:
В начале я не знал, почему это так. Но позже узнал, что спутниковые снимки были разделены на разные полосы. Полосы — это определенные длины волн, которые улавливает спутник. Это позволяет пользователю просматривать изображение с элементами, которые не видны человеческому глазу или могут быть выделены с помощью выбранной длины волны. Например, обычно спутниковые снимки используются для отслеживания сельскохозяйственных угодий. Используя инфракрасный спектр, легче обнаружить растительность.
Википедия дает хороший список длин волн и их использования:
Длины волн приблизительны; точные значения зависят от инструментов конкретного спутника:
- Синий, 450–515..520 нм, используется для визуализации атмосферы и глубоководных объектов и может достигать глубины до 150 футов (50 м) в чистой воде.
- Зеленый, 515..520–590..600 нм, используется для визуализации растительности и глубоководных структур на глубине до 90 футов (30 м) в чистой воде.
- Красный, 600..630–680..690 нм, используется для визуализации искусственных объектов в воде на глубине до 30 футов (9 м), в почве и растительности.
- Ближний инфракрасный диапазон (NIR), 750–900 нм, используется в основном для визуализации растительности.
- Средний инфракрасный диапазон (MIR), 1550–1750 нм, используется для визуализации растительности, влажности почвы и некоторых лесных пожаров.
- Дальний инфракрасный диапазон (FIR), 2080–2350 нм, используется для визуализации почвы, влаги, геологических особенностей, силикатов, глин и пожаров.
- Тепловой инфракрасный, 10400–12500 нм, использует испускаемое вместо отраженного излучения для изображения геологических структур, тепловых перепадов водных потоков, пожаров и для ночных исследований.
- Радар и связанные с ним технологии полезны для картографирования местности и обнаружения различных объектов.
А также комбинации:
- True-color использует только красный, зеленый и синий каналы, сопоставленные с соответствующими цветами. Как обычная цветная фотография, она хороша для анализа искусственных объектов и проста для понимания начинающими аналитиками.
- Зелено-красный-инфракрасный, где синий канал заменен ближним инфракрасным, используется для растительности, которая хорошо отражает в ближнем ИК-диапазоне; затем он отображается синим цветом. Эта комбинация часто используется для обнаружения растительности и маскировки.
- Blue-NIR-MIR, где синий канал использует видимый синий цвет, зеленый использует NIR (поэтому растительность остается зеленой), а MIR отображается красным. Такие изображения позволяют увидеть глубину воды, растительный покров, влажность почвы и наличие пожаров на одном изображении.
Я хотел простое изображение RGB. Это просто видимый свет. Как лучше начать с простого. Для этого нам нужно изображение, объединяющее все 3 полосы в одну. Итак, используя некоторые примеры кода движка Google Earth и мои личные изменения. Мне удалось получить некоторые изображения.
Красный квадрат, покрывающий карту, — это область, которую Google Earth Engine захватит для изображения.
Изображение ниже:
Честно говоря, качество изображения ужасное. Начал замечать проблемы при настройке красного квадрата. Вы видите на изображении общую площадь за пределами красного квадрата. Вы можете видеть, что изображению не хватает четкости. Это означает, что если вы увеличите масштаб еще больше, вы не сможете сказать, что на изображении, потому что качество довольно плохое.
Причиной проблемы стало разрешение изображений. Спутники Sentinel-2 и Landsat имеют разрешение всего 30 метров.
Этот веб-сайт прекрасно объясняет пространственное разрешение:
Пространственное разрешение относится к размеру одного пикселя на земле. Пиксель — это наименьшая «точка», которая составляет оптическое спутниковое изображение и в основном определяет, насколько детализирована картинка. Данные Landsat, например, имеют разрешение 30 м, что означает, что каждый пиксель соответствует области 30 м x 30 м на земле. Считается, что это изображение среднего разрешения, которое может охватывать всю территорию города, но уровень детализации недостаточен для того, чтобы различать отдельные объекты, такие как дома или автомобили.
Пользовательский набор данных
Все данные из открытых источников идут до 30 метров. За более точные данные нужно платить. Поэтому мне пришлось найти решение, позволяющее получать изображения более высокого качества. Не раскошелившись на небольшое состояние.
После долгих раздумий (и переживаний). Я нашел решение, скрытое у всех на виду. При использовании навигационных систем на вашем телефоне. Ваш телефон может дать вам спутниковое изображение вашего района. Вы можете видеть, какие здания какие. И различать предметы. Поэтому я решил использовать (обычный) Google Earth и делать снимки прямо с веб-сайта. Чтобы убедиться, что экран захватывает все одинакового размера, использовал программу под названием PicPick.
Вот одно изображение, которое я захватил:
Теперь мы различаем объекты. А именно деревья.
Маркировка данных
Теперь у нас небольшой размер выборки. Нам нужно решение, чтобы модель машинного обучения знала, что она смотрит на дерево.
Поэтому использовал программу под названием LabelImg from GitHub. Который я использовал, чтобы вручную пометить деревья на изображениях.
Я не маркировал каждое дерево на каждом изображении. Так как это займет вечность. Но хотелось иметь какую-то маркировку, чтобы модель могла выбрать одно или два дерева на тестовом изображении. По той же причине набор данных очень мал. Причина в том, что если мне нужно внести изменения в набор данных. Это не займет много времени. Кроме того, просто создать модель в виде простого прототипа, прежде чем масштабировать работу.
Модель
Этот проект представляет собой проблему обнаружения объектов. Поскольку я имею дело с данными изображения. Я буду использовать какой-то тип сверточной нейронной сети. Один пример, который я хотел использовать для модели, — здесь. Но быстро понял, что, поскольку модель уже обучена, модель не сможет считывать деревья со спутникового изображения. В сообщении в блоге упоминается, что вы занимаетесь передачей обучения или тонкой настройкой. Но сказал, что это выходит за рамки статьи. Так что пришлось искать новую модель.
R-CNN
Через некоторое время гугления. Я нашел интересную модель, которую я могу использовать, под названием R-CNN. Точнее быстрее R CNN. R CNN, что расшифровывается как региональная сверточная нейронная сеть. Где модель выборочно проходит через многие области изображения 2000 предложений. После того, как области предложения выбраны, они затем формируются для ввода сверточной нейронной сети. После того, как машины опорных векторов классифицируют регионы. Затем используется регрессия ограничивающей рамки, чтобы выяснить, куда идет рамка.
Но есть несколько проблем, связанных с использованием традиционной R CNN. В основном то, что обработка изображения занимает много времени. Поскольку модель извлекает 2000 регионов для проверки. Прогноз с помощью модели занимает около 40 секунд.
Быстрый R-CNN
Улучшенная версия R CNN была создана тем же человеком. Вызывается Fast R CNN. Основное отличие заключается в том, что вместо извлечения тысяч областей из изображения. Быстрый R-CNN вводит все изображение. Затем CNN создает карту сверточных объектов на основе предложений выбранного региона. Затем предложения регионов формируются для слоя объединения. После этого он снова преобразуется, чтобы войти в полносвязный слой. Для каждого вектора признаков интересующей области он перемещается на слой SoftMax для прогнозирования класса. Использование регрессии ограничивающей рамки для поиска рамок.
Одна проблема заключается в том, что поскольку Fast R-CNN использует выборочный поиск, это замедляет тестирование. Но Fast R-CNN намного быстрее, чем традиционный R-CNN. Поскольку Fast R-CNN прогнозирует около 2 секунд.
Быстрее R-CNN
Теперь у нас есть более быстрый R-CNN. В приведенных выше примерах используется выборочный поиск для просмотра регионов предложения. Быстрее R-CNN использует отдельную сеть прогнозирования предложений региона. Использование сверточной карты признаков. Затем предложения преобразуются для слоя объединения. Для классификации региона. Также регрессор ограничительной рамки используется для размещения изображений.
Кодирование модели
Я следовал учебнику здесь. В учебнике использовался набор данных клеток крови. Я заменил набор данных своим собственным набором данных фотографий Google Earth. Чтобы подготовить данные для модели, мне пришлось преобразовать ограничивающие рамки из XML в CSV.
Для этого я использовал pandas и модуль ElementTree Python. И заимствованный код из мастерства машинного обучения и файл экспорта, связанный в туториале.
df = pd.DataFrame(None, columns=['filename', 'tree_type', 'xmin', 'ymax', 'ymix', 'ymax']) list_dataframe = [] folder = 'Custom_dataset\\Labels'
В этом разделе устанавливаются переменные, которые будут использоваться для цикла. Пустой кадр данных настроен с именем имен файлов, классом и ограничивающими рамками. Путь к папке, содержащей изображения, сохраняется в переменной папки.
for file in os.listdir(folder): path = 'Custom_dataset\Labels\\' file = path + file print(file)
Начало цикла for начинается с перечисления файлов в папке. Затем путь к файлу распечатывается путем объединения пути к папке и имени файла. Это делается как обычный цикл for без os.listdir, который не работал на моем ноутбуке.
filename = re.sub('Custom_dataset\\\Labels', "", file) filename = filename.replace("\\", "") filename = filename.replace(".xml", ".png")
При печати имени файла было слишком много обратной косой черты. Поэтому, чтобы избавиться от этого, использовались функции str.replace. Кроме того, в качестве папки используются имена меток, а не изображения. Имена файлов заканчивались на XML. Итак, заменили на формат файла PNG.
tree_type = 'Tree' tree = ElementTree.parse(file) # get the root of the document root = tree.getroot() # extract each bounding box boxes = list()
Раздел анализирует файл xml. Сохраняет имя класса. В tree_type. tree = ElementTree.parse(file)
разбирает файл. Затем root = tree.getroot()
получает корень файла. И сохраняет поле склеивания в списке.
for box in root.findall('.//bndbox'): xmin = int(box.find('xmin').text) ymin = int(box.find('ymin').text) xmax = int(box.find('xmax').text) ymax = int(box.find('ymax').text) row_list = [filename, tree_type, xmin, xmax, ymin, ymax] print(row_list) list_dataframe.append(row_list)
Цикл for проходит через все поля и извлекает координаты. Из четырех углов коробки. Затем создается список, в котором сохраняются имя файла, класс и координаты. Затем добавляется к фрейму данных ранее.
print(list_dataframe) df = pd.DataFrame(list_dataframe, columns=['filename', 'tree_type', 'xmin', 'xmax', 'ymin', 'ymax']) print(df.head()) df.to_csv('testing.csv', index=False)
После этого list_dataframe содержит все данные файлов. Затем добавляется в другой фрейм данных с именами столбцов. А df.to_csv превращает фрейм данных в файл CSV.
Реализация модели
Теперь в учебнике предлагается использовать для преобразования файла CSV в файл txt. В качестве модели используется другой формат.
filepath, x1,y1,x2,y2,class_name
"где":
- filepath — это путь к тренировочному изображению
- x1 - координата xmin для ограничивающей рамки
- y1 — координата ymin ограничивающей рамки
- x2 - координата xmax для ограничивающей рамки
- y2 — координата ymax ограничивающей рамки
- class_name — это имя класса в этой ограничивающей рамке.
Теперь руководство просит нас клонировать этот репозиторий GitHub. Когда я запустил модель, я получил несколько ошибок. Итак, я зашел в репозиторий и отредактировал код. Большинство ошибок были AttributeError: module ‘keras.backend’ has no attribute ‘image_dim_ordering’.
Я нашел этот ответ на вопрос GitHub полезным для решения проблемы. Это связано с тем, что часть используемого кода устарела. И вам нужно использовать новый keras API, который имеет разные имена для функций.
Итак, после нескольких часов гугления по другим вопросам модель машинного обучения заработала. Я использовал виртуальную машину для глубокого обучения в облаке Google для обучения своей модели.
Из-за количества времени. Решил уменьшить количество эпох до 5. Так как каждая эпоха занимала 4 часа. И номер по умолчанию был 1000. Что займет пару дней обучения и совсем немного денег.
Теперь мне нужно было протестировать модель. Я сделал это на своем ноутбуке. Поскольку виртуальная машина Google не показывала изображения
Для этого я запустил оператор:
python test_frcnn.py -p test_images
Вывод показывает, что он нашел несколько деревьев:
Модель смогла найти участки с деревьями. Преимущественно густой лесной массив.
А другие, совсем нет:
Похоже, модель не может указывать на отдельные деревья. Но это может указывать на большие площади лесного хозяйства.
Улучшения
Как я упоминал выше, модель не может определить отдельные деревья. Но районы лесного хозяйства. Но и то с участками лесного хозяйства. Он может определить только некоторые разделы. Несколько небольших ящиков покрывают большую площадь лесного хозяйства.
Набор данных был кратким. Таким образом, я могу получить работоспособный прототип и запустить его. Маркировку можно улучшить, поместив в коробку каждое дерево на изображении. И иметь пользовательскую сегментацию для областей лесного хозяйства. Вместо ящиков для покрытия площади лесного хозяйства.
Набор данных очень маленький (20 изображений) и обучен только для 5 эпох. Это можно улучшить, просто добавив больше изображений в набор данных. И тратить больше времени на обучение модели.
Серьезный вопрос, который нужно задать, заключается в том, как я буду маркировать большой набор данных. Маркировать 20 изображений было уже достаточно долго. Маркируя деревья вручную. Заняло около часа или около того. Не представляю, как разметить тысячу изображений вручную. Кроме того, с пользовательской сегментацией для больших лесных массивов я не уверен, как создавать собственные формы. Чтобы покрыть форму лесного хозяйства. Поскольку программа, которую я использовал, допускает только ящики. Не настраиваемые формы, такие как многоугольники.