[Python] Apply VTK color series to render a point cloud

Discussão em 'Python' iniciado por Stack, Março 7, 2025.

  1. Stack

    Stack Membro Participativo

    I have managed to write this code containing a simple load button for laz/las file and the VTK rendering widget. It applies some automatic color scheme (which one?) to the point cloud based on the colors that I produce by normalizing intensity values to 0-1 range. Question: how to apply a VTK color series to it? I have seen this piece of code but I do not really know where to put it. I tried it several times at several places but it did not produce desired effect (i.e. application of the chosen color scheme). Not sure - maybe it is related to me using vertex filter object.

    color_series = vtk.vtkColorSeries()
    color_series.SetColorSchemeName("Blue")
    lut = color_series.CreateLookupTable()
    mapper.SetLookupTable(lut)


    MRE (not containing the color series part above):

    import sys
    import vtk
    from PySide2.QtWidgets import (
    QApplication,
    QMainWindow,
    QVBoxLayout,
    QWidget,
    QPushButton,
    QFileDialog,
    )
    import laspy
    import numpy as np
    from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
    from tqdm import tqdm


    class PointCloudViewer(QMainWindow):
    def __init__(self):
    super().__init__()
    self.setWindowTitle("Point Cloud Viewer")
    self.setGeometry(100, 100, 800, 600)
    layout = QVBoxLayout()
    central_widget = QWidget(self)
    central_widget.setLayout(layout)
    self.setCentralWidget(central_widget)
    load_button = QPushButton("Load Point Cloud", self)
    load_button.clicked.connect(self.load_point_cloud)
    layout.addWidget(load_button)
    self.vtk_widget = QVTKRenderWindowInteractor(self)
    layout.addWidget(self.vtk_widget)
    self.renderer = vtk.vtkRenderer()
    self.vtk_widget.GetRenderWindow().AddRenderer(self.renderer)
    self.vtk_widget.GetRenderWindow().GetInteractor().Initialize()
    self.vtk_widget.GetRenderWindow().GetInteractor().Start()

    def load_point_cloud(self):
    file_dialog = QFileDialog(self)
    file_dialog.setFileMode(QFileDialog.ExistingFiles)
    file_dialog.setNameFilter("Point Cloud Files (*.las *.laz)")
    if file_dialog.exec_():
    file_paths = file_dialog.selectedFiles()
    if file_paths:
    self.display_point_cloud(file_paths[0])

    def display_point_cloud(self, file_path):
    self.renderer.RemoveAllViewProps()
    self.renderer.SetBackground(0.1, 0.1, 0.1)
    points, colors = self.read_point_cloud(file_path)
    poly_data = vtk.vtkPolyData()
    poly_data.SetPoints(points)
    poly_data.GetPointData().SetScalars(colors)
    vertex_filter = vtk.vtkVertexGlyphFilter()
    vertex_filter.SetInputData(poly_data)
    vertex_filter.Update()
    mapper = vtk.vtkPolyDataMapper()
    mapper.SetInputConnection(vertex_filter.GetOutputPort())
    actor = vtk.vtkActor()
    actor.SetMapper(mapper)
    actor.GetProperty().SetPointSize(1)
    self.renderer.AddActor(actor)
    self.renderer.ResetCamera()
    self.vtk_widget.GetRenderWindow().Render()

    def read_point_cloud(self, file_path):
    las = laspy.read(file_path)
    points = np.vstack((las.x, las.y, las.z)).transpose()
    intensity_data = las.intensity
    min_intensity = np.min(intensity_data)
    max_intensity = np.max(intensity_data)
    intensity_data = (intensity_data - min_intensity) / (
    max_intensity - min_intensity
    )
    vtk_colors = vtk.vtkFloatArray()
    vtk_colors.SetName("Intensity")
    vtk_points = vtk.vtkPoints()
    chunk_size = max(10000, len(las) // 100)
    shift = np.array((points[0][0], points[0][1], points[0][2]))
    for i in tqdm(range(0, len(las), chunk_size)):
    chunk = points[i : i + chunk_size] - shift
    chunk_intensity = intensity_data[i : i + chunk_size]
    for j, point in enumerate(chunk):
    vtk_points.InsertNextPoint(point)
    vtk_colors.InsertNextValue(chunk_intensity[j])
    return vtk_points, vtk_colors


    if __name__ == "__main__":
    app = QApplication(sys.argv)
    viewer = PointCloudViewer()
    viewer.show()
    sys.exit(app.exec_())


    I admit that I barely understand the code I managed to assemble in VTK, so any other improvements & explanations not related directly to the question

    Continue reading...

Compartilhe esta Página