portaldacalheta.pt
  • Основен
  • Растеж На Приходите
  • Финансови Процеси
  • Дизайнерски Живот
  • Съвети И Инструменти
Наука За Данни И Бази Данни

3D визуализация на данни с инструменти с отворен код: Урок, използващ VTK



В скорошната си статия в блога на ApeeScape, квалифициран учен за данни Чарлз Кук пише за научни изчисления с инструменти с отворен код . Неговият урок прави важен момент относно инструментите с отворен код и ролята, която те могат да играят при лесното обработване на данни и получаването на резултати.

Но щом решим всички тези сложни диференциални уравнения, възникват други проблеми. Как да разберем и интерпретираме огромните количества данни, излизащи от тези симулации? Как да визуализираме потенциални гигабайта данни, като например данни с милиони мрежови точки в рамките на голяма симулация?



Обучение за визуализация на данни за учени, занимаващи се с данни, които се интересуват от инструментите за 3D визуализация на данни.



По време на работата ми по подобни проблеми за моя Магистърска теза , Влязох в контакт с Visualization Toolkit или VTK - мощна графична библиотека, специализирана за визуализация на данни.



В този урок ще дам кратко въведение в VTK и неговата архитектура на тръбопровода и ще продължа да обсъждам реалния пример за 3D визуализация, използвайки данни от симулиран флуид в работната помпа. Накрая ще изброя силните страни на библиотеката, както и слабите места, които срещнах.

Визуализация на данни и тръбопроводът VTK

Библиотеката с отворен код VTK съдържа солиден конвейер за обработка и изобразяване с много усъвършенствани алгоритми за визуализация. Възможностите му обаче не спират дотук, тъй като с течение на времето са добавени и алгоритми за обработка на изображения и мрежи. В настоящия си проект с компания за стоматологични изследвания използвам VTK за мрежови задачи за обработка в рамките на Qt базирано на CAD-подобно приложение. The VTK казуси показват широката гама от подходящи приложения.



Архитектурата на VTK се върти около мощна концепция на тръбопровода. Основното очертание на тази концепция е показано тук:

Ето как изглежда тръбопроводът за визуализация на данни VTK.



  • Източници са в самото начало на тръбопровода и създават „нещо от нищо“. Например a vtkConeSource създава 3D конус и vtkSTLReader чете *.stl 3D геометрични файлове.
  • Филтри трансформира изхода на източници или други филтри в нещо ново. Например a vtkCutter изрязва изхода на предишния обект в алгоритмите, използвайки неявна функция, например равнина. Всички алгоритми за обработка, които се доставят с VTK, са внедрени като филтри и могат да бъдат свободно свързани помежду си.
  • Картографи трансформиране на данни в графични примитиви. Например, те могат да се използват за определяне на търсеща таблица за оцветяване на научни данни. Те са абстрактен начин да се определи какво да се показва.
  • Актьори представляват обект (геометрия плюс свойства на дисплея) в рамките на сцената. Тук са посочени неща като цвят, непрозрачност, засенчване или ориентация.
  • Рендери и Windows накрая опишете изобразяването на екрана по независим от платформата начин.

Типичният конвейер за рендиране на VTK започва с един или повече източници, обработва ги с помощта на различни филтри в няколко изходни обекта, които след това се изобразяват отделно с помощта на картографи и актьори. Силата зад тази концепция е механизмът за актуализация. Ако настройките на филтрите или източниците се променят, всички зависими филтри, картографи, актьори и прозорци за рендиране се актуализират автоматично. Ако, от друга страна, обект по-надолу по тръбопровода се нуждае от информация, за да изпълнява задачите си, той може лесно да я получи.

Освен това няма нужда да се занимавате директно със системи за рендиране като OpenGL. VTK капсулира всички задачи от ниско ниво по независим от платформата и (частично) визуализиране начин; разработчикът работи на много по-високо ниво.



Пример за код с набор от данни на роторна помпа

Нека да разгледаме пример за визуализация на данни, използващ набор от данни за потока на флуида във въртяща се помпа на работното колело от IEEE Visualization Contest 2011. Самите данни са резултат от изчислителна симулация на динамика на течността, подобно на тази, описана в статията на Чарлз Кук.

Данните за симулация с цип на представената помпа са с размер над 30 GB. Той съдържа множество части и множество времеви стъпки, следователно големият размер. В това ръководство ще си поиграем с роторната част на един от тези времеви стъпки, която има компресиран размер от около 150 MB.



полуконтролирано обучение дълбоко учене

Избраният от мен език за използване на VTK е C ++, но има съпоставяния за няколко други езика като Tcl / Tk, Java и Python. Ако целта е само визуализация на един набор от данни, изобщо не е необходимо да се пише код и вместо това може да се използва Paraview , графичен интерфейс за по-голямата част от функционалността на VTK.

Наборът от данни и защо 64-битовите са необходими

Извадих роторния набор от данни от 30 GB набор от данни, предоставен по-горе, като отворих една стъпка от време в Paraview и извадих роторната част в отделен файл. Това е неструктуриран мрежов файл, т.е. 3D обем, състоящ се от точки и 3D клетки, като хексаедри, тетраедри и т.н. Всяка от 3D точките има свързани стойности. Понякога клетките също имат свързани стойности, но не и в този случай. Това обучение ще се концентрира върху натиска и скоростта в точките и ще се опита да ги визуализира в техния 3D контекст.



Размерът на компресирания файл е около 150 MB, а размерът в паметта е около 280 MB, когато се зарежда с VTK. Чрез обработката му във VTK наборът от данни се кешира няколко пъти в рамките на VTK тръбопровода и бързо достигаме ограничението от 2 GB памет за 32-битови програми. Има начини да спестите памет при използване на VTK, но за да бъде опростено, просто ще компилираме и стартираме примера в 64bit.

c corp срещу корпоративно данъчно облагане

Благодарности : Наборът от данни се предоставя с любезното съдействие на Института по приложна механика, Университет Клаустал, Германия (Dipl. Wirtsch.-Ing. Andreas Lucius).

Целта

Това, което ще постигнем, използвайки VTK като инструмент, е визуализацията, показана на изображението по-долу. Като 3D контекст контурът на набора от данни е показан с помощта на частично прозрачно изобразяване на каркасни рамки. След това лявата част от набора от данни се използва за показване на налягането, като се използва просто цветно кодиране на повърхностите. (Ще пропуснем по-сложното изобразяване на тома за този пример). За да визуализирате полето на скоростта, дясната част от набора от данни е изпълнена с рационализиране , които са цветно кодирани от величината на тяхната скорост. Този избор на визуализация технически не е идеален, но исках да запазя VTK кода възможно най-опростен. Освен това има причина този пример да бъде част от предизвикателство за визуализация, т.е. много турбулентност в потока.

Това е получената 3D визуализация на данните от нашия примерен урок за VTK.

Стъпка по стъпка

Ще обсъдя VTK кода стъпка по стъпка, показвайки как би изглеждал изходът за рендиране на всеки етап. Пълният изходен код може да бъде изтеглен в края на обучението.

Нека започнем, като включим всичко, от което се нуждаем от VTK, и отворим основната функция.

#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char** argv) {

След това настройваме визуализатора и прозореца за изобразяване, за да покажем нашите резултати. Задаваме цвета на фона и размера на прозореца за изобразяване.

// Setup the renderer vtkNew renderer; renderer->SetBackground(0.9, 0.9, 0.9); // Setup the render window vtkNew renWin; renWin->AddRenderer(renderer.Get()); renWin->SetSize(500, 500);

С този код вече бихме могли да покажем статичен прозорец за рендиране. Вместо това избираме да добавим vtkRenderWindowInteractor за интерактивно завъртане, мащабиране и панорамиране на сцената.

// Setup the render window interactor vtkNew interact; vtkNew style; interact->SetRenderWindow(renWin.Get()); interact->SetInteractorStyle(style.Get());

Сега имаме работещ пример, показващ сив, празен прозорец за рендиране.

След това зареждаме набора от данни, използвайки един от многото четци, които се доставят с VTK.

// Read the file vtkSmartPointer pumpReader = vtkSmartPointer::New(); pumpReader->SetFileName('rotor.vtu');

Кратка екскурзия в управлението на паметта VTK : VTK използва удобна концепция за автоматично управление на паметта, въртяща се около преброяването на референции. За разлика от повечето други реализации, броят на референциите се съхранява в самите обекти на VTK, вместо в класа на интелигентния указател. Това има предимството, че броят на референциите може да бъде увеличен, дори ако VTK обектът се предава като суров указател. Има два основни начина за създаване на управлявани VTK обекти. vtkNew и vtkSmartPointer::New(), като основната разлика е, че a vtkSmartPointer е имплицитно приложимо към суровия указател T* и може да бъде върнато от функция. За случаи на vtkNew ще трябва да се обадим .Get() за да получим суров указател и можем да го върнем само като го увием в vtkSmartPointer. В рамките на нашия пример ние никога не се връщаме от функции и всички обекти живеят през цялото време, затова ще използваме краткото vtkNew, само с горното изключение за демонстрационни цели.

Към този момент от файла все още не е прочетено нищо. Ние или филтър по-надолу по веригата ще трябва да извикаме Update() за да се случи четенето на файла. Обикновено най-добрият подход е да оставите VTK класовете да се справят сами с актуализациите. Понякога обаче искаме да получим директен достъп до резултата от даден филтър, например за да получим обхвата на наляганията в този набор от данни. След това трябва да се обадим Update() ръчно. (Не губим производителност, като извикваме Update() няколко пъти, тъй като резултатите се кешират.)

// Get the pressure range pumpReader->Update(); double pressureRange[2]; pumpReader->GetOutput()->GetPointData()->GetArray('Pressure')->GetRange(pressureRange);

След това трябва да извлечем лявата половина от набора от данни, като използваме vtkClipDataSet За да постигнем това, първо дефинираме vtkPlane което определя разделението. След това ще видим за първи път как VTK тръбопроводът е свързан заедно: successor->SetInputConnection(predecessor->GetOutputPort()) Винаги, когато поискаме актуализация от clipperLeft тази връзка вече ще гарантира, че всички предходни филтри също са актуални.

// Clip the left part from the input vtkNew planeLeft; planeLeft->SetOrigin(0.0, 0.0, 0.0); planeLeft->SetNormal(-1.0, 0.0, 0.0); vtkNew clipperLeft; clipperLeft->SetInputConnection(pumpReader->GetOutputPort()); clipperLeft->SetClipFunction(planeLeft.Get());

И накрая, ние създаваме нашите първи актьори и картографи, за да покажем каркасното изобразяване на лявата половина. Забележете, че картографът е свързан към своя филтър точно по същия начин като филтрите един към друг. По-голямата част от времето самият визуализатор задейства актуализациите на всички участници, картографи и основните филтърни вериги!

Единственият ред, който не е обяснителен, може би е leftWireMapper->ScalarVisibilityOff(); - забранява оцветяването на телената рамка чрез стойности на налягането, които са зададени като активния в момента масив.

// Create the wireframe representation for the left part vtkNew leftWireMapper; leftWireMapper->SetInputConnection(clipperLeft->GetOutputPort()); leftWireMapper->ScalarVisibilityOff(); vtkNew leftWireActor; leftWireActor->SetMapper(leftWireMapper.Get()); leftWireActor->GetProperty()->SetRepresentationToWireframe(); leftWireActor->GetProperty()->SetColor(0.8, 0.8, 0.8); leftWireActor->GetProperty()->SetLineWidth(0.5); leftWireActor->GetProperty()->SetOpacity(0.8); renderer->AddActor(leftWireActor.Get());

В този момент прозорецът за рендиране най-накрая показва нещо, т.е. каркаса за лявата част.

колко шрифта има

Това също е резултатен пример за 3D визуализация на данни от инструмента VTK.

Рендерирането на каркасна рамка за дясната част се създава по подобен начин, чрез превключване на равнината нормална на a (новосъздадена) vtkClipDataSet в обратна посока и леко променящ цвета и непрозрачността на (новосъздадения) картограф и актьор. Забележете, че тук нашият VTK тръбопровод се разделя в две посоки (вдясно и вляво) от един и същ набор от данни.

// Clip the right part from the input vtkNew planeRight; planeRight->SetOrigin(0.0, 0.0, 0.0); planeRight->SetNormal(1.0, 0.0, 0.0); vtkNew clipperRight; clipperRight->SetInputConnection(pumpReader->GetOutputPort()); clipperRight->SetClipFunction(planeRight.Get()); // Create the wireframe representation for the right part vtkNew rightWireMapper; rightWireMapper->SetInputConnection(clipperRight->GetOutputPort()); rightWireMapper->ScalarVisibilityOff(); vtkNew rightWireActor; rightWireActor->SetMapper(rightWireMapper.Get()); rightWireActor->GetProperty()->SetRepresentationToWireframe(); rightWireActor->GetProperty()->SetColor(0.2, 0.2, 0.2); rightWireActor->GetProperty()->SetLineWidth(0.5); rightWireActor->GetProperty()->SetOpacity(0.1); renderer->AddActor(rightWireActor.Get());

Изходният прозорец сега показва и двете части на каркаса, както се очаква.

Изходният прозорец за визуализация на данни сега показва и двете части на каркаса, съгласно примера VTK.

Сега сме готови да визуализираме някои полезни данни! За да добавим визуализацията на налягането в лявата част, не е нужно да правим много. Създаваме нов картограф и го свързваме с clipperLeft също, но този път оцветяваме чрез масива под налягане. Също така тук най-накрая използваме pressureRange извлекли сме по-горе.

// Create the pressure representation for the left part vtkNew pressureColorMapper; pressureColorMapper->SetInputConnection(clipperLeft->GetOutputPort()); pressureColorMapper->SelectColorArray('Pressure'); pressureColorMapper->SetScalarRange(pressureRange); vtkNew pressureColorActor; pressureColorActor->SetMapper(pressureColorMapper.Get()); pressureColorActor->GetProperty()->SetOpacity(0.5); renderer->AddActor(pressureColorActor.Get());

Резултатът сега изглежда като изображението, показано по-долу. Налягането в средата е много ниско, всмуква материал в помпата. След това този материал се транспортира навън, бързо набирайки налягане. (Разбира се, трябва да има легенда за цветна карта с действителните стойности, но я оставих, за да запазя примера по-кратък.)

Когато в примера за визуализация на данни се добави цвят, ние наистина започваме да виждаме начина, по който помпата работи.

Сега започва по-сложната част. Искаме да нарисуваме скоростни потоци в дясната част. Потоците се генерират чрез интегриране в векторно поле от изходни точки. Векторното поле вече е част от набора от данни под формата на векторния масив „Скорости“. Така че трябва само да генерираме изходните точки. vtkPointSource генерира сфера от случайни точки. Ще генерираме 1500 източници, тъй като повечето от тях така или иначе няма да се намират в набора от данни и ще бъдат игнорирани от трасиращия поток.

// Create the source points for the streamlines vtkNew pointSource; pointSource->SetCenter(0.0, 0.0, 0.015); pointSource->SetRadius(0.2); pointSource->SetDistributionToUniform(); pointSource->SetNumberOfPoints(1500);

След това създаваме streamtracer и задаваме неговите входни връзки. 'Изчакайте, многократни връзки? ”, може да се каже. Да - това е първият VTK филтър с множество входове, които срещаме. Нормалната входна връзка се използва за векторното поле, а връзката източник се използва за началните точки. Тъй като „Velocities“ е „активният“ векторен масив в clipperRight, не е необходимо да го посочваме тук изрично. Накрая уточняваме, че интегрирането трябва да се извършва в двете посоки от началните точки и да зададем метода на интеграция на Рунге-Кута-4.5 .

vtkNew tracer; tracer->SetInputConnection(clipperRight->GetOutputPort()); tracer->SetSourceConnection(pointSource->GetOutputPort()); tracer->SetIntegrationDirectionToBoth(); tracer->SetIntegratorTypeToRungeKutta45();

Следващият ни проблем е оцветяването на потоците с величина на скоростта. Тъй като няма масив за величините на векторите, ние просто ще изчислим величините в нов скаларен масив. Както се досещате, за тази задача има и VTK филтър: vtkArrayCalculator. Той взема набор от данни и го извежда непроменен, но добавя точно един масив, който се изчислява от един или повече от съществуващите. Конфигурираме този калкулатор на масиви да приема величината на вектора „Скорост“ и да го извежда като „MagVelocity“. Накрая извикваме Update() отново ръчно, за да се извлече обхватът на новия масив.

// Compute the velocity magnitudes and create the ribbons vtkNew magCalc; magCalc->SetInputConnection(tracer->GetOutputPort()); magCalc->AddVectorArrayName('Velocity'); magCalc->SetResultArrayName('MagVelocity'); magCalc->SetFunction('mag(Velocity)'); magCalc->Update(); double magVelocityRange[2]; magCalc->GetOutput()->GetPointData()->GetArray('MagVelocity')->GetRange(magVelocityRange);

vtkStreamTracer директно извежда полилинии и vtkArrayCalculator предава ги непроменени. Следователно можем просто да покажем изхода на magCalc директно с помощта на нов картограф и актьор.

Вместо това, в това обучение ние избираме да направим изхода малко по-хубав, като показваме ленти вместо това. vtkRibbonFilter генерира 2D клетки за показване на панделки за всички полилинии от неговия вход.

// Create and render the ribbons vtkNew ribbonFilter; ribbonFilter->SetInputConnection(magCalc->GetOutputPort()); ribbonFilter->SetWidth(0.0005); vtkNew streamlineMapper; streamlineMapper->SetInputConnection(ribbonFilter->GetOutputPort()); streamlineMapper->SelectColorArray('MagVelocity'); streamlineMapper->SetScalarRange(magVelocityRange); vtkNew streamlineActor; streamlineActor->SetMapper(streamlineMapper.Get()); renderer->AddActor(streamlineActor.Get());

Това, което сега все още липсва и всъщност е необходимо, за да се получат и междинните визуализации, са последните пет реда за рендиране на сцената и инициализиране на интерактора.

// Render and show interactive window renWin->Render(); interact->Initialize(); interact->Start(); return 0; }

Накрая стигаме до завършената визуализация, която ще представя още веднъж тук:

получаване и преобразуване (захранване на запитване)

Обучението VTK дава резултат в този пълен пример за визуализация.

Пълният изходен код за горната визуализация може да бъде намерен тук .

Добрият, лошият и грозният

Ще затворя тази статия със списък с моите лични плюсове и минуси на рамката VTK.

  • За : Активно развитие : VTK е в процес на активно развитие от няколко участници, главно от изследователската общност. Това означава, че са налични някои авангардни алгоритми, много 3D-формати могат да бъдат импортирани и експортирани, грешките са активно отстранени и проблемите обикновено имат готово решение в дискусионните дъски.

  • С : Надеждност : Свързването на много алгоритми от различни сътрудници с отворения дизайн на тръбопровода на VTK обаче може да доведе до проблеми с необичайни комбинации от филтри. Трябваше да вляза в изходния код на VTK няколко пъти, за да разбера защо моята сложна филтърна верига не дава желаните резултати. Силно препоръчвам да настроите VTK по начин, който позволява отстраняване на грешки.

  • За : Софтуерна архитектура : Дизайнът на тръбопровода и общата архитектура на VTK изглежда добре обмислен и е удоволствие да се работи с него. Няколко реда на кода могат да доведат до невероятни резултати. Вградените структури от данни са лесни за разбиране и използване.

  • С : Микро архитектура : Някои решения за микроархитектурен дизайн избягват моето разбиране. Конст-коректността почти не съществува, масивите се предават като входове и изходи без ясна разлика. Облекчих това за собствените си алгоритми, като се отказах от някаква производителност и използвах собствената си обвивка за vtkMath който използва персонализирани 3D типове като typedef std::array Pnt3d;.

  • За : Микродокументация : Документовата документация за всички класове и филтри е обширна и използваема, примерите и тестовите случаи в wiki също са чудесна помощ за разбиране на начина на използване на филтрите.

  • С : Макро документация : В мрежата има няколко добри урока за и въведения за VTK. Доколкото знам обаче, няма голяма справочна документация, която да обяснява как се правят конкретни неща. Ако искате да направите нещо ново, очаквайте да потърсите как да го направите известно време. Освен това е трудно да се намери конкретният филтър за дадена задача. След като го намерите обаче, документацията за кислорода обикновено е достатъчна. Един добър начин за изследване на VTK рамката е да изтеглите и експериментирате с Paraview.

  • За : Имплицитна подкрепа за паралелизиране : Ако вашите източници могат да бъдат разделени на няколко части, които могат да бъдат обработени независимо, успоредяването е толкова просто, колкото създаването на отделна верига от филтри във всяка нишка, която обработва една част. Повечето големи проблеми с визуализацията обикновено попадат в тази категория.

  • С : Няма изрична поддръжка за паралелизиране : Ако не сте благословени с големи, делими проблеми, но искате да използвате множество ядра, вие сте сами. Ще трябва да разберете кои класове са безопасни за нишки или дори да се включите отново чрез проби и грешки или като прочетете източника. Веднъж проследих проблема с паралелизацията до VTK филтър, който използва статична глобална променлива, за да извика някаква C библиотека.

  • За : Buildsystem CMake : Мултиплатформената мета-система за изграждане CMake също се разработва от Kitware (създателите на VTK) и се използва в много проекти извън Kitware. Той се интегрира много добре с VTK и прави създаването на система за изграждане на множество платформи много по-малко болезнено.

  • За : Независимост на платформата, лиценз и дълголетие : VTK е независима от платформата и е лицензирана под много разрешителен лиценз в стил BSD . Освен това се предлага професионална подкрепа за онези важни проекти, които изискват това. Kitware е подкрепен от много изследователски организации и други компании и ще съществува известно време.

Последна дума

Като цяло VTK е най-добрият инструмент за визуализация на данни за видовете проблеми, които обичам. Ако някога попаднете на проект, който изисква визуализация, обработка на мрежи, обработка на изображения или подобни задачи, опитайте да задействате Paraview с входен пример и преценете дали VTK може да бъде инструментът за вас.

Окончателното ръководство за базите данни NoSQL

Back-End

Окончателното ръководство за базите данни NoSQL
Дискусионни разговори: по-добро сътрудничество между дизайнерите и разработчиците с Aarron Walter от InVision

Дискусионни разговори: по-добро сътрудничество между дизайнерите и разработчиците с Aarron Walter от InVision

Ux Дизайн

Популярни Публикации
UI срещу UX: Жизненоважното ръководство за дизайн на потребителския интерфейс
UI срещу UX: Жизненоважното ръководство за дизайн на потребителския интерфейс
Приемане на Firebase без сървъри - Мобилните и уеб приложенията стават лесно
Приемане на Firebase без сървъри - Мобилните и уеб приложенията стават лесно
Ценова еластичност 2.0: от теорията към реалния свят
Ценова еластичност 2.0: от теорията към реалния свят
Проучване на мултимодален дизайн - Урок за Adobe XD
Проучване на мултимодален дизайн - Урок за Adobe XD
Максималистичен дизайн и проблемът с минимализма
Максималистичен дизайн и проблемът с минимализма
 
Agile UX: Как да включите UX и продуктовия дизайн в Agile
Agile UX: Как да включите UX и продуктовия дизайн в Agile
Научете Markdown: Инструмент за писане за разработчици на софтуер
Научете Markdown: Инструмент за писане за разработчици на софтуер
CloudI: Привеждане на толерантността на Erlang към развитие на полиглот
CloudI: Привеждане на толерантността на Erlang към развитие на полиглот
Внедряване на безсървърни функции Node.js с помощта на Google Cloud
Внедряване на безсървърни функции Node.js с помощта на Google Cloud
Презентационен дизайн и изкуството на визуалното разказване на истории
Презентационен дизайн и изкуството на визуалното разказване на истории
Популярни Публикации
  • какво е дизайнът в изкуството
  • как да използвам bootstrap css
  • s corp или c corp за малък бизнес
  • каква е разликата между ac corporation и as corporation
  • mysql конвертирате в utf 8
  • какво прави node js
Категории
  • Растеж На Приходите
  • Финансови Процеси
  • Дизайнерски Живот
  • Съвети И Инструменти
  • © 2022 | Всички Права Запазени

    portaldacalheta.pt