E57 простыми словами: "PDF облаков точек"
Представьте, что Вы фотографируете комнату, но вместо плоского снимка фиксируете точное положение миллиона крошечных точек, покрывающих каждую стену, стул и кофейную кружку. Если достаточно быстро вращать лазер и измерять расстояние до всех объектов, получится облако точек — трёхмерная "фотография" из измеренных точек. Мы без лишних терминов расскажем о том, что на самом деле находится внутри файла E57, и об одном интересном приёме, который наша программа использует при работе с ним.
Зачем вообще нужен специальный формат?
Обычная фотография — это всего лишь сетка цветных пикселей. С 3D-сканом всё сложнее. Для каждой из миллионов точек нужно хранить её положение в пространстве (три числа: X, Y, Z), цвет, силу отражённого лазерного сигнала (интенсивность — своего рода чёрно-белая "лазерная фотография"), а зачастую и панорамные фотографии, одновременно сделанные сканером.
Представьте: один специалист сканирует с помощью Faro, его коллега использует Leica, а заказчик открывает результат в программе Autodesk. Три устройства, три программы — и все они должны читать один и тот же файл даже спустя годы, без необходимости просить у производителя секретный декодер. Именно эту задачу решает E57. Это открытый, независимый от производителя стандарт (опубликованный как ASTM E2807 и основанный на библиотеке libE57 с открытым исходным кодом). Его называют "PDF облаков точек": единый переносимый файл, который все системы читают одинаково.
Главная идея: текстовая карта и мощь бинарных данных
По своей сути файл E57 — это гибрид двух совершенно разных частей: небольшого фрагмента XML — обычного читаемого текста, который служит оглавлением, — и крупных блоков бинарных данных с миллионами исходных числовых значений, компактно упакованных для быстрого доступа.
Зачем помещать карту в конец? Потому что во время записи файла сканер ещё не знает, какого размера всё получится, поэтому сначала последовательно записывает необработанные данные, а по завершении добавляет упорядоченную сводку. Выгода огромна: чтобы извлечь один скан из файла объёмом 20 гигабайт, ПО читает крошечный заголовок, переходит к XML-карте, находит строку "скан #3 находится на позиции 4 812 000 000" и сразу переходит туда.
Незаметная защита: весь файл разделён на "страницы" размером 1024 байта, а последние 4 байта каждой страницы отведены под контрольную сумму — цифровой отпечаток, по которому программа определяет, не повреждён ли файл.
Всё держится на одном корне
Откройте эту XML-карту, и Вы увидите дерево — совсем как папки на компьютере. Есть один root, а основную роль играют две ветви: data3D, нумерованный список сканов, и images2D, нумерованный список фотографий (обычно это панорамы 360°, снятые сканером).
Два способа записать точку
Лазерный сканер на самом деле не оперирует координатами X, Y, Z. Он стоит в одной точке и вращается, определяя для каждой точки три величины: дальность (расстояние, пройденное лучом), азимут (угол поворота влево или вправо) и угол возвышения (насколько луч направлен вверх или вниз). Это сферические координаты — родной язык сканера. Однако большинство программ предпочитает обычные декартовы координаты X, Y, Z. E57 поддерживает оба варианта, а для преобразования одного в другой достаточно простых тригонометрических вычислений.
Три вида встроенных фотографий
Фотографии в images2D — это не ссылки на файлы в какой-то папке: сам файл JPEG или PNG находится прямо внутри E57. При этом встроенные фотографии бывают разных видов. E57 упаковывает каждую в "представление", которое сообщает ПО, насколько можно доверять изображению с геометрической точки зрения. Разница сводится к одному вопросу: насколько полно описана камера?
sphericalRepresentation— полная панорама 360° × 180°, знакомое растянутое эквиректангулярное изображение 2:1. Поскольку проекция известна, каждому пикселю соответствует точное направление, поэтому изображение идеально совмещается с облаком точек. Это основной путь в нашем процессе обработки: мы считываем изображение, приводим его к точному соотношению сторон 2:1 и передаём в просмотрщик панорам.pinholeRepresentation— обычная фотография, снятая объективом и описанная классической моделью камеры-обскуры (фокусное расстояние, размер матрицы, оптический центр). Этого тоже достаточно, чтобы программа определила направление для каждого пикселя, но лишь в пределах более узкого поля зрения. На практике так чаще всего работает Leica: готовая кубическая карта — шесть плоских граней куба, направленных наружу, — записывается прямо в E57, а наш модуль обработки граней объединяет их в полную панораму. Это один из самых простых случаев преобразования в качественное изображение 360°.visualReferenceRepresentation— фотография без какой-либо модели камеры, предназначенная исключительно "для просмотра человеком". По ней нельзя проводить измерения или проецировать её на облако точек; это лишь справочный снимок. Наш импортёр сохраняет такие изображения в виде прикреплённых комментариев, а не размещает их в 3D.
Вот в чём загвоздка. sphericalRepresentation — популярный вариант, но в нём удивительно легко допустить малозаметную ошибку — именно поэтому один и тот же скан может выглядеть по-разному в разных программах.
- Слепые зоны обрезаются. У каждого сканера есть область, которую он не видит, — обычно прямо под ним, где находится его штатив. Некоторые программы экспорта просто обрезают панораму в этом месте, оставляя пустой участок или панораму нестандартной высоты.
- Неквадратные пиксели. В корректной панораме пиксели квадратные (
pixelWidth=pixelHeight), но в некоторых файлах это не так, поэтому до масштабирования изображение выглядит растянутым. - За “направление вперёд” принимают не ту сторону. Сохранённый вместе с панорамой поворот определяет, какое направление находится в центре изображения, но единого понимания того, что означает “вперёд”, нет: одни экспортёры направляют панораму на север, другие — на восток. Малейшая ошибка здесь разворачивает весь обзор.
- Инструменты редактирования могут терять данные. Например, после обработки и повторного экспорта E57 через CloudCompare у изображений
pinholeRepresentationмогут пропасть данные о месте съёмки — фотографии сохраняются, но информация о том, где они были сняты, теряется.
Итог: на практике разные программы часто отображают один и тот же файл E57 по-разному. Наш модуль импорта сглаживает типичные несоответствия: корректирует масштаб при неквадратных пикселях, исправляет ориентацию панорамы и приводит изображение к стандартному формату 2:1. Благодаря этому виртуальный тур выглядит правильно независимо от того, в какой программе создан файл.
Когда панорама встроена прямо в облако точек
Это одна из самых элегантных — и самых недооценённых — идей во всём формате. Помимо панорам, хранящихся как отдельные изображения, панорама может скрываться в самом облаке точек. Лазерный сканер направляет луч не случайным образом: он последовательно обходит упорядоченную угловую сетку, строка за строкой и столбец за столбцом, подобно старому телевизору, который построчно формирует изображение на экране. E57 позволяет сохранить этот порядок: каждой точке присваиваются rowIndex и columnIndex, указывающие, какой ячейке сетки она соответствует. Скан, сохранённый таким образом, называется структурированным.
Преимущество: если точки расположены в виде сетки, облако уже является изображением. Достаточно считывать его строка за строкой, и каждая точка займёт свой пиксель — панорама восстановится без какой-либо сложной перепроекции. В файле даже хранится размер сетки в indexBounds (columnMaximum, rowMaximum), поэтому программа заранее знает разрешение, а наш синтезатор берёт ширину выходного изображения непосредственно из columnMaximum + 1.
Но сетка должна быть идеальным прямоугольником, а реальный мир — нет. Что делать с направлениями, в которых луч ушёл в открытое небо и отражённый сигнал не вернулся? Решение прагматичное: заполнить эти ячейки фиктивными точками — очень часто с дальностью, равной ровно 0, что означает "луч отправлен, но ни во что не попал". Они сохраняют прямоугольную форму сетки, но не относятся к реальной геометрии, поэтому программа должна их отбрасывать. Наш модуль импорта помечает каждую точку с нулевой дальностью, задаёт ей условное большое расстояние, чтобы расчёты по сетке продолжали работать, и при построении карты глубины или экспорте облака точек никогда не принимает эти фантомные точки неба за реальные поверхности.
Как снова превратить скан в фотографию, внутри которой можно оказаться
Не каждый скан хранится в виде готовой сетки — иногда это просто неупорядоченный набор точек без структуры. Хорошая новость: панораму всё равно можно восстановить, и здесь в дело вступает наша собственная разработка. По сути, скан — это "полная сфера точек, измеренных по угловым направлениям из одного положения", которую можно развернуть в плоскую панораму.
Если нанести каждую точку на изображение по её угловым координатам — слева направо по ширине и сверху вниз по высоте, — она попадёт на пиксель знакомой растянутой эквиректангулярной панорамы 2:1. Главный компонент здесь — карта глубины: когда за каждым пикселем хранится расстояние, плоская на вид панорама становится пригодной для измерений и перемещения. Выберите две точки на стене, и программа определит реальное расстояние между ними, поскольку исходные 3D-данные никуда не исчезли.
Так почему же E57 важен?
Потому что это нейтральный формат обмена. Геодезист сканирует мост оборудованием одной марки, инженер открывает результаты в другой программе, а архитектор сохраняет их в архиве на следующие двадцать лет. E57 — единый файл, на который могут положиться все трое, без привязки к поставщику. В нём вместе хранятся цвет, интенсивность, геометрия, панорамы и особенно важные положения датчиков. Это открытый стандарт, который может реализовать любой.
И напоследок интересный факт: время съёмки в E57 отсчитывается по времени GPS — в секундах с 6 января 1980 года, когда начался отсчёт времени GPS, — а не от начала обычной компьютерной эпохи в 1970 году. Если интерпретировать его неправильно, окажется, что сделанный сегодня скан относится к 2013 году.
Хотите узнать больше?
- libE57.org — эталонная библиотека с открытым исходным кодом и главный сайт формата
- ASTM E2807 — официальный стандарт
- libE57Format · Image2D — точные определения сферического представления, представления камеры-обскуры и представления визуальной привязки
- Paul Bourke’s E57 notes — краткий технический разбор заголовка и структуры