【问题标题】:Intersection between 2d image point and 3d mesh2d 图像点和 3d 网格之间的交点
【发布时间】:2021-04-06 12:37:50
【问题描述】:

给定:网格,源相机 - 我有内在和外在参数,图像坐标 2d

输出:3D 点,即从相机中心出发的光线经过图像平面上的 2d 点与网格的交点。 (我正在尝试在网格上找到 3d 点)

这是流程

来自《计算机视觉中的多视图几何》一书:

我已经构造了方程(6.14)

我不确定如何继续并获取位于网格上的 3d 点(我还需要离相机最近的点)。

我认为可以通过以下方式完成:

遍历所有顶点并找到顶点与直线之间的距离,并且距离最短的顶点位于直线上(如果它们接近于零或零),我猜是找到最近的顶点找到相机中心和最近顶点之间的大小,最小的将意味着该点是最近的?

快速更新:这个 repo 似乎确实适用于光线:github.com/szabolcsdombi/python-mesh-raycast

我猜现在的错误在于正确理解D 的观点..

【问题讨论】:

  • 这不是“只是”intersecting an image ray with a 3D mesh的问题吗?如果您正在寻找光线追踪,我认为谷歌搜索提供了一些不错的解决方案。
  • @Grillteller 感谢您的回答,我什至在 python 中找到了一个完全可以使用的 repo,但是在运行它时,不幸的是它不起作用。这是回购:github.com/szabolcsdombi/python-mesh-raycast 从我的网格中获取三角形、相机中心向量和第二个点 D(如原始问题中的图像所示)后,它不会从它在点。

标签: python opencv geometry mesh open3d


【解决方案1】:

正如Grillteller 在评论中指出的那样,这是与 3d 网格的光线相交问题。据我所知,人类还不知道确定任意网格交点的快速方法。在您的问题上下文中,您应该 Ray TracingGrillteller 也指出了这一点,但是这会带来严重的性能问题,尽管它提供了很多着色的可能性。 为了找到光线和网格的交点,光线追踪算法通常使用不同的加速结构。通常这样的结构是由树划分的空间:

presentation 很好地解释了其中一些方法和其他方法。

P.S.:如果你只需要一个简单的可视化,那么最好将问题反过来:对于每个网格元素,执行rasterisation

【讨论】:

    【解决方案2】:

    我使用 python 找到了另一个名为 trimesh 的实现。

    您需要阅读安装指南,然后才能通过以下方式加载网格:

    import numpy as np 
    import trimesh
    
    # attach to logger so trimesh messages will be printed to console 
    trimesh.util.attach_to_log()
    
    mesh = trimesh.load('models/CesiumMilkTruck.glb', force='mesh')
    

    我在scene 中找到了将相机导入为trimesh.scene.Camera 的相关行。 然后您可以使用函数cameras_to_rays(camera)(第 417 行)来“每像素返回一条光线,如 camera.resolution 中设置的那样”。

    所以现在您拥有每个像素和网格的光线,并且可以创建RayMeshIntersector,如ray_triangle.py 所示。然后,您可以使用intersects_location(第 75 行)计算相应光线撞击网格的笛卡尔图像坐标。

    我为您的目的找到了一个示例here

    """
    raytrace.py
    ----------------
    A very simple example of using scene cameras to generate
    rays for image reasons.
    Install `pyembree` for a speedup (600k+ rays per second)
    """
    from __future__ import division
    
    import PIL.Image
    
    import trimesh
    import numpy as np
    
    if __name__ == '__main__':
    
        # test on a simple mesh
        mesh = trimesh.load('../models/featuretype.STL')
    
        # scene will have automatically generated camera and lights
        scene = mesh.scene()
    
        # any of the automatically generated values can be overridden
        # set resolution, in pixels
        scene.camera.resolution = [640, 480]
        # set field of view, in degrees
        # make it relative to resolution so pixels per degree is same
        scene.camera.fov = 60 * (scene.camera.resolution /
                                 scene.camera.resolution.max())
    
        # convert the camera to rays with one ray per pixel
        origins, vectors, pixels = scene.camera_rays()
    
        # do the actual ray- mesh queries
        points, index_ray, index_tri = mesh.ray.intersects_location(
            origins, vectors, multiple_hits=False)
    
        # for each hit, find the distance along its vector
        depth = trimesh.util.diagonal_dot(points - origins[0],
                                          vectors[index_ray])
        # find pixel locations of actual hits
        pixel_ray = pixels[index_ray]
    
        # create a numpy array we can turn into an image
        # doing it with uint8 creates an `L` mode greyscale image
        a = np.zeros(scene.camera.resolution, dtype=np.uint8)
    
        # scale depth against range (0.0 - 1.0)
        depth_float = ((depth - depth.min()) / depth.ptp())
    
        # convert depth into 0 - 255 uint8
        depth_int = (depth_float * 255).round().astype(np.uint8)
        # assign depth to correct pixel locations
        a[pixel_ray[:, 0], pixel_ray[:, 1]] = depth_int
        # create a PIL image from the depth queries
        img = PIL.Image.fromarray(a)
    
        # show the resulting image
        img.show()
    
        # create a raster render of the same scene using OpenGL
        # rendered = PIL.Image.open(trimesh.util.wrap_as_stream(scene.save_image()))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 2019-10-03
      • 2020-05-06
      • 2019-06-06
      相关资源
      最近更新 更多