2016-02-17 4 views
1

У меня есть фрагмент, который преобразует рендеринг vtk (off screen) в 1) облако точек; 2) Цветное изображение. Реализация правильна, это просто проблема/эффективность.Эффективность VTK vtkRenderWindow :: GetZbufferData и vtkWindowToImageFilter :: Update

В начале каждой итерации, я обновляю свой рендеринг по телефону:

renderWin->Render(); 

Для облака точек, я получаю глубину, используя следующую строку, а затем преобразовать его в точку облака (код не отвечал).

float *depth = new float[width * height]; 
renderWin->GetZbufferData (0, 0, width - 1, height - 1, &(depth[0])); 

Для цветного изображения, я использую vtkWindowToImageFilter, чтобы получить текущий цвет вынесенное изображение:

windowToImageFilter->Modified(); // Must have this to get updated rendered image 
windowToImageFilter->Update(); // this line takes a lot of time 
render_img_vtk = windowToImageFilter->GetOutput(); 

Над программой работает в одной и той же нити последовательно. Размер renderWindow составляет около 1000x1000. Не нужно много полидат. VTK был скомпилирован с поддержкой OpenGL2.

Выпуск: Этот код работает только 15-20Hz, когда я отключил/комментировать windowToImageFilter часть (vtkWindowToImageFilter::Update() занимает много времени), фреймрейт идет до 30Гц. Когда я отключил/комментировал vtkRenderWindow::GetZbufferData, он поднимается до 50 Гц (как быстро я вызываю свой цикл и обновляю рендеринг).

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

Update: После некоторого поиска я обнаружил, что функция glReadPixels называется в GetZbufferData причины задержки, как это пытаются синхронизировать данные. Пожалуйста, см. Это сообщение: OpenGL read pixels faster than glReadPixels. В этом сообщении предлагается использовать PBO. VTK имеет класс vtkPixelBufferObject, но для его использования не существует примера, чтобы избежать блокировки трубопровода, когда это делается glReadPixels()

Как я могу это сделать в трубопроводе VTK?

ответ

0

Мой ответ касается части GetZbufferData.

vtkOpenGLRenderWindow уже использует glReadPixels с небольшими накладными расходами, что я могу сказать. here

Что произойдет после этого, я считаю, может ввести накладные расходы. Главное отметить, что vtkOpenGLRenderWindow имеет 3 способа перегрузки для GetZbufferData. Вы используете перегрузку метода с той же подписью, как один используется в vtkWindowToImageFilterhere

Я считаю, что вы копируете эту часть реализации в vtkWindowToImageFilter, что делает общий смысл. Что вы будете делать с указателем float depthBuffer после того, как получите его? Посмотрев на реализацию vtkWindowToImageFilter, я вижу, что у них есть цикл for, который вызывает memcpyhere. Я считаю, что их memcpy должен быть в цикле for, чтобы иметь дело с интервалом из-за переменных inIncrY и outIncrY. Для вашей ситуации вам нужно будет только позвонить memcpy, а затем освободить массив, на который указывает depthBuffer. Если вы просто не используете указатель.Тогда вам нужно подумать о том, кто должен удалить этот массив float, потому что он был создан с помощью new.

Я думаю, что лучшим вариантом является использование метода с этой подписью: int GetZbufferData(int x1, int y1, int x2, int y2, vtkFloatArray* z)

В питона, который выглядит любит это:

import vtk 
# create render pipeline (not shown) 
# define image bounds (not shown) 
vfa = vtk.vtkFloatArray() 
ib = image_bounds 
render_window.GetZbufferData(ib[0], ib[1], ib[2], ib[3], vfa) 

Основное преимущество заключается в том, что указатель на vtkFloatArray получает передан прямо glReadPixels. Кроме того, vtk возьмет сбор мусора vtkFloatArray, если вы его создадите с помощью vtkSmartPointer (не требуется в Python)

Моя реализация python работает на частоте около 150 Гц за один проход. В окне рендеринга 640x480.

редактировать: Бег на 150Гц

+0

Спасибо за ответ, я сделал вещь, вы предложили (обновленный пост), но результат тот же. Я также обнаружил, что PBO (пиксельный буферный объект) должен использоваться, могли бы вы помочь с этим? –