Почему 3D-точка оказывается позади камеры?

Я написал простой скрипт для проецирования 3D-точек на изображение на основе внутренних и внешних характеристик камеры. Но когда у меня есть камера в начале координат, указывающая вниз по оси Z, а 3D указывает дальше по оси Z, она кажется позади камеры, а не перед ней. Вот мой скрипт, я проверял его столько раз.

import numpy as np

def project(point, P):
    Hp = P.dot(point)

    if Hp[-1] < 0:
        print 'Point is behind camera'

    Hp = Hp / Hp[-1]
    print Hp[0][0], 'x', Hp[1][0]
    return Hp[0][0], Hp[1][0]

if __name__ == '__main__':

    # Rc and C are the camera orientation and location in world coordinates
    # Camera posed at origin pointed down the negative z-axis
    Rc = np.eye(3)
    C  = np.array([0, 0, 0])

    # Camera extrinsics
    R = Rc.T
    t = -R.dot(C).reshape(3, 1)

    # The camera projection matrix is then:
    # P = K [ R | t] which projects 3D world points 
    # to 2D homogenous image coordinates.

    # Example intrinsics dont really matter ...

    K = np.array([
        [2000, 0,  2000],
        [0,  2000, 1500],
        [0,  0,  1],
    ])


    # Sample point in front of camera
    # i.e. further down the negative x-axis
    # should project into center of image
    point = np.array([[0, 0, -10, 1]]).T

    # Project point into the camera
    P = K.dot(np.hstack((R, t)))

    # But when projecting it appears to be behind the camera?
    project(point,P)

Единственное, о чем я могу думать, это то, что матрица вращения идентификации не соответствует камере, указывающей вниз по отрицательной оси z с вектором вверх в направлении положительной оси y. Но я не понимаю, как это может быть не так, например, я построил Rc из функции, такой как gluLookAt, и дал ему камеру в начале координат, направленную вниз по отрицательной оси z, я получил бы матрицу идентичности.


person nickponline    schedule 16.09.2017    source источник
comment
Можете ли вы объяснить мне, как вы знаете, что ваша камера указывает на отрицательную ось Z? Возможно, камера в локации (0,0,0) с идентичной матрицей вращения смотрит на положительную ось z, а не на отрицательную.   -  person Amitay Nachmani    schedule 23.09.2017


Ответы (2)


Я думаю, что путаница только в этой строке:

if Hp[-1] < 0:
    print 'Point is behind camera'

потому что в этих формулах предполагается, что положительная ось Z входит в экран, поэтому на самом деле точка с положительным значением Z будет позади камеры:

if Hp[-1] > 0:
    print 'Point is behind camera'

Я, кажется, припоминаю, что этот выбор был произвольным, чтобы 3D-представление хорошо сочеталось с нашими предвзятыми представлениями о 2D: если вы предполагаете, что ваша камера смотрит в направлении -Z, тогда отрицательный X будет слева, когда положительный Y указывает вверх. И в этом случае перед камерой будут только вещи с отрицательным Z.

person Daniel    schedule 27.09.2017

# Rc and C are the camera orientation and location in world coordinates
# Camera posed at origin pointed down the negative z-axis
Rc = np.eye(3)
C  = np.array([0, 0, 0])
# Camera extrinsics
R = Rc.T
t = -R.dot(C).reshape(3, 1)

Прежде всего, вы выполнили транспонирование единичной матрицы. У вас есть матрица вращения камеры:

| 1, 0, 0| 
| 0, 1, 0|
| 0, 0, 1|

Что не делает точку координатного пространства отрицательной Z. Вы должны создать матрицу вращения на основе углов или перевернуть, например:

|1, 0,  0| 
|0, 1,  0|
|0, 0, -1|

Думаю, это решит вашу проблему. Вот удобный инструмент для проверки правильности вычисленной матрицы:

http://www.andre-gaschler.com/rotationconverter/

Еще одно замечание: вы вычисляете R.t() (транспонирование), а R - это матрица идентичности. Это не имеет значения для модели. То же самое для матрицы транспонирования, которая после преобразования по-прежнему равна 0.

https://www.quora.com/What-is-an-inverse-identity-matrix

С Уважением

person Kamil Szelag    schedule 27.09.2017
comment
Транспонированная единичная матрица является единичной матрицей. - person Daniel; 27.09.2017