Вам нужно автоматизировать огромное количество фотограмметрических сканов? Тогда у меня для вас хорошие новости.
В видео показана программа для фотограмметрии Meshroom с открытым исходным кодом. Этот проект в разных формах существует уже довольно давно, но недавно разработчики выпустили двоичные файлы, поэтому их можно просто скачать и использовать. В ролике продемонстрировано использование GUI для загрузки изображений, их обработки, изменения параметров и т.д. Рекомендую вам попробовать эту программу в действии.
Но меня интересует полная автоматизация. Если у вас есть сканирующая установка, на которой вы делаете по 100 и больше сканов в день, то необходимо полностью автоматизированное решение для пакетной обработки этих файлов. Данный пост является руководством и/или туториалом по решению этой задачи.
Для начала важно понять, что Meshroom — не гигантский, монолитный проект. На самом деле, сама обработка выполняется отдельными программами на C++, работающими из командной строки, а Meshroom — это тонкая программа-прокладка на Python, выполняющая соответствующие вызовы. Поэтому вместо использования Meshroom мы будем применять эти программы напрямую. Учтите, что доступны полные исходники, поэтому вы можете привязать библиотеки напрямую.
У Meshroom есть ещё одна удобная особенность: при выполнении каждой операции её команда отображается в терминале. Поэтому чтобы создать этапы этого процесса, я просто работал с Meshroom и смотрел за командами. Затем я заглянул в код, чтобы изменить некоторые параметры. Кроме того, кажется, при запуске Meshroom можно приказать ему собрать набор изображений из командной строки, но я предпочитаю не соединять эти этапы.
Подготовка и установка
0: Требования
Meshroom/AliceVision запустятся не на каждой платформе. Для некоторых этапов необходима CUDA, поэтому для построения карт глубин вам понадобится GPU компании NVIDIA. К сожалению использовать CPU fallback (перенос выполнения функций GPU на ЦП) невозможно., иначе программа бы отлично работала и в Windows, в Linux. Инструкции в этой статье даны для Windows, но с минимальными изменениями их можно подстроить и под Linux.
1: Скачайте релиз Meshroom
Первое, что нужно сделать — установить Meshroom. Выберите папку, из которой хотите выполнять работу, а затем скачайте последнюю версию. В zip-файле есть двоичные файлы всех зависимостей.
Если вас тянет на приключения, то можете попробовать собрать программу самостоятельно. Релизные динамически подключаемые библиотеки работают нормально (/MD), но мне пришлось хакать файлы cmake для создания отладочных сборок и/или сборок со статическим подключением. Если вы будете собирать программу под Windows, то КРАЙНЕ рекомендую использовать VCPKG.
2: Скачайте данные
Очевидно, что весь смысл ПО фотограмметрии заключается в обработке ваших собственных изображений, но для начала я предлагаю использовать изображения, которые гарантированно подходят. Они позволят найти источники проблем, если что-то пойдёт не так. К счастью, разработчики выпустили набор изображений для своего тестового дерева.
3: Скачайте скрипт run_alicevision.py
Это скрипт, который мы будем использовать. Просто скачайте zip-файл и распакуйте его в рабочую папку.
4: Установите Python
https://www.python.org/download/releases/2.7/
Установите Python, если вы ещё этого не сделали. Да, я всё ещё пишу код для Python 2.7.0. Проще всего установить Windows X86-64 MSI Installer из релизов.
5: Установите Meshlab (необязательно)
В качестве необязательного шага нужно также установить MeshLab. На самом деле для обработки она не понадобится, но на нескольких этапах данные выводятся в файлах точек PLY. Их нельзя загрузить в Maya, поэтому для их просмотра я пользуюсь MeshLab.
После распаковки всех файлов папка должна выглядеть следующим образом (за исключением папки build_files, которая генерируется скриптами):
Здесь есть следующее:
- build_files: файлы, которые мы собрали.
- dataset_monstree-master: исходные изображения
- Meshroom-2018.1.0: двоичные файлы Meshroom/AliceVision.
- Всё остальное: скрипты для их запуска, которые взяты из run_alicevision.zip.
Запуск AliceVision
Теперь настало время приглядеться к run_alicevision.py
Файл Python получает 5 аргументов:
python run_alicevision.py <baseDir> <imgDir> <binDir> <numImages> <runStep>
- baseDir: папка, в которую вы хотите помещать временные файлы.
- imgDir: папка, содержащая исходные изображения. В нашем случае IMG_1024.JPG (и другие).
- binDir: папка, содержащая исполняемые файлы AliceVision, например aliceVision_cameraInit.exe.
- numImages: количество изображений в imgDir, в нашем случае 6. Разумеется, можно распознавать это количество автоматически, но цель заключалась в создании как можно более простого python-скрипта, поэтому нужно указывать это число самостоятельно.
- runStep: выполняемая операция.
Подведём итог: мы начинаем с 6 изображений, выглядящих следующим образом:
С помощью python-скрипта run_alicevision.py мы собираемся создать следующую структуру папок:
А в папке 11_Texturing будет находиться готовая модель, открываемая в Meshlab:
Каждая из этих папок является одним из этапов. Мы можем или запускать их по очереди с помощью файлов run_monstree_runXX.bat, или воспользоваться run_monstree_all.bat, чтобы собрать их все сразу.
Вот и всё. Теперь можно запустить файл run_monstree_all.bat, или выполнять по одному этапу за раз. Можете посмотреть на скрипт, чтобы разобраться в его работе. Для тех, кому хочется иметь возможность настройки конвейера обработки я подготовил введение в отдельные этапы.
00_CameraInit
Первый этап сгенерирует файл SFM. Файлы SFM — это файлы в формате JSON, в которых хранятся размер камеры, информация о сенсоре, найденные 3d-точки (наблюдения), коэффициенты искажения и другая информация. Первоначальный файл SFM в этой папке будет содержать только информацию о сенсоре и выбирать значения по умолчанию из локальной базы данных сенсоров. Последующие этапы будут создавать файлы SFM, содержащие полные матрицы внешних параметров камер, точки и т.д.
Вам может потребоваться настройка этого этапа. Если вы используете установку с 4 камерами, но делаете 10 снимков объекта, вращающегося на поворотном столе, то вам пригодится файл SFM с 40 изображениями, но всего с 4 разными калибровками сенсоров. Это основная причина того, почему мне нравится структура AliceVision. В ней легко настраивать пакетные операции (например генерацию собственного файла SFM) без мучений с настройкой других элементов ПО, которые лучше не трогать.
01_FeatureExtraction
Следующий этап извлекает из изображений характерные черты, а также дескрипторы этих черт. Он будет изменять расширение файла в зависимости от типа извлекаемой характерной черты.
02_ImageMatching
02_ImageMatching — это этап постобработки, определяющий, какие из изображений логично сопоставлять друг с другом. Если у вас есть набор из 1000 изображений, то для грубого перебора всех 1000 изображений на соответствие всем 1000 изображениям потребуется 1 миллион пар. На это может потребоваться много времени (на самом деле в два раза меньше, но вы поняли принцип). Этап 02_ImageMatching отсекает эти пары.
03_FeatureMatching
03_FeatureMatching находит соответствия между изображениями с помощью дескрипторов характерных черт. Генерируемые им файлы txt в объяснении не нуждаются.
04_StructureFromMotion
Так, это первый серьёзный этап. На основании соответствий 04_StructureFromMotion вычисляет позиции камер, а также внутренние параметры камер. Следует учесть, что термин «Structure From Motion» используется как общий для вычисления позиций камер. Если у вас есть установка для фотограмметрии из 10 синхронизированных камер, то «Structure From Motion» используется для их привязки, даже если на самом деле ничего не двигается.
По умолчанию Meshroom хранит все вычисленные данные как файл Alembic, но я предпочитаю хранить их в файле SFM. Этот этап создаёт промежуточные данные, позволяющие убедиться в правильной привязке камер. На выходе скрипт создаёт файлы PLY, которые можно просмотреть в Meshlab. Важны следующие файлы:
- bundle.sfm: файл SFM со всеми наблюдениями.
- cameras.fm: файл SFM с данными только привязанных камер.
- cloud_and_poses.ply: найденные точки и камеры.
Вот файл cloud_and_poses.ply. Зелёные точки — это камеры. Я считаю, что этот формат удобнее всего подходит для проверки отсутствия грубых ошибок в привязке камер. Если где-то возникнет ошибка, то вы можете вернуться назад и изменить характерные черты, соответствия или параметры SFM.
05_PrepareDenseScene
Основная задача 05_PrepareDenseScene — устранение искажений в изображениях. Он генерирует изображения EXR без искажений, чтобы последующим этапам вычисления глубин и проекций не нужно было выполнять преобразования туда-обратно из функции искажений. Изображения выглядят так:
Нужно заметить, что вы увидите чёрные области. Последующие этапы AliceVision не используют настоящую матрицу камеры. Вместо этого мы притворяемся, что у камеры есть новая матрица без искажений, а 05_PrepareDenseScene деформирует исходное изображение под эту вымышленную матрицу. Поскольку этот новый виртуальный сенсор больше настоящего сенсора, некоторые области окажутся пустыми (чёрными).
06_CameraConnection
Строго говоря, этот этап нарушает принцип нашего рабочего процесса. Все этапы были разработаны так, чтобы каждая папка становилась совершенно уникальным отдельным этапом. Однако 06_CameraConnection создаёт в папке 05_PrepareDenseScene файл camsPairsMatrixFromSeeds.bin, потому что этот файл должен находиться в той же папке, что и изображения без искажений.
07_DepthMap
Это самый долгий этап AliceVision: генерирование карт глубин. Он создаёт карту глубин для каждого изображения как файл EXR. Я настроил его, чтобы это было проще заметить. Вы можете увидеть небольшой «язык», торчащий из дерева.
Поскольку этот этап занимает много времени, существует параметр, позволяющий нам запускать группы разных камер как разные отдельные команды. Поэтому если у вас есть 1000 камер, то можно создавать карты глубин для групп камер на разных машинах фермы. Или же можно разбить выполнение работы на мелкие группы, чтобы при сбое одной машины не нужно было повторять заново весь процесс.
08_DepthMapFilter
Исходные карты глубин не будут полностью согласованными. Некоторым картам глубин потребуется видеть области, перекрытые другими картами глубин. Этап 08_DepthMapFilter изолирует такие области и принудительно обеспечивает согласованность глубин.
09_Meshing
Это первый этап, на котором непосредственно генерируется меш. С мешем могут быть небольшие проблемы, которые можно решить при помощи…
10_MeshFiltering
Этап 10_MeshFiltering получает меш 09_Meshing и усовершенствует его. Он выполняет следующие операции:
- Сглаживает меш.
- Устраняет большие треугольники.
- Сохраняет наибольший меш, но удаляет все остальные.
Некоторые из этих операций в определённых случаях не всегда желательны, поэтому при необходимости параметры можно настроить.
11_Texturing
Последний этап. 11_Texturing создаёт UV и проецирует текстуры. И на этом этапе всё заканчивается!
Последний трюк, который можно сделать с Meshlab: вы можете перетаскивать разные файлы OBJ и PLY как слои.
В моём примере есть слой и для готового меша, и для точек/камер SFM. Иногда этап сглаживания меша может быть слегка агрессивнее, чем нужно, поэтому полезно сравнить исходный и сглаженный меши. Если меш выглядит поломанным, то для отслеживания проблем в конвейере удобно использовать sfm-данные из PLY и меши из OBJ.
Благодарности
Этот пост был бы неполон без огромной благодарности командам разработчиков AliceVision и OpenMVG. Источником вдохновения послужил проект libmv. Этот проект был предшественником OpenMVG, который является репозиторием инженеров/исследователей компьютерного зрения для разработки новых алгоритмов. AliceVision — это форк OpenMVG, созданный специально для того, чтобы превратить эти алгоритмы в отдельное решение в виде готового продукта.
AliceVision/Meshroom — крупный, амбициозный open-source-проект. Его основное достижение — достижение таким серьёзным проектом финальной черты, и мы обязаны ему очень многим. Также мы обязаны поблагодарить команду OpenMVG (и libmv), чья фундаментальная работа позволила создать AliceVision.
Наконец, я хочу сказать особое спасибо Microsoft за VCPKG. VCPKG — это менеджер пакетов, сильно упростивший сборку крупных open-source-проектов под Windows. Несколько лет назад я пытался собрать под Windows OpenMVG. Всё закончилось не очень хорошо. Поэтому когда несколько месяцев назад я услышал об AliceVision, я попытался скомпилировать его, но потерпел неудачу даже с более простыми вещами. Потом я попробовал VCPKG, и всё сразу заработало. Сложно выразить количественно преимущество использования такого проекта, как VCPKG, но он очень помог экосистеме open-source под Windows.
Автор: PatientZero