Создание облака точек из изображения карты глубины с помощью vtk - PullRequest
0 голосов
/ 17 октября 2018

Я написал код на python для генерации карты глубины 3D-модели и сохранения ее в виде изображения с использованием VTK.
Но когда я писал код для генерации облака точек из изображения, только часть облака точекбыл создан.Я не могу найти причину.Я использую один и тот же параметр камеры в двух кодах. код и 3d модель

Создание изображения карты глубины из сетки

import vtk
import os
import numpy as np
from vtk.util import numpy_support


reader = vtk.vtkXMLPolyDataReader()
data_path = 'C:/Users/jiang/Repository/ModelNet10/chair_train_scaled'
path = os.path.join(data_path, "chair_0001.vtp") #Archive path
reader.SetFileName(path)
reader.Update()

ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

bounds = reader.GetOutput().GetBounds()

voxelModeller = vtk.vtkVoxelModeller ()
voxelModeller.SetSampleDimensions(128,128,128)
voxelModeller.SetModelBounds(bounds)
voxelModeller.SetMaximumDistance(0.1)
voxelModeller.SetScalarTypeToFloat()

voxelModeller.SetInputConnection(reader.GetOutputPort())
voxelModeller.Update()

# Create transfer mapping scalar value to opacity
opacityTransferFunction = vtk.vtkPiecewiseFunction()
opacityTransferFunction.AddPoint(0, 0.0)
opacityTransferFunction.AddPoint(1, 1)

# Create transfer mapping scalar value to color
colorTransferFunction = vtk.vtkColorTransferFunction()
colorTransferFunction.AddRGBPoint(0.0, 1.0, 1.0, 1.0)
colorTransferFunction.AddRGBPoint(1.0, 1.0, 0.0, 0.0)

# The property describes how the data will look
volumeProperty = vtk.vtkVolumeProperty()
volumeProperty.SetColor(colorTransferFunction)
volumeProperty.SetScalarOpacity(opacityTransferFunction)
volumeProperty.ShadeOn()
volumeProperty.SetInterpolationTypeToLinear()

# The mapper / ray cast function know how to render the data
volumeMapper = vtk.vtkGPUVolumeRayCastMapper()
volumeMapper.SetBlendModeToComposite()
volumeMapper.SetInputConnection(voxelModeller.GetOutputPort())
volumeMapper.RenderToImageOn()
# The volume holds the mapper and the property and
# can be used to position/orient the volume
volume = vtk.vtkVolume()
volume.SetMapper(volumeMapper)
volume.SetProperty(volumeProperty)


ren.AddVolume(volume)
ren.SetBackground(1, 1, 1)
renWin.SetSize(128, 128)


ren.GetActiveCamera().SetPosition(32, 0,0)
ren.GetActiveCamera().SetFocalPoint(0, 0, 0)
ren.GetActiveCamera().SetViewUp(0, 0, 1)
ren.GetActiveCamera().SetClippingRange(20,50)
renWin.Render()

dpimg = vtk.vtkImageData()
volumeMapper.GetDepthImage(dpimg)

scale = vtk.vtkImageShiftScale()
scale.SetOutputScalarTypeToUnsignedChar()

scale.SetInputData(dpimg)
scale.SetShift(0)
scale.SetScale(255)


imageWriter = vtk.vtkBMPWriter()
imageWriter.SetFileName("depthmap1.bmp")
imageWriter.SetInputConnection(scale.GetOutputPort())
imageWriter.Write()

Создание точек облачности из изображения карты глубины

import vtk
import os
import numpy as np
from vtk.util import numpy_support

reader = vtk.vtkBMPReader()
reader.SetFileName('depthmap3.bmp')
reader.Update()
dpscalar = reader.GetOutput().GetPointData().GetScalars()
dpnp1d = numpy_support.vtk_to_numpy(dpscalar)
print(np.max(dpnp1d),np.min(dpnp1d))

scale = vtk.vtkImageShiftScale()
scale.SetOutputScalarTypeToFloat()
#scale.SetInputConnection(filter.GetOutputPort())
scale.SetInputConnection(reader.GetOutputPort())
scale.SetShift(0)
#scale.SetScale(-1/255.0)
scale.SetScale(1/255.0)
scale.Update()

dpscalar = scale.GetOutput().GetPointData().GetScalars()
dpnp1d = numpy_support.vtk_to_numpy(dpscalar)
print(np.max(dpnp1d),np.min(dpnp1d))


ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
ren.SetBackground(1, 1, 1)
renWin.SetSize(300,300)
renWin.AddRenderer(ren)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)


camera =ren.GetActiveCamera()
camera.SetPosition(-32, 0,0)
camera.SetFocalPoint(0, 0, 0)
camera.SetViewUp(0, 0, 1)
camera.SetClippingRange(20,50)
axial = vtk.vtkMatrix4x4()
axial.DeepCopy((3.73205, 0, 0, 0,
                 0, 3.73205, 0, 0,
                 0, 0, -2.33333, -66.6667,
                 0, 0, -1, 0)) 
#camera.SetUseExplicitProjectionTransformMatrix(True)
#camera.SetExplicitProjectionTransformMatrix(axial)
print(camera)

print(camera.GetWindowCenter ())

pc = vtk.vtkDepthImageToPointCloud()
pc.SetInputConnection(scale.GetOutputPort())
pc.SetCamera(camera)
pc.CullNearPointsOn()
pc.CullFarPointsOn()
#pc.ProduceVertexCellArrayOff()
pc.Update()
print(pc)
#print(ren.GetActiveCamera())

pcMapper = vtk.vtkPolyDataMapper()
pcMapper.SetInputConnection(pc.GetOutputPort())

# pcMapper = vtk.vtkPointGaussianMapper()
# pcMapper.SetInputConnection(pc.GetOutputPort())
# pcMapper.EmissiveOff()
# pcMapper.SetScaleFactor(0.0)

pcActor = vtk.vtkActor()
pcActor.SetMapper(pcMapper)
iren.Initialize()
ren.AddActor(pcActor)
ren.SetBackground(0,0,0)
# ren.GetActiveCamera().SetPosition(32, 0,0)
# ren.GetActiveCamera().SetFocalPoint(0, 0, 0)
# ren.GetActiveCamera().SetViewUp(0, 0, 1)
ren.ResetCamera()
renWin.Render()
iren.Start()

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Чтобы получить правильную матрицу проекции, вы можете использовать это в C ++, предполагая рендер vtkRenderer *.Код на python должен быть похожим:

vtkCamera* camera = renderer->GetActiveCamera();
vtkSmartPointer<vtkMatrix4x4> projection  = vtkSmartPointer<vtkMatrix4x4>::New();
projection->DeepCopy( camera->GetCompositeProjectionTransformMatrix( renderer->GetTiledAspectRation(), 0.0, 1.0) ); // This maps the z-buffer from 0.0 to 1.0.

Я нашел это использование в таких классах, как vtkRenderer и vtkVolume исходный код.Надеюсь, это поможет.

Кстати, по какой-то причине буфер глубины по умолчанию заполнен 1,0 с, а не 0,0 с, как можно было ожидать.

0 голосов
/ 20 октября 2018

Я выясняю проблему.Когда я использую vtkBMPReader, выход этого класса представляет собой 3-канальный vtkImageData, но vtkDepthImageToPointCloud получает только 1-канальное изображение глубины.Поэтому нам нужно использовать vtkImageExtractComponents, чтобы получить первый канал вывода vtkBMPReader.

Но я до сих пор не понимаю, как vtk вычисляет матрицу преобразования проекции.

...