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

В этой статье я расскажу о том, как можно определить географическое местоположение объекта на фотографии, используя только длину тени и время съёмки. Мы рассмотрим конкретный пример — историческую фотографию 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: Визуализация

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

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

034a99d152b3847cb42baf3f8fdf8e54.jpg

Рассмотрим историческую фотографию протестов в Сайгоне 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'))
)

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

87f3c2073336a7e7ac74f0890a569a20.png

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

Это подтверждает точность нашего метода и демонстрирует, как анализ теней может помочь в геолокации исторических фотографий.

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

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

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

  3. Поверхность должна быть ровной

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

Заключение

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

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

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

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

© Habrahabr.ru