gpt4 book ai didi

安卓和 OpenCV : Homography to Camera Pose considering Camera Intrinsics and Backprojection

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:16:28 24 4
gpt4 key购买 nike

库:OpenCV目标:Android (OpenCV4Android)

我尝试计算世界平面(例如监视器屏幕)的单应性以获得相机姿势,对其进行变换并将点重新投影回以用于跟踪任务。我正在使用 OpenCVs findHomography()/getPerspectiveTransform() 来获得单应性。使用 perspectiveTransform() 对点进行重新投影(如此处解释:http://docs.opencv.org/doc/tutorials/features2d/feature_homography/feature_homography.html)效果很好。 “screenPoints”是显示器边缘的世界坐标(使用宽高比和 0 的 z 值),“imagePoints”是图像中屏幕边缘的 x/y 坐标。

Mat homography = org.opencv.imgproc.Imgproc.getPerspectiveTransform(screenPoints, imagePoints);

我有相机校准矩阵(我使用了 matlab 校准工具箱)并且我发现了一个提示(在评论@ https://dsp.stackexchange.com/questions/2736/step-by-step-camera-pose-estimation-for-visual-tracking-and-planar-markers 中)考虑单应性中的相机参数。

H' = K^-1 * H

(H' - 考虑相机校准的单应矩阵,H - 单应矩阵,K^-1 - 逆相机校准矩阵)。

Mat intrinsicInverse = new Mat(3, 3, CvType.CV_32FC1);
Core.invert(intrinsic, intrinsicInverse);
intrinsicInverse.convertTo(intrinsicInverse, CvType.CV_32FC1);
homography.convertTo(homography, CvType.CV_32FC1);
// compute H respect the intrinsics
Core.gemm(intrinsicInverse, homography, 1, new Mat(), 0, homography);

我的下一步是根据此处描述的单应性计算相机位姿 Computing camera pose with homography matrix based on 4 coplanar points .

因为我试图在 Android 上执行此操作,所以我不得不将 C++ 代码移植到 Java:

private Mat cameraPoseFromHomography(Mat h) {
Log.d("DEBUG", "cameraPoseFromHomography: homography " + matToString(h));

Mat pose = Mat.eye(3, 4, CvType.CV_32FC1); // 3x4 matrix, the camera pose
float norm1 = (float) Core.norm(h.col(0));
float norm2 = (float) Core.norm(h.col(1));
float tnorm = (norm1 + norm2) / 2.0f; // Normalization value

Mat normalizedTemp = new Mat();
Core.normalize(h.col(0), normalizedTemp);
normalizedTemp.convertTo(normalizedTemp, CvType.CV_32FC1);
normalizedTemp.copyTo(pose.col(0));

Core.normalize(h.col(1), normalizedTemp);
normalizedTemp.convertTo(normalizedTemp, CvType.CV_32FC1);
normalizedTemp.copyTo(pose.col(1));

Mat p3 = pose.col(0).cross(pose.col(1));
p3.copyTo(pose.col(2));

Mat temp = h.col(2);
double[] buffer = new double[3];
h.col(2).get(0, 0, buffer);
pose.put(0, 3, buffer[0] / tnorm);
pose.put(1, 3, buffer[1] / tnorm);
pose.put(2, 3, buffer[2] / tnorm);

return pose;
}

我无法检查代码是否在做正确的事情,但它正在运行。在这一点上,考虑到相机校准,我假设有完整的相机姿势。

如此处所述http://opencv.willowgarage.com/documentation/python/calib3d_camera_calibration_and_3d_reconstruction.html#rodrigues2 , 3D 点的重投影就是

p = K * CP * P

(p - 2D 位置,K - 校准矩阵,CP - 相机位姿,P - 3D 点)

    Core.gemm(intrinsic, cameraPosition, 1, new Mat(), 0, vec4t);
Core.gemm(vec4t, point, 1, new Mat(), 0, result);

结果远离屏幕边缘的源图像位置。但我可以通过其相对差异来识别所有三个边缘 - 所以它可能只是一些错误的因素。

这是我第一次做这样的计算机视觉任务,我可能做错了一些基本错误。我有 Zisserman 的“多 View 几何”一书,我阅读了所有相关部分 - 但老实说 - 我没有读懂其中的大部分内容。

更新:

在我的相机矩阵中发现了一个错误 - 上面的实现工作正常!

最佳答案

让它以另一种方式工作。而不是使用 findHomography()/getPerspectiveTransform() 我发现了另一个名为 solvePnP() 的函数,它返回基于世界和图像点以及固有相机矩阵的相机姿势。

将该函数与 projectPoints() 方法结合使用 - 我能够将 3d 点重新投影回图像。

如果屏幕边缘位于图像的正确位置。

更新:

我在我的实现中发现了一个错误——我的相机内在矩阵是错误的。上面单应性实现的相机姿势对我有用!

关于安卓和 OpenCV : Homography to Camera Pose considering Camera Intrinsics and Backprojection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17027277/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com