[英]Intersection between 2d image point and 3d mesh
給定:網格,源相機 - 我有內在和外在參數,圖像坐標 2d
Output : 3D 點,它是從相機中心穿過圖像平面上的 2d 點和網格的光線的交點。 (我試圖在網格上找到 3d 點)
我已經構造了方程(6.14)
。
我不確定如何繼續並獲得位於網格上的 3d 點(我還需要靠近相機的點)。
我認為可以通過以下方式完成:
遍歷所有頂點並找到頂點與直線之間的距離,並且距離最短的頂點位於直線上(如果它們接近於零或零),並且找到最近的頂點是我猜想找到幅度在相機的中心和最近的頂點之間,最小的一個將意味着該點是最近的?
快速更新:這個 repo 似乎確實適用於光線: github.com/szabolcsdombi/python-mesh-raycast
我想現在的錯誤在於讓D
點正確..
正如Grillteller在評論中指出的,這是與 3d 網格的光線相交問題。 據我所知,人類還不知道確定任意網格交點的快速方法。 在您的問題上下文中,您應該使用Ray Tracing ,這也是Grillteller指出的,但是這存在嚴重的性能問題,盡管它提供了很多着色的可能性。 為了找到光線和網格的交點,光線追蹤算法通常使用不同的加速結構。 通常這樣的結構是由樹划分的空間:
本演示文稿很好地解釋了其中一些方法和其他方法。
PS:如果你只需要一個簡單的可視化,那么最好將問題反過來:對於每個網格元素,執行rasterisation 。
我使用 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')
我找到了將場景中的相機導入為trimesh.scene.Camera
的相關行。 然后,您可以使用 function cameras_to_rays(camera)
(第 417 行)“每像素返回一條光線,如 camera.resolution 中設置的那樣”。
所以現在您擁有每個像素和網格的光線,並且可以創建一個RayMeshIntersector
,如ray_triangle.py所示。 然后,您可以使用intersects_location
(第 75 行)計算相應光線撞擊網格的笛卡爾圖像坐標。
我在這里找到了一個適合您的示例:
"""
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()))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.