我正在使用“OpenCV for Unity3d”资产(它与 Java 的 OpenCV 包相同,但为 Unity3d 翻译为 C#),以便为我的理学硕士论文(计算机科学)创建增强现实应用程序。
到目前为止,我能够使用 ORB 特征检测器从视频帧中检测到一个对象,并且我可以使用 OpenCV 的 SolvePnP 方法找到 3D 到 2D 的关系(我也进行了相机校准)。通过这种方法,我得到了平移和旋转向量。问题出现在增强阶段,我必须将 3d 对象显示为虚拟对象并在每一帧更新其位置和旋转。OpenCV返回罗德里格斯旋转矩阵,但Unity3d使用四元数旋转,所以我更新对象的位置和旋转错误,我无法弄清楚如何实现转换论坛(从罗德里格斯到四元数)。
获取 rvec 和 tvec:
Mat rvec = new Mat();
Mat tvec = new Mat();
Mat rotationMatrix = new Mat ();
Calib3d.solvePnP (object_world_corners, scene_flat_corners, CalibrationMatrix, DistortionCoefficientsMatrix, rvec, tvec);
Calib3d.Rodrigues (rvec, rotationMatrix);
更新虚拟对象的位置:
Vector3 objPosition = new Vector3 ();
objPosition.x = (model.transform.position.x + (float)tvec.get (0, 0)[0]);
objPosition.y = (model.transform.position.y + (float)tvec.get (1, 0)[0]);
objPosition.z = (model.transform.position.z - (float)tvec.get (2, 0)[0]);
model.transform.position = objPosition;
Z 轴有一个减号,因为当您将 OpenCV 转换为 Unty3d 的系统坐标时,您必须反转 Z 轴(我自己检查了系统坐标)。
Unity3d的坐标系(绿色为Y,红色为X,蓝色为Z):
OpenCV的坐标系:
此外,我对旋转矩阵做了同样的事情,并更新了虚拟对象的旋转。
ps 我发现了一个类似的问题,但是提出这个问题的人没有明确发布解决方案。
谢谢!