【问题标题】:Mapping 3d vertex to pixel using pyreder/pyglet/openGL使用 pyreder/pyglet/openGL 将 3d 顶点映射到像素
【发布时间】:2021-08-03 15:40:34
【问题描述】:

我正在使用图像实现 3d 点估计的新算法,现在我正在尝试在 3d 虚拟模型上对其进行测试,然后再转向真实对象。

算法输入是最后一次转换为视口大小之前的像素,因此要在渲染图像上测试算法,我需要知道形状中像素的反向转换([0,witdh],[0,height] )。

据我所知,我正在使用 pyrender 库中的透视投影来渲染 3d 网格的 2d 图像,据我所知,该库使用 OpenGL 方法进行渲染。

示例: 我有一个尺寸=(3,1,5), center=(0,0,0) 的盒子网格,并且我有投影和视图矩阵

View Matrix=       [[ 0.96592583, -0.0669873 ,  0.25     ,  3.        ],
                   [ 0.        ,  0.96592583,  0.25881905,  4.        ],
                   [-0.25881905, -0.25      ,  0.9330127 , 10.        ],
                   [ 0.        ,  0.        ,  0.        ,  1.        ]]

Projection Matrix= [[ 2.4142135,  0.        ,  0.        ,  0.        ],
                   [ 0.        ,  2.41421356,  0.        ,  0.        ],
                   [ 0.        ,  0.        , -1.0010005 , -0.10005003],
                   [ 0.        ,  0.        , -1.        ,  0.        ]]

这是我将 3d 点/顶点映射到像素的计算:

def map_to_pixel(point3d,w,h,projection,view):
    p=projection@view@point3d # openGL perspective projection
    p=p/p[3]                  # divide by the w element
    p[0]=w/2*p[0]+w/2         # transformation from [-1,1] -> [0,width]
    p[1]=h/2*p[1]+h/2         # transformation from [-1,1] -> [0,height]
    return p

在 viewport_sizes=(width,height)=(512,512) 时在 box =[-1.5, 0.5, 2.5, 1.] 的顶点左上角进行测试

结果= [150.86775635, 4.28475523, 1.00894365, 1. ]= (151,4)

当 pyrender 对该顶点的实际结果是像素时 ~ (90,342)

如果有人知道 pyrender/OpenGL 幕后的实际过程,或者知道如何正确映射像素,那将非常有帮助。

顺便说一句: 我知道当库使用左上映射时,我的函数使用左下映射,但它仍然会给出意外的输出。

【问题讨论】:

  • 这个问题中给出的值没有意义,对象将位于相机后面,因此会被 OpenGL 裁剪,永远不会到达视口。您当然不能使用该坐标和(仅)该转换来渲染对象。所以要么你遗漏了一些东西(比如模型矩阵?),要么你提供的值不正确。
  • 这些值只是一个例子,View 矩阵的计算是正确的,并且基于 6 个参数(3 个用于平移和 3 个角度用于旋转),投影矩阵由库 pyrender 给出,使用 OpenGL 函数。

标签: python opengl computer-vision mesh pyrender


【解决方案1】:

我弄清楚了计算是如何进行的,我不知道为什么,但是库 pyrender(使用 OpenGL 方法)使用我设置为输入的视图矩阵的逆矩阵。

设置像素的具体函数是:

from numpy.linalg import inv

    def map_to_pixel(point3d,w,h,projection,view):
        p=projection@inv(view)@point3d.T
        p=p/p[3]
        p[0]=(w/2*p[0]+w/2)    #tranformation from [-1,1] ->[0,width]
        p[1]=h-(h/2*p[1]+h/2)  #tranformation from [-1,1] ->[0,height] (top-left image)
        return p

我已经通过这个函数测试了渲染的图像,所有的顶点都完美地映射到了像素中。

【讨论】:

  • 由眼睛位置和视线定义的矩阵从视图空间转换到世界空间。这不是“视图”矩阵。视图矩阵需要从世界空间转换到视图空间。因此,“视图”矩阵是矩阵的逆矩阵,是由眼睛位置和视线定义的矩阵。这也解释了“derhass”的评论,因为您问题中的矩阵是逆视图矩阵。
  • 这很好地解释了这个问题,谢谢你们的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-16
  • 2019-07-10
  • 1970-01-01
  • 1970-01-01
  • 2014-04-23
相关资源
最近更新 更多