среда, 7 мая 2014 г.

PPT: не пошло...




Пару вечеров провозился в попытках сделать что то вменяемое из фотографий полученных моим Ipad3 ... безуспешно. Результат получался не удовлетворительный.
Вчера раздобыл мыльницу Panasonic Lumix FS62. Не сильно круче, конечно, чем мой айпад, но надежа была...   Однако результат был не сильно лучше.
Меня это несколько насторожило, ибо понимание что нет возможности настроить какие либо параметры процесса обработки - несколько удручает.
В связи с этим решил пробовать переходить на второй OpenSource проект для фотограмметрии - связку APERO\MICMAC от французского национального института географии (IGN)...
В подробности вдаваться пока не буду.. но просидел с ним не отрываясь (просто не мог!) до 5 утра сегодняшнюю ночь..   пока что просто напишу - ЭТО БОМБА ! :)

пятница, 2 мая 2014 г.

Преобразование облака точек в геометрию : MeshLab

Дальше будет интересная информация :)  Особенно для тех, кто был (до сегодняшнего дня) не очень знаком с компьютерной графикой..

Прежде чем начнем, нам понадобится программа MeshLab, скачать её можно вот тут.

Если вы успешно преодолели описанные в прошлых постах этапы, то у вас должна быть папочка в которой лежит файл с расширением PLY .
У меня этот файл лежит вот по такому пути:
d:\Research\Photogrammetry\PPT\temp\osm-bundler-p3ydou\pmvs\models\option-0000.ply
Повторюсь, в этом файле хранится облако точек (Point cloud - на бусурманском), сгенерированных  на основе принципов фотограмметрии . То есть это еще не полноценный трехмерный объект, который можно, например, напечатать на 3D принтере..  
Что бы увидеть это облако точек - запускаем программу MeshLab и перетаскиваем в неё наш *.PLY файл..
Файл загружается и мы должны увидеть примерно нечто такое:

Это и есть облако точек.. это отчетливо видно, если приблизиться поближе:


Размер точек можно регулировать, если зажать клавишу CTRL и крутить колёсико мышки:

Теперь нужно включить отображение слоев, для этого нажимаем воот эту кнопочку :

Сейчас у нас всего 1 слой - исходное облако точек.
Моя задача сейчас превратить эти точки в поверхность..  Делать это будем в два этапа.

Этап 1 : создаем упрощенную основу..

1) Проверяем, что точки ориентированы правильно. Для этого идем в меню render и включаем режим отображения нормалей - "show normal\curvature":

Появляются длинные синие линии (как шерсть:). По этим линиям хорошо видно ориентацию точек.. у меня ориентация сейчас вполне традиционная.. так что можно двигаться дальше.
Но если у вас вдруг ориентация хорошая как на изображении, то её всегда можно инвертировать.. но это отдельная тема..

2) Теперь упрощаем само облако точек.. что бы затем создать на нём упрощенную основу..
(нормали можно отключить, что бы не мешали)
Что бы произвести какие то изменения с объектом в MeshLab его нужно "прогнать" через так называемый "фильтр". Этих фильтров огромное количество на все случаи жизни :) .. В данном случае нам нужен фильтр "Poisson-disk Sampling" :


Появляется окно настроек фильтра.. Нас интересует два параметра:
"Number of samples" - вводим там 20000.
Это означает что после прохода через этот фильтр от исходного облака точек останется ровно 20 тысяч точек. Сейчас же в моем облаке 123309 точек. Информация об этом написана внизу экрана ..
Второй параметр который нас интересует - нужно поставить галочку напротив "Base Mesh Subsampling"..
В итоге должно мои настройки выглядят так:

Ещё обратите внимание на белое поле справа - это список слоёв.. Пока что в нём всего один наш базовый слой..  Но как только я применю фильтр - то появится новый слой - с 20 тысячью точек..  И так, нажимаем кнопку "Apply"

Как я и предсказывал - появился новый слой.. К стати, напротив каждого слоя слева есть значек "глаз".. если его выколоть (тыкнуть в него мышкой) - то слой выключится, не будет отображаться . Так я и сделал - отключил исходный слой и теперь вижу только один новый.

Еще один немаловажный момент - порядок. Мой опыт крайне убедительно говорит - в деле, которое предполагает в дальнейшем усложнение - лучше изначально стараться придерживаться какого то порядка\правил, который в дальнейшем позволит легко ориентироваться в проекте..
В случае с мешлабом порядок можно начинать с того, что давать всем слоям понятные имена..
Сейчас у нас два слоя :
первый - это исходный материал.. я его назову "SourcePCloud"
второй - упрощенный пойнтклауд(облако точек).. я его назову "simplifiedPCloud" ..
Что бы переименовать слой - достаточно нажать правой кнопкой мышки по нему и выбрать "Rename Current Mesh":
Вот так теперь выглядят мои слои:


3) И вот теперь, наконец, мы можем создать упрощенную основу для нашей финальной детализированной геометрии..  Обязательно проверьте, что в списке слоев выделен слой с только что созданным  упрощенным облаком точек!
На этот раз нам нужен фильтр "Surface reconstruction: Poisson" :

В появившемся окне настроек вводим следующие значения :
Octree Depth =12
Solver Divide = 7

Нажимаем кнопку "Apply"...
Здесь может произойти несколько интересных ситуаций.. Я очень кратко опишу их.
Если всё нормально, то спустя некоторое время (обычно до минуты) появится созданная поверхность и можно двигаться дальше.
Но может и просто зависнуть.. если в течении минут 5, 10ти ничего не появилось - то это признак того, что все повисло..  нужно закрывать программу и все начинать с начала , только в поле Octree Depth ввести число поменьше..  Я сегодня пробовал запустить этот фильтр на исходное облако точек, и значение "Octree Depth " поставил = 10.. Так вот, мешлаб провисел полтора часа... и я его попросту вырубил и начал сначала..

Но я надеюсь, что у вас , как и у меня - все прошло нормально.
Обращаем внимание что в списке слоев появился ещё один новый слой, который я тут же переименовал в "base_mesh", а так же видим созданную поверхность:

4) Теперь в слоях отключаем все слои, кроме только что созданного :

5) Включаем режим "Flat Lines" - что бы увидеть плотность сетки.. А так же поворачиваем нашу модель фронтально, как на картинке :

6) И заключительным шагом на этом этапе будет - оптимизация сетки. 
Дело в том, что созданная сетка сейчас очень неравномерная и "грязноватая".. Для оптимизации пропустим нашу геометрию через фильтр "Quadric Edge Collapse Decimation":

В появившемся окне настроек оставляем все по умолчанию, разве что - ставим галочку на против "Planar Simplification" :
Жмем Apply и замечаем как сильно упростилась наша геометрия, без особых искажений в форме.

7) И самая самая последняя оптимизация .. - применяем фильтр "Merge Close Vertices" - он сольет несколько вершин в одну, если расстояние между ними меньше порогового значения..
Идем в фильтры..

В настройках фильтра в первое поле вводим 0.004 и жмем Apply..
(внизу справа тут же выдается сообщение, что было найдено 199 вершин удовлетворяющих этому условию)

Первый этап завершен.
И я рекомендую сохранить проект. При сохранении он будет предлагать сохранить каждый слой в отдельный PLY файл.. Имена файлам я давал точно такие же как у меня называется соответствующий слой.


Этап 2 : уплотняем упрощенную основу..

Теерь необходимо подготовить уже созданную упрощенную основу для нанесения на неё детализации. Что бы упрощенная поверхность смогла принять бОльшую детализацию - нужно уплотнить её сетку в тех местах, где мы хотим добавить деталей. В нашем случае это область головы.
Что бы выделить область (или области) которые будем детализировать, нужно активировать режим "Select Faces in a rectangular region", он находится на панели инструментов справа сверху:

и выделяем прямоугольником нужную область, после чего она окрасится красным цветом:

... и выходим из режима выделения "Select Faces.." , нажав на эту кнопку ещё раз:

Осталось всего ничего - пропустить выделенную область через очередной фильтр, который повысит детализацию сетки .. Для этого нам понадобится фильтр
"Subdivision Surfaces : LS3 Loop":
(обратите внимание что бы в списке слоев был выбран слой с этой поверхностью)

 В появившемся окошке можно настроить параметры увеличения детализации. Вы можете с ними играться сами.. В моем примере я, вспомнив Джеймса - ввёл число 0.0007:
(чем меньше число тем плотнее сетка)

.. нажимаем "Apply" и получаем такой результат:

И так! наша основа готова принять финальную детализацию!
Прежде чем это сделать - уберем красное выделение, оно нам больше не понадобится. Для этого, опять же, идем в фильтры : Filters->Selection->Select None:

В появившемся окне нажимаем Apply и выделение пропадет.

Теперь для порядка делаем дубликат этого слоя и называем его : base_mesh_subdivided.
И сохраняем проект.

Это нужно для того случая, если MeshLab вдруг повиснет или произойдет еще что то нежелательное (а я не нашел тут функции CTRL+Z )) - мы всегда можем открыть предыдущую сохраненную версию.. и спокойно продолжить работу не с нуля..


Этап 3 : Наносим детализацию на упрощенную основу..

Суть следующая: у нас есть очень высоко детализированное облако точек.. которые хорошо описывают поверхность.. а так же есть как-бы пластилиновый кусок упрощенной формы, на который мы хотим нанести детализацию, которая есть в облаке точек. 
И в MeshLab для этого есть отличный инструмент - "Vertex Attribute Transfer". Если говорить очень упрощенно, то он позволяет скопировать значение позиции одной точки на другую.. таким образом мы сейчас с помощью облака точек, как-бы "выдавим" из нашей упрощенной "пластилиновой" поверхности все детальки...
Да, помимо копирования позиции , этот инструмент позволяет копировать и другие свойства точки, например - цвет!  Если вы сейчас включите режим отображения "Smooth" , то увидите, что наша поверхность абсолютно белая.. :

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

Вот посмотрите что будет когда мы применим Filters->Sampling->Vertex Attribute Transfer
(не забудьте с начала выделить новый слой : base_mesh_subdivided)


В появившемся окне с параметрами нас интересуют следующие:
Source Mesh - это источник.
Здесь нужно указать слой с исходным облаком точек (SourcePCloud).
Target Mesh - это цель.
Здесь выбираем слой, к которому хотим применить этот фильтр, тоесть наш слой с упрощенной поверхностью (base_mesh_subdivided).
И ещё нужно поставить две галки:
Transfer Geometry - так мы говорим что хотим скопировать положение точек(вершин).
Transfer Color - так мы говорим что хотим скопировать цвет точек(вершин)
Вот так настройки выглядят у меня:


Нажимаем "Apply"..  
У меня результат получился вот такой (обратите внимание, что я отключил лампочку, что бы видеть чисто геометрию с текстурой, без дополнительного освещения) :

Если у вас не видно текстуры, то проверьте что включен режим Render->Color->Per Vertex):

Что бы увидеть модель без сетки, включите режим "Smooth" (тут я включил лампочку).

а тут снова выключил лампочку и поприменял разные режимы отрисовки:




Но это ещё не всё.. Наша моделька сейчас слегка "тяжеловатая".. и её нужно немного подчистить - убрать лишние вершины(вертексы).. После применения трансфера атрибутов некоторые вершины оказались практически в одной точке.. и их правильнее объединить в одну.  Это мы и сделаем.. Воспользуемся уже ранее применяемым фильтром "Merge Close Vertices" Но на этот раз нам нужно сохранить большую детализацию, по этому в поле вводим число не 0.004 как в первый раз, а 0.0002...

И видим что так мы отфильтровали 84684! вершины.. что очень неплохо оптимизировало финальную модель!

Вот и всё! модель готова! Сохраняем проект!
А следующим постом я расскажу как экспортировать нашу модель и затем опубликовать её на сайте sketchfab.com что бы вы могли легко показывать свою 3Д модель всем желающим, в соцсетях и тд итп..

четверг, 1 мая 2014 г.

Sketchfab - сервис для публикации 3D моделей

В интернете сейчас активно развиваются сервисы для работы с 3D . Я для публикаций своих 3D моделей пока что буду пользоваться скетчфабом.  Есть еще крайне интересный ресурс clara.io  но о нем попозже чуть чуть.
И так, в интерактивном режиме можно увидеть мой результат вот тут:


    Lion 01
    by robocop
    on Sketchfab

PPT: результат после внесения информации о камере

И такс..После того как я добавил камеру в базу данных PPT и заново прогнал весь процесс, при этом скейл-фактор я выставил равным единице..   Получил уже куда более преемлемый результат:












Тут видно что все же есть нераспознанные области
С этим мне предстоит поразбираться в дальнейшем..

Python Photogrammetry Toolbox: добавление новой камеры в базу данных

Вся процедура подробно иллюстрирована в этом скринкасте .
Но тем не менее я пройдусь последовательно по каждому шагу..
И так - 
1) Запускаем интерфейс PPT и идем во вкладку "Check Camera Database" и нажимаем кнопку "Select photos Path" что бы выбрать директорию, в которой лежат исходные фотографии..

2) Нажимаем кнопку "Run" что бы программа начала сканировать EXIF данные  фотографий в поисках информации о камере, которой были сделаны эти фото.

3) Переходим в окно консоли и видим, что программа обнаружила камеру (в моем случае это NIKON D70) и выдала такое сообщение - "Type CCD width in mm ..." .
Под CCD - в данном случае имеется в виду матрица камеры (иногда это еще называют Image sensor), и программа просит нас ввести размер широкой стороны матрицы в миллиметрах.  Эту информацию всегда можно найти в интернет, например для камер Nikon идем сюда.

Например, если что бы найти размер матрицы для Ipad то пишем в гугле запрос : Ipad 3 image sensor size и получим кучу ссылок на источники.. например вот этот. Где написано, : The New iPad (iPad 3) utilizes an OmniVision OV5650 1/3.2-inch (4.54 x 3.42 mm) То есть у третьего айпада ширина матрицы = 4.54 мм. Я это сохраню, ибо у меня именно такая железяка.. и я буду экспериментировать на ней в дальнейшем..
Но возвращаясь к Nikon D70.. узнаем по ссылке, что image sensor width = 23.7mm
Вот это число и пишем в консоли :
жмем ENTER и получаем сообщение, что камеру успешно добавлена в базу данных:
Это означает что теперь мы можем переходить в первую вкладку интерфейса PPT и начинать работать с фотографиями сделанными на NIKON D70 !

среда, 30 апреля 2014 г.

Python Photogrammetry Toolbox: начало...

Пойду от простого к сложному, по этому начну с PPT.
Скачать его (помимо других вкусняшек) можно с сайта итальянских археолого-маньяков.

Там же выложены инструкции по тому, как установить пакет на разные платформы.. У меня Windows 7  по этому буду вести рассказ пока что в этом контексте..


  • Скачиваем и устанавливаем Python 2.6 (всё по умолчанию)
  • Скачиваем и устанавливаем PIL 1.1.7  (всё по умолчанию)
  • Скачиваем и устанавливаем PyQt-Py2.6-x86-gpl-xxx  (всё по умолчанию)
  • Скачиваем Python Photogrammetry Toolbox и разархивируем (у меня это будет папка: d:\Research\Photogrammetry\PPT\)
  • Скачиваем  Python Photogrammetry Toolbox GUI, копируем содержимое в папку : ../osm-bundler/osm-bundlerWin32/  .  Должно вылезти окно с предложением перезаписать файлы - соглашаемся. Если окно не вылезло - значит что то не так делаете.
  • Запускаем файл: osm-bundler/osm-bundlerWin32/ppt_gui_start.bat
Должно появиться два окна,  одно - консоль, второе - собственно интерфейс программы. :

Затем скачиваем вот этот архив с фотографиями и смотрим видео скринкаст демонстрирующий последовательность дальнейших действий..
Там титры на английском..  Я тут напишу по русски эти шаги:

1) В интерфейсе программы нажимаем кнопку "Select photos path" и указываем путь к папке с фотографиями объекта геометрию которого планируем воссоздать в 3D..  В моем случае это папка : d:\Research\Photogrammetry\PPT\ExamplesPhoto\topoi_loewen\


2) В поле "Select feature extractor" выбираем алгоритм автоматического поиска общих точек на фотографиях.. Можно выбрать между "siftlowe" и "siftvlfeat" . Первый - это алгоритм, выложенный только для частных исследовательских целей университетом University of British Columbia, что бы его использовать в коммерческих целях, необходимо обратиться в университет за лицензией. Второй вариант -  "siftvlfeat", распространяется по GPL лицензии и его можно использовать как душе угодно без выпрашивания всяких лицензий.    По умолчанию стоит "siftvlfeat" - его и оставляем.

ПС: к стати, если интересно что такое SIFT, то милости просим: SIFT

3) (это опциональный шаг) Выбираем предварительный скейл-фактор фотографий. Чем меньше разрешение исходных фото - тем быстрее будут происходить вычисления.. но в тоже время - будет хуже качество. 1 - это 100% размер исходой фотографии, 0.5 - это 50%, 0.25 - это 25%.  Я выбираю 0.5


4) Жмем кнопку "Run" что бы начать процесс обработки. За процессом можно наблюдать в окне консоли.

... процесс начался.. :
Первое на что обращаю внимание - программа говорит что не может найти информации о фокальном расстоянии объектива, на который были сняты данные фотографии.. А так же говорит что не может найти в своей базе данных информацию о фотоаппарате. И тут же пишет название фотоаппарата : Nikon D70.  (от куда программа это узнала? - из EXIF метаданных, которые имеются во всех JPG файлах и по умолчанию туда записывается много всего интересного... но это отдельная история)
Тем не менее программа пытается делать свое дело.. Однако я обязательно сделаю ещё дин проход, после того, как найду в интернете данные об этом фотоаппарате и добавлю их в базу данных PPT..
Спустя минут 10 на моем ноутбуке процесс успешно завершился и открылась папочка с кучей файлов внутри.. :
И, как сказано на видео, шаги из которого я повторяю - в папке "bundle" находится результат работы программы..  вот так выглядит моя папка бандл :
Так, первый промежуточный этап завершен.. смотрим видео и переходим на второй этап..
Предварительно нужно запомнить путь к созданной программой папке , в моем случае он такой: 
C:\Users\Notebukkoro\AppData\Local\Temp\osm-bundler-qatioi\

5) В окне программы переходим во вкладку "2. Run CMVS/PMVS" И там нажимаем кнопку "Select Bundler Output Path" и указываем на папку , созданную на прошлом этапе.

6) В поле "Number of photos in each cluster" указываем сколько фотографий будет использовать алгоритм для создания облака точек в пространстве. Так, в случае если всего фотографий было 28, и в этом поле поставить число 10, то в результате будет создано 3 файла с облаком точек (PLY-файлы). Чем больше число, тем мощнее требуется процессор для вычислений.. По этому если процесс занимает подозрительно долгое время - можно его прервать и начать второй этап заного, но указав в этом поле число поменьше.  Минус большого количества PLY файлов на выходе в том, что их придется потом все равно объединять в один общий файл облака точек. Я оставлю как и в видео - 20.  

7) Нажимаем кнопку "Run"..

У меня выскочила ошибка, ругающаяся на RadialUndistort :
Попробую перезагрузить компьютер.. есть подозрения кое какие..
И так! к счастью после перезагрузке компа все заработало! и процесс пошел! Процессор загружен на 100% :
Процесс занял 4 минуты примерно.. Как и показано в видео, в указанной нами папке создалась новая папка "pmvs".. вот :
В этой папке есть вложенная папка "models" а в ней уже лежит наш долгожданный файлик с облаком точек, которые удалось извлечь из исходных фотографий..
У меня получился вот такой результат :
Что бы увидеть визуализацию этих точек (PLY формат) - можно воспользоваться например программой MeshLab   Но я еще позже поподробнее остановлюсь на этом процессе.
Что же касаемо результата - то я мягко говоря не доволен им :)   Передо мной стоит задача научиться получать копию объекта с точностью, которая мне потребуется.. в плоть до микрон.. если надо..  Здесь же я пока не вижу этого потенциала :)  Так как опций для настроек параметров особо нету.. (минус простых, полностью автоматических процессов)   Единственное на что могу надеятся это - 1) программа не обнаружила записей о фотокамере в своей базе данных.. и 2) я поставил половинное разрешение для обработки ..
И так, в следующем посте я попробую повторить процедуру , при 100% разрешении и с наличием информации о камере. (заодно расскажу как ее добавлять)