用于 OpenCV 的 Iphone 6 相机校准

Posted

技术标签:

【中文标题】用于 OpenCV 的 Iphone 6 相机校准【英文标题】:Iphone 6 camera calibration for OpenCV 【发布时间】:2016-04-30 00:50:27 【问题描述】:

我正在使用 OpenCV 开发 ios 增强现实应用程序。我在创建相机投影矩阵以允许 OpenGL 覆盖直接映射到标记顶部时遇到问题。我觉得这是由于我的 iPhone 6 相机没有正确校准到应用程序。我知道有 OpenCV 代码可以使用棋盘校准网络摄像头等,但我找不到校准嵌入式 iPhone 摄像头的方法。

有办法吗?或者是否有已知的 iPhone 6 估计值?其中包括:x和y的焦距,x和y的主点,以及畸变系数矩阵。

任何帮助将不胜感激。

编辑:

推导值如下(使用iPhone 6,摄像头分辨率1280x720):

fx=1229
cx=360
fy=1153
cy=640

此代码为当前运行 iOS 9.1 的设备提供焦距和主要点的准确估计。

AVCaptureDeviceFormat *format = deviceInput.device.activeFormat;
CMFormatDescriptionRef fDesc = format.formatDescription;
CGSize dim = CMVideoFormatDescriptionGetPresentationDimensions(fDesc, true, true);

float cx = float(dim.width) / 2.0;
float cy = float(dim.height) / 2.0;

float HFOV = format.videoFieldOfView;
float VFOV = ((HFOV)/cx)*cy;

float fx = abs(float(dim.width) / (2 * tan(HFOV / 180 * float(M_PI) / 2)));
float fy = abs(float(dim.height) / (2 * tan(VFOV / 180 * float(M_PI) / 2)));

注意:

我在使用此代码时遇到了初始化问题。我建议在初始化并正确设置值后,将它们保存到数据文件中并读取该文件以获取值。

【问题讨论】:

非常感谢。 我认为在 eqn 2* tan... 中,2 是错误的。按照这个:codeyarns.com/2015/09/08/… 和我的实验。 【参考方案1】:

在我的非 OpenCV AR 应用程序中,我使用 iPhone 摄像头的视野 (FOV) 来构建摄像头投影矩阵。它可以很好地显示覆盖在相机视图顶部的太阳路径。 不知道你需要多少精度。可能只知道 FOV 是不够的。

iOS API 提供了一种获取相机视野的方法。我是这样理解的:

AVCaptureDevice  * camera = ...
AVCaptureDeviceFormat * format = camera.activeFormat;
float fieldOfView = format.videoFieldOfView;

得到 FOV 后,我计算投影矩阵:

typedef double mat4f_t[16]; // 4x4 matrix in column major order    

mat4f_t projection;
createProjectionMatrix(projection,
                       GRAD_TO_RAD(fieldOfView),
                       viewSize.width/viewSize.height,
                       5.0f,
                       1000.0f);

在哪里

void createProjectionMatrix(
        mat4f_t mout, 
        float fovy,
        float aspect, 
        float zNear,
        float zFar)

    float f = 1.0f / tanf(fovy/2.0f);

    mout[0] = f / aspect;
    mout[1] = 0.0f;
    mout[2] = 0.0f;
    mout[3] = 0.0f;

    mout[4] = 0.0f;
    mout[5] = f;
    mout[6] = 0.0f;
    mout[7] = 0.0f;

    mout[8] = 0.0f;
    mout[9] = 0.0f;
    mout[10] = (zFar+zNear) / (zNear-zFar);
    mout[11] = -1.0f;

    mout[12] = 0.0f;
    mout[13] = 0.0f;
    mout[14] = 2 * zFar * zNear /  (zNear-zFar);
    mout[15] = 0.0f;

【讨论】:

不幸的是,校准不是我的 AR 应用程序的主要问题,所以感谢您提供创建相机投影矩阵的方法;但我还没有找到主要的错误。 @User1994 没问题...也许其他人会发现这个答案很有用..就像找到你的“主要错误”一样好:) 原来这是我的校准问题。在我注意到这个问题之后,调整你提供给我的代码是一种享受。在调试时,很明显,第一次调用此代码的封闭方法时,某些变量未初始化并将校准设置为不正确的值。在第二次迭代中,这些值现在被初始化并返回了正确的值。这些代表 fx、fy、cx 和 cy 现在已被记录并放置在数据文件中以解决问题。感谢您的帮助。

以上是关于用于 OpenCV 的 Iphone 6 相机校准的主要内容,如果未能解决你的问题,请参考以下文章

在线校准相机中校准相机时出现 OpenCV 运行时错误

在 ios7 xcode 中设置相机焦点。 opencv

如何在 Leap Motion 上检测用于相机校准的棋盘?

相机校准 OpenCV 相机作为输入

OpenCV 2.3 相机校准

OpenCV 相机校准