Отложенный выбор ракурса съемки

Meshroom

Предисловие

Желание отложить необходимость выбора старо как мир. Возможность изменить ранее сделанный выбор тоже казалась всегда очень привлекательной. Первоначально в фотографии не было ни первого, ни второго. При съемке дагерротипа необходимо было выбирать ракурс, перспективные искажения за счет наклона и сдвига объектива и экспозицию сразу при съемке. С появлением негативного процесса возможности несколько расширились: меняя время засветки, можно было чуть-чуть исправить ошибки первоначальной экспозиции, а выбирая рецептуру проявителя - контраст изображения. Появление увеличителя еще больше расширило возможности. Стало возможным кадрировать, искажать перспективу, наклоняя увеличитель. Переход с пластинок на пленку и особенно на 35 мм кинопленку позволял быстро сделать множество снимков с одной точки или одного объекта с разных сторон. И уже потом, при печати выбирать, какой из кадров использовать. Цифровая фотография первоначально мало чего изменила. Съемка в сыром формате позволяла отсрочить выбор баланса белого и коррекцию экспозиции и в этом смысле мало отличалась от съемки на цветную негативную пленку. У меня до сих пор сохранился ящик с корректирующими фильтрами и воспоминания о мучительном процессе их использования.

фильтры
Корректирующие фильтры для цветной печати

фильтры

Корректирующие фильтры для черно-белой фотобумаги с переменным контрастом

Замечу, что комфорт в коррекции цифровых снимков тоже появился не сразу, а только тогда, когда мощность компьютеров и качество мониторов достигло определенного уровня. Обработка фотографий была всегда. В доцифровую эпоху это были химические и физические методы. В серебряной фотографии преобладали химические, в электронной - физические. Электронная фотография с аналоговой регистрацией света берет свое начало в 19 веке, а фототелеграфные аппараты начала 20 века уже конструктивно идентичны барабанным сканерам конца 20. Оцифровка стала реальностью в середине 20 века, но для математической обработки не хватало вычислительных мощностей. Оцифровка с избыточной для мониторов и полиграфии точностью стала реальной в 90-х годах прошлого века, но первоначально выбор правильных параметров сканирования существенно ускорял процесс. Правка изображения, сканированного с тысячей градаций серого, затягивалась на часы. Аналогичная ситуация сложилась и с сшивкой панорам. Математика была готова уже в прошлом веке, а машины и программы, позволяющие получить качественные панорамы из серии снимков только уже в 21. Сферические панорамы позволили любой вид с точки съемки извлечь позже, причем можно выбрать необходимые ракурс, угол зрения и проекцию. Т.е. независимо от того, как была сделана круговая панорама, в дальнейшем можно получить как снимки аналогичные снимкам телеобъективом, так и объективом рыбий глаз. Переход количества в качество позволяет нам сегодня получить снимок с любого ракурса с проезжей части всех улиц крупных городов мира.  Доминик Франсуа Жан Араго предложил использовать фотографию для реконструкции рельефа в 1840 году. Стереосъемка ведет свое начало с опытов Мозера в 1844 году. Однако реальная возможность не просто увидеть объемное изображение объекта, но и повертеть его на существенный угол появилась совсем недавно, когда вычислительные мощности массовых компьютеров   позволили  использовать фотограмметрию для того, чтобы из серии снимков получить модель, на которую можно натянуть текстуру из реального снимка за несколько часов. Одновременно появились удобные программы для просмотра и демонстрации через интернет.   Это позволяет нам  отложить выбор ракурса на потом. Одному из возможных вариантов получения и демонстрации текстурированной модели и посвящена  эта статья.

Фотограмметрия

Я недавно обновил свой компьютер, заменив видеокарту на GEFORCE GTX 1650, и это позволило мне воспользоваться последними версиями программы  Meshroom.  От ранее описанной версии 2019  версии 2020 и 2021 отличаются тем, что позволяют не только получать трехмерные модели, но и сшивать сферические панорамы. Т.е.  эта программа позволяет реализовать оба вышеупомянутых метода съемки, позволяющих отложить выбор ракурса. Что касается сшивки панорам, то сравнение ее с Hugin не является темой данной статьи. Отмечу только, что она умеет неплохо сшивать панорамы и при определенных условиях конкурировать с Hugin.  Если  Вы используете Hugin в режиме Expert, то переходить на новую программу смысла не имеет. Отмечу только, что если вы собираетесь попробовать, то первый снимок, который станет центральным для панорамы, должен быть снят строго горизонтальной камерой. В противном случае, чтобы выровнять панораму в эквидистантной проекции, придется воспользоваться Hugin.  Тема этой статьи - получение текстурированной модели барельефа на памятнике Герцену с Огаревым на Воробьевых горах. Я снял 19 кадров камерой Sony NEX 5 с 16 мм объективом и перетащил их в программу Meshroom 2021.1.0. Программа может работать и с сырыми снимками, но я в данном случае для экономии памяти использовал JPEG. Поскольку параметры нашего объектива соответствуют записи в EXIF, то можно, не редактируя начальные параметры, просто нажать вверху кнопку Start и запустить программу. Мелкие недочеты в заданных параметрах выяснятся только по завершению, что, возможно приведет к необходимости пересчета. Я рекомендую выполнять программу по частям. Если используется объектив с насадкой или вообще объектив без электроники, то в CameraInit уточняем фокусное расстояние и тип объектива.  В следующем  FeatureExtraction, если у вас относительно слабый компьютер при современной видеокарте, то стоит снять галочку в пункте Force CPU Extraction. Далее идем в пункт StructureFromMotion и запускаем счет через меню, вызываемое правой кнопкой мыши. После его выполнения программа показывает пригодность снимков,  рассчитанное положение камер и положения  характерных точек в пространстве.

Meshroom

Следующую остановку имеет смысл сделать на пункте Meshing, где генерируется полигональная сетка, называемая на жаргоне  меш (от английского polygon mesh). Дважды щелкнув по прямоугольнику, ее можно рассмотреть и оценить. После этого можно воспользоваться внешним редактором и удалить лишнее. Либо в меню поставить галочку  Custom Bounding Box и задать интересующую нас область.

Meshroom

Ликвидация лишнего на этом этапе позволяет существенно уменьшить файл с текстурой, что весьма важно для экономии трафика при показе через интернет. На приведенном снимке экрана видно, что на гладком обрамлении барельефа практически нет характерных точек, используемых для расчета,  и трехмерная модель в этих областях имеет разрывы. В дальнейшем эти области придется либо ретушировать, либо отрезать. Возможно и добавление новых снимков этой области, если есть такая возможность и повторный расчет. Если мы удалили лишнее, то следующий пункт MeshFiltering мало изменит модель.  Сглаживание, устранение больших треугольников актуально, если мы не ограничиваем размер  области. Если существенно уменьшить параметр Filter Large Triangles Factor  до 10 и поставить галочку Keep Only the Largest Mesh, то  иногда  удается автоматически хорошо обособить основной объект. После этого можно правой кнопкой мыши добавить пункт MeshDecimate для упрощения сетки. И запустить финальную процедуру  Texturing, которая создает UV развертку и проецирует текстуры.

В результате, мы получаем три файла с расширениями OBJ (формат описания геометрии), MTL (Material Library - файл спутник  формата OBJ) и PNG. Этот результат можно просматривать и редактировать в разных программах и в принципе возможен показ модели через интернет с помощью three.js. Но, для показа удобнее иметь один файл, и самая простая в использовании программа model-viewer  поддерживает только формат GLB, который является бинарной версией glTF (GL Transmission Format).  Этот формат сжимает трехмерные сцены и минимизирует обработку во время выполнения приложений, использующих WebGL. Вероятно, самый простой и доступный способ преобразовать наши 3 файла в один - это воспользоваться программой Blender. Кроме преобразования, эта программа позволяет редактировать, как полигональную сетку, так и натянутую на объект текстуру. Я обычно перемещаю и поворачиваю модель таким образом, чтобы она правильно выглядела при виде спереди в Blender.

Как только у нас появится файл в формате GLB, мы можем воспользоваться  сетевым редактором и загрузить в него файл, повернуть и зафиксировать начальное положение, а также откорректировать экспозицию и цвет текстуры. На выходе мы получим архив, содержащий все необходимые файлы для размещения на сервере. 

model-viewer
model-viewer
model-viewer

Для просмотра на локальной машине сервер для конкретной папки с файлами можно организовать командой  python -m http.server 8500, а просматривать по адресу http://0.0.0.0:8500/ .

Если нет подключения к интернету, то презентацию на локальном сервере можно организовать и не пользуясь редактором. Для этого пишем нижеприведенный код и подставляем в него имя файла GLB. В этом случае для работы нам понадобятся и локально размещенные, предварительно скаченные файлы  model-viewer.min.js и model-viewer.min.js.map.
<!doctype html>
<html>
<head>     <title>3D Test</title> <style>
model-viewer#tc1 {     overflow-x: hidden;     --poster-color: #eee; position: absolute;     left: 0;     right: 0;     top: 0;     bottom: 0;     overflow: hidden;         width: 100%;     height: 100%;   } </style> <meta name="viewport" content="width=device-width, initial-scale=1"> </head> <body bgcolor="#eee"> <div align="center" >    <model-viewer id="tc1" src="tmp/go5.glb" alt="A 3D model"     camera-controls camera-orbit="0deg 90deg 1.5m" exposure="0.45"     background-color: #eee   ></model-viewer> </div>     <!-- Loads model-viewer for modern browsers -->     <script type="module" src="model-viewer.min.js"></script> </body> </html>

Результат можно увидеть, запустив вышеприведенный файл tog4.html с моего сервера.

Другой метод представления реализуется с помощью three.js. Возможностей много, но и файлов, которые нужно разместить на сервере, тоже много. Причем, даже если используется часть возможностей, то необходимые файлы нужно будет размещать строго в своих папках. В html мы ссылаемся на файл, который в свою очередь ссылается на другие с соблюдением полной иерархии папок.  В простейшем случае, повторяющем возможности model-viewer, понадобится разместить на сервере следующие файлы:

minjsm

И создать следующий html файл:

<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - glTF 2.0 - compressed</title>
<meta charset="utf-8">


<link type="text/css" rel="stylesheet" href="main.css">
</head>

<body>


<script type="module">

import * as THREE from '../build/three.module.js';

import { RoomEnvironment } from './minjsm/environments/RoomEnvironment.js';
import { OrbitControls } from './minjsm/controls/OrbitControls.js';
import { GLTFLoader } from './minjsm/loader/GLTFLoader.js';

import { KTX2Loader } from './minjsm/loader/KTX2Loader.js';
import { MeshoptDecoder } from './minjsm/libs/meshopt_decoder.module.js';

let camera, scene, renderer;

init();
render();

function init() {

const container = document.createElement( 'div' );
document.body.appendChild( container );

renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1;
renderer.outputEncoding = THREE.sRGBEncoding;
container.appendChild( renderer.domElement );

camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 0, 0, 1.5 );

const environment = new RoomEnvironment();
const pmremGenerator = new THREE.PMREMGenerator( renderer );

scene = new THREE.Scene();
scene.background = new THREE.Color( 0xbbbbbb );
scene.environment = pmremGenerator.fromScene( environment ).texture;


const ktx2Loader = new KTX2Loader()
.setTranscoderPath( 'minjsm/libs/basis/' )
.detectSupport( renderer );

const loader = new GLTFLoader().setPath( 'tmp/' );
loader.setKTX2Loader( ktx2Loader );
loader.setMeshoptDecoder( MeshoptDecoder );
loader.load( 'k4.glb', function ( gltf ) {


gltf.scene.position.y = 0;

scene.add( gltf.scene );

render();

} );

const controls = new OrbitControls( camera, renderer.domElement );
controls.addEventListener( 'change', render ); // use if there is no animation loop
controls.minDistance = 1.2;

controls.maxDistance = 2;
controls.target.set( 0, 0, 0 );
controls.update();

window.addEventListener( 'resize', onWindowResize, false );

}

function onWindowResize() {

camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();

renderer.setSize( window.innerWidth, window.innerHeight );

render();

}

//

function render() {

renderer.render( scene, camera );

}

</script>

</body>
</html>

Результат можно увидеть, запустив вышеприведенный файл webglk4.html с моего сервера.

20.04.2021
Установите проигрыватель Flash

Облако тегов:
3D печать
Arduino
Raspberry Pi
Аэрофотосъемка
Байдарки
Геомеханика
История
Камеры
Макросъемка
Объективы
Освещение
Панорамы
Принадлежности
Принтеры
Программы
Сканеры
Стереосъемка
Фильтры
Фокусировка
Фотокубики
...
rss