寻找建议以摆脱光线投射中低效的循环

时间:2019-07-02 08:20:21

标签: python vtk raytracing

我目前正在研究一个项目,该项目使用3D深度相机实时测量生产线上的物体数量。会有混淆和更糟或更佳的角度,因此我们要在构建装备并进行生产测试之前模拟不同的相机配置。我们对这些对象进行了大量的CT扫描,因此我们希望基于这些对象模拟不同的相机视图。我们要模拟的是一个点云,该点云将由相机在给定位置生成。

我发现每种方法一次都跟踪一束射线,而您必须在python循环中遍历射线。这是最慢的部分,我正在寻找摆脱该python循环的方法。我的直觉是应该有一个GPU加速库可以非常快地完成此操作,但是我找不到它,我通常进行CT扫描的分段和配准,而不是3d图形。下面是我到目前为止尝试过的一些细节。

我有一个摄影课。与这些计算相关的是,我有一个源点self.pos和一个要投影到self.points_plane的点的平面,它们是3D空间中的点。因此,所有光线都起源于self.pos,并终止于self.points_plane中的元素之一。我最初的尝试是使用scipy.ndimage.map_coordinates:

for point in self.points_plane:
    dist = int(np.sqrt((self.pos[0]-point[0])**2+(self.pos[1]-point[1])**2+(self.pos[2]-point[2])**2))
    z_line = np.linspace(self.pos[0],point[0],dist)
    y_line = np.linspace(self.pos[1],point[1],dist)
    x_line = np.linspace(self.pos[2],point[2],dist)

    stack = ndimage.map_coordinates(array,np.vstack((z_line,y_line,x_line)),order=1,cval=-1000)
    # Hounsfield value check, air is -1000 and our objects are in the range -200:1000
    intersections = np.argwhere(stack > -500) 
    if intersections.size > 0:
         point_cloud.append([z_line[intersections[0][0]],y_line[intersections [0][0]],x_line[intersections [0][0]]])

它可以工作,并且结果看起来不错,但是它太慢了,我们将在明年完成仿真……CuPy是numpy / scipy的CUDA实现,这是下一个尝试,因为存在所有必需的方法。地图坐标速度更快,但向GPU传输和向后传输速度很慢,并且我们仍然存在python循环。并不是真正的重大改进,代码几乎与非CUDA代码相同。

我尝试使用VTK.vtkOBBTree()和obbTree.IntersectWithLine()方法来查看这是否是一个很好的解决方案,并且适用于少量点。 IntersectWithLine方法获取每条线的起点和终点,并检查与从STL文件生成的obbTree的交点。只要我们不遍历太多点,该方法就很快速,在我们正在研究的规模上,要模拟相关数据仍需要大约一个月的时间。

for point in self.points_plane:
    pointsVTKintersection = vtk.vtkPoints()
    obbTree.IntersectWithLine(self.pos, point,pointsVTKintersection,None)
    pointsVTKIntersectionData = pointsVTKintersection.GetData()
    noPointsVTKIntersection = pointsVTKIntersectionData.GetNumberOfTuples()

    if noPointsVTKIntersection > 0:
        point_c.append(pointsVTKIntersectionData.GetTuple3(0))
    self.point_cloud = np.array(point_c)

关于如何摆脱for循环的任何建议,是否有一个库可以针对多条光线并行执行此操作?

1 个答案:

答案 0 :(得分:0)

我不知道trimesh是否在此方面更快,但可能值得尝试。 我有一个示例here