我正在使用“ OpenCV for Unity3d”资产(与Java的OpenCV包相同,但已转换为Unity3d的C#),以便为我的MSc论文(计算机科学)创建增强现实应用程序。
到目前为止,我已经能够使用ORB特征检测器从视频帧中检测到物体,并且还可以使用OpenCV的SolvePnP方法找到3D到2D关系(我也进行了摄像机校准)。通过这种方法,我得到了平移和旋转向量。问题发生在增强阶段,在此阶段,我必须将3d对象显示为虚拟对象,并在每个帧上更新其位置和旋转。OpenCV返回Rodrigues旋转矩阵,但是Unity3d使用Quaternion旋转,因此我错误地更新了对象的位置和旋转,因此我不知道如何实现论坛(从Rodrigues到Quaternion)。
获取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);
Run Code Online (Sandbox Code Playgroud)
更新虚拟对象的位置:
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;
Run Code Online (Sandbox Code Playgroud)
我的Z轴有一个负号,因为当您将OpenCV转换为Unty3d的系统坐标时,必须反转Z轴(我自己检查了系统坐标)。
Unity3d的坐标系(绿色是Y,红色是X,蓝色是Z):
OpenCV的坐标系:
另外,我对旋转矩阵做了同样的事情,并且更新了虚拟对象的旋转。
ps我发现了一个类似的问题,但提出这个问题的人没有清楚地发布解决方案。
谢谢!
c# opencv unity-game-engine augmented-reality pose-estimation