В этой статье я расскажу о том, как можно определить географическое местоположение объекта на фотографии, используя только длину тени и время съёмки. Мы рассмотрим конкретный пример — историческую фотографию 1963 года из Сайгона (ныне Хошимин), и напишем Python-скрипт для анализа возможных локаций.
Теория: как работают тени?
Представьте, что вы стоите рано утром на улице. Солнце только поднимается над горизонтом, и ваша тень очень длинная. К полудню солнце поднимается высоко в небо, и тень становится совсем короткой. А к вечеру тень снова удлиняется.
Давайте разберем эту геометрию подробнее. Вот простая схема:
Солнце • /| Угол высоты / | солнца (θ) → / θ| / | Высота / | объекта (h) / | / | --------+------+-------- Горизонт Длина тени (s)
Что мы видим на этой схеме:
-
Солнце находится под углом θ к горизонту (это называется «угол высоты солнца»)
-
У нас есть объект высотой h (например, человек или столб)
-
Этот объект отбрасывает тень длиной s
Связь между этими величинами описывается простой формулой:
длина_тени = высота_объекта / tan(угол_высоты_солнца)
Или математически:
s = h / tan(θ)
Что это значит на практике?
-
Когда солнце низко (маленький угол θ), тень длинная
-
Когда солнце высоко (большой угол θ), тень короткая
-
Отношение длины тени к высоте объекта (s/h) зависит только от угла высоты солнца
Алгоритм поиска места съёмки:
-
Берём конкретное время и дату фотографии
-
Для каждой точки на карте мира:
-
Вычисляем, под каким углом там было солнце в этот момент
-
Рассчитываем, какой длины должна была быть тень
-
Сравниваем с реальной тенью на фотографии
-
-
Точки, где расчётная длина совпадает с реальной — потенциальные места съёмки
В итоге на карте мы получим линию возможных локаций — все места, где в заданный момент времени тени имели именно такую длину.
Реализация алгоритма
Давайте разберем, как реализовать наш метод пошагово
Шаг 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) находится именно на этой дуге.
Ограничения метода
-
Необходимо точное время съёмки
-
Объект должен отбрасывать чёткую тень
-
Поверхность должна быть ровной(То есть в расчетах могут быть ошибки из-за кривизны Земли, линзы и так далее. Чем точнее измерения, тем корректнее модель.)
-
Метод даёт не точку, а линию возможных локаций
Заключение
Метод геолокации по теням — инструмент для анализа фотографий. В сочетании с другими методами (анализ архитектуры, надписей, ландшафта) он может помочь определить место съёмки.
Полный исходный код проекта доступен на GitHub [https://github.com/HovhannesManushyan/SunTrack/blob/main/suntrack.py].
Благодарности
Этот проект основан на идеях и коде из проекта ShadowFinder. ShadowFinder — это открытый инструмент для геолокации изображений по теням, и я настоятельно рекомендую ознакомиться с оригинальным проектом.
ссылка на оригинал статьи https://habr.com/ru/articles/872566/
Добавить комментарий