Геолокация по теням: как определить место съёмки исторической фотографии

от автора

В этой статье я расскажу о том, как можно определить географическое местоположение объекта на фотографии, используя только длину тени и время съёмки. Мы рассмотрим конкретный пример — историческую фотографию 1963 года из Сайгона (ныне Хошимин), и напишем Python-скрипт для анализа возможных локаций.

Теория: как работают тени?

Представьте, что вы стоите рано утром на улице. Солнце только поднимается над горизонтом, и ваша тень очень длинная. К полудню солнце поднимается высоко в небо, и тень становится совсем короткой. А к вечеру тень снова удлиняется.

Давайте разберем эту геометрию подробнее. Вот простая схема:

             Солнце •                    /|     Угол высоты   / |     солнца (θ) → / θ|                 /   | Высота                /    | объекта (h)               /     |              /      |     --------+------+--------     Горизонт    Длина               тени (s) 

Что мы видим на этой схеме:

  • Солнце находится под углом θ к горизонту (это называется «угол высоты солнца»)

  • У нас есть объект высотой h (например, человек или столб)

  • Этот объект отбрасывает тень длиной s

Связь между этими величинами описывается простой формулой:

длина_тени = высота_объекта / tan(угол_высоты_солнца)

Или математически:

s = h / tan(θ)

Что это значит на практике?

  • Когда солнце низко (маленький угол θ), тень длинная

  • Когда солнце высоко (большой угол θ), тень короткая

  • Отношение длины тени к высоте объекта (s/h) зависит только от угла высоты солнца

Алгоритм поиска места съёмки:

  1. Берём конкретное время и дату фотографии

  2. Для каждой точки на карте мира:

    • Вычисляем, под каким углом там было солнце в этот момент

    • Рассчитываем, какой длины должна была быть тень

    • Сравниваем с реальной тенью на фотографии

  3. Точки, где расчётная длина совпадает с реальной — потенциальные места съёмки

В итоге на карте мы получим линию возможных локаций — все места, где в заданный момент времени тени имели именно такую длину.

Реализация алгоритма

Давайте разберем, как реализовать наш метод пошагово

Шаг 1: Создание координатной сетки

Сначала мы создаём сетку возможных координат на поверхности Земли. Мы используем шаг в 0.5 градуса как компромисс между точностью и скоростью вычислений:

lat_resolution = 0.5  # шаг по широте в градусах lon_resolution = 0.5  # шаг по долготе в градусах  # Создаём массивы координат # Широта от -60° до +85° (исключаем полярные регионы) lats = np.arange(-60, 85, lat_resolution) # Долгота от -180° до +180° lons = np.arange(-180, 180, lon_resolution)  # Создаём сетку координат lons_grid, lats_grid = np.meshgrid(lons, lats) 

Шаг 2: Расчёт высоты солнца с помощью suncalc

Для расчёта положения солнца мы используем библиотеку suncalc. Это JavaScript библиотека, портированная на Python, которая вычисляет видимое положение солнца для любой точки на Земле в заданный момент времени. Она учитывает:

  • Орбиту Земли

  • Наклон земной оси

  • Точное время и дату

  • Географические координаты

Функция get_position возвращает несколько параметров, но нас интересует прежде всего altitude — угол высоты солнца над горизонтом в радианах.

Для каждой точки нашей сетки мы вычисляем этот угол:

sun_altitudes = np.zeros_like(lons_grid)  # массив для хранения углов  for i in range(len(lats)):     for j in range(len(lons)):         # Получаем положение солнца для заданных координат и времени         pos = get_position(date_time, lons[j], lats[i])         # Сохраняем угол высоты солнца (в радианах)         sun_altitudes[i, j] = pos['altitude'] 

Шаг 3: Расчёт ожидаемой длины тени

Теперь, когда у нас есть углы высоты солнца для каждой точки на карте, мы можем рассчитать, какой длины должна быть тень в этой точке. Используя нашу формулу из теоретической части (s = h / tan(θ)), вычисляем ожидаемый размер тени для объекта известной высоты:

# Рассчитываем ожидаемую длину тени для каждой точки сетки # object_height - высота объекта (например, человека на фото) # sun_altitudes - массив углов высоты солнца в радианах expected_shadow_lengths = object_height / np.tan(sun_altitudes)  # Сравниваем ожидаемую длину с реально измеренной на фотографии # shadow_length - длина тени, измеренная на фотографии relative_differences = np.abs((expected_shadow_lengths - shadow_length) / shadow_length) 

Шаг 4: Визуализация

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

Практический пример: фотография из Сайгона

Рассмотрим историческую фотографию протестов в Сайгоне 1963 года. На фотографии видны люди и их тени, также присутствует вывеска на вьетнамском языке «TRUNG HOC TU THUC NGUYEN-KHUYEN».

Измерив в пикселях высоту человека и длину его тени (например, используя GIMP или Photoshop), получаем отношение примерно 160:75.

Зная дату (11 июня 1963 года) и предполагаемое время (6:30 UTC, что соответствует 14:30 по местному времени), мы можем запустить наш скрипт:

find_locations_from_shadow(     object_height=160,     shadow_length=75,     date_time=datetime(1963, 6, 11, 6, 30, tzinfo=timezone('UTC')) ) 

Результаты анализа

Запустив скрипт, мы получаем карту возможных локаций. Как видно из визуализации, возможные места образуют дугу, проходящую через Юго-Восточную Азию. И действительно, Сайгон (современный Хошимин, координаты примерно 10.8°N, 106.7°E) находится именно на этой дуге.

Ограничения метода

  1. Необходимо точное время съёмки

  2. Объект должен отбрасывать чёткую тень

  3. Поверхность должна быть ровной(То есть в расчетах могут быть ошибки из-за кривизны Земли, линзы и так далее. Чем точнее измерения, тем корректнее модель.)

  4. Метод даёт не точку, а линию возможных локаций

Заключение

Метод геолокации по теням — инструмент для анализа фотографий. В сочетании с другими методами (анализ архитектуры, надписей, ландшафта) он может помочь определить место съёмки.

Полный исходный код проекта доступен на GitHub [https://github.com/HovhannesManushyan/SunTrack/blob/main/suntrack.py].

Благодарности

Этот проект основан на идеях и коде из проекта ShadowFinder. ShadowFinder — это открытый инструмент для геолокации изображений по теням, и я настоятельно рекомендую ознакомиться с оригинальным проектом.


ссылка на оригинал статьи https://habr.com/ru/articles/872566/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *