如何固定VTK的addPoint循环(Python)

2 人关注

当我开始用VTK为一些数据可视化建立一些基本的三维可视化的绘图方法时,我遇到了以下问题。

我的数据集通常大小为200e6-1000e6个数据点(传感器值)及其相应的坐标、点(X、Y、Z)。 我的可视化方法运行良好,但至少有一个瓶颈。除了代码的其他部分,有2个for循环的schown例子是整个方法中最耗时的部分。

我对通过foor循环向VTK对象添加坐标(点,numpy(n,3))和传感器值(强度,numpy(n,1))感到不满意。

特殊代码的例子。

    vtkpoints = vtk.vtkPoints()                                                     # https://vtk.org/doc/nightly/html/classvtkPoints.html
    vtkpoints.SetNumberOfPoints(self.points.shape[0])
    # Bottleneck - Faster way?
    self.start = time.time()
    for i in range(self.points.shape[0]):
        vtkpoints.SetPoint(i, self.points[i])
    self.vtkpoly = vtk.vtkPolyData()                                                # https://vtk.org/doc/nightly/html/classvtkPolyData.html
    self.vtkpoly.SetPoints(vtkpoints)
    self.elapsed_time_normal = (time.time() - self.start) 
    print(f" AddPoints took : {self.elapsed_time_normal}")
    # Bottleneck - Faster way?
    vtkcells = vtk.vtkCellArray()                                                   # https://vtk.org/doc/nightly/html/classvtkCellArray.html
    self.start = time.time()
    for i in range(self.points.shape[0]):
        vtkcells.InsertNextCell(1)
        vtkcells.InsertCellPoint(i)
    map(vtkcells.InsertNextCell(1),self.points)
    self.elapsed_time_normal = (time.time() - self.start) 
    print(f" AddCells took : {self.elapsed_time_normal}")
    # Inserts Cells to vtkpoly 
    self.vtkpoly.SetVerts(vtkcells)

Times:

  • Convert DataFrame took: 6.499739646911621
  • AddPoints took : 58.41245102882385b
  • AddCells took : 48.29743027687073
  • LookUpTable took : 0.7522616386413574
  • 所有的输入数据都是int类型的,基本是通过numpy_to_vtk方法将Dataframe转换为vtknumpy对象。

    我很高兴,如果有人有办法加快这个速度。

    5 个评论
    vtkPoints::SetData和vtkCellArray::SetCells应该可以做到这一点。但不确定如何在Python中使用它们。
    嘿,@MathieuWestphal,vtkPoints.SetData(numpy_to_vtk(point))比我的第一个for循环快了很多,非常感谢!但是,当我尝试对单元格进行处理时,vtkcells = vtk.vtkCellArray(),vtkcells.SetCells(point.shape[0], cells)。然而,当我试图对单元格进行处理时,vtkcells = vtk.vtkCellArray()和vtkcells.SetCells(point.shape[0], cells_test)在我调用vtk.vtkPolyData.GetBounds()来处理多维数据的边界时失败了。也许我在做vtkcells.SetCells(point.shape[0], cells_test)时遗漏了什么,即使我在应用这个方法后没有直接得到任何错误。最好的建议
    我想,ComputeBounds需要手动调用。
    我手动计算了边界,似乎还行。但是当我开始使用渲染器时(比如resetcamera)或者启动renderWindow.Render()时,就会出现异常。Windows致命的异常:访问违规--当前线程0x000043f8(最近一次调用在先)......。似乎我在通过SetCells(point.shape[0], numpy_to_vtkIdTypeArray(cell_test))添加单元时做错了。cells_test看起来像这样(numberofcells, [ 3,1x,1y,1z, ..., 3, Nx, Ny, Nz])。暂时没办法了,有什么建议吗?BR
    不知道,我需要测试一下。你可以在那里问。 discourse.vtk.org
    python
    plot
    3d
    visualization
    vtk
    AM_Guy
    AM_Guy
    发布于 2021-02-24
    1 个回答
    AM_Guy
    AM_Guy
    发布于 2021-02-28
    已采纳
    0 人赞同

    对于第一个Loop,@Mathieu Westphal给了我一个不错的解决方案。

    vtkpoints = vtk.vtkPoints()                                                  
    vtkpoints.SetData(numpy_to_vtk(self.points))
    self.vtkpoly = vtk.vtkPolyData()                                             
    self.vtkpoly.SetPoints(vtkpoints)
    

    新的加分时间。

  • AddPoints took : 0.03202845573425293
  • 对于第二个循环,我花了一点时间来找到这个解决方案,但在vtk社区的一些提示下,我也得到了它的运行。下面是我用来设置vtkpoly的Verts的代码。

    vtkcells = vtk.vtkCellArray()
    cells_array_init = np.arange(len(self.points)).reshape(len(self.points),1)
    cells_array_set = np.repeat(cells_array_init, repeats=3, axis=1)
    cells_npy = np.column_stack([np.full(len(self.points), 3, dtype=np.int64), cells_array_set.astype(np.int64)]).ravel()
    vtkcells.SetCells(len(self.points), numpy_to_vtkIdTypeArray(cells_npy) 
    # Inserts Cells to vtkpoly 
    self.vtkpoly.SetVerts(vtkcells)
    

    增加细胞/Verts的新时间。

  • AddCells took : 2.73202845573425293
  •