Отображение трехмерной вершины в пиксель с использованием pyreder/pyglet/openGL

Я реализую новый алгоритм для оценки трехмерных точек с использованием изображений, и прямо сейчас я пытаюсь протестировать его на трехмерных виртуальных моделях, прежде чем перейти к реальным объектам.

Входные данные алгоритма - это пиксели до последнего преобразования в размеры области просмотра, поэтому для тестирования алгоритма на визуализированных изображениях мне нужно знать обратное преобразование из пикселя в форме ([0,witdh],[0,height]).

Я использую перспективную проекцию из библиотеки pyrender для рендеринга 2D-изображений 3D-сетки, насколько мне известно, эта библиотека использует методы 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.        ]]

это мой расчет для отображения трехмерной точки / вершины в пиксель:

      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

протестируйте его на вершине слева вверху-закрытие окна =[-1.5, 0.5, 2.5, 1.], когда viewport_sizes=(width,height)=(512512)

результаты = = (151,4)

когда фактические результаты pyrender для этой вершины - пиксель ~ (90,342)

Если кто-то знает, как работает pyrender / OpenGL, или знает, как правильно отображать пиксели, это будет очень полезно.

btw: я знаю, что моя функция использует отображение левого нижнего угла, когда библиотека использует отображение левого верхнего угла, но она все равно дает неожиданный результат.

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

Я протестировал визуализированные изображения с помощью этой функции, и все вершины были идеально сопоставлены с пикселями.

Другие вопросы по тегам