Почему 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, я бы получил единичную матрицу.
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 будут перед камерой.
# 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/
Еще одно замечание: вы вычисляете Rt() (транспонирование), а R - матрица идентичности. Это не имеет значения для модели. То же самое для матрицы транспозиции, которая все еще равна 0 после преобразования.
https://www.quora.com/What-is-an-inverse-identity-matrix
С уважением