admin管理员组

文章数量:1405513

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

本文标签: pythonApply VTK color series to render a point cloudStack Overflow