К сожалению, это не полный пример, поэтому неясно, где ошибка. В любом случае, кажется, что в том, что вы опубликовали, все еще может быть проблема, поэтому, возможно, мои разговоры из-за путаницы будут полезны.
RotX
, кажется, предназначен для учета разностей осей между OpenCV (X
вправо, Y
вниз, Z
in) и SceneKit (X
вправо, Y
up, Z
out).
tvec
и rvec
представляют мировое происхождение относительно камеры OpenCV.
R.t()
совпадает с R.inv()
для ортонормированных вращений, поэтому R
теперь является обратной матрицей исходного rvec
через R = R.t()
.
То есть Mat tvecConverted = -R * tvec;
(или, точнее, R * -tvec
) - камера в мировых координатах Rodrigues(R, rvecConverted);
кажется похожим преобразованием для фрейма мира для rvec
.
Затем каждый умножается на RotX
, чтобы взять координаты OpenCV в координаты SceneKit, и присваивается payload
.
ОБНОВЛЕНИЕ: после обновления вашего кода мы видим, что значения, присвоенные payload
, в конечном итоге присваиваются значениям cameraNode
position
и rotation
. Так как SceneKit SCNCamera
всегда указывает вдоль отрицательной оси Z своего родителя SCNNode
с одинаковой ориентацией, расположение и ориентация родителя SCNNode
позиционирует и ориентирует саму камеру. Это говорит о том, что tvecConverted
и rvecConverted
выше верны, так как SCNNode
камеры, кажется, является родственным корневому узлу.
Однако все еще остается вопрос проецирования из пространства камеры ScenKit в пиксельное пространство дисплея, которого, похоже, нет в отрывке кода, который вы опубликовали. Я подозреваю, что это должно соответствовать внутренней матрице камеры и искажению, используемому при рисовании на стороне OpenCV, чтобы они правильно выровнялись.
На странице SCNCamera
документов свойство projectionTransform
описывается так:
Это преобразование выражает комбинацию всех
Геометрические свойства камеры: тип проекции (перспектива
или орфографический), поле зрения, пределы глубины и орфографический
масштаб (если применимо). SceneKit использует это преобразование для
преобразовать точки в координатном пространстве узла камеры в
2D-пространство рендерера при рендеринге и обработке событий.
Вы можете использовать это преобразование напрямую, если ваше приложение должно
конвертировать между координатами представления и рендеринга для других целей.
В качестве альтернативы, если вы вычисляете свою собственную матрицу проекционного преобразования,
Вы можете установить это свойство, чтобы переопределить преобразование
синтезированы из геометрических свойств камеры.
Поскольку вы не опубликовали код, связанный с внутренними характеристиками камеры, неясно, является ли это проблемой или нет. Тем не менее, я подозреваю, что выравнивание встроенных функций между OpenCV и SceneKit решит проблему. Кроме того, преобразования SceneKit оцениваются по отношению к свойству pivot
узла, поэтому вам следует быть осторожным, если вы его используете (например, для размещения SCNBox
относительно его угла, а не его центра.)