适用于OpenCV的iPhone 6相机校准

Use*_*710 4 opencv computer-vision augmented-reality ios iphone-6

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

有办法吗?还是有iPhone 6的已知估算值?其中包括:x和y的焦距,x和y的原点以及失真系数矩阵。

任何帮助将不胜感激。

编辑:

推导值如下(使用iPhone 6,相机Feed分辨率为1280x720):

fx=1229
cx=360
fy=1153
cy=640
Run Code Online (Sandbox Code Playgroud)

该代码可准确估算当前运行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)));
Run Code Online (Sandbox Code Playgroud)

注意:

我有此代码的初始化问题。我建议对值进行初始化和正确设置后,将其保存到数据文件中并在其中读取该文件以获取值。

小智 5

在我的非OpenCV AR应用程序中,我使用iPhone相机的视场(FOV)来构建相机投影矩阵。它可以正常显示覆盖摄像机视图顶部的太阳路径。我不知道您需要多少精度。可能仅了解FOV并不能满足您的需求。

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

AVCaptureDevice  * camera = ...
AVCaptureDeviceFormat * format = camera.activeFormat;
float fieldOfView = format.videoFieldOfView;
Run Code Online (Sandbox Code Playgroud)

得到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);
Run Code Online (Sandbox Code Playgroud)

哪里

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;
}
Run Code Online (Sandbox Code Playgroud)