Несколько лет назад я приступал к этому вопросу, но так тогда до конца и не довёл решение по разным причинам. Сейчас вот решил снова этим заняться, пока есть немного свободного времени. Да и хочется всё-таки сделать нормальную визуализацию в будущих проектах. Естественно, речь о . В общем, есть глобальная задача, связанная с 3D-реконструкцией. А её небольшая часть - построение 3D-карты (поля) высот по 2D-массиву пикселей, где яркость каждого пикселя (U8 / U16) представляет собой относительную высоту (координата Z), а положение пикселя в массиве (строка, столбец) - это координаты Y и X соответственно. Эта небольшая подзадача легко решаема (что я покажу ниже), но есть кое какие нюансы, которые хотелось бы уточнить. Сначала рассмотрим все доступные варианты.
Решение 1 (очевидное) - использование инструментов 3D Picture Control.
В принципе, всё просто - создаём сцену (Create Object) и загоняем на неё наше поле высот, полученное из 2D-массива через Create Height Field. В итоге имеем что-то такое:
Видео:
kzfVagr1ZSM
Решение 2 (также довольно очевидное) - использование инструмента 3D Graph -> Surface.
Здесь всё ещё проще - помещаем на FP график 3D Surface из палитры 3D Graph, на BD загоняем в Plot Helper наш 2D-массив. Если хорошенько поднастроить внешний вид графика (отключить оси и т.п.), то получится следующее:
Видео:
1cRT3LYYVtU
Решение 3 (уже не такое очевидное) - использование сторонних инструментов для визуализации.
В этом плане очень сложно сделать хороший выбор. Я выбрал среду машинного зрения HALCON от компании MVTec, просто потому что раньше пользовался ей и в ней есть поддержка .NET/ActiveX. Среда отнюдь не бесплатная, но она стоит своих денег. Используем в внешнюю процедуру visualize_object_model_3d, которую запускаем с помощью .NET узлов. Оставляя за кадром технические детали реализации, покажу сразу картинки:
Видео:
ZTuQRJDP2L8
(Если кому-то станет интересно и он решит протестировать HALCON в триал-режиме или даже купить, то я выложу , использовавшийся для вызова процедуры.)
Теперь, собственно, мои замечания.
Решение 1.
1) Насколько я понимаю, инструмент Create Height Field строит классическую карту высот, т.е. набор точек (вертексов), соединённых между собой (аналог terrain в 3D-моделировании). Временами получается красиво, временами нет. Я не нашёл способа отключить этот "частокол", т.е. сделать так, чтобы отображались только точки, без соединяющих связей.
2) Плохо, что вручную нужно выставлять положение камеры. Признаю, долго подбирал такие координаты, чтобы меня устраивала исходная позиция объекта. И я не совсем уверен, что такие координаты подойдут для другого объекта. В принципе, можно рассчитывать каждый раз положение камеры по геометрическим параметрам объекта. Но это, опять же, лишняя работа. А магической опции "поместить в центр и отдалить камеру" нигде нет. :( Также совсем неочевидна связь параметра ModelView Matrix и исходного положения (Camera Position, Target, Up Direction). В сети есть , преобразующий ModelView Matrix, но в итоге реально получаем только один кластер - Camera Position. Как рассчитать другие два -
3) Не понятно, как окрасить модель в градиент. Одним цветом, к сожалению, плохо передаётся глубина объекта. А с градиентом становится и красиво, и информативно. Если только применить текстуру на объект, но её сначала нужно создать, либо загрузить из файла. Короче, опять лишняя работа.
4) Не совсем представляю, как исключить нулевые точки из построения. Слева/справа ещё можно обрезать. А что делать там, где находится полезная информация...
5) На LV 2014 64-bit как-то глючит: рисует артефакты по всему экрану, хотя должен рендерить сугубо в своё окошко. Надо проверить на 2015.
Решение 2.
Это решение понравилось даже больше, чем предыдущее. Однако осталась проблема 1, хотя на неё можно при желании забить. Проблема 2 решена - объект всегда помещён по центру, а камера отдалена так, как нужно. Проблема 3 решена - можем выбрать любой градиент, как душе угодно. Проблема 4 осталась, но теперь она менее выражена - мы можем окрасить нулевые точки цветом фона (чёрным, например) и тогда они будут почти не видны (иногда можно увидеть в некоторых позициях).
1) Вторая проблема решилась, но породила другую - объект всегда по центру, сдвинуть его мы не можем. При сдвиге он возвращается на своё место. Это мешает разглядывать детали.
2) При длительном использовании графика (открытие свойств, вращение/зуммирование объекта) может либо зависнуть, либо вылететь Правда, я это мало тестировал, надо будет на последних версиях проверить.
3) В ран-тайме недоступен рендер в отдельное окно (в отличие от 3D Picture и HALCON). Хотя в отладке этот режим есть. Может, как-то включается, не нашёл.
А так, решение вроде бы удачное. Если пренебречь описанными траблами, то можно использовать.
Решение 3.
Хорошее решение, удовлетворяет большинство моих запросов. Решены проблемы 1, 2, 3 и 4. Однако, кое что стоит отметить.
1) Оператор gen_object_model_3d_from_points создаёт не карту высот (height map), а облако точек (point field). То есть, получаем несвязанные между собой точки (вертексы). Это удобно в большинстве случаев. Но если вдруг потребуется карта высот, то не совсем понятно, как на неё переключиться. Проблема, скорее, надуманная, ибо сам не решил, что мне будет удобнее. Да и с имеющимся функционалом HALCON'а решение найти не составит труда.
2) Продукт платный, что вызывает естественные сложности с лицензированием, распространением и т.д. Известная в таких случаях проблема.
3) Интерфейс ActiveX какой-то глючный, техподдержка не советует его использовать. Рекомендуют работать на .NET. Что вызывает жёсткую привязку к .NET Framework и его библиотекам. Можно, конечно, попробовать DLL, но такой подход имеет ряд минусов (типа отсутствия встроенного окна HALCON на панели LabVIEW).
Все три решения имеют ещё один общий минус. Так как везде используется OpenGL, а когда его нет - программная обработка, то на слабых машинах (в т.ч. со встроенной видяхой) визуализация заметно подтормаживает. Хотя таких машин всё меньше становится с каждым годом. Современные компы спокойно тянут обработку сотен тысяч точек.
Возможны так же какие-то альтернативные решения. Беглый поиск в гугле мало что дал, но может кто-то уже применял подобные альтернативы или видел подходящие тулкиты... Я когда-то пробовал приспособить под это дело движок Irrlicht, но дальше копания в примерах у меня дело не пошло. Знаю, что можно реализовать многое с нуля, например тот же OpenGL прикрутить, но сейчас абсолютно нет никакого желания и времени, чтобы писать обёртки, разбираться в вызовах библиотек и прочее. Интересуют только готовые решения для LabVIEW. В общем, интересно, кто и как решает похожие задачи 3D-визуализации.
Построение карты высот: решения, особенности, плюсы и минусы
-
dadreamer
- professor
- Сообщения: 3926
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2022
- Благодарил (а): 11 раз
- Поблагодарили: 127 раз
- Контактная информация:
Построение карты высот: решения, особенности, плюсы и минусы
Последний раз редактировалось dadreamer 16 апр 2016, 15:09, всего редактировалось 1 раз.
-
- professor
- Сообщения: 3408
- Зарегистрирован: 31 июл 2011, 23:05
- Награды: 2
- Версия LabVIEW: 12-18
- Благодарил (а): 49 раз
- Поблагодарили: 176 раз
- Контактная информация:
Re: Построение карты высот: решения, специфика, особенности
мои три копейки
и головой вверх, ногами вниз. т.е. нет смысла без необходимости переворачивать камеру вверх ногами.
вот как выглядит точечное колесо после волшебной кнопки В приложении код этого самого примера. Насчёт текстур не знаю, код выдрал из своего проекта. Без чего можно обойтись, не проверял.
как-то так draw mode: pointsdadreamer писал(а): Решение 1.
1) Насколько я понимаю, инструмент Create Height Field строит классическую карту высот, т.е. набор точек (вертексов), соединённых между собой (аналог terrain в 3D-моделировании). Временами получается красиво, временами нет. Я не нашёл способа отключить этот "частокол", т.е. сделать так, чтобы отображались только точки, без соединяющих связей.
однако есть2) Плохо, что вручную нужно выставлять положение камеры. Признаю, долго подбирал такие координаты, чтобы меня устраивала исходная позиция объекта. И я не совсем уверен, что такие координаты подойдут для другого объекта. В принципе, можно рассчитывать каждый раз положение камеры по геометрическим параметрам объекта. Но это, опять же, лишняя работа. А магической опции "поместить в центр и отдалить камеру" нигде нет. :(
довольно очевидно, что смотреть стоит в центр объекта (масс, геометрический, какой угодно)Также совсем неочевидна связь параметра ModelView Matrix и исходного положения (Camera Position, Target, Up Direction). В сети есть , преобразующий ModelView Matrix, но в итоге реально получаем только один кластер - Camera Position. Как рассчитать другие два -
и головой вверх, ногами вниз. т.е. нет смысла без необходимости переворачивать камеру вверх ногами.
на форуме NI народ извращается, детально не смотрел3) Не понятно, как окрасить модель в градиент. Одним цветом, к сожалению, плохо передаётся глубина объекта. А с градиентом становится и красиво, и информативно. Если только применить текстуру на объект, но её сначала нужно создать, либо загрузить из файла. Короче, опять лишняя работа.
это я не понял4) Не совсем представляю, как исключить нулевые точки из построения. Слева/справа ещё можно обрезать. А что делать там, где находится полезная информация...
2014/32 глюков не наблюдал, толко кошмарное качество больших объектов, но всё в рамках 3Д индикатора.5) На LV 2014 64-bit как-то глючит: рисует артефакты по всему экрану, хотя должен рендерить сугубо в своё окошко. Надо проверить на 2015.
вот как выглядит точечное колесо после волшебной кнопки В приложении код этого самого примера. Насчёт текстур не знаю, код выдрал из своего проекта. Без чего можно обойтись, не проверял.
- Вложения
-
- Untitled 1.vi
- LV9
- (14.86 КБ) 228 скачиваний
-
dadreamer
- professor
- Сообщения: 3926
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2022
- Благодарил (а): 11 раз
- Поблагодарили: 127 раз
- Контактная информация:
Re: Построение карты высот: решения, специфика, особенности
Большое спасибо! Не думал, что можно поточечно Mesh построить. Использовал Create Mesh With Attributes, получилось как-то так:Artem.spb писал(а):draw mode: pointsdadreamer писал(а):Решение 1.
1) Насколько я понимаю, инструмент Create Height Field строит классическую карту высот, т.е. набор точек (вертексов), соединённых между собой (аналог terrain в 3D-моделировании). Временами получается красиво, временами нет. Я не нашёл способа отключить этот "частокол", т.е. сделать так, чтобы отображались только точки, без соединяющих связей.
Картинку модели уж приводить не буду, получилось нормальное облако точек. Что теперь хорошо - я могу не строить нулевые точки (цикл For в начале диаграммы). С освещением только пока не разобрался. Сверху точки окрашены в выбранный мной цвет, переворачиваю модель - цвет становится почти чёрный. Как сделать одинаковый окрас во всех позициях? Источник света нужно ставить?..
Вот за это отдельное спасибо! Что-то я проглядел этот метод. Смотрел в основном на свойства контрола. Реально работает, можно не париться с положением камеры.Artem.spb писал(а):однако естьdadreamer писал(а):2) Плохо, что вручную нужно выставлять положение камеры. Признаю, долго подбирал такие координаты, чтобы меня устраивала исходная позиция объекта. И я не совсем уверен, что такие координаты подойдут для другого объекта. В принципе, можно рассчитывать каждый раз положение камеры по геометрическим параметрам объекта. Но это, опять же, лишняя работа. А магической опции "поместить в центр и отдалить камеру" нигде нет. :(
Ну, это да, согласно этому правилу я и выставлял положение камеры. Я к тому, что в реальном времени, вращая/зуммируя/перетаскивая модель, мы меняем её положение и положение камеры. Получить текущие координаты можно только с помощью свойства ModelView Matrix. Оно связано с Camera Position, Target, Up Direction, но получить из одного другое не так просто. Один параметр я вытащил, остальные два - нет. Мне кажется, NI могли бы сделать эту работу за пользователя, странно, что это до сих пор не реализовано как отдельное свойство/метод.Artem.spb писал(а):довольно очевидно, что смотреть стоит в центр объекта (масс, геометрический, какой угодно)dadreamer писал(а):Также совсем неочевидна связь параметра ModelView Matrix и исходного положения (Camera Position, Target, Up Direction). В сети есть , преобразующий ModelView Matrix, но в итоге реально получаем только один кластер - Camera Position. Как рассчитать другие два -
и головой вверх, ногами вниз. т.е. нет смысла без необходимости переворачивать камеру вверх ногами.
Так там экспериментируют с графиками из палитры 3D Graph, а не с 3D Picture Control. Причём примеры приведены на старых версиях графиков, работающих на ComponentWorks ActiveX. Как я выше писал, градиент прекрасно устанавливается на 3D графики. А вот с 3D Picture Control загвоздка.Artem.spb писал(а):на форуме NI народ извращается, детально не смотрелdadreamer писал(а):3) Не понятно, как окрасить модель в градиент. Одним цветом, к сожалению, плохо передаётся глубина объекта. А с градиентом становится и красиво, и информативно. Если только применить текстуру на объект, но её сначала нужно создать, либо загрузить из файла. Короче, опять лишняя работа.
Вариант с Mesh'ем решил эту проблему (см. код выше). Просто в исходных картинках обязательно есть пиксели с нулевой яркостью. Такие пиксели не несут никакой информации, строить по ним вертексы не нужно. Потому я такие пиксели фильтрую. В принципе, можно установить порог по яркости и выше, единиц 20-30, если захочется.Artem.spb писал(а):это я не понялdadreamer писал(а):4) Не совсем представляю, как исключить нулевые точки из построения. Слева/справа ещё можно обрезать. А что делать там, где находится полезная информация...
Проверил сегодня на LV 2015 SP1 64-bit - артефактов нет, всё в порядке. Видимо, проблема была только в 2014-й версии на 64 бита. Проверял на других на 32 бита, тоже всё нормально.Artem.spb писал(а):2014/32 глюков не наблюдал, толко кошмарное качество больших объектов, но всё в рамках 3Д индикатора.dadreamer писал(а):5) На LV 2014 64-bit как-то глючит: рисует артефакты по всему экрану, хотя должен рендерить сугубо в своё окошко. Надо проверить на 2015.
В общем, благодаря советам Artem.spb удалось решить большую часть проблем, связанных с 3D Picture Control. Осталось разобраться с цветами и всё-таки как-то задать градиент. Я вижу, у вас текстура из файла грузится. Она готовая у вас или вы её отдельно как-то генерируете?
-
- professor
- Сообщения: 3408
- Зарегистрирован: 31 июл 2011, 23:05
- Награды: 2
- Версия LabVIEW: 12-18
- Благодарил (а): 49 раз
- Поблагодарили: 176 раз
- Контактная информация:
Re: Построение карты высот: решения, специфика, особенности
освещение - это что-то адовое. Там дофига параметров и не очень понятно, как они работают. Есть некий параметр "равномерно со всех сторон", но результат он мне дал вовсе не тот, что я ожидал (никакой равномерности). В итоге я экспериментально подобрал настройки источников.dadreamer писал(а):С освещением только пока не разобрался. Сверху точки окрашены в выбранный мной цвет, переворачиваю модель - цвет становится почти чёрный. Как сделать одинаковый окрас во всех позициях? Источник света нужно ставить?.
Согласен. Я тоже смог определить только положение камеры. Но в итоге имеющиеся задачи решались другими способами, поэтому я не парился.Artem.spb писал(а):Получить текущие координаты можно только с помощью свойства ModelView Matrix. Оно связано с Camera Position, Target, Up Direction, но получить из одного другое не так просто. Один параметр я вытащил, остальные два - нет. Мне кажется, NI могли бы сделать эту работу за пользователя, странно, что это до сих пор не реализовано как отдельное свойство/метод.
Ну с ходу приходит в голову идея разделить точки на группы и каждой группе свой цвет отрисовки назначить. Опять же через одно место, но других вариантов не знаю.3) Не понятно, как окрасить модель в градиент. Одним цветом, к сожалению, плохо передаётся глубина объекта. А с градиентом становится и красиво, и информативно.
там сложная модель собирается из деталей. Рама на колёсах катается по рельсам. К сожалению, заказчик попросил удалить видео с ютуба.Я вижу, у вас текстура из файла грузится. Она готовая у вас или вы её отдельно как-то генерируете?
Отдельный части загружаются из независимых Файлов. Модели рисовались в солиде, потом экспортировались в то, что понимает. Задачи обновлять их постоянно не стояло, только вращать и перемещать. Ну и ещё цвет менять (лампочка вкл/выкл).
-
dadreamer
- professor
- Сообщения: 3926
- Зарегистрирован: 17 фев 2013, 16:33
- Награды: 4
- Версия LabVIEW: 2.5 — 2022
- Благодарил (а): 11 раз
- Поблагодарили: 127 раз
- Контактная информация:
Re: Построение карты высот: решения, особенности, плюсы и ми
Продолжаю свои эксперименты.
Покопался также немного в Halcon'е. Так и не нашёл простого метода для конвертации "облако точек" -> "карта высот". Есть вариант с триангуляцией облака по нормалям, но он медленный и изменяет модель. Не совсем мне понравилось. Буду ещё экспериментировать.
Как оказалось, нужно просто выключить освещение: SceneObject.Specials.Lighting = Off. Теперь во всех положениях точки модели имеют одинаковый цвет и яркость.dadreamer писал(а):С освещением только пока не разобрался. Сверху точки окрашены в выбранный мной цвет, переворачиваю модель - цвет становится почти чёрный. Как сделать одинаковый окрас во всех позициях? Источник света нужно ставить?..
Сперва попробовал самостоятельно создать градиентный массив - при применении на объект получилась фигня. :) Потом нашёл вот такой : https://decibel.ni.com/content/docs/DOC-9294 Подходит как раз на 8-битный объект и можно сколько угодно задать цветов для перехода. При создании Mesh-объекта ставим Color Binding Mode = Per Vertex. Работает очень хорошо: Так что, в принципе, все описанные выше неприятности с 3D Picture Control удачно разрешились. Это относится к режиму "облако точек". Для режима "поле высот" цвета отдельных вертексов не выставляются. Но можно применить текстуру, полученную наложением градиента на яркости пикселей объекта: Ещё бы как-то сглаживание применить, а то местами выглядит как в игре с низким разрешением. Ну, и остаётся минус с невозможностью отсечения нулевых точек. Но, в общем и целом, задача построения карты высот и облака точек в достигнута.dadreamer писал(а):Осталось [...] всё-таки как-то задать градиент.
Покопался также немного в Halcon'е. Так и не нашёл простого метода для конвертации "облако точек" -> "карта высот". Есть вариант с триангуляцией облака по нормалям, но он медленный и изменяет модель. Не совсем мне понравилось. Буду ещё экспериментировать.