Поиск гнезда Эстонского аиста

Автор:

LastTeamLead

19 февраля 2026

165

19.02.2026

В прошлом году попалась интересная задача по GEOINT на L3akCTF 2025. Нужно было найти гнездо аиста в поле. Дана была только панорама места без опознавательных знаков. Ниже — 4 скрина панорамы с обзором на каждую сторону света.

Из полутора тысяч команд во время соревнования только три смогли найти нужное место. Соревнования закончились, но загадка покоя не давала — посидев несколько вечеров, всё же удалось придумать решение.

Проанализировав окрестности, смогли определить, что это Эстония. Поняли по форме дорожного знака. Перечень знаков ПДД Эстонии можно посмотреть тут: ссылка.

Угол дороги на знаке заострен

Угол дороги на знаке заострен

После определения страны начали искать информацию об аистах и нашли сайт с мониторингом всех гнёзд белых аистов: https://www.eoy.ee/valgetoonekurg/. На сайте есть карта всех гнёзд, их там 3366 штук.

Мониторинг гнёзд белых аистов в Эстонии

Мониторинг гнёзд белых аистов в Эстонии

Чисто теоретически задачу можно решить и в ручном режиме, просто перебрав все гнёзда Эстонии. Но на это может уйти не один день. Поэтому искали автоматизированное решение или какие-то дополнительные подсказки, чтобы сузить поиски. В итоге удалось придумать автоматизацию, и гнездо находится скриптами за 20 минут.

Для автоматизации нужны отформатированные и структурированные данные. Их легко вытащить с сайта мониторинга гнёзд. Даже парсить ничего не нужно, поскольку координаты приходят по API в JSON одним объектом. Ответ API тут: https://www.eoy.ee/valgetoonekurg/?load_events. Из всего объекта нужны только координаты, остальное — мусор.

Но когда начал писать парсер, нашёл поле «added» — это признак, где размещено гнездо. И среди прочего оказалось полезное: «На бетонных столбах без проводов». Такая фильтрация сократила количество точек до 429 штук — в 8 раз меньше, такое вполне реально и «руками» обработать. Однако признак я нашёл уже после реализации основного скрипта поиска, да и автоматизировать всё равно интереснее.

Идея автоматизированного поиска простая: пишем бота, который будет бегать по всем известным координатам и смотреть обстановку. Оглядывается по сторонам и сравнивает местность с известными фотками. Достаточно перейти в панораму Google Карт и сделать четыре скрина: дефолтная панорама, которая открывается сразу, — обычно это положение, параллельное дороге. А также ещё три фотки с шагом 90 градусов. На Картах Google, если кликать по компасу в углу экрана, обзор поворачивается ровно на 90 градусов.

Запускаем бота по всем точкам, чтобы скринить панораму с четырёх сторон света. А чтобы удобнее было обрабатывать результаты, делаем скрины с именем lat_lng_degree.jpg.

Когда насобирали скрины всех мест, нужно сравнить с исходными фото. Просто попиксельное сравнение тут не годится из-за разных масштабов и ракурсов. Но справится машинное зрение; для этого удобно использовать библиотеку OpenCV — она есть под множество языков, но, как по мне, в Python проще использовать. Базовое сравнение в OpenCV не учитывает цвет, так как картинки сравниваются в оттенках серого, а алгоритм производит сравнение по контрольным точкам и объектам, которые считает важными. Это даёт хорошие данные, но в нашем случае недостаточно.

Поэтому пришлось немного помудрить и добавить три уровня проверки:

  • Сравнение в шести разных масштабах — с шагом 10% шаблон уменьшается и увеличивается перед сверкой, а в итоге берётся лучший результат.

  • Сравнение на основе ORB — поиск ключевых точек. OpenCV ищет точки на изображениях, которые по «его мнению» являются значимыми, и сравнивает наличие и расположение таких точек на обоих изображениях.

  • Сравнение гистограмм — это сравнение по распределению цветов и яркости. Такая проверка может напортачить, если оригиналы сделаны зимой, а на панорамах будет лето или наоборот. Но если сезон один и тот же, то поможет отбросить лишние варианты.

Этими тремя алгоритмами сравниваем шаблонные картинки с каждой стороной света из набора одних и тех же координат. Выбираем лучшие варианты по всем сторонам света и высчитываем итоговый результат схожести шаблона и места с панорамы.

В итоге бот пробегается по всем местам, делает фотки с четырёх сторон и сравнивает их с шаблонными изображениями. Все результаты сортируем, и после выполнения нужное место оказалось на первом месте, набрав 32,5% схожести. На втором и третьем местах — по 29%, далее — ниже 25%.

Результат сверки мест на карте

Первая версия скрипта «бегала» по панорамам 13 часов, а потом ещё около часа сравнивала результаты. Но после фильтрации точек до 430 дело пошло шустрее — 2,5 часа. Это всё равно много, пришлось запустить бота на 10 потоков, больше мой ноут не вытянул (это 10 открытых в фоне браузеров). Скрипт сверки фоток тоже разделил на потоки. Итоговое время работы составило 19 минут: 13,5 минут — сбор фоток, и 5,5 минут — сверка с исходными фотками.

Код писал, безжалостно мучая нейронку, объясняя, что дописывать в мои алгоритмы, потом руками до ума доводил. Поэтому качество может немного хромать, но для баловства — самый раз, и понять идею можно. Все скрипты — в репозитории на GitHub.

Посмотреть на аиста можно тут: карта с панорамой.

Если вы нашли опечатку или ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter

Также по теме:

/Разборы задач

Разбор задачи «Ангара-1: Вход в ОС»

Эта первая задача из трех связанных. Цель миссии всех трех задач – запустить ракету в космос. Сперва нужно войти в ОС BugOS для управления полетами, но пароль потерялся, нужно его как-то восстановить.
Прочитать

111

0

/Разборы задач

Разбор задачи «Стул 3: Земля в иллюминаторе»

Задание все то же – определить координаты стула (в данном случае кресла) с точностью до 3-го знака
Прочитать

170

0